OSDN Git Service

12470eae14e651f9b7974507a99260cba4fb53c9
[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 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
63
64 ;; UNSPEC usage:
65
66 (define_c_enum "unspec" [
67   ;; Relocation specifiers
68   UNSPEC_GOT
69   UNSPEC_GOTOFF
70   UNSPEC_GOTPCREL
71   UNSPEC_GOTTPOFF
72   UNSPEC_TPOFF
73   UNSPEC_NTPOFF
74   UNSPEC_DTPOFF
75   UNSPEC_GOTNTPOFF
76   UNSPEC_INDNTPOFF
77   UNSPEC_PLTOFF
78   UNSPEC_MACHOPIC_OFFSET
79   UNSPEC_PCREL
80
81   ;; Prologue support
82   UNSPEC_STACK_ALLOC
83   UNSPEC_SET_GOT
84   UNSPEC_REG_SAVE
85   UNSPEC_DEF_CFA
86   UNSPEC_SET_RIP
87   UNSPEC_SET_GOT_OFFSET
88   UNSPEC_MEMORY_BLOCKAGE
89   UNSPEC_STACK_CHECK
90
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
97
98   ;; Other random patterns
99   UNSPEC_SCAS
100   UNSPEC_FNSTSW
101   UNSPEC_SAHF
102   UNSPEC_PARITY
103   UNSPEC_FSTCW
104   UNSPEC_ADD_CARRY
105   UNSPEC_FLDCW
106   UNSPEC_REP
107   UNSPEC_LD_MPIC        ; load_macho_picbase
108   UNSPEC_TRUNC_NOOP
109   UNSPEC_DIV_ALREADY_SPLIT
110   UNSPEC_CALL_NEEDS_VZEROUPPER
111
112   ;; For SSE/MMX support:
113   UNSPEC_FIX_NOTRUNC
114   UNSPEC_MASKMOV
115   UNSPEC_MOVMSK
116   UNSPEC_MOVNT
117   UNSPEC_MOVU
118   UNSPEC_RCP
119   UNSPEC_RSQRT
120   UNSPEC_SFENCE
121   UNSPEC_PFRCP
122   UNSPEC_PFRCPIT1
123   UNSPEC_PFRCPIT2
124   UNSPEC_PFRSQRT
125   UNSPEC_PFRSQIT1
126   UNSPEC_MFENCE
127   UNSPEC_LFENCE
128   UNSPEC_PSADBW
129   UNSPEC_LDDQU
130   UNSPEC_MS_TO_SYSV_CALL
131
132   ;; Generic math support
133   UNSPEC_COPYSIGN
134   UNSPEC_IEEE_MIN       ; not commutative
135   UNSPEC_IEEE_MAX       ; not commutative
136
137   ;; x87 Floating point
138   UNSPEC_SIN
139   UNSPEC_COS
140   UNSPEC_FPATAN
141   UNSPEC_FYL2X
142   UNSPEC_FYL2XP1
143   UNSPEC_FRNDINT
144   UNSPEC_FIST
145   UNSPEC_F2XM1
146   UNSPEC_TAN
147   UNSPEC_FXAM
148
149   ;; x87 Rounding
150   UNSPEC_FRNDINT_FLOOR
151   UNSPEC_FRNDINT_CEIL
152   UNSPEC_FRNDINT_TRUNC
153   UNSPEC_FRNDINT_MASK_PM
154   UNSPEC_FIST_FLOOR
155   UNSPEC_FIST_CEIL
156
157   ;; x87 Double output FP
158   UNSPEC_SINCOS_COS
159   UNSPEC_SINCOS_SIN
160   UNSPEC_XTRACT_FRACT
161   UNSPEC_XTRACT_EXP
162   UNSPEC_FSCALE_FRACT
163   UNSPEC_FSCALE_EXP
164   UNSPEC_FPREM_F
165   UNSPEC_FPREM_U
166   UNSPEC_FPREM1_F
167   UNSPEC_FPREM1_U
168
169   UNSPEC_C2_FLAG
170   UNSPEC_FXAM_MEM
171
172   ;; SSP patterns
173   UNSPEC_SP_SET
174   UNSPEC_SP_TEST
175   UNSPEC_SP_TLS_SET
176   UNSPEC_SP_TLS_TEST
177
178   ;; SSSE3
179   UNSPEC_PSHUFB
180   UNSPEC_PSIGN
181   UNSPEC_PALIGNR
182
183   ;; For SSE4A support
184   UNSPEC_EXTRQI
185   UNSPEC_EXTRQ
186   UNSPEC_INSERTQI
187   UNSPEC_INSERTQ
188
189   ;; For SSE4.1 support
190   UNSPEC_BLENDV
191   UNSPEC_INSERTPS
192   UNSPEC_DP
193   UNSPEC_MOVNTDQA
194   UNSPEC_MPSADBW
195   UNSPEC_PHMINPOSUW
196   UNSPEC_PTEST
197   UNSPEC_ROUND
198
199   ;; For SSE4.2 support
200   UNSPEC_CRC32
201   UNSPEC_PCMPESTR
202   UNSPEC_PCMPISTR
203
204   ;; For FMA4 support
205   UNSPEC_FMADDSUB
206   UNSPEC_XOP_UNSIGNED_CMP
207   UNSPEC_XOP_TRUEFALSE
208   UNSPEC_XOP_PERMUTE
209   UNSPEC_FRCZ
210
211   ;; For AES support
212   UNSPEC_AESENC
213   UNSPEC_AESENCLAST
214   UNSPEC_AESDEC
215   UNSPEC_AESDECLAST
216   UNSPEC_AESIMC
217   UNSPEC_AESKEYGENASSIST
218
219   ;; For PCLMUL support
220   UNSPEC_PCLMUL
221
222   ;; For AVX support
223   UNSPEC_PCMP
224   UNSPEC_VPERMIL
225   UNSPEC_VPERMIL2
226   UNSPEC_VPERMIL2F128
227   UNSPEC_MASKLOAD
228   UNSPEC_MASKSTORE
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,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,1)")
420          (eq_attr "type" "imov,test")
421            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
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, 1, 1)")
530       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
531     (if_then_else (eq_attr "prefix_vex_w" "1")
532       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
533       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
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 ;; Describe a user's asm statement.
702 (define_asm_attributes
703   [(set_attr "length" "128")
704    (set_attr "type" "multi")])
705
706 (define_code_iterator plusminus [plus minus])
707
708 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
709
710 ;; Base name for define_insn
711 (define_code_attr plusminus_insn
712   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
713    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
714
715 ;; Base name for insn mnemonic.
716 (define_code_attr plusminus_mnemonic
717   [(plus "add") (ss_plus "adds") (us_plus "addus")
718    (minus "sub") (ss_minus "subs") (us_minus "subus")])
719 (define_code_attr plusminus_carry_mnemonic
720   [(plus "adc") (minus "sbb")])
721
722 ;; Mark commutative operators as such in constraints.
723 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
724                         (minus "") (ss_minus "") (us_minus "")])
725
726 ;; Mapping of signed max and min
727 (define_code_iterator smaxmin [smax smin])
728
729 ;; Mapping of unsigned max and min
730 (define_code_iterator umaxmin [umax umin])
731
732 ;; Base name for integer and FP insn mnemonic
733 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
734                               (umax "maxu") (umin "minu")])
735 (define_code_attr maxmin_float [(smax "max") (smin "min")])
736
737 ;; Mapping of logic operators
738 (define_code_iterator any_logic [and ior xor])
739 (define_code_iterator any_or [ior xor])
740
741 ;; Base name for insn mnemonic.
742 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
743
744 ;; Mapping of shift-right operators
745 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
746
747 ;; Base name for define_insn
748 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
749
750 ;; Base name for insn mnemonic.
751 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
752
753 ;; Mapping of rotate operators
754 (define_code_iterator any_rotate [rotate rotatert])
755
756 ;; Base name for define_insn
757 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
758
759 ;; Base name for insn mnemonic.
760 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
761
762 ;; Mapping of abs neg operators
763 (define_code_iterator absneg [abs neg])
764
765 ;; Base name for x87 insn mnemonic.
766 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
767
768 ;; Used in signed and unsigned widening multiplications.
769 (define_code_iterator any_extend [sign_extend zero_extend])
770
771 ;; Various insn prefixes for signed and unsigned operations.
772 (define_code_attr u [(sign_extend "") (zero_extend "u")
773                      (div "") (udiv "u")])
774 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
775
776 ;; Used in signed and unsigned divisions.
777 (define_code_iterator any_div [div udiv])
778
779 ;; Instruction prefix for signed and unsigned operations.
780 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
781                              (div "i") (udiv "")])
782
783 ;; 64bit single word integer modes.
784 (define_mode_iterator SWI1248x [QI HI SI DI])
785
786 ;; 64bit single word integer modes without QImode and HImode.
787 (define_mode_iterator SWI48x [SI DI])
788
789 ;; Single word integer modes.
790 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
791
792 ;; Single word integer modes without SImode and DImode.
793 (define_mode_iterator SWI12 [QI HI])
794
795 ;; Single word integer modes without DImode.
796 (define_mode_iterator SWI124 [QI HI SI])
797
798 ;; Single word integer modes without QImode and DImode.
799 (define_mode_iterator SWI24 [HI SI])
800
801 ;; Single word integer modes without QImode.
802 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
803
804 ;; Single word integer modes without QImode and HImode.
805 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
806
807 ;; All math-dependant single and double word integer modes.
808 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
809                              (HI "TARGET_HIMODE_MATH")
810                              SI DI (TI "TARGET_64BIT")])
811
812 ;; Math-dependant single word integer modes.
813 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
814                             (HI "TARGET_HIMODE_MATH")
815                             SI (DI "TARGET_64BIT")])
816
817 ;; Math-dependant single word integer modes without DImode.
818 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
819                                (HI "TARGET_HIMODE_MATH")
820                                SI])
821
822 ;; Math-dependant single word integer modes without QImode.
823 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
824                                SI (DI "TARGET_64BIT")])
825
826 ;; Double word integer modes.
827 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
828                            (TI "TARGET_64BIT")])
829
830 ;; Double word integer modes as mode attribute.
831 (define_mode_attr DWI [(SI "DI") (DI "TI")])
832 (define_mode_attr dwi [(SI "di") (DI "ti")])
833
834 ;; Half mode for double word integer modes.
835 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
836                             (DI "TARGET_64BIT")])
837
838 ;; Instruction suffix for integer modes.
839 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
840
841 ;; Pointer size prefix for integer modes (Intel asm dialect)
842 (define_mode_attr iptrsize [(QI "BYTE")
843                             (HI "WORD")
844                             (SI "DWORD")
845                             (DI "QWORD")])
846
847 ;; Register class for integer modes.
848 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
849
850 ;; Immediate operand constraint for integer modes.
851 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
852
853 ;; General operand constraint for word modes.
854 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
855
856 ;; Immediate operand constraint for double integer modes.
857 (define_mode_attr di [(SI "iF") (DI "e")])
858
859 ;; Immediate operand constraint for shifts.
860 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
861
862 ;; General operand predicate for integer modes.
863 (define_mode_attr general_operand
864         [(QI "general_operand")
865          (HI "general_operand")
866          (SI "general_operand")
867          (DI "x86_64_general_operand")
868          (TI "x86_64_general_operand")])
869
870 ;; General sign/zero extend operand predicate for integer modes.
871 (define_mode_attr general_szext_operand
872         [(QI "general_operand")
873          (HI "general_operand")
874          (SI "general_operand")
875          (DI "x86_64_szext_general_operand")])
876
877 ;; Immediate operand predicate for integer modes.
878 (define_mode_attr immediate_operand
879         [(QI "immediate_operand")
880          (HI "immediate_operand")
881          (SI "immediate_operand")
882          (DI "x86_64_immediate_operand")])
883
884 ;; Nonmemory operand predicate for integer modes.
885 (define_mode_attr nonmemory_operand
886         [(QI "nonmemory_operand")
887          (HI "nonmemory_operand")
888          (SI "nonmemory_operand")
889          (DI "x86_64_nonmemory_operand")])
890
891 ;; Operand predicate for shifts.
892 (define_mode_attr shift_operand
893         [(QI "nonimmediate_operand")
894          (HI "nonimmediate_operand")
895          (SI "nonimmediate_operand")
896          (DI "shiftdi_operand")
897          (TI "register_operand")])
898
899 ;; Operand predicate for shift argument.
900 (define_mode_attr shift_immediate_operand
901         [(QI "const_1_to_31_operand")
902          (HI "const_1_to_31_operand")
903          (SI "const_1_to_31_operand")
904          (DI "const_1_to_63_operand")])
905
906 ;; Input operand predicate for arithmetic left shifts.
907 (define_mode_attr ashl_input_operand
908         [(QI "nonimmediate_operand")
909          (HI "nonimmediate_operand")
910          (SI "nonimmediate_operand")
911          (DI "ashldi_input_operand")
912          (TI "reg_or_pm1_operand")])
913
914 ;; SSE and x87 SFmode and DFmode floating point modes
915 (define_mode_iterator MODEF [SF DF])
916
917 ;; All x87 floating point modes
918 (define_mode_iterator X87MODEF [SF DF XF])
919
920 ;; All integer modes handled by x87 fisttp operator.
921 (define_mode_iterator X87MODEI [HI SI DI])
922
923 ;; All integer modes handled by integer x87 operators.
924 (define_mode_iterator X87MODEI12 [HI SI])
925
926 ;; All integer modes handled by SSE cvtts?2si* operators.
927 (define_mode_iterator SSEMODEI24 [SI DI])
928
929 ;; SSE asm suffix for floating point modes
930 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
931
932 ;; SSE vector mode corresponding to a scalar mode
933 (define_mode_attr ssevecmode
934   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
935
936 ;; Instruction suffix for REX 64bit operators.
937 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
938
939 ;; This mode iterator allows :P to be used for patterns that operate on
940 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
941 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
942 \f
943 ;; Scheduling descriptions
944
945 (include "pentium.md")
946 (include "ppro.md")
947 (include "k6.md")
948 (include "athlon.md")
949 (include "bdver1.md")
950 (include "geode.md")
951 (include "atom.md")
952 (include "core2.md")
953
954 \f
955 ;; Operand and operator predicates and constraints
956
957 (include "predicates.md")
958 (include "constraints.md")
959
960 \f
961 ;; Compare and branch/compare and store instructions.
962
963 (define_expand "cbranch<mode>4"
964   [(set (reg:CC FLAGS_REG)
965         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
966                     (match_operand:SDWIM 2 "<general_operand>" "")))
967    (set (pc) (if_then_else
968                (match_operator 0 "ordered_comparison_operator"
969                 [(reg:CC FLAGS_REG) (const_int 0)])
970                (label_ref (match_operand 3 "" ""))
971                (pc)))]
972   ""
973 {
974   if (MEM_P (operands[1]) && MEM_P (operands[2]))
975     operands[1] = force_reg (<MODE>mode, operands[1]);
976   ix86_expand_branch (GET_CODE (operands[0]),
977                       operands[1], operands[2], operands[3]);
978   DONE;
979 })
980
981 (define_expand "cstore<mode>4"
982   [(set (reg:CC FLAGS_REG)
983         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
984                     (match_operand:SWIM 3 "<general_operand>" "")))
985    (set (match_operand:QI 0 "register_operand" "")
986         (match_operator 1 "ordered_comparison_operator"
987           [(reg:CC FLAGS_REG) (const_int 0)]))]
988   ""
989 {
990   if (MEM_P (operands[2]) && MEM_P (operands[3]))
991     operands[2] = force_reg (<MODE>mode, operands[2]);
992   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
993                      operands[2], operands[3]);
994   DONE;
995 })
996
997 (define_expand "cmp<mode>_1"
998   [(set (reg:CC FLAGS_REG)
999         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1000                     (match_operand:SWI48 1 "<general_operand>" "")))])
1001
1002 (define_insn "*cmp<mode>_ccno_1"
1003   [(set (reg FLAGS_REG)
1004         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1005                  (match_operand:SWI 1 "const0_operand" "")))]
1006   "ix86_match_ccmode (insn, CCNOmode)"
1007   "@
1008    test{<imodesuffix>}\t%0, %0
1009    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1010   [(set_attr "type" "test,icmp")
1011    (set_attr "length_immediate" "0,1")
1012    (set_attr "mode" "<MODE>")])
1013
1014 (define_insn "*cmp<mode>_1"
1015   [(set (reg FLAGS_REG)
1016         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1017                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1018   "ix86_match_ccmode (insn, CCmode)"
1019   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1020   [(set_attr "type" "icmp")
1021    (set_attr "mode" "<MODE>")])
1022
1023 (define_insn "*cmp<mode>_minus_1"
1024   [(set (reg FLAGS_REG)
1025         (compare
1026           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1027                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1028           (const_int 0)))]
1029   "ix86_match_ccmode (insn, CCGOCmode)"
1030   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1031   [(set_attr "type" "icmp")
1032    (set_attr "mode" "<MODE>")])
1033
1034 (define_insn "*cmpqi_ext_1"
1035   [(set (reg FLAGS_REG)
1036         (compare
1037           (match_operand:QI 0 "general_operand" "Qm")
1038           (subreg:QI
1039             (zero_extract:SI
1040               (match_operand 1 "ext_register_operand" "Q")
1041               (const_int 8)
1042               (const_int 8)) 0)))]
1043   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1044   "cmp{b}\t{%h1, %0|%0, %h1}"
1045   [(set_attr "type" "icmp")
1046    (set_attr "mode" "QI")])
1047
1048 (define_insn "*cmpqi_ext_1_rex64"
1049   [(set (reg FLAGS_REG)
1050         (compare
1051           (match_operand:QI 0 "register_operand" "Q")
1052           (subreg:QI
1053             (zero_extract:SI
1054               (match_operand 1 "ext_register_operand" "Q")
1055               (const_int 8)
1056               (const_int 8)) 0)))]
1057   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1058   "cmp{b}\t{%h1, %0|%0, %h1}"
1059   [(set_attr "type" "icmp")
1060    (set_attr "mode" "QI")])
1061
1062 (define_insn "*cmpqi_ext_2"
1063   [(set (reg FLAGS_REG)
1064         (compare
1065           (subreg:QI
1066             (zero_extract:SI
1067               (match_operand 0 "ext_register_operand" "Q")
1068               (const_int 8)
1069               (const_int 8)) 0)
1070           (match_operand:QI 1 "const0_operand" "")))]
1071   "ix86_match_ccmode (insn, CCNOmode)"
1072   "test{b}\t%h0, %h0"
1073   [(set_attr "type" "test")
1074    (set_attr "length_immediate" "0")
1075    (set_attr "mode" "QI")])
1076
1077 (define_expand "cmpqi_ext_3"
1078   [(set (reg:CC FLAGS_REG)
1079         (compare:CC
1080           (subreg:QI
1081             (zero_extract:SI
1082               (match_operand 0 "ext_register_operand" "")
1083               (const_int 8)
1084               (const_int 8)) 0)
1085           (match_operand:QI 1 "immediate_operand" "")))])
1086
1087 (define_insn "*cmpqi_ext_3_insn"
1088   [(set (reg FLAGS_REG)
1089         (compare
1090           (subreg:QI
1091             (zero_extract:SI
1092               (match_operand 0 "ext_register_operand" "Q")
1093               (const_int 8)
1094               (const_int 8)) 0)
1095           (match_operand:QI 1 "general_operand" "Qmn")))]
1096   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1097   "cmp{b}\t{%1, %h0|%h0, %1}"
1098   [(set_attr "type" "icmp")
1099    (set_attr "modrm" "1")
1100    (set_attr "mode" "QI")])
1101
1102 (define_insn "*cmpqi_ext_3_insn_rex64"
1103   [(set (reg FLAGS_REG)
1104         (compare
1105           (subreg:QI
1106             (zero_extract:SI
1107               (match_operand 0 "ext_register_operand" "Q")
1108               (const_int 8)
1109               (const_int 8)) 0)
1110           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1111   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1112   "cmp{b}\t{%1, %h0|%h0, %1}"
1113   [(set_attr "type" "icmp")
1114    (set_attr "modrm" "1")
1115    (set_attr "mode" "QI")])
1116
1117 (define_insn "*cmpqi_ext_4"
1118   [(set (reg FLAGS_REG)
1119         (compare
1120           (subreg:QI
1121             (zero_extract:SI
1122               (match_operand 0 "ext_register_operand" "Q")
1123               (const_int 8)
1124               (const_int 8)) 0)
1125           (subreg:QI
1126             (zero_extract:SI
1127               (match_operand 1 "ext_register_operand" "Q")
1128               (const_int 8)
1129               (const_int 8)) 0)))]
1130   "ix86_match_ccmode (insn, CCmode)"
1131   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1132   [(set_attr "type" "icmp")
1133    (set_attr "mode" "QI")])
1134
1135 ;; These implement float point compares.
1136 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1137 ;; which would allow mix and match FP modes on the compares.  Which is what
1138 ;; the old patterns did, but with many more of them.
1139
1140 (define_expand "cbranchxf4"
1141   [(set (reg:CC FLAGS_REG)
1142         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1143                     (match_operand:XF 2 "nonmemory_operand" "")))
1144    (set (pc) (if_then_else
1145               (match_operator 0 "ix86_fp_comparison_operator"
1146                [(reg:CC FLAGS_REG)
1147                 (const_int 0)])
1148               (label_ref (match_operand 3 "" ""))
1149               (pc)))]
1150   "TARGET_80387"
1151 {
1152   ix86_expand_branch (GET_CODE (operands[0]),
1153                       operands[1], operands[2], operands[3]);
1154   DONE;
1155 })
1156
1157 (define_expand "cstorexf4"
1158   [(set (reg:CC FLAGS_REG)
1159         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1160                     (match_operand:XF 3 "nonmemory_operand" "")))
1161    (set (match_operand:QI 0 "register_operand" "")
1162               (match_operator 1 "ix86_fp_comparison_operator"
1163                [(reg:CC FLAGS_REG)
1164                 (const_int 0)]))]
1165   "TARGET_80387"
1166 {
1167   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1168                      operands[2], operands[3]);
1169   DONE;
1170 })
1171
1172 (define_expand "cbranch<mode>4"
1173   [(set (reg:CC FLAGS_REG)
1174         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1175                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1176    (set (pc) (if_then_else
1177               (match_operator 0 "ix86_fp_comparison_operator"
1178                [(reg:CC FLAGS_REG)
1179                 (const_int 0)])
1180               (label_ref (match_operand 3 "" ""))
1181               (pc)))]
1182   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1183 {
1184   ix86_expand_branch (GET_CODE (operands[0]),
1185                       operands[1], operands[2], operands[3]);
1186   DONE;
1187 })
1188
1189 (define_expand "cstore<mode>4"
1190   [(set (reg:CC FLAGS_REG)
1191         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1192                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1193    (set (match_operand:QI 0 "register_operand" "")
1194               (match_operator 1 "ix86_fp_comparison_operator"
1195                [(reg:CC FLAGS_REG)
1196                 (const_int 0)]))]
1197   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1198 {
1199   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1200                      operands[2], operands[3]);
1201   DONE;
1202 })
1203
1204 (define_expand "cbranchcc4"
1205   [(set (pc) (if_then_else
1206               (match_operator 0 "comparison_operator"
1207                [(match_operand 1 "flags_reg_operand" "")
1208                 (match_operand 2 "const0_operand" "")])
1209               (label_ref (match_operand 3 "" ""))
1210               (pc)))]
1211   ""
1212 {
1213   ix86_expand_branch (GET_CODE (operands[0]),
1214                       operands[1], operands[2], operands[3]);
1215   DONE;
1216 })
1217
1218 (define_expand "cstorecc4"
1219   [(set (match_operand:QI 0 "register_operand" "")
1220               (match_operator 1 "comparison_operator"
1221                [(match_operand 2 "flags_reg_operand" "")
1222                 (match_operand 3 "const0_operand" "")]))]
1223   ""
1224 {
1225   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1226                      operands[2], operands[3]);
1227   DONE;
1228 })
1229
1230
1231 ;; FP compares, step 1:
1232 ;; Set the FP condition codes.
1233 ;;
1234 ;; CCFPmode     compare with exceptions
1235 ;; CCFPUmode    compare with no exceptions
1236
1237 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1238 ;; used to manage the reg stack popping would not be preserved.
1239
1240 (define_insn "*cmpfp_0"
1241   [(set (match_operand:HI 0 "register_operand" "=a")
1242         (unspec:HI
1243           [(compare:CCFP
1244              (match_operand 1 "register_operand" "f")
1245              (match_operand 2 "const0_operand" ""))]
1246         UNSPEC_FNSTSW))]
1247   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1248    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1249   "* return output_fp_compare (insn, operands, 0, 0);"
1250   [(set_attr "type" "multi")
1251    (set_attr "unit" "i387")
1252    (set (attr "mode")
1253      (cond [(match_operand:SF 1 "" "")
1254               (const_string "SF")
1255             (match_operand:DF 1 "" "")
1256               (const_string "DF")
1257            ]
1258            (const_string "XF")))])
1259
1260 (define_insn_and_split "*cmpfp_0_cc"
1261   [(set (reg:CCFP FLAGS_REG)
1262         (compare:CCFP
1263           (match_operand 1 "register_operand" "f")
1264           (match_operand 2 "const0_operand" "")))
1265    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1266   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1267    && TARGET_SAHF && !TARGET_CMOVE
1268    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1269   "#"
1270   "&& reload_completed"
1271   [(set (match_dup 0)
1272         (unspec:HI
1273           [(compare:CCFP (match_dup 1)(match_dup 2))]
1274         UNSPEC_FNSTSW))
1275    (set (reg:CC FLAGS_REG)
1276         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1277   ""
1278   [(set_attr "type" "multi")
1279    (set_attr "unit" "i387")
1280    (set (attr "mode")
1281      (cond [(match_operand:SF 1 "" "")
1282               (const_string "SF")
1283             (match_operand:DF 1 "" "")
1284               (const_string "DF")
1285            ]
1286            (const_string "XF")))])
1287
1288 (define_insn "*cmpfp_xf"
1289   [(set (match_operand:HI 0 "register_operand" "=a")
1290         (unspec:HI
1291           [(compare:CCFP
1292              (match_operand:XF 1 "register_operand" "f")
1293              (match_operand:XF 2 "register_operand" "f"))]
1294           UNSPEC_FNSTSW))]
1295   "TARGET_80387"
1296   "* return output_fp_compare (insn, operands, 0, 0);"
1297   [(set_attr "type" "multi")
1298    (set_attr "unit" "i387")
1299    (set_attr "mode" "XF")])
1300
1301 (define_insn_and_split "*cmpfp_xf_cc"
1302   [(set (reg:CCFP FLAGS_REG)
1303         (compare:CCFP
1304           (match_operand:XF 1 "register_operand" "f")
1305           (match_operand:XF 2 "register_operand" "f")))
1306    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1307   "TARGET_80387
1308    && TARGET_SAHF && !TARGET_CMOVE"
1309   "#"
1310   "&& reload_completed"
1311   [(set (match_dup 0)
1312         (unspec:HI
1313           [(compare:CCFP (match_dup 1)(match_dup 2))]
1314         UNSPEC_FNSTSW))
1315    (set (reg:CC FLAGS_REG)
1316         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1317   ""
1318   [(set_attr "type" "multi")
1319    (set_attr "unit" "i387")
1320    (set_attr "mode" "XF")])
1321
1322 (define_insn "*cmpfp_<mode>"
1323   [(set (match_operand:HI 0 "register_operand" "=a")
1324         (unspec:HI
1325           [(compare:CCFP
1326              (match_operand:MODEF 1 "register_operand" "f")
1327              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1328           UNSPEC_FNSTSW))]
1329   "TARGET_80387"
1330   "* return output_fp_compare (insn, operands, 0, 0);"
1331   [(set_attr "type" "multi")
1332    (set_attr "unit" "i387")
1333    (set_attr "mode" "<MODE>")])
1334
1335 (define_insn_and_split "*cmpfp_<mode>_cc"
1336   [(set (reg:CCFP FLAGS_REG)
1337         (compare:CCFP
1338           (match_operand:MODEF 1 "register_operand" "f")
1339           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1340    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1341   "TARGET_80387
1342    && TARGET_SAHF && !TARGET_CMOVE"
1343   "#"
1344   "&& reload_completed"
1345   [(set (match_dup 0)
1346         (unspec:HI
1347           [(compare:CCFP (match_dup 1)(match_dup 2))]
1348         UNSPEC_FNSTSW))
1349    (set (reg:CC FLAGS_REG)
1350         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351   ""
1352   [(set_attr "type" "multi")
1353    (set_attr "unit" "i387")
1354    (set_attr "mode" "<MODE>")])
1355
1356 (define_insn "*cmpfp_u"
1357   [(set (match_operand:HI 0 "register_operand" "=a")
1358         (unspec:HI
1359           [(compare:CCFPU
1360              (match_operand 1 "register_operand" "f")
1361              (match_operand 2 "register_operand" "f"))]
1362           UNSPEC_FNSTSW))]
1363   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1364    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1365   "* return output_fp_compare (insn, operands, 0, 1);"
1366   [(set_attr "type" "multi")
1367    (set_attr "unit" "i387")
1368    (set (attr "mode")
1369      (cond [(match_operand:SF 1 "" "")
1370               (const_string "SF")
1371             (match_operand:DF 1 "" "")
1372               (const_string "DF")
1373            ]
1374            (const_string "XF")))])
1375
1376 (define_insn_and_split "*cmpfp_u_cc"
1377   [(set (reg:CCFPU FLAGS_REG)
1378         (compare:CCFPU
1379           (match_operand 1 "register_operand" "f")
1380           (match_operand 2 "register_operand" "f")))
1381    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1382   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1383    && TARGET_SAHF && !TARGET_CMOVE
1384    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1385   "#"
1386   "&& reload_completed"
1387   [(set (match_dup 0)
1388         (unspec:HI
1389           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1390         UNSPEC_FNSTSW))
1391    (set (reg:CC FLAGS_REG)
1392         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1393   ""
1394   [(set_attr "type" "multi")
1395    (set_attr "unit" "i387")
1396    (set (attr "mode")
1397      (cond [(match_operand:SF 1 "" "")
1398               (const_string "SF")
1399             (match_operand:DF 1 "" "")
1400               (const_string "DF")
1401            ]
1402            (const_string "XF")))])
1403
1404 (define_insn "*cmpfp_<mode>"
1405   [(set (match_operand:HI 0 "register_operand" "=a")
1406         (unspec:HI
1407           [(compare:CCFP
1408              (match_operand 1 "register_operand" "f")
1409              (match_operator 3 "float_operator"
1410                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1411           UNSPEC_FNSTSW))]
1412   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1413    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1414    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1415   "* return output_fp_compare (insn, operands, 0, 0);"
1416   [(set_attr "type" "multi")
1417    (set_attr "unit" "i387")
1418    (set_attr "fp_int_src" "true")
1419    (set_attr "mode" "<MODE>")])
1420
1421 (define_insn_and_split "*cmpfp_<mode>_cc"
1422   [(set (reg:CCFP FLAGS_REG)
1423         (compare:CCFP
1424           (match_operand 1 "register_operand" "f")
1425           (match_operator 3 "float_operator"
1426             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1427    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1428   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429    && TARGET_SAHF && !TARGET_CMOVE
1430    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1431    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1432   "#"
1433   "&& reload_completed"
1434   [(set (match_dup 0)
1435         (unspec:HI
1436           [(compare:CCFP
1437              (match_dup 1)
1438              (match_op_dup 3 [(match_dup 2)]))]
1439         UNSPEC_FNSTSW))
1440    (set (reg:CC FLAGS_REG)
1441         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1442   ""
1443   [(set_attr "type" "multi")
1444    (set_attr "unit" "i387")
1445    (set_attr "fp_int_src" "true")
1446    (set_attr "mode" "<MODE>")])
1447
1448 ;; FP compares, step 2
1449 ;; Move the fpsw to ax.
1450
1451 (define_insn "x86_fnstsw_1"
1452   [(set (match_operand:HI 0 "register_operand" "=a")
1453         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1454   "TARGET_80387"
1455   "fnstsw\t%0"
1456   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1457    (set_attr "mode" "SI")
1458    (set_attr "unit" "i387")])
1459
1460 ;; FP compares, step 3
1461 ;; Get ax into flags, general case.
1462
1463 (define_insn "x86_sahf_1"
1464   [(set (reg:CC FLAGS_REG)
1465         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1466                    UNSPEC_SAHF))]
1467   "TARGET_SAHF"
1468 {
1469 #ifndef HAVE_AS_IX86_SAHF
1470   if (TARGET_64BIT)
1471     return ASM_BYTE "0x9e";
1472   else
1473 #endif
1474   return "sahf";
1475 }
1476   [(set_attr "length" "1")
1477    (set_attr "athlon_decode" "vector")
1478    (set_attr "amdfam10_decode" "direct")
1479    (set_attr "bdver1_decode" "direct")
1480    (set_attr "mode" "SI")])
1481
1482 ;; Pentium Pro can do steps 1 through 3 in one go.
1483 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1484 (define_insn "*cmpfp_i_mixed"
1485   [(set (reg:CCFP FLAGS_REG)
1486         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1487                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1488   "TARGET_MIX_SSE_I387
1489    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1490    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1491   "* return output_fp_compare (insn, operands, 1, 0);"
1492   [(set_attr "type" "fcmp,ssecomi")
1493    (set_attr "prefix" "orig,maybe_vex")
1494    (set (attr "mode")
1495      (if_then_else (match_operand:SF 1 "" "")
1496         (const_string "SF")
1497         (const_string "DF")))
1498    (set (attr "prefix_rep")
1499         (if_then_else (eq_attr "type" "ssecomi")
1500                       (const_string "0")
1501                       (const_string "*")))
1502    (set (attr "prefix_data16")
1503         (cond [(eq_attr "type" "fcmp")
1504                  (const_string "*")
1505                (eq_attr "mode" "DF")
1506                  (const_string "1")
1507               ]
1508               (const_string "0")))
1509    (set_attr "athlon_decode" "vector")
1510    (set_attr "amdfam10_decode" "direct")
1511    (set_attr "bdver1_decode" "double")])
1512
1513 (define_insn "*cmpfp_i_sse"
1514   [(set (reg:CCFP FLAGS_REG)
1515         (compare:CCFP (match_operand 0 "register_operand" "x")
1516                       (match_operand 1 "nonimmediate_operand" "xm")))]
1517   "TARGET_SSE_MATH
1518    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1519    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520   "* return output_fp_compare (insn, operands, 1, 0);"
1521   [(set_attr "type" "ssecomi")
1522    (set_attr "prefix" "maybe_vex")
1523    (set (attr "mode")
1524      (if_then_else (match_operand:SF 1 "" "")
1525         (const_string "SF")
1526         (const_string "DF")))
1527    (set_attr "prefix_rep" "0")
1528    (set (attr "prefix_data16")
1529         (if_then_else (eq_attr "mode" "DF")
1530                       (const_string "1")
1531                       (const_string "0")))
1532    (set_attr "athlon_decode" "vector")
1533    (set_attr "amdfam10_decode" "direct")
1534    (set_attr "bdver1_decode" "double")])
1535
1536 (define_insn "*cmpfp_i_i387"
1537   [(set (reg:CCFP FLAGS_REG)
1538         (compare:CCFP (match_operand 0 "register_operand" "f")
1539                       (match_operand 1 "register_operand" "f")))]
1540   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1541    && TARGET_CMOVE
1542    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1543    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1544   "* return output_fp_compare (insn, operands, 1, 0);"
1545   [(set_attr "type" "fcmp")
1546    (set (attr "mode")
1547      (cond [(match_operand:SF 1 "" "")
1548               (const_string "SF")
1549             (match_operand:DF 1 "" "")
1550               (const_string "DF")
1551            ]
1552            (const_string "XF")))
1553    (set_attr "athlon_decode" "vector")
1554    (set_attr "amdfam10_decode" "direct")
1555    (set_attr "bdver1_decode" "double")])
1556
1557 (define_insn "*cmpfp_iu_mixed"
1558   [(set (reg:CCFPU FLAGS_REG)
1559         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1560                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1561   "TARGET_MIX_SSE_I387
1562    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1563    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1564   "* return output_fp_compare (insn, operands, 1, 1);"
1565   [(set_attr "type" "fcmp,ssecomi")
1566    (set_attr "prefix" "orig,maybe_vex")
1567    (set (attr "mode")
1568      (if_then_else (match_operand:SF 1 "" "")
1569         (const_string "SF")
1570         (const_string "DF")))
1571    (set (attr "prefix_rep")
1572         (if_then_else (eq_attr "type" "ssecomi")
1573                       (const_string "0")
1574                       (const_string "*")))
1575    (set (attr "prefix_data16")
1576         (cond [(eq_attr "type" "fcmp")
1577                  (const_string "*")
1578                (eq_attr "mode" "DF")
1579                  (const_string "1")
1580               ]
1581               (const_string "0")))
1582    (set_attr "athlon_decode" "vector")
1583    (set_attr "amdfam10_decode" "direct")
1584    (set_attr "bdver1_decode" "double")])
1585
1586 (define_insn "*cmpfp_iu_sse"
1587   [(set (reg:CCFPU FLAGS_REG)
1588         (compare:CCFPU (match_operand 0 "register_operand" "x")
1589                        (match_operand 1 "nonimmediate_operand" "xm")))]
1590   "TARGET_SSE_MATH
1591    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1592    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1593   "* return output_fp_compare (insn, operands, 1, 1);"
1594   [(set_attr "type" "ssecomi")
1595    (set_attr "prefix" "maybe_vex")
1596    (set (attr "mode")
1597      (if_then_else (match_operand:SF 1 "" "")
1598         (const_string "SF")
1599         (const_string "DF")))
1600    (set_attr "prefix_rep" "0")
1601    (set (attr "prefix_data16")
1602         (if_then_else (eq_attr "mode" "DF")
1603                       (const_string "1")
1604                       (const_string "0")))
1605    (set_attr "athlon_decode" "vector")
1606    (set_attr "amdfam10_decode" "direct")
1607    (set_attr "bdver1_decode" "double")])
1608
1609 (define_insn "*cmpfp_iu_387"
1610   [(set (reg:CCFPU FLAGS_REG)
1611         (compare:CCFPU (match_operand 0 "register_operand" "f")
1612                        (match_operand 1 "register_operand" "f")))]
1613   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1614    && TARGET_CMOVE
1615    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1616    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1617   "* return output_fp_compare (insn, operands, 1, 1);"
1618   [(set_attr "type" "fcmp")
1619    (set (attr "mode")
1620      (cond [(match_operand:SF 1 "" "")
1621               (const_string "SF")
1622             (match_operand:DF 1 "" "")
1623               (const_string "DF")
1624            ]
1625            (const_string "XF")))
1626    (set_attr "athlon_decode" "vector")
1627    (set_attr "amdfam10_decode" "direct")
1628    (set_attr "bdver1_decode" "direct")])
1629 \f
1630 ;; Push/pop instructions.
1631
1632 (define_insn "*push<mode>2"
1633   [(set (match_operand:DWI 0 "push_operand" "=<")
1634         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1635   ""
1636   "#")
1637
1638 (define_split
1639   [(set (match_operand:TI 0 "push_operand" "")
1640         (match_operand:TI 1 "general_operand" ""))]
1641   "TARGET_64BIT && reload_completed
1642    && !SSE_REG_P (operands[1])"
1643   [(const_int 0)]
1644   "ix86_split_long_move (operands); DONE;")
1645
1646 (define_insn "*pushdi2_rex64"
1647   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1648         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1649   "TARGET_64BIT"
1650   "@
1651    push{q}\t%1
1652    #"
1653   [(set_attr "type" "push,multi")
1654    (set_attr "mode" "DI")])
1655
1656 ;; Convert impossible pushes of immediate to existing instructions.
1657 ;; First try to get scratch register and go through it.  In case this
1658 ;; fails, push sign extended lower part first and then overwrite
1659 ;; upper part by 32bit move.
1660 (define_peephole2
1661   [(match_scratch:DI 2 "r")
1662    (set (match_operand:DI 0 "push_operand" "")
1663         (match_operand:DI 1 "immediate_operand" ""))]
1664   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1665    && !x86_64_immediate_operand (operands[1], DImode)"
1666   [(set (match_dup 2) (match_dup 1))
1667    (set (match_dup 0) (match_dup 2))])
1668
1669 ;; We need to define this as both peepholer and splitter for case
1670 ;; peephole2 pass is not run.
1671 ;; "&& 1" is needed to keep it from matching the previous pattern.
1672 (define_peephole2
1673   [(set (match_operand:DI 0 "push_operand" "")
1674         (match_operand:DI 1 "immediate_operand" ""))]
1675   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1676    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1677   [(set (match_dup 0) (match_dup 1))
1678    (set (match_dup 2) (match_dup 3))]
1679 {
1680   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1681
1682   operands[1] = gen_lowpart (DImode, operands[2]);
1683   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1684                                                    GEN_INT (4)));
1685 })
1686
1687 (define_split
1688   [(set (match_operand:DI 0 "push_operand" "")
1689         (match_operand:DI 1 "immediate_operand" ""))]
1690   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1691                     ? epilogue_completed : reload_completed)
1692    && !symbolic_operand (operands[1], DImode)
1693    && !x86_64_immediate_operand (operands[1], DImode)"
1694   [(set (match_dup 0) (match_dup 1))
1695    (set (match_dup 2) (match_dup 3))]
1696 {
1697   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1698
1699   operands[1] = gen_lowpart (DImode, operands[2]);
1700   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1701                                                    GEN_INT (4)));
1702 })
1703
1704 (define_split
1705   [(set (match_operand:DI 0 "push_operand" "")
1706         (match_operand:DI 1 "general_operand" ""))]
1707   "!TARGET_64BIT && reload_completed
1708    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1709   [(const_int 0)]
1710   "ix86_split_long_move (operands); DONE;")
1711
1712 (define_insn "*pushsi2"
1713   [(set (match_operand:SI 0 "push_operand" "=<")
1714         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1715   "!TARGET_64BIT"
1716   "push{l}\t%1"
1717   [(set_attr "type" "push")
1718    (set_attr "mode" "SI")])
1719
1720 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1721 ;; "push a byte/word".  But actually we use pushl, which has the effect
1722 ;; of rounding the amount pushed up to a word.
1723
1724 ;; For TARGET_64BIT we always round up to 8 bytes.
1725 (define_insn "*push<mode>2_rex64"
1726   [(set (match_operand:SWI124 0 "push_operand" "=X")
1727         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1728   "TARGET_64BIT"
1729   "push{q}\t%q1"
1730   [(set_attr "type" "push")
1731    (set_attr "mode" "DI")])
1732
1733 (define_insn "*push<mode>2"
1734   [(set (match_operand:SWI12 0 "push_operand" "=X")
1735         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1736   "!TARGET_64BIT"
1737   "push{l}\t%k1"
1738   [(set_attr "type" "push")
1739    (set_attr "mode" "SI")])
1740
1741 (define_insn "*push<mode>2_prologue"
1742   [(set (match_operand:P 0 "push_operand" "=<")
1743         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1744    (clobber (mem:BLK (scratch)))]
1745   ""
1746   "push{<imodesuffix>}\t%1"
1747   [(set_attr "type" "push")
1748    (set_attr "mode" "<MODE>")])
1749
1750 (define_insn "*pop<mode>1"
1751   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1752         (match_operand:P 1 "pop_operand" ">"))]
1753   ""
1754   "pop{<imodesuffix>}\t%0"
1755   [(set_attr "type" "pop")
1756    (set_attr "mode" "<MODE>")])
1757
1758 (define_insn "*pop<mode>1_epilogue"
1759   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1760         (match_operand:P 1 "pop_operand" ">"))
1761    (clobber (mem:BLK (scratch)))]
1762   ""
1763   "pop{<imodesuffix>}\t%0"
1764   [(set_attr "type" "pop")
1765    (set_attr "mode" "<MODE>")])
1766 \f
1767 ;; Move instructions.
1768
1769 (define_expand "movoi"
1770   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1771         (match_operand:OI 1 "general_operand" ""))]
1772   "TARGET_AVX"
1773   "ix86_expand_move (OImode, operands); DONE;")
1774
1775 (define_expand "movti"
1776   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1777         (match_operand:TI 1 "nonimmediate_operand" ""))]
1778   "TARGET_64BIT || TARGET_SSE"
1779 {
1780   if (TARGET_64BIT)
1781     ix86_expand_move (TImode, operands);
1782   else if (push_operand (operands[0], TImode))
1783     ix86_expand_push (TImode, operands[1]);
1784   else
1785     ix86_expand_vector_move (TImode, operands);
1786   DONE;
1787 })
1788
1789 ;; This expands to what emit_move_complex would generate if we didn't
1790 ;; have a movti pattern.  Having this avoids problems with reload on
1791 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1792 ;; to have around all the time.
1793 (define_expand "movcdi"
1794   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1795         (match_operand:CDI 1 "general_operand" ""))]
1796   ""
1797 {
1798   if (push_operand (operands[0], CDImode))
1799     emit_move_complex_push (CDImode, operands[0], operands[1]);
1800   else
1801     emit_move_complex_parts (operands[0], operands[1]);
1802   DONE;
1803 })
1804
1805 (define_expand "mov<mode>"
1806   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1807         (match_operand:SWI1248x 1 "general_operand" ""))]
1808   ""
1809   "ix86_expand_move (<MODE>mode, operands); DONE;")
1810
1811 (define_insn "*mov<mode>_xor"
1812   [(set (match_operand:SWI48 0 "register_operand" "=r")
1813         (match_operand:SWI48 1 "const0_operand" ""))
1814    (clobber (reg:CC FLAGS_REG))]
1815   "reload_completed"
1816   "xor{l}\t%k0, %k0"
1817   [(set_attr "type" "alu1")
1818    (set_attr "mode" "SI")
1819    (set_attr "length_immediate" "0")])
1820
1821 (define_insn "*mov<mode>_or"
1822   [(set (match_operand:SWI48 0 "register_operand" "=r")
1823         (match_operand:SWI48 1 "const_int_operand" ""))
1824    (clobber (reg:CC FLAGS_REG))]
1825   "reload_completed
1826    && operands[1] == constm1_rtx"
1827   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1828   [(set_attr "type" "alu1")
1829    (set_attr "mode" "<MODE>")
1830    (set_attr "length_immediate" "1")])
1831
1832 (define_insn "*movoi_internal_avx"
1833   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1834         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1835   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1836 {
1837   switch (which_alternative)
1838     {
1839     case 0:
1840       return "vxorps\t%0, %0, %0";
1841     case 1:
1842     case 2:
1843       if (misaligned_operand (operands[0], OImode)
1844           || misaligned_operand (operands[1], OImode))
1845         return "vmovdqu\t{%1, %0|%0, %1}";
1846       else
1847         return "vmovdqa\t{%1, %0|%0, %1}";
1848     default:
1849       gcc_unreachable ();
1850     }
1851 }
1852   [(set_attr "type" "sselog1,ssemov,ssemov")
1853    (set_attr "prefix" "vex")
1854    (set_attr "mode" "OI")])
1855
1856 (define_insn "*movti_internal_rex64"
1857   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1858         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1859   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1860 {
1861   switch (which_alternative)
1862     {
1863     case 0:
1864     case 1:
1865       return "#";
1866     case 2:
1867       if (get_attr_mode (insn) == MODE_V4SF)
1868         return "%vxorps\t%0, %d0";
1869       else
1870         return "%vpxor\t%0, %d0";
1871     case 3:
1872     case 4:
1873       /* TDmode values are passed as TImode on the stack.  Moving them
1874          to stack may result in unaligned memory access.  */
1875       if (misaligned_operand (operands[0], TImode)
1876           || misaligned_operand (operands[1], TImode))
1877         {
1878           if (get_attr_mode (insn) == MODE_V4SF)
1879             return "%vmovups\t{%1, %0|%0, %1}";
1880          else
1881            return "%vmovdqu\t{%1, %0|%0, %1}";
1882         }
1883       else
1884         {
1885           if (get_attr_mode (insn) == MODE_V4SF)
1886             return "%vmovaps\t{%1, %0|%0, %1}";
1887          else
1888            return "%vmovdqa\t{%1, %0|%0, %1}";
1889         }
1890     default:
1891       gcc_unreachable ();
1892     }
1893 }
1894   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1895    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1896    (set (attr "mode")
1897         (cond [(eq_attr "alternative" "2,3")
1898                  (if_then_else
1899                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1900                        (const_int 0))
1901                    (const_string "V4SF")
1902                    (const_string "TI"))
1903                (eq_attr "alternative" "4")
1904                  (if_then_else
1905                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1906                             (const_int 0))
1907                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1908                             (const_int 0)))
1909                    (const_string "V4SF")
1910                    (const_string "TI"))]
1911                (const_string "DI")))])
1912
1913 (define_split
1914   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1915         (match_operand:TI 1 "general_operand" ""))]
1916   "reload_completed
1917    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1918   [(const_int 0)]
1919   "ix86_split_long_move (operands); DONE;")
1920
1921 (define_insn "*movti_internal_sse"
1922   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1923         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1924   "TARGET_SSE && !TARGET_64BIT
1925    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1926 {
1927   switch (which_alternative)
1928     {
1929     case 0:
1930       if (get_attr_mode (insn) == MODE_V4SF)
1931         return "%vxorps\t%0, %d0";
1932       else
1933         return "%vpxor\t%0, %d0";
1934     case 1:
1935     case 2:
1936       /* TDmode values are passed as TImode on the stack.  Moving them
1937          to stack may result in unaligned memory access.  */
1938       if (misaligned_operand (operands[0], TImode)
1939           || misaligned_operand (operands[1], TImode))
1940         {
1941           if (get_attr_mode (insn) == MODE_V4SF)
1942             return "%vmovups\t{%1, %0|%0, %1}";
1943          else
1944            return "%vmovdqu\t{%1, %0|%0, %1}";
1945         }
1946       else
1947         {
1948           if (get_attr_mode (insn) == MODE_V4SF)
1949             return "%vmovaps\t{%1, %0|%0, %1}";
1950          else
1951            return "%vmovdqa\t{%1, %0|%0, %1}";
1952         }
1953     default:
1954       gcc_unreachable ();
1955     }
1956 }
1957   [(set_attr "type" "sselog1,ssemov,ssemov")
1958    (set_attr "prefix" "maybe_vex")
1959    (set (attr "mode")
1960         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1961                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1962                         (const_int 0)))
1963                  (const_string "V4SF")
1964                (and (eq_attr "alternative" "2")
1965                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1966                         (const_int 0)))
1967                  (const_string "V4SF")]
1968               (const_string "TI")))])
1969
1970 (define_insn "*movdi_internal_rex64"
1971   [(set (match_operand:DI 0 "nonimmediate_operand"
1972           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1973         (match_operand:DI 1 "general_operand"
1974           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1975   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1976 {
1977   switch (get_attr_type (insn))
1978     {
1979     case TYPE_SSECVT:
1980       if (SSE_REG_P (operands[0]))
1981         return "movq2dq\t{%1, %0|%0, %1}";
1982       else
1983         return "movdq2q\t{%1, %0|%0, %1}";
1984
1985     case TYPE_SSEMOV:
1986       if (TARGET_AVX)
1987         {
1988           if (get_attr_mode (insn) == MODE_TI)
1989             return "vmovdqa\t{%1, %0|%0, %1}";
1990           else
1991             return "vmovq\t{%1, %0|%0, %1}";
1992         }
1993
1994       if (get_attr_mode (insn) == MODE_TI)
1995         return "movdqa\t{%1, %0|%0, %1}";
1996       /* FALLTHRU */
1997
1998     case TYPE_MMXMOV:
1999       /* Moves from and into integer register is done using movd
2000          opcode with REX prefix.  */
2001       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2002         return "movd\t{%1, %0|%0, %1}";
2003       return "movq\t{%1, %0|%0, %1}";
2004
2005     case TYPE_SSELOG1:
2006       return "%vpxor\t%0, %d0";
2007
2008     case TYPE_MMX:
2009       return "pxor\t%0, %0";
2010
2011     case TYPE_MULTI:
2012       return "#";
2013
2014     case TYPE_LEA:
2015       return "lea{q}\t{%a1, %0|%0, %a1}";
2016
2017     default:
2018       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2019       if (get_attr_mode (insn) == MODE_SI)
2020         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2021       else if (which_alternative == 2)
2022         return "movabs{q}\t{%1, %0|%0, %1}";
2023       else
2024         return "mov{q}\t{%1, %0|%0, %1}";
2025     }
2026 }
2027   [(set (attr "type")
2028      (cond [(eq_attr "alternative" "5")
2029               (const_string "mmx")
2030             (eq_attr "alternative" "6,7,8,9,10")
2031               (const_string "mmxmov")
2032             (eq_attr "alternative" "11")
2033               (const_string "sselog1")
2034             (eq_attr "alternative" "12,13,14,15,16")
2035               (const_string "ssemov")
2036             (eq_attr "alternative" "17,18")
2037               (const_string "ssecvt")
2038             (eq_attr "alternative" "4")
2039               (const_string "multi")
2040             (match_operand:DI 1 "pic_32bit_operand" "")
2041               (const_string "lea")
2042            ]
2043            (const_string "imov")))
2044    (set (attr "modrm")
2045      (if_then_else
2046        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2047          (const_string "0")
2048          (const_string "*")))
2049    (set (attr "length_immediate")
2050      (if_then_else
2051        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2052          (const_string "8")
2053          (const_string "*")))
2054    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2055    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2056    (set (attr "prefix")
2057      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2058        (const_string "maybe_vex")
2059        (const_string "orig")))
2060    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2061
2062 ;; Convert impossible stores of immediate to existing instructions.
2063 ;; First try to get scratch register and go through it.  In case this
2064 ;; fails, move by 32bit parts.
2065 (define_peephole2
2066   [(match_scratch:DI 2 "r")
2067    (set (match_operand:DI 0 "memory_operand" "")
2068         (match_operand:DI 1 "immediate_operand" ""))]
2069   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2070    && !x86_64_immediate_operand (operands[1], DImode)"
2071   [(set (match_dup 2) (match_dup 1))
2072    (set (match_dup 0) (match_dup 2))])
2073
2074 ;; We need to define this as both peepholer and splitter for case
2075 ;; peephole2 pass is not run.
2076 ;; "&& 1" is needed to keep it from matching the previous pattern.
2077 (define_peephole2
2078   [(set (match_operand:DI 0 "memory_operand" "")
2079         (match_operand:DI 1 "immediate_operand" ""))]
2080   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2082   [(set (match_dup 2) (match_dup 3))
2083    (set (match_dup 4) (match_dup 5))]
2084   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2085
2086 (define_split
2087   [(set (match_operand:DI 0 "memory_operand" "")
2088         (match_operand:DI 1 "immediate_operand" ""))]
2089   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2090                     ? epilogue_completed : reload_completed)
2091    && !symbolic_operand (operands[1], DImode)
2092    && !x86_64_immediate_operand (operands[1], DImode)"
2093   [(set (match_dup 2) (match_dup 3))
2094    (set (match_dup 4) (match_dup 5))]
2095   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2096
2097 (define_insn "*movdi_internal"
2098   [(set (match_operand:DI 0 "nonimmediate_operand"
2099                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2100         (match_operand:DI 1 "general_operand"
2101                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2102   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2103   "@
2104    #
2105    #
2106    pxor\t%0, %0
2107    movq\t{%1, %0|%0, %1}
2108    movq\t{%1, %0|%0, %1}
2109    %vpxor\t%0, %d0
2110    %vmovq\t{%1, %0|%0, %1}
2111    %vmovdqa\t{%1, %0|%0, %1}
2112    %vmovq\t{%1, %0|%0, %1}
2113    xorps\t%0, %0
2114    movlps\t{%1, %0|%0, %1}
2115    movaps\t{%1, %0|%0, %1}
2116    movlps\t{%1, %0|%0, %1}"
2117   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2118    (set (attr "prefix")
2119      (if_then_else (eq_attr "alternative" "5,6,7,8")
2120        (const_string "vex")
2121        (const_string "orig")))
2122    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2123
2124 (define_split
2125   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2126         (match_operand:DI 1 "general_operand" ""))]
2127   "!TARGET_64BIT && reload_completed
2128    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2129    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2130   [(const_int 0)]
2131   "ix86_split_long_move (operands); DONE;")
2132
2133 (define_insn "*movsi_internal"
2134   [(set (match_operand:SI 0 "nonimmediate_operand"
2135                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2136         (match_operand:SI 1 "general_operand"
2137                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2138   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2139 {
2140   switch (get_attr_type (insn))
2141     {
2142     case TYPE_SSELOG1:
2143       if (get_attr_mode (insn) == MODE_TI)
2144         return "%vpxor\t%0, %d0";
2145       return "%vxorps\t%0, %d0";
2146
2147     case TYPE_SSEMOV:
2148       switch (get_attr_mode (insn))
2149         {
2150         case MODE_TI:
2151           return "%vmovdqa\t{%1, %0|%0, %1}";
2152         case MODE_V4SF:
2153           return "%vmovaps\t{%1, %0|%0, %1}";
2154         case MODE_SI:
2155           return "%vmovd\t{%1, %0|%0, %1}";
2156         case MODE_SF:
2157           return "%vmovss\t{%1, %0|%0, %1}";
2158         default:
2159           gcc_unreachable ();
2160         }
2161
2162     case TYPE_MMX:
2163       return "pxor\t%0, %0";
2164
2165     case TYPE_MMXMOV:
2166       if (get_attr_mode (insn) == MODE_DI)
2167         return "movq\t{%1, %0|%0, %1}";
2168       return "movd\t{%1, %0|%0, %1}";
2169
2170     case TYPE_LEA:
2171       return "lea{l}\t{%a1, %0|%0, %a1}";
2172
2173     default:
2174       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2175       return "mov{l}\t{%1, %0|%0, %1}";
2176     }
2177 }
2178   [(set (attr "type")
2179      (cond [(eq_attr "alternative" "2")
2180               (const_string "mmx")
2181             (eq_attr "alternative" "3,4,5")
2182               (const_string "mmxmov")
2183             (eq_attr "alternative" "6")
2184               (const_string "sselog1")
2185             (eq_attr "alternative" "7,8,9,10,11")
2186               (const_string "ssemov")
2187             (match_operand:DI 1 "pic_32bit_operand" "")
2188               (const_string "lea")
2189            ]
2190            (const_string "imov")))
2191    (set (attr "prefix")
2192      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2193        (const_string "orig")
2194        (const_string "maybe_vex")))
2195    (set (attr "prefix_data16")
2196      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2197        (const_string "1")
2198        (const_string "*")))
2199    (set (attr "mode")
2200      (cond [(eq_attr "alternative" "2,3")
2201               (const_string "DI")
2202             (eq_attr "alternative" "6,7")
2203               (if_then_else
2204                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2205                 (const_string "V4SF")
2206                 (const_string "TI"))
2207             (and (eq_attr "alternative" "8,9,10,11")
2208                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2209               (const_string "SF")
2210            ]
2211            (const_string "SI")))])
2212
2213 (define_insn "*movhi_internal"
2214   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2215         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2216   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217 {
2218   switch (get_attr_type (insn))
2219     {
2220     case TYPE_IMOVX:
2221       /* movzwl is faster than movw on p2 due to partial word stalls,
2222          though not as fast as an aligned movl.  */
2223       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2224     default:
2225       if (get_attr_mode (insn) == MODE_SI)
2226         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2227       else
2228         return "mov{w}\t{%1, %0|%0, %1}";
2229     }
2230 }
2231   [(set (attr "type")
2232      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2233                 (const_int 0))
2234               (const_string "imov")
2235             (and (eq_attr "alternative" "0")
2236                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2237                           (const_int 0))
2238                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2239                           (const_int 0))))
2240               (const_string "imov")
2241             (and (eq_attr "alternative" "1,2")
2242                  (match_operand:HI 1 "aligned_operand" ""))
2243               (const_string "imov")
2244             (and (ne (symbol_ref "TARGET_MOVX")
2245                      (const_int 0))
2246                  (eq_attr "alternative" "0,2"))
2247               (const_string "imovx")
2248            ]
2249            (const_string "imov")))
2250     (set (attr "mode")
2251       (cond [(eq_attr "type" "imovx")
2252                (const_string "SI")
2253              (and (eq_attr "alternative" "1,2")
2254                   (match_operand:HI 1 "aligned_operand" ""))
2255                (const_string "SI")
2256              (and (eq_attr "alternative" "0")
2257                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2258                            (const_int 0))
2259                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2260                            (const_int 0))))
2261                (const_string "SI")
2262             ]
2263             (const_string "HI")))])
2264
2265 ;; Situation is quite tricky about when to choose full sized (SImode) move
2266 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2267 ;; partial register dependency machines (such as AMD Athlon), where QImode
2268 ;; moves issue extra dependency and for partial register stalls machines
2269 ;; that don't use QImode patterns (and QImode move cause stall on the next
2270 ;; instruction).
2271 ;;
2272 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2273 ;; register stall machines with, where we use QImode instructions, since
2274 ;; partial register stall can be caused there.  Then we use movzx.
2275 (define_insn "*movqi_internal"
2276   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2277         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2278   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2279 {
2280   switch (get_attr_type (insn))
2281     {
2282     case TYPE_IMOVX:
2283       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2284       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2285     default:
2286       if (get_attr_mode (insn) == MODE_SI)
2287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2288       else
2289         return "mov{b}\t{%1, %0|%0, %1}";
2290     }
2291 }
2292   [(set (attr "type")
2293      (cond [(and (eq_attr "alternative" "5")
2294                  (not (match_operand:QI 1 "aligned_operand" "")))
2295               (const_string "imovx")
2296             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2297                 (const_int 0))
2298               (const_string "imov")
2299             (and (eq_attr "alternative" "3")
2300                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2301                           (const_int 0))
2302                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2303                           (const_int 0))))
2304               (const_string "imov")
2305             (eq_attr "alternative" "3,5")
2306               (const_string "imovx")
2307             (and (ne (symbol_ref "TARGET_MOVX")
2308                      (const_int 0))
2309                  (eq_attr "alternative" "2"))
2310               (const_string "imovx")
2311            ]
2312            (const_string "imov")))
2313    (set (attr "mode")
2314       (cond [(eq_attr "alternative" "3,4,5")
2315                (const_string "SI")
2316              (eq_attr "alternative" "6")
2317                (const_string "QI")
2318              (eq_attr "type" "imovx")
2319                (const_string "SI")
2320              (and (eq_attr "type" "imov")
2321                   (and (eq_attr "alternative" "0,1")
2322                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2323                                 (const_int 0))
2324                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2325                                      (const_int 0))
2326                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2327                                      (const_int 0))))))
2328                (const_string "SI")
2329              ;; Avoid partial register stalls when not using QImode arithmetic
2330              (and (eq_attr "type" "imov")
2331                   (and (eq_attr "alternative" "0,1")
2332                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2333                                 (const_int 0))
2334                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2335                                 (const_int 0)))))
2336                (const_string "SI")
2337            ]
2338            (const_string "QI")))])
2339
2340 ;; Stores and loads of ax to arbitrary constant address.
2341 ;; We fake an second form of instruction to force reload to load address
2342 ;; into register when rax is not available
2343 (define_insn "*movabs<mode>_1"
2344   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2345         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2346   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2347   "@
2348    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2349    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2350   [(set_attr "type" "imov")
2351    (set_attr "modrm" "0,*")
2352    (set_attr "length_address" "8,0")
2353    (set_attr "length_immediate" "0,*")
2354    (set_attr "memory" "store")
2355    (set_attr "mode" "<MODE>")])
2356
2357 (define_insn "*movabs<mode>_2"
2358   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2359         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2360   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2361   "@
2362    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2363    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2364   [(set_attr "type" "imov")
2365    (set_attr "modrm" "0,*")
2366    (set_attr "length_address" "8,0")
2367    (set_attr "length_immediate" "0")
2368    (set_attr "memory" "load")
2369    (set_attr "mode" "<MODE>")])
2370
2371 (define_insn "*swap<mode>"
2372   [(set (match_operand:SWI48 0 "register_operand" "+r")
2373         (match_operand:SWI48 1 "register_operand" "+r"))
2374    (set (match_dup 1)
2375         (match_dup 0))]
2376   ""
2377   "xchg{<imodesuffix>}\t%1, %0"
2378   [(set_attr "type" "imov")
2379    (set_attr "mode" "<MODE>")
2380    (set_attr "pent_pair" "np")
2381    (set_attr "athlon_decode" "vector")
2382    (set_attr "amdfam10_decode" "double")
2383    (set_attr "bdver1_decode" "double")])
2384
2385 (define_insn "*swap<mode>_1"
2386   [(set (match_operand:SWI12 0 "register_operand" "+r")
2387         (match_operand:SWI12 1 "register_operand" "+r"))
2388    (set (match_dup 1)
2389         (match_dup 0))]
2390   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2391   "xchg{l}\t%k1, %k0"
2392   [(set_attr "type" "imov")
2393    (set_attr "mode" "SI")
2394    (set_attr "pent_pair" "np")
2395    (set_attr "athlon_decode" "vector")
2396    (set_attr "amdfam10_decode" "double")
2397    (set_attr "bdver1_decode" "double")])
2398
2399 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2400 ;; is disabled for AMDFAM10
2401 (define_insn "*swap<mode>_2"
2402   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2403         (match_operand:SWI12 1 "register_operand" "+<r>"))
2404    (set (match_dup 1)
2405         (match_dup 0))]
2406   "TARGET_PARTIAL_REG_STALL"
2407   "xchg{<imodesuffix>}\t%1, %0"
2408   [(set_attr "type" "imov")
2409    (set_attr "mode" "<MODE>")
2410    (set_attr "pent_pair" "np")
2411    (set_attr "athlon_decode" "vector")])
2412
2413 (define_expand "movstrict<mode>"
2414   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2415         (match_operand:SWI12 1 "general_operand" ""))]
2416   ""
2417 {
2418   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2419     FAIL;
2420   /* Don't generate memory->memory moves, go through a register */
2421   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2422     operands[1] = force_reg (<MODE>mode, operands[1]);
2423 })
2424
2425 (define_insn "*movstrict<mode>_1"
2426   [(set (strict_low_part
2427           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2428         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2429   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2430    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2431   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2432   [(set_attr "type" "imov")
2433    (set_attr "mode" "<MODE>")])
2434
2435 (define_insn "*movstrict<mode>_xor"
2436   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2437         (match_operand:SWI12 1 "const0_operand" ""))
2438    (clobber (reg:CC FLAGS_REG))]
2439   "reload_completed"
2440   "xor{<imodesuffix>}\t%0, %0"
2441   [(set_attr "type" "alu1")
2442    (set_attr "mode" "<MODE>")
2443    (set_attr "length_immediate" "0")])
2444
2445 (define_insn "*mov<mode>_extv_1"
2446   [(set (match_operand:SWI24 0 "register_operand" "=R")
2447         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2448                             (const_int 8)
2449                             (const_int 8)))]
2450   ""
2451   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2452   [(set_attr "type" "imovx")
2453    (set_attr "mode" "SI")])
2454
2455 (define_insn "*movqi_extv_1_rex64"
2456   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2457         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2458                          (const_int 8)
2459                          (const_int 8)))]
2460   "TARGET_64BIT"
2461 {
2462   switch (get_attr_type (insn))
2463     {
2464     case TYPE_IMOVX:
2465       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2466     default:
2467       return "mov{b}\t{%h1, %0|%0, %h1}";
2468     }
2469 }
2470   [(set (attr "type")
2471      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2472                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2473                              (ne (symbol_ref "TARGET_MOVX")
2474                                  (const_int 0))))
2475         (const_string "imovx")
2476         (const_string "imov")))
2477    (set (attr "mode")
2478      (if_then_else (eq_attr "type" "imovx")
2479         (const_string "SI")
2480         (const_string "QI")))])
2481
2482 (define_insn "*movqi_extv_1"
2483   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2484         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2485                          (const_int 8)
2486                          (const_int 8)))]
2487   "!TARGET_64BIT"
2488 {
2489   switch (get_attr_type (insn))
2490     {
2491     case TYPE_IMOVX:
2492       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2493     default:
2494       return "mov{b}\t{%h1, %0|%0, %h1}";
2495     }
2496 }
2497   [(set (attr "type")
2498      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2499                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2500                              (ne (symbol_ref "TARGET_MOVX")
2501                                  (const_int 0))))
2502         (const_string "imovx")
2503         (const_string "imov")))
2504    (set (attr "mode")
2505      (if_then_else (eq_attr "type" "imovx")
2506         (const_string "SI")
2507         (const_string "QI")))])
2508
2509 (define_insn "*mov<mode>_extzv_1"
2510   [(set (match_operand:SWI48 0 "register_operand" "=R")
2511         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2512                             (const_int 8)
2513                             (const_int 8)))]
2514   ""
2515   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2516   [(set_attr "type" "imovx")
2517    (set_attr "mode" "SI")])
2518
2519 (define_insn "*movqi_extzv_2_rex64"
2520   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2521         (subreg:QI
2522           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2523                            (const_int 8)
2524                            (const_int 8)) 0))]
2525   "TARGET_64BIT"
2526 {
2527   switch (get_attr_type (insn))
2528     {
2529     case TYPE_IMOVX:
2530       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2531     default:
2532       return "mov{b}\t{%h1, %0|%0, %h1}";
2533     }
2534 }
2535   [(set (attr "type")
2536      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2537                         (ne (symbol_ref "TARGET_MOVX")
2538                             (const_int 0)))
2539         (const_string "imovx")
2540         (const_string "imov")))
2541    (set (attr "mode")
2542      (if_then_else (eq_attr "type" "imovx")
2543         (const_string "SI")
2544         (const_string "QI")))])
2545
2546 (define_insn "*movqi_extzv_2"
2547   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2548         (subreg:QI
2549           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2550                            (const_int 8)
2551                            (const_int 8)) 0))]
2552   "!TARGET_64BIT"
2553 {
2554   switch (get_attr_type (insn))
2555     {
2556     case TYPE_IMOVX:
2557       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2558     default:
2559       return "mov{b}\t{%h1, %0|%0, %h1}";
2560     }
2561 }
2562   [(set (attr "type")
2563      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2564                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2565                              (ne (symbol_ref "TARGET_MOVX")
2566                                  (const_int 0))))
2567         (const_string "imovx")
2568         (const_string "imov")))
2569    (set (attr "mode")
2570      (if_then_else (eq_attr "type" "imovx")
2571         (const_string "SI")
2572         (const_string "QI")))])
2573
2574 (define_expand "mov<mode>_insv_1"
2575   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2576                             (const_int 8)
2577                             (const_int 8))
2578         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2579
2580 (define_insn "*mov<mode>_insv_1_rex64"
2581   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2582                              (const_int 8)
2583                              (const_int 8))
2584         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2585   "TARGET_64BIT"
2586   "mov{b}\t{%b1, %h0|%h0, %b1}"
2587   [(set_attr "type" "imov")
2588    (set_attr "mode" "QI")])
2589
2590 (define_insn "*movsi_insv_1"
2591   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2592                          (const_int 8)
2593                          (const_int 8))
2594         (match_operand:SI 1 "general_operand" "Qmn"))]
2595   "!TARGET_64BIT"
2596   "mov{b}\t{%b1, %h0|%h0, %b1}"
2597   [(set_attr "type" "imov")
2598    (set_attr "mode" "QI")])
2599
2600 (define_insn "*movqi_insv_2"
2601   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2602                          (const_int 8)
2603                          (const_int 8))
2604         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2605                      (const_int 8)))]
2606   ""
2607   "mov{b}\t{%h1, %h0|%h0, %h1}"
2608   [(set_attr "type" "imov")
2609    (set_attr "mode" "QI")])
2610 \f
2611 ;; Floating point push instructions.
2612
2613 (define_insn "*pushtf"
2614   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2615         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2616   "TARGET_SSE2"
2617 {
2618   /* This insn should be already split before reg-stack.  */
2619   gcc_unreachable ();
2620 }
2621   [(set_attr "type" "multi")
2622    (set_attr "unit" "sse,*,*")
2623    (set_attr "mode" "TF,SI,SI")])
2624
2625 (define_split
2626   [(set (match_operand:TF 0 "push_operand" "")
2627         (match_operand:TF 1 "sse_reg_operand" ""))]
2628   "TARGET_SSE2 && reload_completed"
2629   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2630    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2631
2632 (define_split
2633   [(set (match_operand:TF 0 "push_operand" "")
2634         (match_operand:TF 1 "general_operand" ""))]
2635   "TARGET_SSE2 && reload_completed
2636    && !SSE_REG_P (operands[1])"
2637   [(const_int 0)]
2638   "ix86_split_long_move (operands); DONE;")
2639
2640 (define_insn "*pushxf"
2641   [(set (match_operand:XF 0 "push_operand" "=<,<")
2642         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2643   "optimize_function_for_speed_p (cfun)"
2644 {
2645   /* This insn should be already split before reg-stack.  */
2646   gcc_unreachable ();
2647 }
2648   [(set_attr "type" "multi")
2649    (set_attr "unit" "i387,*")
2650    (set_attr "mode" "XF,SI")])
2651
2652 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2653 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2654 ;; Pushing using integer instructions is longer except for constants
2655 ;; and direct memory references (assuming that any given constant is pushed
2656 ;; only once, but this ought to be handled elsewhere).
2657
2658 (define_insn "*pushxf_nointeger"
2659   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2660         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2661   "optimize_function_for_size_p (cfun)"
2662 {
2663   /* This insn should be already split before reg-stack.  */
2664   gcc_unreachable ();
2665 }
2666   [(set_attr "type" "multi")
2667    (set_attr "unit" "i387,*,*")
2668    (set_attr "mode" "XF,SI,SI")])
2669
2670 (define_split
2671   [(set (match_operand:XF 0 "push_operand" "")
2672         (match_operand:XF 1 "fp_register_operand" ""))]
2673   "reload_completed"
2674   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2675    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2676   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2677
2678 (define_split
2679   [(set (match_operand:XF 0 "push_operand" "")
2680         (match_operand:XF 1 "general_operand" ""))]
2681   "reload_completed
2682    && !FP_REG_P (operands[1])"
2683   [(const_int 0)]
2684   "ix86_split_long_move (operands); DONE;")
2685
2686 (define_insn "*pushdf"
2687   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2688         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2689   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2690 {
2691   /* This insn should be already split before reg-stack.  */
2692   gcc_unreachable ();
2693 }
2694   [(set_attr "type" "multi")
2695    (set_attr "unit" "i387,*,*")
2696    (set_attr "mode" "DF,SI,DF")])
2697
2698 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2699 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2700 ;; On the average, pushdf using integers can be still shorter.  Allow this
2701 ;; pattern for optimize_size too.
2702
2703 (define_insn "*pushdf_nointeger"
2704   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2705         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2706   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2707 {
2708   /* This insn should be already split before reg-stack.  */
2709   gcc_unreachable ();
2710 }
2711   [(set_attr "type" "multi")
2712    (set_attr "unit" "i387,*,*,*")
2713    (set_attr "mode" "DF,SI,SI,DF")])
2714
2715 ;; %%% Kill this when call knows how to work this out.
2716 (define_split
2717   [(set (match_operand:DF 0 "push_operand" "")
2718         (match_operand:DF 1 "any_fp_register_operand" ""))]
2719   "reload_completed"
2720   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2721    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2722
2723 (define_split
2724   [(set (match_operand:DF 0 "push_operand" "")
2725         (match_operand:DF 1 "general_operand" ""))]
2726   "reload_completed
2727    && !ANY_FP_REG_P (operands[1])"
2728   [(const_int 0)]
2729   "ix86_split_long_move (operands); DONE;")
2730
2731 (define_insn "*pushsf_rex64"
2732   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2733         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2734   "TARGET_64BIT"
2735 {
2736   /* Anything else should be already split before reg-stack.  */
2737   gcc_assert (which_alternative == 1);
2738   return "push{q}\t%q1";
2739 }
2740   [(set_attr "type" "multi,push,multi")
2741    (set_attr "unit" "i387,*,*")
2742    (set_attr "mode" "SF,DI,SF")])
2743
2744 (define_insn "*pushsf"
2745   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2746         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2747   "!TARGET_64BIT"
2748 {
2749   /* Anything else should be already split before reg-stack.  */
2750   gcc_assert (which_alternative == 1);
2751   return "push{l}\t%1";
2752 }
2753   [(set_attr "type" "multi,push,multi")
2754    (set_attr "unit" "i387,*,*")
2755    (set_attr "mode" "SF,SI,SF")])
2756
2757 (define_split
2758   [(set (match_operand:SF 0 "push_operand" "")
2759         (match_operand:SF 1 "memory_operand" ""))]
2760   "reload_completed
2761    && MEM_P (operands[1])
2762    && (operands[2] = find_constant_src (insn))"
2763   [(set (match_dup 0)
2764         (match_dup 2))])
2765
2766 ;; %%% Kill this when call knows how to work this out.
2767 (define_split
2768   [(set (match_operand:SF 0 "push_operand" "")
2769         (match_operand:SF 1 "any_fp_register_operand" ""))]
2770   "reload_completed"
2771   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2772    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2773   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2774 \f
2775 ;; Floating point move instructions.
2776
2777 (define_expand "movtf"
2778   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2779         (match_operand:TF 1 "nonimmediate_operand" ""))]
2780   "TARGET_SSE2"
2781 {
2782   ix86_expand_move (TFmode, operands);
2783   DONE;
2784 })
2785
2786 (define_expand "mov<mode>"
2787   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2788         (match_operand:X87MODEF 1 "general_operand" ""))]
2789   ""
2790   "ix86_expand_move (<MODE>mode, operands); DONE;")
2791
2792 (define_insn "*movtf_internal"
2793   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2794         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2795   "TARGET_SSE2
2796    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2797 {
2798   switch (which_alternative)
2799     {
2800     case 0:
2801     case 1:
2802       if (get_attr_mode (insn) == MODE_V4SF)
2803         return "%vmovaps\t{%1, %0|%0, %1}";
2804       else
2805         return "%vmovdqa\t{%1, %0|%0, %1}";
2806     case 2:
2807       if (get_attr_mode (insn) == MODE_V4SF)
2808         return "%vxorps\t%0, %d0";
2809       else
2810         return "%vpxor\t%0, %d0";
2811     case 3:
2812     case 4:
2813         return "#";
2814     default:
2815       gcc_unreachable ();
2816     }
2817 }
2818   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2819    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2820    (set (attr "mode")
2821         (cond [(eq_attr "alternative" "0,2")
2822                  (if_then_else
2823                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2824                        (const_int 0))
2825                    (const_string "V4SF")
2826                    (const_string "TI"))
2827                (eq_attr "alternative" "1")
2828                  (if_then_else
2829                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2830                             (const_int 0))
2831                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2832                             (const_int 0)))
2833                    (const_string "V4SF")
2834                    (const_string "TI"))]
2835                (const_string "DI")))])
2836
2837 (define_split
2838   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2839         (match_operand:TF 1 "general_operand" ""))]
2840   "reload_completed
2841    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2842   [(const_int 0)]
2843   "ix86_split_long_move (operands); DONE;")
2844
2845 (define_insn "*movxf_internal"
2846   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2847         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2848   "optimize_function_for_speed_p (cfun)
2849    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2850    && (reload_in_progress || reload_completed
2851        || GET_CODE (operands[1]) != CONST_DOUBLE
2852        || memory_operand (operands[0], XFmode))"
2853 {
2854   switch (which_alternative)
2855     {
2856     case 0:
2857     case 1:
2858       return output_387_reg_move (insn, operands);
2859
2860     case 2:
2861       return standard_80387_constant_opcode (operands[1]);
2862
2863     case 3: case 4:
2864       return "#";
2865
2866     default:
2867       gcc_unreachable ();
2868     }
2869 }
2870   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2871    (set_attr "mode" "XF,XF,XF,SI,SI")])
2872
2873 ;; Do not use integer registers when optimizing for size
2874 (define_insn "*movxf_internal_nointeger"
2875   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2876         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2877   "optimize_function_for_size_p (cfun)
2878    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2879    && (reload_in_progress || reload_completed
2880        || standard_80387_constant_p (operands[1])
2881        || GET_CODE (operands[1]) != CONST_DOUBLE
2882        || memory_operand (operands[0], XFmode))"
2883 {
2884   switch (which_alternative)
2885     {
2886     case 0:
2887     case 1:
2888       return output_387_reg_move (insn, operands);
2889
2890     case 2:
2891       return standard_80387_constant_opcode (operands[1]);
2892
2893     case 3: case 4:
2894       return "#";
2895     default:
2896       gcc_unreachable ();
2897     }
2898 }
2899   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2900    (set_attr "mode" "XF,XF,XF,SI,SI")])
2901
2902 (define_split
2903   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2904         (match_operand:XF 1 "general_operand" ""))]
2905   "reload_completed
2906    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2907    && ! (FP_REG_P (operands[0]) ||
2908          (GET_CODE (operands[0]) == SUBREG
2909           && FP_REG_P (SUBREG_REG (operands[0]))))
2910    && ! (FP_REG_P (operands[1]) ||
2911          (GET_CODE (operands[1]) == SUBREG
2912           && FP_REG_P (SUBREG_REG (operands[1]))))"
2913   [(const_int 0)]
2914   "ix86_split_long_move (operands); DONE;")
2915
2916 (define_insn "*movdf_internal_rex64"
2917   [(set (match_operand:DF 0 "nonimmediate_operand"
2918                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2919         (match_operand:DF 1 "general_operand"
2920                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2921   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922    && (reload_in_progress || reload_completed
2923        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2925            && optimize_function_for_size_p (cfun)
2926            && standard_80387_constant_p (operands[1]))
2927        || GET_CODE (operands[1]) != CONST_DOUBLE
2928        || memory_operand (operands[0], DFmode))"
2929 {
2930   switch (which_alternative)
2931     {
2932     case 0:
2933     case 1:
2934       return output_387_reg_move (insn, operands);
2935
2936     case 2:
2937       return standard_80387_constant_opcode (operands[1]);
2938
2939     case 3:
2940     case 4:
2941       return "#";
2942
2943     case 5:
2944       switch (get_attr_mode (insn))
2945         {
2946         case MODE_V4SF:
2947           return "%vxorps\t%0, %d0";
2948         case MODE_V2DF:
2949           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2950             return "%vxorps\t%0, %d0";
2951           else
2952             return "%vxorpd\t%0, %d0";
2953         case MODE_TI:
2954           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2955             return "%vxorps\t%0, %d0";
2956           else
2957             return "%vpxor\t%0, %d0";
2958         default:
2959           gcc_unreachable ();
2960         }
2961     case 6:
2962     case 7:
2963     case 8:
2964       switch (get_attr_mode (insn))
2965         {
2966         case MODE_V4SF:
2967           return "%vmovaps\t{%1, %0|%0, %1}";
2968         case MODE_V2DF:
2969           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2970             return "%vmovaps\t{%1, %0|%0, %1}";
2971           else
2972             return "%vmovapd\t{%1, %0|%0, %1}";
2973         case MODE_TI:
2974           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2975             return "%vmovaps\t{%1, %0|%0, %1}";
2976           else
2977             return "%vmovdqa\t{%1, %0|%0, %1}";
2978         case MODE_DI:
2979           return "%vmovq\t{%1, %0|%0, %1}";
2980         case MODE_DF:
2981           if (TARGET_AVX)
2982             {
2983               if (REG_P (operands[0]) && REG_P (operands[1]))
2984                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2985               else
2986                 return "vmovsd\t{%1, %0|%0, %1}";
2987             }
2988           else
2989             return "movsd\t{%1, %0|%0, %1}";
2990         case MODE_V1DF:
2991           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2992         case MODE_V2SF:
2993           return "%vmovlps\t{%1, %d0|%d0, %1}";
2994         default:
2995           gcc_unreachable ();
2996         }
2997
2998     case 9:
2999     case 10:
3000     return "%vmovd\t{%1, %0|%0, %1}";
3001
3002     default:
3003       gcc_unreachable();
3004     }
3005 }
3006   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3007    (set (attr "prefix")
3008      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3009        (const_string "orig")
3010        (const_string "maybe_vex")))
3011    (set (attr "prefix_data16")
3012      (if_then_else (eq_attr "mode" "V1DF")
3013        (const_string "1")
3014        (const_string "*")))
3015    (set (attr "mode")
3016         (cond [(eq_attr "alternative" "0,1,2")
3017                  (const_string "DF")
3018                (eq_attr "alternative" "3,4,9,10")
3019                  (const_string "DI")
3020
3021                /* For SSE1, we have many fewer alternatives.  */
3022                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3023                  (cond [(eq_attr "alternative" "5,6")
3024                           (const_string "V4SF")
3025                        ]
3026                    (const_string "V2SF"))
3027
3028                /* xorps is one byte shorter.  */
3029                (eq_attr "alternative" "5")
3030                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3031                             (const_int 0))
3032                           (const_string "V4SF")
3033                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3034                             (const_int 0))
3035                           (const_string "TI")
3036                        ]
3037                        (const_string "V2DF"))
3038
3039                /* For architectures resolving dependencies on
3040                   whole SSE registers use APD move to break dependency
3041                   chains, otherwise use short move to avoid extra work.
3042
3043                   movaps encodes one byte shorter.  */
3044                (eq_attr "alternative" "6")
3045                  (cond
3046                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3047                         (const_int 0))
3048                       (const_string "V4SF")
3049                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3050                         (const_int 0))
3051                       (const_string "V2DF")
3052                    ]
3053                    (const_string "DF"))
3054                /* For architectures resolving dependencies on register
3055                   parts we may avoid extra work to zero out upper part
3056                   of register.  */
3057                (eq_attr "alternative" "7")
3058                  (if_then_else
3059                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3060                        (const_int 0))
3061                    (const_string "V1DF")
3062                    (const_string "DF"))
3063               ]
3064               (const_string "DF")))])
3065
3066 (define_insn "*movdf_internal"
3067   [(set (match_operand:DF 0 "nonimmediate_operand"
3068                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3069         (match_operand:DF 1 "general_operand"
3070                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3071   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3072    && optimize_function_for_speed_p (cfun)
3073    && TARGET_INTEGER_DFMODE_MOVES
3074    && (reload_in_progress || reload_completed
3075        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3076        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3077            && optimize_function_for_size_p (cfun)
3078            && standard_80387_constant_p (operands[1]))
3079        || GET_CODE (operands[1]) != CONST_DOUBLE
3080        || memory_operand (operands[0], DFmode))"
3081 {
3082   switch (which_alternative)
3083     {
3084     case 0:
3085     case 1:
3086       return output_387_reg_move (insn, operands);
3087
3088     case 2:
3089       return standard_80387_constant_opcode (operands[1]);
3090
3091     case 3:
3092     case 4:
3093       return "#";
3094
3095     case 5:
3096       switch (get_attr_mode (insn))
3097         {
3098         case MODE_V4SF:
3099           return "xorps\t%0, %0";
3100         case MODE_V2DF:
3101           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3102             return "xorps\t%0, %0";
3103           else
3104             return "xorpd\t%0, %0";
3105         case MODE_TI:
3106           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3107             return "xorps\t%0, %0";
3108           else
3109             return "pxor\t%0, %0";
3110         default:
3111           gcc_unreachable ();
3112         }
3113     case 6:
3114     case 7:
3115     case 8:
3116       switch (get_attr_mode (insn))
3117         {
3118         case MODE_V4SF:
3119           return "movaps\t{%1, %0|%0, %1}";
3120         case MODE_V2DF:
3121           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3122             return "movaps\t{%1, %0|%0, %1}";
3123           else
3124             return "movapd\t{%1, %0|%0, %1}";
3125         case MODE_TI:
3126           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3127             return "movaps\t{%1, %0|%0, %1}";
3128           else
3129             return "movdqa\t{%1, %0|%0, %1}";
3130         case MODE_DI:
3131           return "movq\t{%1, %0|%0, %1}";
3132         case MODE_DF:
3133           return "movsd\t{%1, %0|%0, %1}";
3134         case MODE_V1DF:
3135           return "movlpd\t{%1, %0|%0, %1}";
3136         case MODE_V2SF:
3137           return "movlps\t{%1, %0|%0, %1}";
3138         default:
3139           gcc_unreachable ();
3140         }
3141
3142     default:
3143       gcc_unreachable();
3144     }
3145 }
3146   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3147    (set (attr "prefix_data16")
3148      (if_then_else (eq_attr "mode" "V1DF")
3149        (const_string "1")
3150        (const_string "*")))
3151    (set (attr "mode")
3152         (cond [(eq_attr "alternative" "0,1,2")
3153                  (const_string "DF")
3154                (eq_attr "alternative" "3,4")
3155                  (const_string "SI")
3156
3157                /* For SSE1, we have many fewer alternatives.  */
3158                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3159                  (cond [(eq_attr "alternative" "5,6")
3160                           (const_string "V4SF")
3161                        ]
3162                    (const_string "V2SF"))
3163
3164                /* xorps is one byte shorter.  */
3165                (eq_attr "alternative" "5")
3166                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3167                             (const_int 0))
3168                           (const_string "V4SF")
3169                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3170                             (const_int 0))
3171                           (const_string "TI")
3172                        ]
3173                        (const_string "V2DF"))
3174
3175                /* For architectures resolving dependencies on
3176                   whole SSE registers use APD move to break dependency
3177                   chains, otherwise use short move to avoid extra work.
3178
3179                   movaps encodes one byte shorter.  */
3180                (eq_attr "alternative" "6")
3181                  (cond
3182                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3183                         (const_int 0))
3184                       (const_string "V4SF")
3185                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3186                         (const_int 0))
3187                       (const_string "V2DF")
3188                    ]
3189                    (const_string "DF"))
3190                /* For architectures resolving dependencies on register
3191                   parts we may avoid extra work to zero out upper part
3192                   of register.  */
3193                (eq_attr "alternative" "7")
3194                  (if_then_else
3195                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3196                        (const_int 0))
3197                    (const_string "V1DF")
3198                    (const_string "DF"))
3199               ]
3200               (const_string "DF")))])
3201
3202 ;; Moving is usually shorter when only FP registers are used. This separate
3203 ;; movdf pattern avoids the use of integer registers for FP operations
3204 ;; when optimizing for size.
3205
3206 (define_insn "*movdf_internal_nointeger"
3207   [(set (match_operand:DF 0 "nonimmediate_operand"
3208                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3209         (match_operand:DF 1 "general_operand"
3210                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3211   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3212    && ((optimize_function_for_size_p (cfun)
3213        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3214    && (reload_in_progress || reload_completed
3215        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3216        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3217            && optimize_function_for_size_p (cfun)
3218            && !memory_operand (operands[0], DFmode)
3219            && standard_80387_constant_p (operands[1]))
3220        || GET_CODE (operands[1]) != CONST_DOUBLE
3221        || ((optimize_function_for_size_p (cfun)
3222             || !TARGET_MEMORY_MISMATCH_STALL
3223             || reload_in_progress || reload_completed)
3224            && memory_operand (operands[0], DFmode)))"
3225 {
3226   switch (which_alternative)
3227     {
3228     case 0:
3229     case 1:
3230       return output_387_reg_move (insn, operands);
3231
3232     case 2:
3233       return standard_80387_constant_opcode (operands[1]);
3234
3235     case 3:
3236     case 4:
3237       return "#";
3238
3239     case 5:
3240       switch (get_attr_mode (insn))
3241         {
3242         case MODE_V4SF:
3243           return "%vxorps\t%0, %d0";
3244         case MODE_V2DF:
3245           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3246             return "%vxorps\t%0, %d0";
3247           else
3248             return "%vxorpd\t%0, %d0";
3249         case MODE_TI:
3250           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3251             return "%vxorps\t%0, %d0";
3252           else
3253             return "%vpxor\t%0, %d0";
3254         default:
3255           gcc_unreachable ();
3256         }
3257     case 6:
3258     case 7:
3259     case 8:
3260       switch (get_attr_mode (insn))
3261         {
3262         case MODE_V4SF:
3263           return "%vmovaps\t{%1, %0|%0, %1}";
3264         case MODE_V2DF:
3265           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3266             return "%vmovaps\t{%1, %0|%0, %1}";
3267           else
3268             return "%vmovapd\t{%1, %0|%0, %1}";
3269         case MODE_TI:
3270           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3271             return "%vmovaps\t{%1, %0|%0, %1}";
3272           else
3273             return "%vmovdqa\t{%1, %0|%0, %1}";
3274         case MODE_DI:
3275           return "%vmovq\t{%1, %0|%0, %1}";
3276         case MODE_DF:
3277           if (TARGET_AVX)
3278             {
3279               if (REG_P (operands[0]) && REG_P (operands[1]))
3280                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3281               else
3282                 return "vmovsd\t{%1, %0|%0, %1}";
3283             }
3284           else
3285             return "movsd\t{%1, %0|%0, %1}";
3286         case MODE_V1DF:
3287           if (TARGET_AVX)
3288             {
3289               if (REG_P (operands[0]))
3290                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3291               else
3292                 return "vmovlpd\t{%1, %0|%0, %1}";
3293             }
3294           else
3295             return "movlpd\t{%1, %0|%0, %1}";
3296         case MODE_V2SF:
3297           if (TARGET_AVX)
3298             {
3299               if (REG_P (operands[0]))
3300                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3301               else
3302                 return "vmovlps\t{%1, %0|%0, %1}";
3303             }
3304           else
3305             return "movlps\t{%1, %0|%0, %1}";
3306         default:
3307           gcc_unreachable ();
3308         }
3309
3310     default:
3311       gcc_unreachable ();
3312     }
3313 }
3314   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3315    (set (attr "prefix")
3316      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3317        (const_string "orig")
3318        (const_string "maybe_vex")))
3319    (set (attr "prefix_data16")
3320      (if_then_else (eq_attr "mode" "V1DF")
3321        (const_string "1")
3322        (const_string "*")))
3323    (set (attr "mode")
3324         (cond [(eq_attr "alternative" "0,1,2")
3325                  (const_string "DF")
3326                (eq_attr "alternative" "3,4")
3327                  (const_string "SI")
3328
3329                /* For SSE1, we have many fewer alternatives.  */
3330                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3331                  (cond [(eq_attr "alternative" "5,6")
3332                           (const_string "V4SF")
3333                        ]
3334                    (const_string "V2SF"))
3335
3336                /* xorps is one byte shorter.  */
3337                (eq_attr "alternative" "5")
3338                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3339                             (const_int 0))
3340                           (const_string "V4SF")
3341                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3342                             (const_int 0))
3343                           (const_string "TI")
3344                        ]
3345                        (const_string "V2DF"))
3346
3347                /* For architectures resolving dependencies on
3348                   whole SSE registers use APD move to break dependency
3349                   chains, otherwise use short move to avoid extra work.
3350
3351                   movaps encodes one byte shorter.  */
3352                (eq_attr "alternative" "6")
3353                  (cond
3354                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3355                         (const_int 0))
3356                       (const_string "V4SF")
3357                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3358                         (const_int 0))
3359                       (const_string "V2DF")
3360                    ]
3361                    (const_string "DF"))
3362                /* For architectures resolving dependencies on register
3363                   parts we may avoid extra work to zero out upper part
3364                   of register.  */
3365                (eq_attr "alternative" "7")
3366                  (if_then_else
3367                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3368                        (const_int 0))
3369                    (const_string "V1DF")
3370                    (const_string "DF"))
3371               ]
3372               (const_string "DF")))])
3373
3374 (define_split
3375   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3376         (match_operand:DF 1 "general_operand" ""))]
3377   "reload_completed
3378    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3379    && ! (ANY_FP_REG_P (operands[0]) ||
3380          (GET_CODE (operands[0]) == SUBREG
3381           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3382    && ! (ANY_FP_REG_P (operands[1]) ||
3383          (GET_CODE (operands[1]) == SUBREG
3384           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3385   [(const_int 0)]
3386   "ix86_split_long_move (operands); DONE;")
3387
3388 (define_insn "*movsf_internal"
3389   [(set (match_operand:SF 0 "nonimmediate_operand"
3390           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3391         (match_operand:SF 1 "general_operand"
3392           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3393   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3394    && (reload_in_progress || reload_completed
3395        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3396        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3397            && standard_80387_constant_p (operands[1]))
3398        || GET_CODE (operands[1]) != CONST_DOUBLE
3399        || memory_operand (operands[0], SFmode))"
3400 {
3401   switch (which_alternative)
3402     {
3403     case 0:
3404     case 1:
3405       return output_387_reg_move (insn, operands);
3406
3407     case 2:
3408       return standard_80387_constant_opcode (operands[1]);
3409
3410     case 3:
3411     case 4:
3412       return "mov{l}\t{%1, %0|%0, %1}";
3413     case 5:
3414       if (get_attr_mode (insn) == MODE_TI)
3415         return "%vpxor\t%0, %d0";
3416       else
3417         return "%vxorps\t%0, %d0";
3418     case 6:
3419       if (get_attr_mode (insn) == MODE_V4SF)
3420         return "%vmovaps\t{%1, %0|%0, %1}";
3421       else
3422         return "%vmovss\t{%1, %d0|%d0, %1}";
3423     case 7:
3424       if (TARGET_AVX)
3425         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3426                                    : "vmovss\t{%1, %0|%0, %1}";
3427       else
3428         return "movss\t{%1, %0|%0, %1}";
3429     case 8:
3430       return "%vmovss\t{%1, %0|%0, %1}";
3431
3432     case 9: case 10: case 14: case 15:
3433       return "movd\t{%1, %0|%0, %1}";
3434     case 12: case 13:
3435       return "%vmovd\t{%1, %0|%0, %1}";
3436
3437     case 11:
3438       return "movq\t{%1, %0|%0, %1}";
3439
3440     default:
3441       gcc_unreachable ();
3442     }
3443 }
3444   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3445    (set (attr "prefix")
3446      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3447        (const_string "maybe_vex")
3448        (const_string "orig")))
3449    (set (attr "mode")
3450         (cond [(eq_attr "alternative" "3,4,9,10")
3451                  (const_string "SI")
3452                (eq_attr "alternative" "5")
3453                  (if_then_else
3454                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3455                                  (const_int 0))
3456                              (ne (symbol_ref "TARGET_SSE2")
3457                                  (const_int 0)))
3458                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3459                             (const_int 0)))
3460                    (const_string "TI")
3461                    (const_string "V4SF"))
3462                /* For architectures resolving dependencies on
3463                   whole SSE registers use APS move to break dependency
3464                   chains, otherwise use short move to avoid extra work.
3465
3466                   Do the same for architectures resolving dependencies on
3467                   the parts.  While in DF mode it is better to always handle
3468                   just register parts, the SF mode is different due to lack
3469                   of instructions to load just part of the register.  It is
3470                   better to maintain the whole registers in single format
3471                   to avoid problems on using packed logical operations.  */
3472                (eq_attr "alternative" "6")
3473                  (if_then_else
3474                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3475                             (const_int 0))
3476                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3477                             (const_int 0)))
3478                    (const_string "V4SF")
3479                    (const_string "SF"))
3480                (eq_attr "alternative" "11")
3481                  (const_string "DI")]
3482                (const_string "SF")))])
3483
3484 (define_split
3485   [(set (match_operand 0 "register_operand" "")
3486         (match_operand 1 "memory_operand" ""))]
3487   "reload_completed
3488    && MEM_P (operands[1])
3489    && (GET_MODE (operands[0]) == TFmode
3490        || GET_MODE (operands[0]) == XFmode
3491        || GET_MODE (operands[0]) == DFmode
3492        || GET_MODE (operands[0]) == SFmode)
3493    && (operands[2] = find_constant_src (insn))"
3494   [(set (match_dup 0) (match_dup 2))]
3495 {
3496   rtx c = operands[2];
3497   rtx r = operands[0];
3498
3499   if (GET_CODE (r) == SUBREG)
3500     r = SUBREG_REG (r);
3501
3502   if (SSE_REG_P (r))
3503     {
3504       if (!standard_sse_constant_p (c))
3505         FAIL;
3506     }
3507   else if (FP_REG_P (r))
3508     {
3509       if (!standard_80387_constant_p (c))
3510         FAIL;
3511     }
3512   else if (MMX_REG_P (r))
3513     FAIL;
3514 })
3515
3516 (define_split
3517   [(set (match_operand 0 "register_operand" "")
3518         (float_extend (match_operand 1 "memory_operand" "")))]
3519   "reload_completed
3520    && MEM_P (operands[1])
3521    && (GET_MODE (operands[0]) == TFmode
3522        || GET_MODE (operands[0]) == XFmode
3523        || GET_MODE (operands[0]) == DFmode
3524        || GET_MODE (operands[0]) == SFmode)
3525    && (operands[2] = find_constant_src (insn))"
3526   [(set (match_dup 0) (match_dup 2))]
3527 {
3528   rtx c = operands[2];
3529   rtx r = operands[0];
3530
3531   if (GET_CODE (r) == SUBREG)
3532     r = SUBREG_REG (r);
3533
3534   if (SSE_REG_P (r))
3535     {
3536       if (!standard_sse_constant_p (c))
3537         FAIL;
3538     }
3539   else if (FP_REG_P (r))
3540     {
3541       if (!standard_80387_constant_p (c))
3542         FAIL;
3543     }
3544   else if (MMX_REG_P (r))
3545     FAIL;
3546 })
3547
3548 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3549 (define_split
3550   [(set (match_operand:X87MODEF 0 "register_operand" "")
3551         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3552   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3553    && (standard_80387_constant_p (operands[1]) == 8
3554        || standard_80387_constant_p (operands[1]) == 9)"
3555   [(set (match_dup 0)(match_dup 1))
3556    (set (match_dup 0)
3557         (neg:X87MODEF (match_dup 0)))]
3558 {
3559   REAL_VALUE_TYPE r;
3560
3561   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3562   if (real_isnegzero (&r))
3563     operands[1] = CONST0_RTX (<MODE>mode);
3564   else
3565     operands[1] = CONST1_RTX (<MODE>mode);
3566 })
3567
3568 (define_insn "swapxf"
3569   [(set (match_operand:XF 0 "register_operand" "+f")
3570         (match_operand:XF 1 "register_operand" "+f"))
3571    (set (match_dup 1)
3572         (match_dup 0))]
3573   "TARGET_80387"
3574 {
3575   if (STACK_TOP_P (operands[0]))
3576     return "fxch\t%1";
3577   else
3578     return "fxch\t%0";
3579 }
3580   [(set_attr "type" "fxch")
3581    (set_attr "mode" "XF")])
3582
3583 (define_insn "*swap<mode>"
3584   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3585         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3586    (set (match_dup 1)
3587         (match_dup 0))]
3588   "TARGET_80387 || reload_completed"
3589 {
3590   if (STACK_TOP_P (operands[0]))
3591     return "fxch\t%1";
3592   else
3593     return "fxch\t%0";
3594 }
3595   [(set_attr "type" "fxch")
3596    (set_attr "mode" "<MODE>")])
3597 \f
3598 ;; Zero extension instructions
3599
3600 (define_expand "zero_extendsidi2"
3601   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3602         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3603   ""
3604 {
3605   if (!TARGET_64BIT)
3606     {
3607       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3608       DONE;
3609     }
3610 })
3611
3612 (define_insn "*zero_extendsidi2_rex64"
3613   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3614         (zero_extend:DI
3615          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3616   "TARGET_64BIT"
3617   "@
3618    mov\t{%k1, %k0|%k0, %k1}
3619    #
3620    movd\t{%1, %0|%0, %1}
3621    movd\t{%1, %0|%0, %1}
3622    %vmovd\t{%1, %0|%0, %1}
3623    %vmovd\t{%1, %0|%0, %1}"
3624   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3625    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3626    (set_attr "prefix_0f" "0,*,*,*,*,*")
3627    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3628
3629 (define_split
3630   [(set (match_operand:DI 0 "memory_operand" "")
3631         (zero_extend:DI (match_dup 0)))]
3632   "TARGET_64BIT"
3633   [(set (match_dup 4) (const_int 0))]
3634   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3635
3636 ;; %%% Kill me once multi-word ops are sane.
3637 (define_insn "zero_extendsidi2_1"
3638   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3639         (zero_extend:DI
3640          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3641    (clobber (reg:CC FLAGS_REG))]
3642   "!TARGET_64BIT"
3643   "@
3644    #
3645    #
3646    #
3647    movd\t{%1, %0|%0, %1}
3648    movd\t{%1, %0|%0, %1}
3649    %vmovd\t{%1, %0|%0, %1}
3650    %vmovd\t{%1, %0|%0, %1}"
3651   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3652    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3653    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3654
3655 (define_split
3656   [(set (match_operand:DI 0 "register_operand" "")
3657         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3658    (clobber (reg:CC FLAGS_REG))]
3659   "!TARGET_64BIT && reload_completed
3660    && true_regnum (operands[0]) == true_regnum (operands[1])"
3661   [(set (match_dup 4) (const_int 0))]
3662   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3663
3664 (define_split
3665   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3666         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3667    (clobber (reg:CC FLAGS_REG))]
3668   "!TARGET_64BIT && reload_completed
3669    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3670   [(set (match_dup 3) (match_dup 1))
3671    (set (match_dup 4) (const_int 0))]
3672   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3673
3674 (define_insn "zero_extend<mode>di2"
3675   [(set (match_operand:DI 0 "register_operand" "=r")
3676         (zero_extend:DI
3677          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3678   "TARGET_64BIT"
3679   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3680   [(set_attr "type" "imovx")
3681    (set_attr "mode" "SI")])
3682
3683 (define_expand "zero_extendhisi2"
3684   [(set (match_operand:SI 0 "register_operand" "")
3685         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3686   ""
3687 {
3688   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3689     {
3690       operands[1] = force_reg (HImode, operands[1]);
3691       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3692       DONE;
3693     }
3694 })
3695
3696 (define_insn_and_split "zero_extendhisi2_and"
3697   [(set (match_operand:SI 0 "register_operand" "=r")
3698         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3699    (clobber (reg:CC FLAGS_REG))]
3700   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3701   "#"
3702   "&& reload_completed"
3703   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3704               (clobber (reg:CC FLAGS_REG))])]
3705   ""
3706   [(set_attr "type" "alu1")
3707    (set_attr "mode" "SI")])
3708
3709 (define_insn "*zero_extendhisi2_movzwl"
3710   [(set (match_operand:SI 0 "register_operand" "=r")
3711         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3712   "!TARGET_ZERO_EXTEND_WITH_AND
3713    || optimize_function_for_size_p (cfun)"
3714   "movz{wl|x}\t{%1, %0|%0, %1}"
3715   [(set_attr "type" "imovx")
3716    (set_attr "mode" "SI")])
3717
3718 (define_expand "zero_extendqi<mode>2"
3719   [(parallel
3720     [(set (match_operand:SWI24 0 "register_operand" "")
3721           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3722      (clobber (reg:CC FLAGS_REG))])])
3723
3724 (define_insn "*zero_extendqi<mode>2_and"
3725   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3726         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3727    (clobber (reg:CC FLAGS_REG))]
3728   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3729   "#"
3730   [(set_attr "type" "alu1")
3731    (set_attr "mode" "<MODE>")])
3732
3733 ;; When source and destination does not overlap, clear destination
3734 ;; first and then do the movb
3735 (define_split
3736   [(set (match_operand:SWI24 0 "register_operand" "")
3737         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3738    (clobber (reg:CC FLAGS_REG))]
3739   "reload_completed
3740    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3741    && ANY_QI_REG_P (operands[0])
3742    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3743    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3744   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3745 {
3746   operands[2] = gen_lowpart (QImode, operands[0]);
3747   ix86_expand_clear (operands[0]);
3748 })
3749
3750 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3751   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3752         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3753    (clobber (reg:CC FLAGS_REG))]
3754   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3755   "#"
3756   [(set_attr "type" "imovx,alu1")
3757    (set_attr "mode" "<MODE>")])
3758
3759 ;; For the movzbl case strip only the clobber
3760 (define_split
3761   [(set (match_operand:SWI24 0 "register_operand" "")
3762         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3763    (clobber (reg:CC FLAGS_REG))]
3764   "reload_completed
3765    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3766    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3767   [(set (match_dup 0)
3768         (zero_extend:SWI24 (match_dup 1)))])
3769
3770 ; zero extend to SImode to avoid partial register stalls
3771 (define_insn "*zero_extendqi<mode>2_movzbl"
3772   [(set (match_operand:SWI24 0 "register_operand" "=r")
3773         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3774   "reload_completed
3775    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3776   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3777   [(set_attr "type" "imovx")
3778    (set_attr "mode" "SI")])
3779
3780 ;; Rest is handled by single and.
3781 (define_split
3782   [(set (match_operand:SWI24 0 "register_operand" "")
3783         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3784    (clobber (reg:CC FLAGS_REG))]
3785   "reload_completed
3786    && true_regnum (operands[0]) == true_regnum (operands[1])"
3787   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3788               (clobber (reg:CC FLAGS_REG))])])
3789 \f
3790 ;; Sign extension instructions
3791
3792 (define_expand "extendsidi2"
3793   [(set (match_operand:DI 0 "register_operand" "")
3794         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3795   ""
3796 {
3797   if (!TARGET_64BIT)
3798     {
3799       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3800       DONE;
3801     }
3802 })
3803
3804 (define_insn "*extendsidi2_rex64"
3805   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3806         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3807   "TARGET_64BIT"
3808   "@
3809    {cltq|cdqe}
3810    movs{lq|x}\t{%1, %0|%0, %1}"
3811   [(set_attr "type" "imovx")
3812    (set_attr "mode" "DI")
3813    (set_attr "prefix_0f" "0")
3814    (set_attr "modrm" "0,1")])
3815
3816 (define_insn "extendsidi2_1"
3817   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3818         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3819    (clobber (reg:CC FLAGS_REG))
3820    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3821   "!TARGET_64BIT"
3822   "#")
3823
3824 ;; Extend to memory case when source register does die.
3825 (define_split
3826   [(set (match_operand:DI 0 "memory_operand" "")
3827         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3828    (clobber (reg:CC FLAGS_REG))
3829    (clobber (match_operand:SI 2 "register_operand" ""))]
3830   "(reload_completed
3831     && dead_or_set_p (insn, operands[1])
3832     && !reg_mentioned_p (operands[1], operands[0]))"
3833   [(set (match_dup 3) (match_dup 1))
3834    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3835               (clobber (reg:CC FLAGS_REG))])
3836    (set (match_dup 4) (match_dup 1))]
3837   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3838
3839 ;; Extend to memory case when source register does not die.
3840 (define_split
3841   [(set (match_operand:DI 0 "memory_operand" "")
3842         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3843    (clobber (reg:CC FLAGS_REG))
3844    (clobber (match_operand:SI 2 "register_operand" ""))]
3845   "reload_completed"
3846   [(const_int 0)]
3847 {
3848   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3849
3850   emit_move_insn (operands[3], operands[1]);
3851
3852   /* Generate a cltd if possible and doing so it profitable.  */
3853   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3854       && true_regnum (operands[1]) == AX_REG
3855       && true_regnum (operands[2]) == DX_REG)
3856     {
3857       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3858     }
3859   else
3860     {
3861       emit_move_insn (operands[2], operands[1]);
3862       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3863     }
3864   emit_move_insn (operands[4], operands[2]);
3865   DONE;
3866 })
3867
3868 ;; Extend to register case.  Optimize case where source and destination
3869 ;; registers match and cases where we can use cltd.
3870 (define_split
3871   [(set (match_operand:DI 0 "register_operand" "")
3872         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3873    (clobber (reg:CC FLAGS_REG))
3874    (clobber (match_scratch:SI 2 ""))]
3875   "reload_completed"
3876   [(const_int 0)]
3877 {
3878   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3879
3880   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3881     emit_move_insn (operands[3], operands[1]);
3882
3883   /* Generate a cltd if possible and doing so it profitable.  */
3884   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3885       && true_regnum (operands[3]) == AX_REG
3886       && true_regnum (operands[4]) == DX_REG)
3887     {
3888       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3889       DONE;
3890     }
3891
3892   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3893     emit_move_insn (operands[4], operands[1]);
3894
3895   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3896   DONE;
3897 })
3898
3899 (define_insn "extend<mode>di2"
3900   [(set (match_operand:DI 0 "register_operand" "=r")
3901         (sign_extend:DI
3902          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3903   "TARGET_64BIT"
3904   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3905   [(set_attr "type" "imovx")
3906    (set_attr "mode" "DI")])
3907
3908 (define_insn "extendhisi2"
3909   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3910         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3911   ""
3912 {
3913   switch (get_attr_prefix_0f (insn))
3914     {
3915     case 0:
3916       return "{cwtl|cwde}";
3917     default:
3918       return "movs{wl|x}\t{%1, %0|%0, %1}";
3919     }
3920 }
3921   [(set_attr "type" "imovx")
3922    (set_attr "mode" "SI")
3923    (set (attr "prefix_0f")
3924      ;; movsx is short decodable while cwtl is vector decoded.
3925      (if_then_else (and (eq_attr "cpu" "!k6")
3926                         (eq_attr "alternative" "0"))
3927         (const_string "0")
3928         (const_string "1")))
3929    (set (attr "modrm")
3930      (if_then_else (eq_attr "prefix_0f" "0")
3931         (const_string "0")
3932         (const_string "1")))])
3933
3934 (define_insn "*extendhisi2_zext"
3935   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3936         (zero_extend:DI
3937          (sign_extend:SI
3938           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3939   "TARGET_64BIT"
3940 {
3941   switch (get_attr_prefix_0f (insn))
3942     {
3943     case 0:
3944       return "{cwtl|cwde}";
3945     default:
3946       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3947     }
3948 }
3949   [(set_attr "type" "imovx")
3950    (set_attr "mode" "SI")
3951    (set (attr "prefix_0f")
3952      ;; movsx is short decodable while cwtl is vector decoded.
3953      (if_then_else (and (eq_attr "cpu" "!k6")
3954                         (eq_attr "alternative" "0"))
3955         (const_string "0")
3956         (const_string "1")))
3957    (set (attr "modrm")
3958      (if_then_else (eq_attr "prefix_0f" "0")
3959         (const_string "0")
3960         (const_string "1")))])
3961
3962 (define_insn "extendqisi2"
3963   [(set (match_operand:SI 0 "register_operand" "=r")
3964         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3965   ""
3966   "movs{bl|x}\t{%1, %0|%0, %1}"
3967    [(set_attr "type" "imovx")
3968     (set_attr "mode" "SI")])
3969
3970 (define_insn "*extendqisi2_zext"
3971   [(set (match_operand:DI 0 "register_operand" "=r")
3972         (zero_extend:DI
3973           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3974   "TARGET_64BIT"
3975   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3976    [(set_attr "type" "imovx")
3977     (set_attr "mode" "SI")])
3978
3979 (define_insn "extendqihi2"
3980   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3981         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3982   ""
3983 {
3984   switch (get_attr_prefix_0f (insn))
3985     {
3986     case 0:
3987       return "{cbtw|cbw}";
3988     default:
3989       return "movs{bw|x}\t{%1, %0|%0, %1}";
3990     }
3991 }
3992   [(set_attr "type" "imovx")
3993    (set_attr "mode" "HI")
3994    (set (attr "prefix_0f")
3995      ;; movsx is short decodable while cwtl is vector decoded.
3996      (if_then_else (and (eq_attr "cpu" "!k6")
3997                         (eq_attr "alternative" "0"))
3998         (const_string "0")
3999         (const_string "1")))
4000    (set (attr "modrm")
4001      (if_then_else (eq_attr "prefix_0f" "0")
4002         (const_string "0")
4003         (const_string "1")))])
4004 \f
4005 ;; Conversions between float and double.
4006
4007 ;; These are all no-ops in the model used for the 80387.
4008 ;; So just emit moves.
4009
4010 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4011 (define_split
4012   [(set (match_operand:DF 0 "push_operand" "")
4013         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4014   "reload_completed"
4015   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4016    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4017
4018 (define_split
4019   [(set (match_operand:XF 0 "push_operand" "")
4020         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4021   "reload_completed"
4022   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4023    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4024   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4025
4026 (define_expand "extendsfdf2"
4027   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4028         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4029   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4030 {
4031   /* ??? Needed for compress_float_constant since all fp constants
4032      are LEGITIMATE_CONSTANT_P.  */
4033   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4034     {
4035       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4036           && standard_80387_constant_p (operands[1]) > 0)
4037         {
4038           operands[1] = simplify_const_unary_operation
4039             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4040           emit_move_insn_1 (operands[0], operands[1]);
4041           DONE;
4042         }
4043       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4044     }
4045 })
4046
4047 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4048    cvtss2sd:
4049       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4050       cvtps2pd xmm2,xmm1
4051    We do the conversion post reload to avoid producing of 128bit spills
4052    that might lead to ICE on 32bit target.  The sequence unlikely combine
4053    anyway.  */
4054 (define_split
4055   [(set (match_operand:DF 0 "register_operand" "")
4056         (float_extend:DF
4057           (match_operand:SF 1 "nonimmediate_operand" "")))]
4058   "TARGET_USE_VECTOR_FP_CONVERTS
4059    && optimize_insn_for_speed_p ()
4060    && reload_completed && SSE_REG_P (operands[0])"
4061    [(set (match_dup 2)
4062          (float_extend:V2DF
4063            (vec_select:V2SF
4064              (match_dup 3)
4065              (parallel [(const_int 0) (const_int 1)]))))]
4066 {
4067   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4068   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4069   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4070      Try to avoid move when unpacking can be done in source.  */
4071   if (REG_P (operands[1]))
4072     {
4073       /* If it is unsafe to overwrite upper half of source, we need
4074          to move to destination and unpack there.  */
4075       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4076            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4077           && true_regnum (operands[0]) != true_regnum (operands[1]))
4078         {
4079           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4080           emit_move_insn (tmp, operands[1]);
4081         }
4082       else
4083         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4084       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4085                                              operands[3]));
4086     }
4087   else
4088     emit_insn (gen_vec_setv4sf_0 (operands[3],
4089                                   CONST0_RTX (V4SFmode), operands[1]));
4090 })
4091
4092 (define_insn "*extendsfdf2_mixed"
4093   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4094         (float_extend:DF
4095           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4096   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4097 {
4098   switch (which_alternative)
4099     {
4100     case 0:
4101     case 1:
4102       return output_387_reg_move (insn, operands);
4103
4104     case 2:
4105       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4106
4107     default:
4108       gcc_unreachable ();
4109     }
4110 }
4111   [(set_attr "type" "fmov,fmov,ssecvt")
4112    (set_attr "prefix" "orig,orig,maybe_vex")
4113    (set_attr "mode" "SF,XF,DF")])
4114
4115 (define_insn "*extendsfdf2_sse"
4116   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4117         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4118   "TARGET_SSE2 && TARGET_SSE_MATH"
4119   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4120   [(set_attr "type" "ssecvt")
4121    (set_attr "prefix" "maybe_vex")
4122    (set_attr "mode" "DF")])
4123
4124 (define_insn "*extendsfdf2_i387"
4125   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4126         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4127   "TARGET_80387"
4128   "* return output_387_reg_move (insn, operands);"
4129   [(set_attr "type" "fmov")
4130    (set_attr "mode" "SF,XF")])
4131
4132 (define_expand "extend<mode>xf2"
4133   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4134         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4135   "TARGET_80387"
4136 {
4137   /* ??? Needed for compress_float_constant since all fp constants
4138      are LEGITIMATE_CONSTANT_P.  */
4139   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4140     {
4141       if (standard_80387_constant_p (operands[1]) > 0)
4142         {
4143           operands[1] = simplify_const_unary_operation
4144             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4145           emit_move_insn_1 (operands[0], operands[1]);
4146           DONE;
4147         }
4148       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4149     }
4150 })
4151
4152 (define_insn "*extend<mode>xf2_i387"
4153   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4154         (float_extend:XF
4155           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4156   "TARGET_80387"
4157   "* return output_387_reg_move (insn, operands);"
4158   [(set_attr "type" "fmov")
4159    (set_attr "mode" "<MODE>,XF")])
4160
4161 ;; %%% This seems bad bad news.
4162 ;; This cannot output into an f-reg because there is no way to be sure
4163 ;; of truncating in that case.  Otherwise this is just like a simple move
4164 ;; insn.  So we pretend we can output to a reg in order to get better
4165 ;; register preferencing, but we really use a stack slot.
4166
4167 ;; Conversion from DFmode to SFmode.
4168
4169 (define_expand "truncdfsf2"
4170   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4171         (float_truncate:SF
4172           (match_operand:DF 1 "nonimmediate_operand" "")))]
4173   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4174 {
4175   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4176     ;
4177   else if (flag_unsafe_math_optimizations)
4178     ;
4179   else
4180     {
4181       enum ix86_stack_slot slot = (virtuals_instantiated
4182                                    ? SLOT_TEMP
4183                                    : SLOT_VIRTUAL);
4184       rtx temp = assign_386_stack_local (SFmode, slot);
4185       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4186       DONE;
4187     }
4188 })
4189
4190 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4191    cvtsd2ss:
4192       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4193       cvtpd2ps xmm2,xmm1
4194    We do the conversion post reload to avoid producing of 128bit spills
4195    that might lead to ICE on 32bit target.  The sequence unlikely combine
4196    anyway.  */
4197 (define_split
4198   [(set (match_operand:SF 0 "register_operand" "")
4199         (float_truncate:SF
4200           (match_operand:DF 1 "nonimmediate_operand" "")))]
4201   "TARGET_USE_VECTOR_FP_CONVERTS
4202    && optimize_insn_for_speed_p ()
4203    && reload_completed && SSE_REG_P (operands[0])"
4204    [(set (match_dup 2)
4205          (vec_concat:V4SF
4206            (float_truncate:V2SF
4207              (match_dup 4))
4208            (match_dup 3)))]
4209 {
4210   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4211   operands[3] = CONST0_RTX (V2SFmode);
4212   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4213   /* Use movsd for loading from memory, unpcklpd for registers.
4214      Try to avoid move when unpacking can be done in source, or SSE3
4215      movddup is available.  */
4216   if (REG_P (operands[1]))
4217     {
4218       if (!TARGET_SSE3
4219           && true_regnum (operands[0]) != true_regnum (operands[1])
4220           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4221               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4222         {
4223           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4224           emit_move_insn (tmp, operands[1]);
4225           operands[1] = tmp;
4226         }
4227       else if (!TARGET_SSE3)
4228         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4229       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4230     }
4231   else
4232     emit_insn (gen_sse2_loadlpd (operands[4],
4233                                  CONST0_RTX (V2DFmode), operands[1]));
4234 })
4235
4236 (define_expand "truncdfsf2_with_temp"
4237   [(parallel [(set (match_operand:SF 0 "" "")
4238                    (float_truncate:SF (match_operand:DF 1 "" "")))
4239               (clobber (match_operand:SF 2 "" ""))])])
4240
4241 (define_insn "*truncdfsf_fast_mixed"
4242   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4243         (float_truncate:SF
4244           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4245   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4246 {
4247   switch (which_alternative)
4248     {
4249     case 0:
4250       return output_387_reg_move (insn, operands);
4251     case 1:
4252       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4253     default:
4254       gcc_unreachable ();
4255     }
4256 }
4257   [(set_attr "type" "fmov,ssecvt")
4258    (set_attr "prefix" "orig,maybe_vex")
4259    (set_attr "mode" "SF")])
4260
4261 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4262 ;; because nothing we do here is unsafe.
4263 (define_insn "*truncdfsf_fast_sse"
4264   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4265         (float_truncate:SF
4266           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4267   "TARGET_SSE2 && TARGET_SSE_MATH"
4268   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4269   [(set_attr "type" "ssecvt")
4270    (set_attr "prefix" "maybe_vex")
4271    (set_attr "mode" "SF")])
4272
4273 (define_insn "*truncdfsf_fast_i387"
4274   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4275         (float_truncate:SF
4276           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4277   "TARGET_80387 && flag_unsafe_math_optimizations"
4278   "* return output_387_reg_move (insn, operands);"
4279   [(set_attr "type" "fmov")
4280    (set_attr "mode" "SF")])
4281
4282 (define_insn "*truncdfsf_mixed"
4283   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4284         (float_truncate:SF
4285           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4286    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4287   "TARGET_MIX_SSE_I387"
4288 {
4289   switch (which_alternative)
4290     {
4291     case 0:
4292       return output_387_reg_move (insn, operands);
4293     case 1:
4294       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4295
4296     default:
4297       return "#";
4298     }
4299 }
4300   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4301    (set_attr "unit" "*,*,i387,i387,i387")
4302    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4303    (set_attr "mode" "SF")])
4304
4305 (define_insn "*truncdfsf_i387"
4306   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4307         (float_truncate:SF
4308           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4309    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4310   "TARGET_80387"
4311 {
4312   switch (which_alternative)
4313     {
4314     case 0:
4315       return output_387_reg_move (insn, operands);
4316
4317     default:
4318       return "#";
4319     }
4320 }
4321   [(set_attr "type" "fmov,multi,multi,multi")
4322    (set_attr "unit" "*,i387,i387,i387")
4323    (set_attr "mode" "SF")])
4324
4325 (define_insn "*truncdfsf2_i387_1"
4326   [(set (match_operand:SF 0 "memory_operand" "=m")
4327         (float_truncate:SF
4328           (match_operand:DF 1 "register_operand" "f")))]
4329   "TARGET_80387
4330    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4331    && !TARGET_MIX_SSE_I387"
4332   "* return output_387_reg_move (insn, operands);"
4333   [(set_attr "type" "fmov")
4334    (set_attr "mode" "SF")])
4335
4336 (define_split
4337   [(set (match_operand:SF 0 "register_operand" "")
4338         (float_truncate:SF
4339          (match_operand:DF 1 "fp_register_operand" "")))
4340    (clobber (match_operand 2 "" ""))]
4341   "reload_completed"
4342   [(set (match_dup 2) (match_dup 1))
4343    (set (match_dup 0) (match_dup 2))]
4344   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4345
4346 ;; Conversion from XFmode to {SF,DF}mode
4347
4348 (define_expand "truncxf<mode>2"
4349   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4350                    (float_truncate:MODEF
4351                      (match_operand:XF 1 "register_operand" "")))
4352               (clobber (match_dup 2))])]
4353   "TARGET_80387"
4354 {
4355   if (flag_unsafe_math_optimizations)
4356     {
4357       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4358       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4359       if (reg != operands[0])
4360         emit_move_insn (operands[0], reg);
4361       DONE;
4362     }
4363   else
4364     {
4365       enum ix86_stack_slot slot = (virtuals_instantiated
4366                                    ? SLOT_TEMP
4367                                    : SLOT_VIRTUAL);
4368       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4369     }
4370 })
4371
4372 (define_insn "*truncxfsf2_mixed"
4373   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4374         (float_truncate:SF
4375           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4376    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4377   "TARGET_80387"
4378 {
4379   gcc_assert (!which_alternative);
4380   return output_387_reg_move (insn, operands);
4381 }
4382   [(set_attr "type" "fmov,multi,multi,multi")
4383    (set_attr "unit" "*,i387,i387,i387")
4384    (set_attr "mode" "SF")])
4385
4386 (define_insn "*truncxfdf2_mixed"
4387   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4388         (float_truncate:DF
4389           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4390    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4391   "TARGET_80387"
4392 {
4393   gcc_assert (!which_alternative);
4394   return output_387_reg_move (insn, operands);
4395 }
4396   [(set_attr "type" "fmov,multi,multi,multi")
4397    (set_attr "unit" "*,i387,i387,i387")
4398    (set_attr "mode" "DF")])
4399
4400 (define_insn "truncxf<mode>2_i387_noop"
4401   [(set (match_operand:MODEF 0 "register_operand" "=f")
4402         (float_truncate:MODEF
4403           (match_operand:XF 1 "register_operand" "f")))]
4404   "TARGET_80387 && flag_unsafe_math_optimizations"
4405   "* return output_387_reg_move (insn, operands);"
4406   [(set_attr "type" "fmov")
4407    (set_attr "mode" "<MODE>")])
4408
4409 (define_insn "*truncxf<mode>2_i387"
4410   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4411         (float_truncate:MODEF
4412           (match_operand:XF 1 "register_operand" "f")))]
4413   "TARGET_80387"
4414   "* return output_387_reg_move (insn, operands);"
4415   [(set_attr "type" "fmov")
4416    (set_attr "mode" "<MODE>")])
4417
4418 (define_split
4419   [(set (match_operand:MODEF 0 "register_operand" "")
4420         (float_truncate:MODEF
4421           (match_operand:XF 1 "register_operand" "")))
4422    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4423   "TARGET_80387 && reload_completed"
4424   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4425    (set (match_dup 0) (match_dup 2))])
4426
4427 (define_split
4428   [(set (match_operand:MODEF 0 "memory_operand" "")
4429         (float_truncate:MODEF
4430           (match_operand:XF 1 "register_operand" "")))
4431    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4432   "TARGET_80387"
4433   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4434 \f
4435 ;; Signed conversion to DImode.
4436
4437 (define_expand "fix_truncxfdi2"
4438   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4439                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4440               (clobber (reg:CC FLAGS_REG))])]
4441   "TARGET_80387"
4442 {
4443   if (TARGET_FISTTP)
4444    {
4445      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4446      DONE;
4447    }
4448 })
4449
4450 (define_expand "fix_trunc<mode>di2"
4451   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4452                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4453               (clobber (reg:CC FLAGS_REG))])]
4454   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4455 {
4456   if (TARGET_FISTTP
4457       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4458    {
4459      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4460      DONE;
4461    }
4462   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4463    {
4464      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4465      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4466      if (out != operands[0])
4467         emit_move_insn (operands[0], out);
4468      DONE;
4469    }
4470 })
4471
4472 ;; Signed conversion to SImode.
4473
4474 (define_expand "fix_truncxfsi2"
4475   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4476                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4477               (clobber (reg:CC FLAGS_REG))])]
4478   "TARGET_80387"
4479 {
4480   if (TARGET_FISTTP)
4481    {
4482      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4483      DONE;
4484    }
4485 })
4486
4487 (define_expand "fix_trunc<mode>si2"
4488   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4489                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4490               (clobber (reg:CC FLAGS_REG))])]
4491   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4492 {
4493   if (TARGET_FISTTP
4494       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4495    {
4496      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4497      DONE;
4498    }
4499   if (SSE_FLOAT_MODE_P (<MODE>mode))
4500    {
4501      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4502      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4503      if (out != operands[0])
4504         emit_move_insn (operands[0], out);
4505      DONE;
4506    }
4507 })
4508
4509 ;; Signed conversion to HImode.
4510
4511 (define_expand "fix_trunc<mode>hi2"
4512   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4513                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4514               (clobber (reg:CC FLAGS_REG))])]
4515   "TARGET_80387
4516    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4517 {
4518   if (TARGET_FISTTP)
4519    {
4520      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4521      DONE;
4522    }
4523 })
4524
4525 ;; Unsigned conversion to SImode.
4526
4527 (define_expand "fixuns_trunc<mode>si2"
4528   [(parallel
4529     [(set (match_operand:SI 0 "register_operand" "")
4530           (unsigned_fix:SI
4531             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4532      (use (match_dup 2))
4533      (clobber (match_scratch:<ssevecmode> 3 ""))
4534      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4535   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4536 {
4537   enum machine_mode mode = <MODE>mode;
4538   enum machine_mode vecmode = <ssevecmode>mode;
4539   REAL_VALUE_TYPE TWO31r;
4540   rtx two31;
4541
4542   if (optimize_insn_for_size_p ())
4543     FAIL;
4544
4545   real_ldexp (&TWO31r, &dconst1, 31);
4546   two31 = const_double_from_real_value (TWO31r, mode);
4547   two31 = ix86_build_const_vector (vecmode, true, two31);
4548   operands[2] = force_reg (vecmode, two31);
4549 })
4550
4551 (define_insn_and_split "*fixuns_trunc<mode>_1"
4552   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4553         (unsigned_fix:SI
4554           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4555    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4556    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4557    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4558   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4559    && optimize_function_for_speed_p (cfun)"
4560   "#"
4561   "&& reload_completed"
4562   [(const_int 0)]
4563 {
4564   ix86_split_convert_uns_si_sse (operands);
4565   DONE;
4566 })
4567
4568 ;; Unsigned conversion to HImode.
4569 ;; Without these patterns, we'll try the unsigned SI conversion which
4570 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4571
4572 (define_expand "fixuns_trunc<mode>hi2"
4573   [(set (match_dup 2)
4574         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4575    (set (match_operand:HI 0 "nonimmediate_operand" "")
4576         (subreg:HI (match_dup 2) 0))]
4577   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4578   "operands[2] = gen_reg_rtx (SImode);")
4579
4580 ;; When SSE is available, it is always faster to use it!
4581 (define_insn "fix_trunc<mode>di_sse"
4582   [(set (match_operand:DI 0 "register_operand" "=r,r")
4583         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4584   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4585    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4586   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4587   [(set_attr "type" "sseicvt")
4588    (set_attr "prefix" "maybe_vex")
4589    (set_attr "prefix_rex" "1")
4590    (set_attr "mode" "<MODE>")
4591    (set_attr "athlon_decode" "double,vector")
4592    (set_attr "amdfam10_decode" "double,double")
4593    (set_attr "bdver1_decode" "double,double")])
4594
4595 (define_insn "fix_trunc<mode>si_sse"
4596   [(set (match_operand:SI 0 "register_operand" "=r,r")
4597         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4598   "SSE_FLOAT_MODE_P (<MODE>mode)
4599    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4600   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4601   [(set_attr "type" "sseicvt")
4602    (set_attr "prefix" "maybe_vex")
4603    (set_attr "mode" "<MODE>")
4604    (set_attr "athlon_decode" "double,vector")
4605    (set_attr "amdfam10_decode" "double,double")
4606    (set_attr "bdver1_decode" "double,double")])
4607
4608 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4609 (define_peephole2
4610   [(set (match_operand:MODEF 0 "register_operand" "")
4611         (match_operand:MODEF 1 "memory_operand" ""))
4612    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4613         (fix:SSEMODEI24 (match_dup 0)))]
4614   "TARGET_SHORTEN_X87_SSE
4615    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4616    && peep2_reg_dead_p (2, operands[0])"
4617   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4618
4619 ;; Avoid vector decoded forms of the instruction.
4620 (define_peephole2
4621   [(match_scratch:DF 2 "Y2")
4622    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4623         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4624   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4625   [(set (match_dup 2) (match_dup 1))
4626    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4627
4628 (define_peephole2
4629   [(match_scratch:SF 2 "x")
4630    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4631         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4632   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4633   [(set (match_dup 2) (match_dup 1))
4634    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4635
4636 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4637   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4638         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4639   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4640    && TARGET_FISTTP
4641    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4642          && (TARGET_64BIT || <MODE>mode != DImode))
4643         && TARGET_SSE_MATH)
4644    && can_create_pseudo_p ()"
4645   "#"
4646   "&& 1"
4647   [(const_int 0)]
4648 {
4649   if (memory_operand (operands[0], VOIDmode))
4650     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4651   else
4652     {
4653       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4654       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4655                                                             operands[1],
4656                                                             operands[2]));
4657     }
4658   DONE;
4659 }
4660   [(set_attr "type" "fisttp")
4661    (set_attr "mode" "<MODE>")])
4662
4663 (define_insn "fix_trunc<mode>_i387_fisttp"
4664   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4665         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4666    (clobber (match_scratch:XF 2 "=&1f"))]
4667   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4668    && TARGET_FISTTP
4669    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4670          && (TARGET_64BIT || <MODE>mode != DImode))
4671         && TARGET_SSE_MATH)"
4672   "* return output_fix_trunc (insn, operands, 1);"
4673   [(set_attr "type" "fisttp")
4674    (set_attr "mode" "<MODE>")])
4675
4676 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4677   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4678         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4679    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4680    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4681   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4682    && TARGET_FISTTP
4683    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4684         && (TARGET_64BIT || <MODE>mode != DImode))
4685         && TARGET_SSE_MATH)"
4686   "#"
4687   [(set_attr "type" "fisttp")
4688    (set_attr "mode" "<MODE>")])
4689
4690 (define_split
4691   [(set (match_operand:X87MODEI 0 "register_operand" "")
4692         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4693    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4694    (clobber (match_scratch 3 ""))]
4695   "reload_completed"
4696   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4697               (clobber (match_dup 3))])
4698    (set (match_dup 0) (match_dup 2))])
4699
4700 (define_split
4701   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4702         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4703    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4704    (clobber (match_scratch 3 ""))]
4705   "reload_completed"
4706   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4707               (clobber (match_dup 3))])])
4708
4709 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4710 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4711 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4712 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4713 ;; function in i386.c.
4714 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4715   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4716         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4717    (clobber (reg:CC FLAGS_REG))]
4718   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4719    && !TARGET_FISTTP
4720    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4721          && (TARGET_64BIT || <MODE>mode != DImode))
4722    && can_create_pseudo_p ()"
4723   "#"
4724   "&& 1"
4725   [(const_int 0)]
4726 {
4727   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4728
4729   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4730   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4731   if (memory_operand (operands[0], VOIDmode))
4732     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4733                                          operands[2], operands[3]));
4734   else
4735     {
4736       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4737       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4738                                                      operands[2], operands[3],
4739                                                      operands[4]));
4740     }
4741   DONE;
4742 }
4743   [(set_attr "type" "fistp")
4744    (set_attr "i387_cw" "trunc")
4745    (set_attr "mode" "<MODE>")])
4746
4747 (define_insn "fix_truncdi_i387"
4748   [(set (match_operand:DI 0 "memory_operand" "=m")
4749         (fix:DI (match_operand 1 "register_operand" "f")))
4750    (use (match_operand:HI 2 "memory_operand" "m"))
4751    (use (match_operand:HI 3 "memory_operand" "m"))
4752    (clobber (match_scratch:XF 4 "=&1f"))]
4753   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4754    && !TARGET_FISTTP
4755    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4756   "* return output_fix_trunc (insn, operands, 0);"
4757   [(set_attr "type" "fistp")
4758    (set_attr "i387_cw" "trunc")
4759    (set_attr "mode" "DI")])
4760
4761 (define_insn "fix_truncdi_i387_with_temp"
4762   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4763         (fix:DI (match_operand 1 "register_operand" "f,f")))
4764    (use (match_operand:HI 2 "memory_operand" "m,m"))
4765    (use (match_operand:HI 3 "memory_operand" "m,m"))
4766    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4767    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4768   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4769    && !TARGET_FISTTP
4770    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4771   "#"
4772   [(set_attr "type" "fistp")
4773    (set_attr "i387_cw" "trunc")
4774    (set_attr "mode" "DI")])
4775
4776 (define_split
4777   [(set (match_operand:DI 0 "register_operand" "")
4778         (fix:DI (match_operand 1 "register_operand" "")))
4779    (use (match_operand:HI 2 "memory_operand" ""))
4780    (use (match_operand:HI 3 "memory_operand" ""))
4781    (clobber (match_operand:DI 4 "memory_operand" ""))
4782    (clobber (match_scratch 5 ""))]
4783   "reload_completed"
4784   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4785               (use (match_dup 2))
4786               (use (match_dup 3))
4787               (clobber (match_dup 5))])
4788    (set (match_dup 0) (match_dup 4))])
4789
4790 (define_split
4791   [(set (match_operand:DI 0 "memory_operand" "")
4792         (fix:DI (match_operand 1 "register_operand" "")))
4793    (use (match_operand:HI 2 "memory_operand" ""))
4794    (use (match_operand:HI 3 "memory_operand" ""))
4795    (clobber (match_operand:DI 4 "memory_operand" ""))
4796    (clobber (match_scratch 5 ""))]
4797   "reload_completed"
4798   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4799               (use (match_dup 2))
4800               (use (match_dup 3))
4801               (clobber (match_dup 5))])])
4802
4803 (define_insn "fix_trunc<mode>_i387"
4804   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4805         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4806    (use (match_operand:HI 2 "memory_operand" "m"))
4807    (use (match_operand:HI 3 "memory_operand" "m"))]
4808   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4809    && !TARGET_FISTTP
4810    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4811   "* return output_fix_trunc (insn, operands, 0);"
4812   [(set_attr "type" "fistp")
4813    (set_attr "i387_cw" "trunc")
4814    (set_attr "mode" "<MODE>")])
4815
4816 (define_insn "fix_trunc<mode>_i387_with_temp"
4817   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4818         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4819    (use (match_operand:HI 2 "memory_operand" "m,m"))
4820    (use (match_operand:HI 3 "memory_operand" "m,m"))
4821    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4822   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4823    && !TARGET_FISTTP
4824    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4825   "#"
4826   [(set_attr "type" "fistp")
4827    (set_attr "i387_cw" "trunc")
4828    (set_attr "mode" "<MODE>")])
4829
4830 (define_split
4831   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4832         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4833    (use (match_operand:HI 2 "memory_operand" ""))
4834    (use (match_operand:HI 3 "memory_operand" ""))
4835    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4836   "reload_completed"
4837   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4838               (use (match_dup 2))
4839               (use (match_dup 3))])
4840    (set (match_dup 0) (match_dup 4))])
4841
4842 (define_split
4843   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4844         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4845    (use (match_operand:HI 2 "memory_operand" ""))
4846    (use (match_operand:HI 3 "memory_operand" ""))
4847    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4848   "reload_completed"
4849   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4850               (use (match_dup 2))
4851               (use (match_dup 3))])])
4852
4853 (define_insn "x86_fnstcw_1"
4854   [(set (match_operand:HI 0 "memory_operand" "=m")
4855         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4856   "TARGET_80387"
4857   "fnstcw\t%0"
4858   [(set (attr "length")
4859         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4860    (set_attr "mode" "HI")
4861    (set_attr "unit" "i387")
4862    (set_attr "bdver1_decode" "vector")])
4863
4864 (define_insn "x86_fldcw_1"
4865   [(set (reg:HI FPCR_REG)
4866         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4867   "TARGET_80387"
4868   "fldcw\t%0"
4869   [(set (attr "length")
4870         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4871    (set_attr "mode" "HI")
4872    (set_attr "unit" "i387")
4873    (set_attr "athlon_decode" "vector")
4874    (set_attr "amdfam10_decode" "vector")
4875    (set_attr "bdver1_decode" "vector")])
4876 \f
4877 ;; Conversion between fixed point and floating point.
4878
4879 ;; Even though we only accept memory inputs, the backend _really_
4880 ;; wants to be able to do this between registers.
4881
4882 (define_expand "floathi<mode>2"
4883   [(set (match_operand:X87MODEF 0 "register_operand" "")
4884         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4885   "TARGET_80387
4886    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4887        || TARGET_MIX_SSE_I387)")
4888
4889 ;; Pre-reload splitter to add memory clobber to the pattern.
4890 (define_insn_and_split "*floathi<mode>2_1"
4891   [(set (match_operand:X87MODEF 0 "register_operand" "")
4892         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4893   "TARGET_80387
4894    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4895        || TARGET_MIX_SSE_I387)
4896    && can_create_pseudo_p ()"
4897   "#"
4898   "&& 1"
4899   [(parallel [(set (match_dup 0)
4900               (float:X87MODEF (match_dup 1)))
4901    (clobber (match_dup 2))])]
4902   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4903
4904 (define_insn "*floathi<mode>2_i387_with_temp"
4905   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4906         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4907   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4908   "TARGET_80387
4909    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4910        || TARGET_MIX_SSE_I387)"
4911   "#"
4912   [(set_attr "type" "fmov,multi")
4913    (set_attr "mode" "<MODE>")
4914    (set_attr "unit" "*,i387")
4915    (set_attr "fp_int_src" "true")])
4916
4917 (define_insn "*floathi<mode>2_i387"
4918   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4919         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4920   "TARGET_80387
4921    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4922        || TARGET_MIX_SSE_I387)"
4923   "fild%Z1\t%1"
4924   [(set_attr "type" "fmov")
4925    (set_attr "mode" "<MODE>")
4926    (set_attr "fp_int_src" "true")])
4927
4928 (define_split
4929   [(set (match_operand:X87MODEF 0 "register_operand" "")
4930         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4931    (clobber (match_operand:HI 2 "memory_operand" ""))]
4932   "TARGET_80387
4933    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4934        || TARGET_MIX_SSE_I387)
4935    && reload_completed"
4936   [(set (match_dup 2) (match_dup 1))
4937    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4938
4939 (define_split
4940   [(set (match_operand:X87MODEF 0 "register_operand" "")
4941         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4942    (clobber (match_operand:HI 2 "memory_operand" ""))]
4943    "TARGET_80387
4944     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4945         || TARGET_MIX_SSE_I387)
4946     && reload_completed"
4947   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4948
4949 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4950   [(set (match_operand:X87MODEF 0 "register_operand" "")
4951         (float:X87MODEF
4952           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4953   "TARGET_80387
4954    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4955        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4956 {
4957   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4958         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4959       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4960     {
4961       rtx reg = gen_reg_rtx (XFmode);
4962       rtx insn;
4963
4964       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4965
4966       if (<X87MODEF:MODE>mode == SFmode)
4967         insn = gen_truncxfsf2 (operands[0], reg);
4968       else if (<X87MODEF:MODE>mode == DFmode)
4969         insn = gen_truncxfdf2 (operands[0], reg);
4970       else
4971         gcc_unreachable ();
4972
4973       emit_insn (insn);
4974       DONE;
4975     }
4976 })
4977
4978 ;; Pre-reload splitter to add memory clobber to the pattern.
4979 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4980   [(set (match_operand:X87MODEF 0 "register_operand" "")
4981         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4982   "((TARGET_80387
4983      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4984      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4985            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4986          || TARGET_MIX_SSE_I387))
4987     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4988         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4989         && ((<SSEMODEI24:MODE>mode == SImode
4990              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4991              && optimize_function_for_speed_p (cfun)
4992              && flag_trapping_math)
4993             || !(TARGET_INTER_UNIT_CONVERSIONS
4994                  || optimize_function_for_size_p (cfun)))))
4995    && can_create_pseudo_p ()"
4996   "#"
4997   "&& 1"
4998   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4999               (clobber (match_dup 2))])]
5000 {
5001   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5002
5003   /* Avoid store forwarding (partial memory) stall penalty
5004      by passing DImode value through XMM registers.  */
5005   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5006       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5007       && optimize_function_for_speed_p (cfun))
5008     {
5009       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5010                                                             operands[1],
5011                                                             operands[2]));
5012       DONE;
5013     }
5014 })
5015
5016 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5017   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5018         (float:MODEF
5019           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5020    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5021   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5022    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5023   "#"
5024   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5025    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5026    (set_attr "unit" "*,i387,*,*,*")
5027    (set_attr "athlon_decode" "*,*,double,direct,double")
5028    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5029    (set_attr "bdver1_decode" "*,*,double,direct,double")
5030    (set_attr "fp_int_src" "true")])
5031
5032 (define_insn "*floatsi<mode>2_vector_mixed"
5033   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5034         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5035   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5036    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5037   "@
5038    fild%Z1\t%1
5039    #"
5040   [(set_attr "type" "fmov,sseicvt")
5041    (set_attr "mode" "<MODE>,<ssevecmode>")
5042    (set_attr "unit" "i387,*")
5043    (set_attr "athlon_decode" "*,direct")
5044    (set_attr "amdfam10_decode" "*,double")
5045    (set_attr "bdver1_decode" "*,direct")
5046    (set_attr "fp_int_src" "true")])
5047
5048 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5049   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5050         (float:MODEF
5051           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5052   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5053   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5054    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5055   "#"
5056   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5057    (set_attr "mode" "<MODEF:MODE>")
5058    (set_attr "unit" "*,i387,*,*")
5059    (set_attr "athlon_decode" "*,*,double,direct")
5060    (set_attr "amdfam10_decode" "*,*,vector,double")
5061    (set_attr "bdver1_decode" "*,*,double,direct")
5062    (set_attr "fp_int_src" "true")])
5063
5064 (define_split
5065   [(set (match_operand:MODEF 0 "register_operand" "")
5066         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5067    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5068   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5069    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5070    && TARGET_INTER_UNIT_CONVERSIONS
5071    && reload_completed
5072    && (SSE_REG_P (operands[0])
5073        || (GET_CODE (operands[0]) == SUBREG
5074            && SSE_REG_P (operands[0])))"
5075   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5076
5077 (define_split
5078   [(set (match_operand:MODEF 0 "register_operand" "")
5079         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5080    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5081   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5083    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5084    && reload_completed
5085    && (SSE_REG_P (operands[0])
5086        || (GET_CODE (operands[0]) == SUBREG
5087            && SSE_REG_P (operands[0])))"
5088   [(set (match_dup 2) (match_dup 1))
5089    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5090
5091 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5092   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5093         (float:MODEF
5094           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5095   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5096    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5097    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5098   "@
5099    fild%Z1\t%1
5100    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5101    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5102   [(set_attr "type" "fmov,sseicvt,sseicvt")
5103    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5104    (set_attr "mode" "<MODEF:MODE>")
5105    (set (attr "prefix_rex")
5106      (if_then_else
5107        (and (eq_attr "prefix" "maybe_vex")
5108             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5109        (const_string "1")
5110        (const_string "*")))
5111    (set_attr "unit" "i387,*,*")
5112    (set_attr "athlon_decode" "*,double,direct")
5113    (set_attr "amdfam10_decode" "*,vector,double")
5114    (set_attr "bdver1_decode" "*,double,direct")
5115    (set_attr "fp_int_src" "true")])
5116
5117 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5118   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5119         (float:MODEF
5120           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5121   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5122    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5123    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5124   "@
5125    fild%Z1\t%1
5126    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5127   [(set_attr "type" "fmov,sseicvt")
5128    (set_attr "prefix" "orig,maybe_vex")
5129    (set_attr "mode" "<MODEF:MODE>")
5130    (set (attr "prefix_rex")
5131      (if_then_else
5132        (and (eq_attr "prefix" "maybe_vex")
5133             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5134        (const_string "1")
5135        (const_string "*")))
5136    (set_attr "athlon_decode" "*,direct")
5137    (set_attr "amdfam10_decode" "*,double")
5138    (set_attr "bdver1_decode" "*,direct")
5139    (set_attr "fp_int_src" "true")])
5140
5141 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5142   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5143         (float:MODEF
5144           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5145    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5146   "TARGET_SSE2 && TARGET_SSE_MATH
5147    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5148   "#"
5149   [(set_attr "type" "sseicvt")
5150    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5151    (set_attr "athlon_decode" "double,direct,double")
5152    (set_attr "amdfam10_decode" "vector,double,double")
5153    (set_attr "bdver1_decode" "double,direct,double")
5154    (set_attr "fp_int_src" "true")])
5155
5156 (define_insn "*floatsi<mode>2_vector_sse"
5157   [(set (match_operand:MODEF 0 "register_operand" "=x")
5158         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5159   "TARGET_SSE2 && TARGET_SSE_MATH
5160    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5161   "#"
5162   [(set_attr "type" "sseicvt")
5163    (set_attr "mode" "<MODE>")
5164    (set_attr "athlon_decode" "direct")
5165    (set_attr "amdfam10_decode" "double")
5166    (set_attr "bdver1_decode" "direct")
5167    (set_attr "fp_int_src" "true")])
5168
5169 (define_split
5170   [(set (match_operand:MODEF 0 "register_operand" "")
5171         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5172    (clobber (match_operand:SI 2 "memory_operand" ""))]
5173   "TARGET_SSE2 && TARGET_SSE_MATH
5174    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5175    && reload_completed
5176    && (SSE_REG_P (operands[0])
5177        || (GET_CODE (operands[0]) == SUBREG
5178            && SSE_REG_P (operands[0])))"
5179   [(const_int 0)]
5180 {
5181   rtx op1 = operands[1];
5182
5183   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5184                                      <MODE>mode, 0);
5185   if (GET_CODE (op1) == SUBREG)
5186     op1 = SUBREG_REG (op1);
5187
5188   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5189     {
5190       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5191       emit_insn (gen_sse2_loadld (operands[4],
5192                                   CONST0_RTX (V4SImode), operands[1]));
5193     }
5194   /* We can ignore possible trapping value in the
5195      high part of SSE register for non-trapping math. */
5196   else if (SSE_REG_P (op1) && !flag_trapping_math)
5197     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5198   else
5199     {
5200       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5201       emit_move_insn (operands[2], operands[1]);
5202       emit_insn (gen_sse2_loadld (operands[4],
5203                                   CONST0_RTX (V4SImode), operands[2]));
5204     }
5205   emit_insn
5206     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5207   DONE;
5208 })
5209
5210 (define_split
5211   [(set (match_operand:MODEF 0 "register_operand" "")
5212         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5213    (clobber (match_operand:SI 2 "memory_operand" ""))]
5214   "TARGET_SSE2 && TARGET_SSE_MATH
5215    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5216    && reload_completed
5217    && (SSE_REG_P (operands[0])
5218        || (GET_CODE (operands[0]) == SUBREG
5219            && SSE_REG_P (operands[0])))"
5220   [(const_int 0)]
5221 {
5222   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5223                                      <MODE>mode, 0);
5224   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5225
5226   emit_insn (gen_sse2_loadld (operands[4],
5227                               CONST0_RTX (V4SImode), operands[1]));
5228   emit_insn
5229     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5230   DONE;
5231 })
5232
5233 (define_split
5234   [(set (match_operand:MODEF 0 "register_operand" "")
5235         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5236   "TARGET_SSE2 && TARGET_SSE_MATH
5237    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5238    && reload_completed
5239    && (SSE_REG_P (operands[0])
5240        || (GET_CODE (operands[0]) == SUBREG
5241            && SSE_REG_P (operands[0])))"
5242   [(const_int 0)]
5243 {
5244   rtx op1 = operands[1];
5245
5246   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5247                                      <MODE>mode, 0);
5248   if (GET_CODE (op1) == SUBREG)
5249     op1 = SUBREG_REG (op1);
5250
5251   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5252     {
5253       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5254       emit_insn (gen_sse2_loadld (operands[4],
5255                                   CONST0_RTX (V4SImode), operands[1]));
5256     }
5257   /* We can ignore possible trapping value in the
5258      high part of SSE register for non-trapping math. */
5259   else if (SSE_REG_P (op1) && !flag_trapping_math)
5260     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5261   else
5262     gcc_unreachable ();
5263   emit_insn
5264     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5265   DONE;
5266 })
5267
5268 (define_split
5269   [(set (match_operand:MODEF 0 "register_operand" "")
5270         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5271   "TARGET_SSE2 && TARGET_SSE_MATH
5272    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5273    && reload_completed
5274    && (SSE_REG_P (operands[0])
5275        || (GET_CODE (operands[0]) == SUBREG
5276            && SSE_REG_P (operands[0])))"
5277   [(const_int 0)]
5278 {
5279   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5280                                      <MODE>mode, 0);
5281   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5282
5283   emit_insn (gen_sse2_loadld (operands[4],
5284                               CONST0_RTX (V4SImode), operands[1]));
5285   emit_insn
5286     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5287   DONE;
5288 })
5289
5290 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5291   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5292         (float:MODEF
5293           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5294   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5295   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5296    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5297   "#"
5298   [(set_attr "type" "sseicvt")
5299    (set_attr "mode" "<MODEF:MODE>")
5300    (set_attr "athlon_decode" "double,direct")
5301    (set_attr "amdfam10_decode" "vector,double")
5302    (set_attr "bdver1_decode" "double,direct")
5303    (set_attr "fp_int_src" "true")])
5304
5305 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5306   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5307         (float:MODEF
5308           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5309   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5310    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5311    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5312   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5313   [(set_attr "type" "sseicvt")
5314    (set_attr "prefix" "maybe_vex")
5315    (set_attr "mode" "<MODEF:MODE>")
5316    (set (attr "prefix_rex")
5317      (if_then_else
5318        (and (eq_attr "prefix" "maybe_vex")
5319             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5320        (const_string "1")
5321        (const_string "*")))
5322    (set_attr "athlon_decode" "double,direct")
5323    (set_attr "amdfam10_decode" "vector,double")
5324    (set_attr "bdver1_decode" "double,direct")
5325    (set_attr "fp_int_src" "true")])
5326
5327 (define_split
5328   [(set (match_operand:MODEF 0 "register_operand" "")
5329         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5330    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5331   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5332    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5333    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5334    && reload_completed
5335    && (SSE_REG_P (operands[0])
5336        || (GET_CODE (operands[0]) == SUBREG
5337            && SSE_REG_P (operands[0])))"
5338   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5339
5340 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5341   [(set (match_operand:MODEF 0 "register_operand" "=x")
5342         (float:MODEF
5343           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5344   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5345    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5346    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5347   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5348   [(set_attr "type" "sseicvt")
5349    (set_attr "prefix" "maybe_vex")
5350    (set_attr "mode" "<MODEF:MODE>")
5351    (set (attr "prefix_rex")
5352      (if_then_else
5353        (and (eq_attr "prefix" "maybe_vex")
5354             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5355        (const_string "1")
5356        (const_string "*")))
5357    (set_attr "athlon_decode" "direct")
5358    (set_attr "amdfam10_decode" "double")
5359    (set_attr "bdver1_decode" "direct")
5360    (set_attr "fp_int_src" "true")])
5361
5362 (define_split
5363   [(set (match_operand:MODEF 0 "register_operand" "")
5364         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5365    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5366   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5367    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5368    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5369    && reload_completed
5370    && (SSE_REG_P (operands[0])
5371        || (GET_CODE (operands[0]) == SUBREG
5372            && SSE_REG_P (operands[0])))"
5373   [(set (match_dup 2) (match_dup 1))
5374    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5375
5376 (define_split
5377   [(set (match_operand:MODEF 0 "register_operand" "")
5378         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5379    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5380   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5381    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5382    && reload_completed
5383    && (SSE_REG_P (operands[0])
5384        || (GET_CODE (operands[0]) == SUBREG
5385            && SSE_REG_P (operands[0])))"
5386   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5387
5388 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5389   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5390         (float:X87MODEF
5391           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5392   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5393   "TARGET_80387
5394    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5395   "@
5396    fild%Z1\t%1
5397    #"
5398   [(set_attr "type" "fmov,multi")
5399    (set_attr "mode" "<X87MODEF:MODE>")
5400    (set_attr "unit" "*,i387")
5401    (set_attr "fp_int_src" "true")])
5402
5403 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5404   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5405         (float:X87MODEF
5406           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5407   "TARGET_80387
5408    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5409   "fild%Z1\t%1"
5410   [(set_attr "type" "fmov")
5411    (set_attr "mode" "<X87MODEF:MODE>")
5412    (set_attr "fp_int_src" "true")])
5413
5414 (define_split
5415   [(set (match_operand:X87MODEF 0 "register_operand" "")
5416         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5417    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5418   "TARGET_80387
5419    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5420    && reload_completed
5421    && FP_REG_P (operands[0])"
5422   [(set (match_dup 2) (match_dup 1))
5423    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5424
5425 (define_split
5426   [(set (match_operand:X87MODEF 0 "register_operand" "")
5427         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5428    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5429   "TARGET_80387
5430    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5431    && reload_completed
5432    && FP_REG_P (operands[0])"
5433   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5434
5435 ;; Avoid store forwarding (partial memory) stall penalty
5436 ;; by passing DImode value through XMM registers.  */
5437
5438 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5439   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5440         (float:X87MODEF
5441           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5442    (clobber (match_scratch:V4SI 3 "=X,x"))
5443    (clobber (match_scratch:V4SI 4 "=X,x"))
5444    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5445   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5446    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5447    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5448   "#"
5449   [(set_attr "type" "multi")
5450    (set_attr "mode" "<X87MODEF:MODE>")
5451    (set_attr "unit" "i387")
5452    (set_attr "fp_int_src" "true")])
5453
5454 (define_split
5455   [(set (match_operand:X87MODEF 0 "register_operand" "")
5456         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5457    (clobber (match_scratch:V4SI 3 ""))
5458    (clobber (match_scratch:V4SI 4 ""))
5459    (clobber (match_operand:DI 2 "memory_operand" ""))]
5460   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5461    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5462    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5463    && reload_completed
5464    && FP_REG_P (operands[0])"
5465   [(set (match_dup 2) (match_dup 3))
5466    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5467 {
5468   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5469      Assemble the 64-bit DImode value in an xmm register.  */
5470   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5471                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5472   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5473                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5474   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5475                                          operands[4]));
5476
5477   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5478 })
5479
5480 (define_split
5481   [(set (match_operand:X87MODEF 0 "register_operand" "")
5482         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5483    (clobber (match_scratch:V4SI 3 ""))
5484    (clobber (match_scratch:V4SI 4 ""))
5485    (clobber (match_operand:DI 2 "memory_operand" ""))]
5486   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5487    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5488    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5489    && reload_completed
5490    && FP_REG_P (operands[0])"
5491   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5492
5493 ;; Avoid store forwarding (partial memory) stall penalty by extending
5494 ;; SImode value to DImode through XMM register instead of pushing two
5495 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5496 ;; targets benefit from this optimization. Also note that fild
5497 ;; loads from memory only.
5498
5499 (define_insn "*floatunssi<mode>2_1"
5500   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5501         (unsigned_float:X87MODEF
5502           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5503    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5504    (clobber (match_scratch:SI 3 "=X,x"))]
5505   "!TARGET_64BIT
5506    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5507    && TARGET_SSE"
5508   "#"
5509   [(set_attr "type" "multi")
5510    (set_attr "mode" "<MODE>")])
5511
5512 (define_split
5513   [(set (match_operand:X87MODEF 0 "register_operand" "")
5514         (unsigned_float:X87MODEF
5515           (match_operand:SI 1 "register_operand" "")))
5516    (clobber (match_operand:DI 2 "memory_operand" ""))
5517    (clobber (match_scratch:SI 3 ""))]
5518   "!TARGET_64BIT
5519    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5520    && TARGET_SSE
5521    && reload_completed"
5522   [(set (match_dup 2) (match_dup 1))
5523    (set (match_dup 0)
5524         (float:X87MODEF (match_dup 2)))]
5525   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5526
5527 (define_split
5528   [(set (match_operand:X87MODEF 0 "register_operand" "")
5529         (unsigned_float:X87MODEF
5530           (match_operand:SI 1 "memory_operand" "")))
5531    (clobber (match_operand:DI 2 "memory_operand" ""))
5532    (clobber (match_scratch:SI 3 ""))]
5533   "!TARGET_64BIT
5534    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5535    && TARGET_SSE
5536    && reload_completed"
5537   [(set (match_dup 2) (match_dup 3))
5538    (set (match_dup 0)
5539         (float:X87MODEF (match_dup 2)))]
5540 {
5541   emit_move_insn (operands[3], operands[1]);
5542   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5543 })
5544
5545 (define_expand "floatunssi<mode>2"
5546   [(parallel
5547      [(set (match_operand:X87MODEF 0 "register_operand" "")
5548            (unsigned_float:X87MODEF
5549              (match_operand:SI 1 "nonimmediate_operand" "")))
5550       (clobber (match_dup 2))
5551       (clobber (match_scratch:SI 3 ""))])]
5552   "!TARGET_64BIT
5553    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5554         && TARGET_SSE)
5555        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5556 {
5557   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5558     {
5559       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5560       DONE;
5561     }
5562   else
5563     {
5564       enum ix86_stack_slot slot = (virtuals_instantiated
5565                                    ? SLOT_TEMP
5566                                    : SLOT_VIRTUAL);
5567       operands[2] = assign_386_stack_local (DImode, slot);
5568     }
5569 })
5570
5571 (define_expand "floatunsdisf2"
5572   [(use (match_operand:SF 0 "register_operand" ""))
5573    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5574   "TARGET_64BIT && TARGET_SSE_MATH"
5575   "x86_emit_floatuns (operands); DONE;")
5576
5577 (define_expand "floatunsdidf2"
5578   [(use (match_operand:DF 0 "register_operand" ""))
5579    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5580   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5581    && TARGET_SSE2 && TARGET_SSE_MATH"
5582 {
5583   if (TARGET_64BIT)
5584     x86_emit_floatuns (operands);
5585   else
5586     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5587   DONE;
5588 })
5589 \f
5590 ;; Add instructions
5591
5592 (define_expand "add<mode>3"
5593   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5594         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5595                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5596   ""
5597   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5598
5599 (define_insn_and_split "*add<dwi>3_doubleword"
5600   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5601         (plus:<DWI>
5602           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5603           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5604    (clobber (reg:CC FLAGS_REG))]
5605   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5606   "#"
5607   "reload_completed"
5608   [(parallel [(set (reg:CC FLAGS_REG)
5609                    (unspec:CC [(match_dup 1) (match_dup 2)]
5610                               UNSPEC_ADD_CARRY))
5611               (set (match_dup 0)
5612                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5613    (parallel [(set (match_dup 3)
5614                    (plus:DWIH
5615                      (match_dup 4)
5616                      (plus:DWIH
5617                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5618                        (match_dup 5))))
5619               (clobber (reg:CC FLAGS_REG))])]
5620   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5621
5622 (define_insn "*add<mode>3_cc"
5623   [(set (reg:CC FLAGS_REG)
5624         (unspec:CC
5625           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5626            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5627           UNSPEC_ADD_CARRY))
5628    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5629         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5630   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5631   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5632   [(set_attr "type" "alu")
5633    (set_attr "mode" "<MODE>")])
5634
5635 (define_insn "addqi3_cc"
5636   [(set (reg:CC FLAGS_REG)
5637         (unspec:CC
5638           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5639            (match_operand:QI 2 "general_operand" "qn,qm")]
5640           UNSPEC_ADD_CARRY))
5641    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5642         (plus:QI (match_dup 1) (match_dup 2)))]
5643   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5644   "add{b}\t{%2, %0|%0, %2}"
5645   [(set_attr "type" "alu")
5646    (set_attr "mode" "QI")])
5647
5648 (define_insn "*lea_1"
5649   [(set (match_operand:P 0 "register_operand" "=r")
5650         (match_operand:P 1 "no_seg_address_operand" "p"))]
5651   ""
5652   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5653   [(set_attr "type" "lea")
5654    (set_attr "mode" "<MODE>")])
5655
5656 (define_insn "*lea_2"
5657   [(set (match_operand:SI 0 "register_operand" "=r")
5658         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5659   "TARGET_64BIT"
5660   "lea{l}\t{%a1, %0|%0, %a1}"
5661   [(set_attr "type" "lea")
5662    (set_attr "mode" "SI")])
5663
5664 (define_insn "*lea_2_zext"
5665   [(set (match_operand:DI 0 "register_operand" "=r")
5666         (zero_extend:DI
5667           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5668   "TARGET_64BIT"
5669   "lea{l}\t{%a1, %k0|%k0, %a1}"
5670   [(set_attr "type" "lea")
5671    (set_attr "mode" "SI")])
5672
5673 (define_insn "*add<mode>_1"
5674   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5675         (plus:SWI48
5676           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5677           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5678    (clobber (reg:CC FLAGS_REG))]
5679   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5680 {
5681   switch (get_attr_type (insn))
5682     {
5683     case TYPE_LEA:
5684       return "#";
5685
5686     case TYPE_INCDEC:
5687       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688       if (operands[2] == const1_rtx)
5689         return "inc{<imodesuffix>}\t%0";
5690       else
5691         {
5692           gcc_assert (operands[2] == constm1_rtx);
5693           return "dec{<imodesuffix>}\t%0";
5694         }
5695
5696     default:
5697       /* For most processors, ADD is faster than LEA.  This alternative
5698          was added to use ADD as much as possible.  */
5699       if (which_alternative == 2)
5700         {
5701           rtx tmp;
5702           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5703         }
5704         
5705       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5706       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5707         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5708
5709       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5710     }
5711 }
5712   [(set (attr "type")
5713      (cond [(eq_attr "alternative" "3")
5714               (const_string "lea")
5715             (match_operand:SWI48 2 "incdec_operand" "")
5716               (const_string "incdec")
5717            ]
5718            (const_string "alu")))
5719    (set (attr "length_immediate")
5720       (if_then_else
5721         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5722         (const_string "1")
5723         (const_string "*")))
5724    (set_attr "mode" "<MODE>")])
5725
5726 ;; It may seem that nonimmediate operand is proper one for operand 1.
5727 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5728 ;; we take care in ix86_binary_operator_ok to not allow two memory
5729 ;; operands so proper swapping will be done in reload.  This allow
5730 ;; patterns constructed from addsi_1 to match.
5731
5732 (define_insn "*addsi_1_zext"
5733   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5734         (zero_extend:DI
5735           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5736                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5737    (clobber (reg:CC FLAGS_REG))]
5738   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5739 {
5740   switch (get_attr_type (insn))
5741     {
5742     case TYPE_LEA:
5743       return "#";
5744
5745     case TYPE_INCDEC:
5746       if (operands[2] == const1_rtx)
5747         return "inc{l}\t%k0";
5748       else
5749         {
5750           gcc_assert (operands[2] == constm1_rtx);
5751           return "dec{l}\t%k0";
5752         }
5753
5754     default:
5755       /* For most processors, ADD is faster than LEA.  This alternative
5756          was added to use ADD as much as possible.  */
5757       if (which_alternative == 1)
5758         {
5759           rtx tmp;
5760           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5761         }
5762
5763       if (x86_maybe_negate_const_int (&operands[2], SImode))
5764         return "sub{l}\t{%2, %k0|%k0, %2}";
5765
5766       return "add{l}\t{%2, %k0|%k0, %2}";
5767     }
5768 }
5769   [(set (attr "type")
5770      (cond [(eq_attr "alternative" "2")
5771               (const_string "lea")
5772             (match_operand:SI 2 "incdec_operand" "")
5773               (const_string "incdec")
5774            ]
5775            (const_string "alu")))
5776    (set (attr "length_immediate")
5777       (if_then_else
5778         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5779         (const_string "1")
5780         (const_string "*")))
5781    (set_attr "mode" "SI")])
5782
5783 (define_insn "*addhi_1"
5784   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5785         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5786                  (match_operand:HI 2 "general_operand" "rn,rm")))
5787    (clobber (reg:CC FLAGS_REG))]
5788   "TARGET_PARTIAL_REG_STALL
5789    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5790 {
5791   switch (get_attr_type (insn))
5792     {
5793     case TYPE_INCDEC:
5794       if (operands[2] == const1_rtx)
5795         return "inc{w}\t%0";
5796       else
5797         {
5798           gcc_assert (operands[2] == constm1_rtx);
5799           return "dec{w}\t%0";
5800         }
5801
5802     default:
5803       if (x86_maybe_negate_const_int (&operands[2], HImode))
5804         return "sub{w}\t{%2, %0|%0, %2}";
5805
5806       return "add{w}\t{%2, %0|%0, %2}";
5807     }
5808 }
5809   [(set (attr "type")
5810      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5811         (const_string "incdec")
5812         (const_string "alu")))
5813    (set (attr "length_immediate")
5814       (if_then_else
5815         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5816         (const_string "1")
5817         (const_string "*")))
5818    (set_attr "mode" "HI")])
5819
5820 (define_insn "*addhi_1_lea"
5821   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5822         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5823                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5824    (clobber (reg:CC FLAGS_REG))]
5825   "!TARGET_PARTIAL_REG_STALL
5826    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5827 {
5828   switch (get_attr_type (insn))
5829     {
5830     case TYPE_LEA:
5831       return "#";
5832
5833     case TYPE_INCDEC:
5834       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5835       if (operands[2] == const1_rtx)
5836         return "inc{w}\t%0";
5837       else
5838         {
5839           gcc_assert (operands[2] == constm1_rtx);
5840           return "dec{w}\t%0";
5841         }
5842
5843     default:
5844       /* For most processors, ADD is faster than LEA.  This alternative
5845          was added to use ADD as much as possible.  */
5846       if (which_alternative == 2)
5847         {
5848           rtx tmp;
5849           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5850         }
5851
5852       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5853       if (x86_maybe_negate_const_int (&operands[2], HImode))
5854         return "sub{w}\t{%2, %0|%0, %2}";
5855
5856       return "add{w}\t{%2, %0|%0, %2}";
5857     }
5858 }
5859   [(set (attr "type")
5860      (cond [(eq_attr "alternative" "3")
5861               (const_string "lea")
5862             (match_operand:HI 2 "incdec_operand" "")
5863               (const_string "incdec")
5864            ]
5865            (const_string "alu")))
5866    (set (attr "length_immediate")
5867       (if_then_else
5868         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5869         (const_string "1")
5870         (const_string "*")))
5871    (set_attr "mode" "HI,HI,HI,SI")])
5872
5873 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5874 (define_insn "*addqi_1"
5875   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5876         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5877                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5878    (clobber (reg:CC FLAGS_REG))]
5879   "TARGET_PARTIAL_REG_STALL
5880    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5881 {
5882   int widen = (which_alternative == 2);
5883   switch (get_attr_type (insn))
5884     {
5885     case TYPE_INCDEC:
5886       if (operands[2] == const1_rtx)
5887         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5888       else
5889         {
5890           gcc_assert (operands[2] == constm1_rtx);
5891           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5892         }
5893
5894     default:
5895       if (x86_maybe_negate_const_int (&operands[2], QImode))
5896         {
5897           if (widen)
5898             return "sub{l}\t{%2, %k0|%k0, %2}";
5899           else
5900             return "sub{b}\t{%2, %0|%0, %2}";
5901         }
5902       if (widen)
5903         return "add{l}\t{%k2, %k0|%k0, %k2}";
5904       else
5905         return "add{b}\t{%2, %0|%0, %2}";
5906     }
5907 }
5908   [(set (attr "type")
5909      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5910         (const_string "incdec")
5911         (const_string "alu")))
5912    (set (attr "length_immediate")
5913       (if_then_else
5914         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5915         (const_string "1")
5916         (const_string "*")))
5917    (set_attr "mode" "QI,QI,SI")])
5918
5919 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5920 (define_insn "*addqi_1_lea"
5921   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5922         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5923                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5924    (clobber (reg:CC FLAGS_REG))]
5925   "!TARGET_PARTIAL_REG_STALL
5926    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5927 {
5928   int widen = (which_alternative == 3 || which_alternative == 4);
5929
5930   switch (get_attr_type (insn))
5931     {
5932     case TYPE_LEA:
5933       return "#";
5934
5935     case TYPE_INCDEC:
5936       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5937       if (operands[2] == const1_rtx)
5938         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5939       else
5940         {
5941           gcc_assert (operands[2] == constm1_rtx);
5942           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5943         }
5944
5945     default:
5946       /* For most processors, ADD is faster than LEA.  These alternatives
5947          were added to use ADD as much as possible.  */
5948       if (which_alternative == 2 || which_alternative == 4)
5949         {
5950           rtx tmp;
5951           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5952         }
5953
5954       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5955       if (x86_maybe_negate_const_int (&operands[2], QImode))
5956         {
5957           if (widen)
5958             return "sub{l}\t{%2, %k0|%k0, %2}";
5959           else
5960             return "sub{b}\t{%2, %0|%0, %2}";
5961         }
5962       if (widen)
5963         return "add{l}\t{%k2, %k0|%k0, %k2}";
5964       else
5965         return "add{b}\t{%2, %0|%0, %2}";
5966     }
5967 }
5968   [(set (attr "type")
5969      (cond [(eq_attr "alternative" "5")
5970               (const_string "lea")
5971             (match_operand:QI 2 "incdec_operand" "")
5972               (const_string "incdec")
5973            ]
5974            (const_string "alu")))
5975    (set (attr "length_immediate")
5976       (if_then_else
5977         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5978         (const_string "1")
5979         (const_string "*")))
5980    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5981
5982 (define_insn "*addqi_1_slp"
5983   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5984         (plus:QI (match_dup 0)
5985                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5986    (clobber (reg:CC FLAGS_REG))]
5987   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5988    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5989 {
5990   switch (get_attr_type (insn))
5991     {
5992     case TYPE_INCDEC:
5993       if (operands[1] == const1_rtx)
5994         return "inc{b}\t%0";
5995       else
5996         {
5997           gcc_assert (operands[1] == constm1_rtx);
5998           return "dec{b}\t%0";
5999         }
6000
6001     default:
6002       if (x86_maybe_negate_const_int (&operands[1], QImode))
6003         return "sub{b}\t{%1, %0|%0, %1}";
6004
6005       return "add{b}\t{%1, %0|%0, %1}";
6006     }
6007 }
6008   [(set (attr "type")
6009      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6010         (const_string "incdec")
6011         (const_string "alu1")))
6012    (set (attr "memory")
6013      (if_then_else (match_operand 1 "memory_operand" "")
6014         (const_string "load")
6015         (const_string "none")))
6016    (set_attr "mode" "QI")])
6017
6018 ;; Convert lea to the lea pattern to avoid flags dependency.
6019 (define_split
6020   [(set (match_operand 0 "register_operand" "")
6021         (plus (match_operand 1 "register_operand" "")
6022               (match_operand 2 "nonmemory_operand" "")))
6023    (clobber (reg:CC FLAGS_REG))]
6024   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6025   [(const_int 0)]
6026 {
6027   rtx pat;
6028   enum machine_mode mode = GET_MODE (operands[0]);
6029
6030   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6031      may confuse gen_lowpart.  */
6032   if (mode != Pmode)
6033     {
6034       operands[1] = gen_lowpart (Pmode, operands[1]);
6035       operands[2] = gen_lowpart (Pmode, operands[2]);
6036     }
6037
6038   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6039
6040   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6041     operands[0] = gen_lowpart (SImode, operands[0]);
6042
6043   if (TARGET_64BIT && mode != Pmode)
6044     pat = gen_rtx_SUBREG (SImode, pat, 0);
6045
6046   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6047   DONE;
6048 })
6049
6050 ;; Convert lea to the lea pattern to avoid flags dependency.
6051 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6052 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6053 (define_split
6054   [(set (match_operand:DI 0 "register_operand" "")
6055         (plus:DI (match_operand:DI 1 "register_operand" "")
6056                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6057    (clobber (reg:CC FLAGS_REG))]
6058   "TARGET_64BIT && reload_completed 
6059    && true_regnum (operands[0]) != true_regnum (operands[1])"
6060   [(set (match_dup 0)
6061         (plus:DI (match_dup 1) (match_dup 2)))])
6062
6063 ;; Convert lea to the lea pattern to avoid flags dependency.
6064 (define_split
6065   [(set (match_operand:DI 0 "register_operand" "")
6066         (zero_extend:DI
6067           (plus:SI (match_operand:SI 1 "register_operand" "")
6068                    (match_operand:SI 2 "nonmemory_operand" ""))))
6069    (clobber (reg:CC FLAGS_REG))]
6070   "TARGET_64BIT && reload_completed
6071    && ix86_lea_for_add_ok (insn, operands)"
6072   [(set (match_dup 0)
6073         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6074 {
6075   operands[1] = gen_lowpart (DImode, operands[1]);
6076   operands[2] = gen_lowpart (DImode, operands[2]);
6077 })
6078
6079 (define_insn "*add<mode>_2"
6080   [(set (reg FLAGS_REG)
6081         (compare
6082           (plus:SWI
6083             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6084             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6085           (const_int 0)))
6086    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6087         (plus:SWI (match_dup 1) (match_dup 2)))]
6088   "ix86_match_ccmode (insn, CCGOCmode)
6089    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6090 {
6091   switch (get_attr_type (insn))
6092     {
6093     case TYPE_INCDEC:
6094       if (operands[2] == const1_rtx)
6095         return "inc{<imodesuffix>}\t%0";
6096       else
6097         {
6098           gcc_assert (operands[2] == constm1_rtx);
6099           return "dec{<imodesuffix>}\t%0";
6100         }
6101
6102     default:
6103       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6104         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6105
6106       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6107     }
6108 }
6109   [(set (attr "type")
6110      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6111         (const_string "incdec")
6112         (const_string "alu")))
6113    (set (attr "length_immediate")
6114       (if_then_else
6115         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6116         (const_string "1")
6117         (const_string "*")))
6118    (set_attr "mode" "<MODE>")])
6119
6120 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6121 (define_insn "*addsi_2_zext"
6122   [(set (reg FLAGS_REG)
6123         (compare
6124           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6125                    (match_operand:SI 2 "general_operand" "g"))
6126           (const_int 0)))
6127    (set (match_operand:DI 0 "register_operand" "=r")
6128         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6129   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6130    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6131 {
6132   switch (get_attr_type (insn))
6133     {
6134     case TYPE_INCDEC:
6135       if (operands[2] == const1_rtx)
6136         return "inc{l}\t%k0";
6137       else
6138         {
6139           gcc_assert (operands[2] == constm1_rtx);
6140           return "dec{l}\t%k0";
6141         }
6142
6143     default:
6144       if (x86_maybe_negate_const_int (&operands[2], SImode))
6145         return "sub{l}\t{%2, %k0|%k0, %2}";
6146
6147       return "add{l}\t{%2, %k0|%k0, %2}";
6148     }
6149 }
6150   [(set (attr "type")
6151      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6152         (const_string "incdec")
6153         (const_string "alu")))
6154    (set (attr "length_immediate")
6155       (if_then_else
6156         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6157         (const_string "1")
6158         (const_string "*")))
6159    (set_attr "mode" "SI")])
6160
6161 (define_insn "*add<mode>_3"
6162   [(set (reg FLAGS_REG)
6163         (compare
6164           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6165           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6166    (clobber (match_scratch:SWI 0 "=<r>"))]
6167   "ix86_match_ccmode (insn, CCZmode)
6168    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6169 {
6170   switch (get_attr_type (insn))
6171     {
6172     case TYPE_INCDEC:
6173       if (operands[2] == const1_rtx)
6174         return "inc{<imodesuffix>}\t%0";
6175       else
6176         {
6177           gcc_assert (operands[2] == constm1_rtx);
6178           return "dec{<imodesuffix>}\t%0";
6179         }
6180
6181     default:
6182       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6183         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6184
6185       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6186     }
6187 }
6188   [(set (attr "type")
6189      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6190         (const_string "incdec")
6191         (const_string "alu")))
6192    (set (attr "length_immediate")
6193       (if_then_else
6194         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6195         (const_string "1")
6196         (const_string "*")))
6197    (set_attr "mode" "<MODE>")])
6198
6199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6200 (define_insn "*addsi_3_zext"
6201   [(set (reg FLAGS_REG)
6202         (compare
6203           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6204           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6205    (set (match_operand:DI 0 "register_operand" "=r")
6206         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6207   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6208    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6209 {
6210   switch (get_attr_type (insn))
6211     {
6212     case TYPE_INCDEC:
6213       if (operands[2] == const1_rtx)
6214         return "inc{l}\t%k0";
6215       else
6216         {
6217           gcc_assert (operands[2] == constm1_rtx);
6218           return "dec{l}\t%k0";
6219         }
6220
6221     default:
6222       if (x86_maybe_negate_const_int (&operands[2], SImode))
6223         return "sub{l}\t{%2, %k0|%k0, %2}";
6224
6225       return "add{l}\t{%2, %k0|%k0, %2}";
6226     }
6227 }
6228   [(set (attr "type")
6229      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6230         (const_string "incdec")
6231         (const_string "alu")))
6232    (set (attr "length_immediate")
6233       (if_then_else
6234         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6235         (const_string "1")
6236         (const_string "*")))
6237    (set_attr "mode" "SI")])
6238
6239 ; For comparisons against 1, -1 and 128, we may generate better code
6240 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6241 ; is matched then.  We can't accept general immediate, because for
6242 ; case of overflows,  the result is messed up.
6243 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6244 ; only for comparisons not depending on it.
6245
6246 (define_insn "*adddi_4"
6247   [(set (reg FLAGS_REG)
6248         (compare
6249           (match_operand:DI 1 "nonimmediate_operand" "0")
6250           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6251    (clobber (match_scratch:DI 0 "=rm"))]
6252   "TARGET_64BIT
6253    && ix86_match_ccmode (insn, CCGCmode)"
6254 {
6255   switch (get_attr_type (insn))
6256     {
6257     case TYPE_INCDEC:
6258       if (operands[2] == constm1_rtx)
6259         return "inc{q}\t%0";
6260       else
6261         {
6262           gcc_assert (operands[2] == const1_rtx);
6263           return "dec{q}\t%0";
6264         }
6265
6266     default:
6267       if (x86_maybe_negate_const_int (&operands[2], DImode))
6268         return "add{q}\t{%2, %0|%0, %2}";
6269
6270       return "sub{q}\t{%2, %0|%0, %2}";
6271     }
6272 }
6273   [(set (attr "type")
6274      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6275         (const_string "incdec")
6276         (const_string "alu")))
6277    (set (attr "length_immediate")
6278       (if_then_else
6279         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6280         (const_string "1")
6281         (const_string "*")))
6282    (set_attr "mode" "DI")])
6283
6284 ; For comparisons against 1, -1 and 128, we may generate better code
6285 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6286 ; is matched then.  We can't accept general immediate, because for
6287 ; case of overflows,  the result is messed up.
6288 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6289 ; only for comparisons not depending on it.
6290
6291 (define_insn "*add<mode>_4"
6292   [(set (reg FLAGS_REG)
6293         (compare
6294           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6295           (match_operand:SWI124 2 "const_int_operand" "n")))
6296    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6297   "ix86_match_ccmode (insn, CCGCmode)"
6298 {
6299   switch (get_attr_type (insn))
6300     {
6301     case TYPE_INCDEC:
6302       if (operands[2] == constm1_rtx)
6303         return "inc{<imodesuffix>}\t%0";
6304       else
6305         {
6306           gcc_assert (operands[2] == const1_rtx);
6307           return "dec{<imodesuffix>}\t%0";
6308         }
6309
6310     default:
6311       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6312         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6313
6314       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6315     }
6316 }
6317   [(set (attr "type")
6318      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6319         (const_string "incdec")
6320         (const_string "alu")))
6321    (set (attr "length_immediate")
6322       (if_then_else
6323         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6324         (const_string "1")
6325         (const_string "*")))
6326    (set_attr "mode" "<MODE>")])
6327
6328 (define_insn "*add<mode>_5"
6329   [(set (reg FLAGS_REG)
6330         (compare
6331           (plus:SWI
6332             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6333             (match_operand:SWI 2 "<general_operand>" "<g>"))
6334           (const_int 0)))
6335    (clobber (match_scratch:SWI 0 "=<r>"))]
6336   "ix86_match_ccmode (insn, CCGOCmode)
6337    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6338 {
6339   switch (get_attr_type (insn))
6340     {
6341     case TYPE_INCDEC:
6342       if (operands[2] == const1_rtx)
6343         return "inc{<imodesuffix>}\t%0";
6344       else
6345         {
6346           gcc_assert (operands[2] == constm1_rtx);
6347           return "dec{<imodesuffix>}\t%0";
6348         }
6349
6350     default:
6351       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6352         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6353
6354       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6355     }
6356 }
6357   [(set (attr "type")
6358      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6359         (const_string "incdec")
6360         (const_string "alu")))
6361    (set (attr "length_immediate")
6362       (if_then_else
6363         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6364         (const_string "1")
6365         (const_string "*")))
6366    (set_attr "mode" "<MODE>")])
6367
6368 (define_insn "*addqi_ext_1_rex64"
6369   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6370                          (const_int 8)
6371                          (const_int 8))
6372         (plus:SI
6373           (zero_extract:SI
6374             (match_operand 1 "ext_register_operand" "0")
6375             (const_int 8)
6376             (const_int 8))
6377           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6378    (clobber (reg:CC FLAGS_REG))]
6379   "TARGET_64BIT"
6380 {
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_INCDEC:
6384       if (operands[2] == const1_rtx)
6385         return "inc{b}\t%h0";
6386       else
6387         {
6388           gcc_assert (operands[2] == constm1_rtx);
6389           return "dec{b}\t%h0";
6390         }
6391
6392     default:
6393       return "add{b}\t{%2, %h0|%h0, %2}";
6394     }
6395 }
6396   [(set (attr "type")
6397      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6398         (const_string "incdec")
6399         (const_string "alu")))
6400    (set_attr "modrm" "1")
6401    (set_attr "mode" "QI")])
6402
6403 (define_insn "addqi_ext_1"
6404   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6405                          (const_int 8)
6406                          (const_int 8))
6407         (plus:SI
6408           (zero_extract:SI
6409             (match_operand 1 "ext_register_operand" "0")
6410             (const_int 8)
6411             (const_int 8))
6412           (match_operand:QI 2 "general_operand" "Qmn")))
6413    (clobber (reg:CC FLAGS_REG))]
6414   "!TARGET_64BIT"
6415 {
6416   switch (get_attr_type (insn))
6417     {
6418     case TYPE_INCDEC:
6419       if (operands[2] == const1_rtx)
6420         return "inc{b}\t%h0";
6421       else
6422         {
6423           gcc_assert (operands[2] == constm1_rtx);
6424           return "dec{b}\t%h0";
6425         }
6426
6427     default:
6428       return "add{b}\t{%2, %h0|%h0, %2}";
6429     }
6430 }
6431   [(set (attr "type")
6432      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6433         (const_string "incdec")
6434         (const_string "alu")))
6435    (set_attr "modrm" "1")
6436    (set_attr "mode" "QI")])
6437
6438 (define_insn "*addqi_ext_2"
6439   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6440                          (const_int 8)
6441                          (const_int 8))
6442         (plus:SI
6443           (zero_extract:SI
6444             (match_operand 1 "ext_register_operand" "%0")
6445             (const_int 8)
6446             (const_int 8))
6447           (zero_extract:SI
6448             (match_operand 2 "ext_register_operand" "Q")
6449             (const_int 8)
6450             (const_int 8))))
6451    (clobber (reg:CC FLAGS_REG))]
6452   ""
6453   "add{b}\t{%h2, %h0|%h0, %h2}"
6454   [(set_attr "type" "alu")
6455    (set_attr "mode" "QI")])
6456
6457 ;; The lea patterns for non-Pmodes needs to be matched by
6458 ;; several insns converted to real lea by splitters.
6459
6460 (define_insn_and_split "*lea_general_1"
6461   [(set (match_operand 0 "register_operand" "=r")
6462         (plus (plus (match_operand 1 "index_register_operand" "l")
6463                     (match_operand 2 "register_operand" "r"))
6464               (match_operand 3 "immediate_operand" "i")))]
6465   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6466     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6467    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6468    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6469    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6470    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6471        || GET_MODE (operands[3]) == VOIDmode)"
6472   "#"
6473   "&& reload_completed"
6474   [(const_int 0)]
6475 {
6476   rtx pat;
6477   operands[0] = gen_lowpart (SImode, operands[0]);
6478   operands[1] = gen_lowpart (Pmode, operands[1]);
6479   operands[2] = gen_lowpart (Pmode, operands[2]);
6480   operands[3] = gen_lowpart (Pmode, operands[3]);
6481   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6482                       operands[3]);
6483   if (Pmode != SImode)
6484     pat = gen_rtx_SUBREG (SImode, pat, 0);
6485   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6486   DONE;
6487 }
6488   [(set_attr "type" "lea")
6489    (set_attr "mode" "SI")])
6490
6491 (define_insn_and_split "*lea_general_1_zext"
6492   [(set (match_operand:DI 0 "register_operand" "=r")
6493         (zero_extend:DI
6494           (plus:SI (plus:SI
6495                      (match_operand:SI 1 "index_register_operand" "l")
6496                      (match_operand:SI 2 "register_operand" "r"))
6497                    (match_operand:SI 3 "immediate_operand" "i"))))]
6498   "TARGET_64BIT"
6499   "#"
6500   "&& reload_completed"
6501   [(set (match_dup 0)
6502         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6503                                                      (match_dup 2))
6504                                             (match_dup 3)) 0)))]
6505 {
6506   operands[1] = gen_lowpart (Pmode, operands[1]);
6507   operands[2] = gen_lowpart (Pmode, operands[2]);
6508   operands[3] = gen_lowpart (Pmode, operands[3]);
6509 }
6510   [(set_attr "type" "lea")
6511    (set_attr "mode" "SI")])
6512
6513 (define_insn_and_split "*lea_general_2"
6514   [(set (match_operand 0 "register_operand" "=r")
6515         (plus (mult (match_operand 1 "index_register_operand" "l")
6516                     (match_operand 2 "const248_operand" "i"))
6517               (match_operand 3 "nonmemory_operand" "ri")))]
6518   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6519     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6520    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6521    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6522    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6523        || GET_MODE (operands[3]) == VOIDmode)"
6524   "#"
6525   "&& reload_completed"
6526   [(const_int 0)]
6527 {
6528   rtx pat;
6529   operands[0] = gen_lowpart (SImode, operands[0]);
6530   operands[1] = gen_lowpart (Pmode, operands[1]);
6531   operands[3] = gen_lowpart (Pmode, operands[3]);
6532   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6533                       operands[3]);
6534   if (Pmode != SImode)
6535     pat = gen_rtx_SUBREG (SImode, pat, 0);
6536   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6537   DONE;
6538 }
6539   [(set_attr "type" "lea")
6540    (set_attr "mode" "SI")])
6541
6542 (define_insn_and_split "*lea_general_2_zext"
6543   [(set (match_operand:DI 0 "register_operand" "=r")
6544         (zero_extend:DI
6545           (plus:SI (mult:SI
6546                      (match_operand:SI 1 "index_register_operand" "l")
6547                      (match_operand:SI 2 "const248_operand" "n"))
6548                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6549   "TARGET_64BIT"
6550   "#"
6551   "&& reload_completed"
6552   [(set (match_dup 0)
6553         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6554                                                      (match_dup 2))
6555                                             (match_dup 3)) 0)))]
6556 {
6557   operands[1] = gen_lowpart (Pmode, operands[1]);
6558   operands[3] = gen_lowpart (Pmode, operands[3]);
6559 }
6560   [(set_attr "type" "lea")
6561    (set_attr "mode" "SI")])
6562
6563 (define_insn_and_split "*lea_general_3"
6564   [(set (match_operand 0 "register_operand" "=r")
6565         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6566                           (match_operand 2 "const248_operand" "i"))
6567                     (match_operand 3 "register_operand" "r"))
6568               (match_operand 4 "immediate_operand" "i")))]
6569   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6570     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6571    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6572    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6573    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6574   "#"
6575   "&& reload_completed"
6576   [(const_int 0)]
6577 {
6578   rtx pat;
6579   operands[0] = gen_lowpart (SImode, operands[0]);
6580   operands[1] = gen_lowpart (Pmode, operands[1]);
6581   operands[3] = gen_lowpart (Pmode, operands[3]);
6582   operands[4] = gen_lowpart (Pmode, operands[4]);
6583   pat = gen_rtx_PLUS (Pmode,
6584                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6585                                                          operands[2]),
6586                                     operands[3]),
6587                       operands[4]);
6588   if (Pmode != SImode)
6589     pat = gen_rtx_SUBREG (SImode, pat, 0);
6590   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6591   DONE;
6592 }
6593   [(set_attr "type" "lea")
6594    (set_attr "mode" "SI")])
6595
6596 (define_insn_and_split "*lea_general_3_zext"
6597   [(set (match_operand:DI 0 "register_operand" "=r")
6598         (zero_extend:DI
6599           (plus:SI (plus:SI
6600                      (mult:SI
6601                        (match_operand:SI 1 "index_register_operand" "l")
6602                        (match_operand:SI 2 "const248_operand" "n"))
6603                      (match_operand:SI 3 "register_operand" "r"))
6604                    (match_operand:SI 4 "immediate_operand" "i"))))]
6605   "TARGET_64BIT"
6606   "#"
6607   "&& reload_completed"
6608   [(set (match_dup 0)
6609         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6610                                                               (match_dup 2))
6611                                                      (match_dup 3))
6612                                             (match_dup 4)) 0)))]
6613 {
6614   operands[1] = gen_lowpart (Pmode, operands[1]);
6615   operands[3] = gen_lowpart (Pmode, operands[3]);
6616   operands[4] = gen_lowpart (Pmode, operands[4]);
6617 }
6618   [(set_attr "type" "lea")
6619    (set_attr "mode" "SI")])
6620 \f
6621 ;; Subtract instructions
6622
6623 (define_expand "sub<mode>3"
6624   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6625         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6626                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6627   ""
6628   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6629
6630 (define_insn_and_split "*sub<dwi>3_doubleword"
6631   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6632         (minus:<DWI>
6633           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6634           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6635    (clobber (reg:CC FLAGS_REG))]
6636   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6637   "#"
6638   "reload_completed"
6639   [(parallel [(set (reg:CC FLAGS_REG)
6640                    (compare:CC (match_dup 1) (match_dup 2)))
6641               (set (match_dup 0)
6642                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6643    (parallel [(set (match_dup 3)
6644                    (minus:DWIH
6645                      (match_dup 4)
6646                      (plus:DWIH
6647                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6648                        (match_dup 5))))
6649               (clobber (reg:CC FLAGS_REG))])]
6650   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6651
6652 (define_insn "*sub<mode>_1"
6653   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6654         (minus:SWI
6655           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6656           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6659   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6660   [(set_attr "type" "alu")
6661    (set_attr "mode" "<MODE>")])
6662
6663 (define_insn "*subsi_1_zext"
6664   [(set (match_operand:DI 0 "register_operand" "=r")
6665         (zero_extend:DI
6666           (minus:SI (match_operand:SI 1 "register_operand" "0")
6667                     (match_operand:SI 2 "general_operand" "g"))))
6668    (clobber (reg:CC FLAGS_REG))]
6669   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6670   "sub{l}\t{%2, %k0|%k0, %2}"
6671   [(set_attr "type" "alu")
6672    (set_attr "mode" "SI")])
6673
6674 (define_insn "*subqi_1_slp"
6675   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6676         (minus:QI (match_dup 0)
6677                   (match_operand:QI 1 "general_operand" "qn,qm")))
6678    (clobber (reg:CC FLAGS_REG))]
6679   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6680    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6681   "sub{b}\t{%1, %0|%0, %1}"
6682   [(set_attr "type" "alu1")
6683    (set_attr "mode" "QI")])
6684
6685 (define_insn "*sub<mode>_2"
6686   [(set (reg FLAGS_REG)
6687         (compare
6688           (minus:SWI
6689             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6690             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6691           (const_int 0)))
6692    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6693         (minus:SWI (match_dup 1) (match_dup 2)))]
6694   "ix86_match_ccmode (insn, CCGOCmode)
6695    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6696   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "mode" "<MODE>")])
6699
6700 (define_insn "*subsi_2_zext"
6701   [(set (reg FLAGS_REG)
6702         (compare
6703           (minus:SI (match_operand:SI 1 "register_operand" "0")
6704                     (match_operand:SI 2 "general_operand" "g"))
6705           (const_int 0)))
6706    (set (match_operand:DI 0 "register_operand" "=r")
6707         (zero_extend:DI
6708           (minus:SI (match_dup 1)
6709                     (match_dup 2))))]
6710   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6711    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6712   "sub{l}\t{%2, %k0|%k0, %2}"
6713   [(set_attr "type" "alu")
6714    (set_attr "mode" "SI")])
6715
6716 (define_insn "*sub<mode>_3"
6717   [(set (reg FLAGS_REG)
6718         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6719                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6720    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6721         (minus:SWI (match_dup 1) (match_dup 2)))]
6722   "ix86_match_ccmode (insn, CCmode)
6723    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6724   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6725   [(set_attr "type" "alu")
6726    (set_attr "mode" "<MODE>")])
6727
6728 (define_insn "*subsi_3_zext"
6729   [(set (reg FLAGS_REG)
6730         (compare (match_operand:SI 1 "register_operand" "0")
6731                  (match_operand:SI 2 "general_operand" "g")))
6732    (set (match_operand:DI 0 "register_operand" "=r")
6733         (zero_extend:DI
6734           (minus:SI (match_dup 1)
6735                     (match_dup 2))))]
6736   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6737    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6738   "sub{l}\t{%2, %1|%1, %2}"
6739   [(set_attr "type" "alu")
6740    (set_attr "mode" "SI")])
6741 \f
6742 ;; Add with carry and subtract with borrow
6743
6744 (define_expand "<plusminus_insn><mode>3_carry"
6745   [(parallel
6746     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6747           (plusminus:SWI
6748             (match_operand:SWI 1 "nonimmediate_operand" "")
6749             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6750                        [(match_operand 3 "flags_reg_operand" "")
6751                         (const_int 0)])
6752                       (match_operand:SWI 2 "<general_operand>" ""))))
6753      (clobber (reg:CC FLAGS_REG))])]
6754   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6755
6756 (define_insn "*<plusminus_insn><mode>3_carry"
6757   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6758         (plusminus:SWI
6759           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6760           (plus:SWI
6761             (match_operator 3 "ix86_carry_flag_operator"
6762              [(reg FLAGS_REG) (const_int 0)])
6763             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6764    (clobber (reg:CC FLAGS_REG))]
6765   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6766   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6767   [(set_attr "type" "alu")
6768    (set_attr "use_carry" "1")
6769    (set_attr "pent_pair" "pu")
6770    (set_attr "mode" "<MODE>")])
6771
6772 (define_insn "*addsi3_carry_zext"
6773   [(set (match_operand:DI 0 "register_operand" "=r")
6774         (zero_extend:DI
6775           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6776                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6777                              [(reg FLAGS_REG) (const_int 0)])
6778                             (match_operand:SI 2 "general_operand" "g")))))
6779    (clobber (reg:CC FLAGS_REG))]
6780   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6781   "adc{l}\t{%2, %k0|%k0, %2}"
6782   [(set_attr "type" "alu")
6783    (set_attr "use_carry" "1")
6784    (set_attr "pent_pair" "pu")
6785    (set_attr "mode" "SI")])
6786
6787 (define_insn "*subsi3_carry_zext"
6788   [(set (match_operand:DI 0 "register_operand" "=r")
6789         (zero_extend:DI
6790           (minus:SI (match_operand:SI 1 "register_operand" "0")
6791                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6792                               [(reg FLAGS_REG) (const_int 0)])
6793                              (match_operand:SI 2 "general_operand" "g")))))
6794    (clobber (reg:CC FLAGS_REG))]
6795   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6796   "sbb{l}\t{%2, %k0|%k0, %2}"
6797   [(set_attr "type" "alu")
6798    (set_attr "pent_pair" "pu")
6799    (set_attr "mode" "SI")])
6800 \f
6801 ;; Overflow setting add and subtract instructions
6802
6803 (define_insn "*add<mode>3_cconly_overflow"
6804   [(set (reg:CCC FLAGS_REG)
6805         (compare:CCC
6806           (plus:SWI
6807             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6808             (match_operand:SWI 2 "<general_operand>" "<g>"))
6809           (match_dup 1)))
6810    (clobber (match_scratch:SWI 0 "=<r>"))]
6811   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6813   [(set_attr "type" "alu")
6814    (set_attr "mode" "<MODE>")])
6815
6816 (define_insn "*sub<mode>3_cconly_overflow"
6817   [(set (reg:CCC FLAGS_REG)
6818         (compare:CCC
6819           (minus:SWI
6820             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6821             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6822           (match_dup 0)))]
6823   ""
6824   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6825   [(set_attr "type" "icmp")
6826    (set_attr "mode" "<MODE>")])
6827
6828 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6829   [(set (reg:CCC FLAGS_REG)
6830         (compare:CCC
6831             (plusminus:SWI
6832                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6833                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6834             (match_dup 1)))
6835    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6836         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6837   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6838   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6839   [(set_attr "type" "alu")
6840    (set_attr "mode" "<MODE>")])
6841
6842 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6843   [(set (reg:CCC FLAGS_REG)
6844         (compare:CCC
6845           (plusminus:SI
6846             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6847             (match_operand:SI 2 "general_operand" "g"))
6848           (match_dup 1)))
6849    (set (match_operand:DI 0 "register_operand" "=r")
6850         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6851   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6852   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6853   [(set_attr "type" "alu")
6854    (set_attr "mode" "SI")])
6855
6856 ;; The patterns that match these are at the end of this file.
6857
6858 (define_expand "<plusminus_insn>xf3"
6859   [(set (match_operand:XF 0 "register_operand" "")
6860         (plusminus:XF
6861           (match_operand:XF 1 "register_operand" "")
6862           (match_operand:XF 2 "register_operand" "")))]
6863   "TARGET_80387")
6864
6865 (define_expand "<plusminus_insn><mode>3"
6866   [(set (match_operand:MODEF 0 "register_operand" "")
6867         (plusminus:MODEF
6868           (match_operand:MODEF 1 "register_operand" "")
6869           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6870   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6871     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6872 \f
6873 ;; Multiply instructions
6874
6875 (define_expand "mul<mode>3"
6876   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6877                    (mult:SWIM248
6878                      (match_operand:SWIM248 1 "register_operand" "")
6879                      (match_operand:SWIM248 2 "<general_operand>" "")))
6880               (clobber (reg:CC FLAGS_REG))])])
6881
6882 (define_expand "mulqi3"
6883   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6884                    (mult:QI
6885                      (match_operand:QI 1 "register_operand" "")
6886                      (match_operand:QI 2 "nonimmediate_operand" "")))
6887               (clobber (reg:CC FLAGS_REG))])]
6888   "TARGET_QIMODE_MATH")
6889
6890 ;; On AMDFAM10
6891 ;; IMUL reg32/64, reg32/64, imm8        Direct
6892 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6893 ;; IMUL reg32/64, reg32/64, imm32       Direct
6894 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6895 ;; IMUL reg32/64, reg32/64              Direct
6896 ;; IMUL reg32/64, mem32/64              Direct
6897 ;;
6898 ;; On BDVER1, all above IMULs use DirectPath
6899
6900 (define_insn "*mul<mode>3_1"
6901   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6902         (mult:SWI48
6903           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6904           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6905    (clobber (reg:CC FLAGS_REG))]
6906   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6907   "@
6908    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6909    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6910    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6911   [(set_attr "type" "imul")
6912    (set_attr "prefix_0f" "0,0,1")
6913    (set (attr "athlon_decode")
6914         (cond [(eq_attr "cpu" "athlon")
6915                   (const_string "vector")
6916                (eq_attr "alternative" "1")
6917                   (const_string "vector")
6918                (and (eq_attr "alternative" "2")
6919                     (match_operand 1 "memory_operand" ""))
6920                   (const_string "vector")]
6921               (const_string "direct")))
6922    (set (attr "amdfam10_decode")
6923         (cond [(and (eq_attr "alternative" "0,1")
6924                     (match_operand 1 "memory_operand" ""))
6925                   (const_string "vector")]
6926               (const_string "direct")))
6927    (set_attr "bdver1_decode" "direct")
6928    (set_attr "mode" "<MODE>")])
6929
6930 (define_insn "*mulsi3_1_zext"
6931   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6932         (zero_extend:DI
6933           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6934                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6935    (clobber (reg:CC FLAGS_REG))]
6936   "TARGET_64BIT
6937    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6938   "@
6939    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6940    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6941    imul{l}\t{%2, %k0|%k0, %2}"
6942   [(set_attr "type" "imul")
6943    (set_attr "prefix_0f" "0,0,1")
6944    (set (attr "athlon_decode")
6945         (cond [(eq_attr "cpu" "athlon")
6946                   (const_string "vector")
6947                (eq_attr "alternative" "1")
6948                   (const_string "vector")
6949                (and (eq_attr "alternative" "2")
6950                     (match_operand 1 "memory_operand" ""))
6951                   (const_string "vector")]
6952               (const_string "direct")))
6953    (set (attr "amdfam10_decode")
6954         (cond [(and (eq_attr "alternative" "0,1")
6955                     (match_operand 1 "memory_operand" ""))
6956                   (const_string "vector")]
6957               (const_string "direct")))
6958    (set_attr "bdver1_decode" "direct")
6959    (set_attr "mode" "SI")])
6960
6961 ;; On AMDFAM10
6962 ;; IMUL reg16, reg16, imm8      VectorPath
6963 ;; IMUL reg16, mem16, imm8      VectorPath
6964 ;; IMUL reg16, reg16, imm16     VectorPath
6965 ;; IMUL reg16, mem16, imm16     VectorPath
6966 ;; IMUL reg16, reg16            Direct
6967 ;; IMUL reg16, mem16            Direct
6968 ;;
6969 ;; On BDVER1, all HI MULs use DoublePath
6970
6971 (define_insn "*mulhi3_1"
6972   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6973         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6974                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6975    (clobber (reg:CC FLAGS_REG))]
6976   "TARGET_HIMODE_MATH
6977    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6978   "@
6979    imul{w}\t{%2, %1, %0|%0, %1, %2}
6980    imul{w}\t{%2, %1, %0|%0, %1, %2}
6981    imul{w}\t{%2, %0|%0, %2}"
6982   [(set_attr "type" "imul")
6983    (set_attr "prefix_0f" "0,0,1")
6984    (set (attr "athlon_decode")
6985         (cond [(eq_attr "cpu" "athlon")
6986                   (const_string "vector")
6987                (eq_attr "alternative" "1,2")
6988                   (const_string "vector")]
6989               (const_string "direct")))
6990    (set (attr "amdfam10_decode")
6991         (cond [(eq_attr "alternative" "0,1")
6992                   (const_string "vector")]
6993               (const_string "direct")))
6994    (set_attr "bdver1_decode" "double")
6995    (set_attr "mode" "HI")])
6996
6997 ;;On AMDFAM10 and BDVER1
6998 ;; MUL reg8     Direct
6999 ;; MUL mem8     Direct
7000
7001 (define_insn "*mulqi3_1"
7002   [(set (match_operand:QI 0 "register_operand" "=a")
7003         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7004                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7005    (clobber (reg:CC FLAGS_REG))]
7006   "TARGET_QIMODE_MATH
7007    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7008   "mul{b}\t%2"
7009   [(set_attr "type" "imul")
7010    (set_attr "length_immediate" "0")
7011    (set (attr "athlon_decode")
7012      (if_then_else (eq_attr "cpu" "athlon")
7013         (const_string "vector")
7014         (const_string "direct")))
7015    (set_attr "amdfam10_decode" "direct")
7016    (set_attr "bdver1_decode" "direct")
7017    (set_attr "mode" "QI")])
7018
7019 (define_expand "<u>mul<mode><dwi>3"
7020   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7021                    (mult:<DWI>
7022                      (any_extend:<DWI>
7023                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7024                      (any_extend:<DWI>
7025                        (match_operand:DWIH 2 "register_operand" ""))))
7026               (clobber (reg:CC FLAGS_REG))])])
7027
7028 (define_expand "<u>mulqihi3"
7029   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7030                    (mult:HI
7031                      (any_extend:HI
7032                        (match_operand:QI 1 "nonimmediate_operand" ""))
7033                      (any_extend:HI
7034                        (match_operand:QI 2 "register_operand" ""))))
7035               (clobber (reg:CC FLAGS_REG))])]
7036   "TARGET_QIMODE_MATH")
7037
7038 (define_insn "*<u>mul<mode><dwi>3_1"
7039   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7040         (mult:<DWI>
7041           (any_extend:<DWI>
7042             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7043           (any_extend:<DWI>
7044             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7045    (clobber (reg:CC FLAGS_REG))]
7046   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7047   "<sgnprefix>mul{<imodesuffix>}\t%2"
7048   [(set_attr "type" "imul")
7049    (set_attr "length_immediate" "0")
7050    (set (attr "athlon_decode")
7051      (if_then_else (eq_attr "cpu" "athlon")
7052         (const_string "vector")
7053         (const_string "double")))
7054    (set_attr "amdfam10_decode" "double")
7055    (set_attr "bdver1_decode" "direct")
7056    (set_attr "mode" "<MODE>")])
7057
7058 (define_insn "*<u>mulqihi3_1"
7059   [(set (match_operand:HI 0 "register_operand" "=a")
7060         (mult:HI
7061           (any_extend:HI
7062             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7063           (any_extend:HI
7064             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7065    (clobber (reg:CC FLAGS_REG))]
7066   "TARGET_QIMODE_MATH
7067    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7068   "<sgnprefix>mul{b}\t%2"
7069   [(set_attr "type" "imul")
7070    (set_attr "length_immediate" "0")
7071    (set (attr "athlon_decode")
7072      (if_then_else (eq_attr "cpu" "athlon")
7073         (const_string "vector")
7074         (const_string "direct")))
7075    (set_attr "amdfam10_decode" "direct")
7076    (set_attr "bdver1_decode" "direct")
7077    (set_attr "mode" "QI")])
7078
7079 (define_expand "<s>mul<mode>3_highpart"
7080   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7081                    (truncate:SWI48
7082                      (lshiftrt:<DWI>
7083                        (mult:<DWI>
7084                          (any_extend:<DWI>
7085                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7086                          (any_extend:<DWI>
7087                            (match_operand:SWI48 2 "register_operand" "")))
7088                        (match_dup 4))))
7089               (clobber (match_scratch:SWI48 3 ""))
7090               (clobber (reg:CC FLAGS_REG))])]
7091   ""
7092   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7093
7094 (define_insn "*<s>muldi3_highpart_1"
7095   [(set (match_operand:DI 0 "register_operand" "=d")
7096         (truncate:DI
7097           (lshiftrt:TI
7098             (mult:TI
7099               (any_extend:TI
7100                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7101               (any_extend:TI
7102                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7103             (const_int 64))))
7104    (clobber (match_scratch:DI 3 "=1"))
7105    (clobber (reg:CC FLAGS_REG))]
7106   "TARGET_64BIT
7107    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7108   "<sgnprefix>mul{q}\t%2"
7109   [(set_attr "type" "imul")
7110    (set_attr "length_immediate" "0")
7111    (set (attr "athlon_decode")
7112      (if_then_else (eq_attr "cpu" "athlon")
7113         (const_string "vector")
7114         (const_string "double")))
7115    (set_attr "amdfam10_decode" "double")
7116    (set_attr "bdver1_decode" "direct")
7117    (set_attr "mode" "DI")])
7118
7119 (define_insn "*<s>mulsi3_highpart_1"
7120   [(set (match_operand:SI 0 "register_operand" "=d")
7121         (truncate:SI
7122           (lshiftrt:DI
7123             (mult:DI
7124               (any_extend:DI
7125                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7126               (any_extend:DI
7127                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7128             (const_int 32))))
7129    (clobber (match_scratch:SI 3 "=1"))
7130    (clobber (reg:CC FLAGS_REG))]
7131   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7132   "<sgnprefix>mul{l}\t%2"
7133   [(set_attr "type" "imul")
7134    (set_attr "length_immediate" "0")
7135    (set (attr "athlon_decode")
7136      (if_then_else (eq_attr "cpu" "athlon")
7137         (const_string "vector")
7138         (const_string "double")))
7139    (set_attr "amdfam10_decode" "double")
7140    (set_attr "bdver1_decode" "direct")
7141    (set_attr "mode" "SI")])
7142
7143 (define_insn "*<s>mulsi3_highpart_zext"
7144   [(set (match_operand:DI 0 "register_operand" "=d")
7145         (zero_extend:DI (truncate:SI
7146           (lshiftrt:DI
7147             (mult:DI (any_extend:DI
7148                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7149                      (any_extend:DI
7150                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7151             (const_int 32)))))
7152    (clobber (match_scratch:SI 3 "=1"))
7153    (clobber (reg:CC FLAGS_REG))]
7154   "TARGET_64BIT
7155    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7156   "<sgnprefix>mul{l}\t%2"
7157   [(set_attr "type" "imul")
7158    (set_attr "length_immediate" "0")
7159    (set (attr "athlon_decode")
7160      (if_then_else (eq_attr "cpu" "athlon")
7161         (const_string "vector")
7162         (const_string "double")))
7163    (set_attr "amdfam10_decode" "double")
7164    (set_attr "bdver1_decode" "direct")
7165    (set_attr "mode" "SI")])
7166
7167 ;; The patterns that match these are at the end of this file.
7168
7169 (define_expand "mulxf3"
7170   [(set (match_operand:XF 0 "register_operand" "")
7171         (mult:XF (match_operand:XF 1 "register_operand" "")
7172                  (match_operand:XF 2 "register_operand" "")))]
7173   "TARGET_80387")
7174
7175 (define_expand "mul<mode>3"
7176   [(set (match_operand:MODEF 0 "register_operand" "")
7177         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7178                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7179   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7180     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7181 \f
7182 ;; Divide instructions
7183
7184 ;; The patterns that match these are at the end of this file.
7185
7186 (define_expand "divxf3"
7187   [(set (match_operand:XF 0 "register_operand" "")
7188         (div:XF (match_operand:XF 1 "register_operand" "")
7189                 (match_operand:XF 2 "register_operand" "")))]
7190   "TARGET_80387")
7191
7192 (define_expand "divdf3"
7193   [(set (match_operand:DF 0 "register_operand" "")
7194         (div:DF (match_operand:DF 1 "register_operand" "")
7195                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7196    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7197     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7198
7199 (define_expand "divsf3"
7200   [(set (match_operand:SF 0 "register_operand" "")
7201         (div:SF (match_operand:SF 1 "register_operand" "")
7202                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7203   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7204     || TARGET_SSE_MATH"
7205 {
7206   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7207       && flag_finite_math_only && !flag_trapping_math
7208       && flag_unsafe_math_optimizations)
7209     {
7210       ix86_emit_swdivsf (operands[0], operands[1],
7211                          operands[2], SFmode);
7212       DONE;
7213     }
7214 })
7215 \f
7216 ;; Divmod instructions.
7217
7218 (define_expand "divmod<mode>4"
7219   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7220                    (div:SWIM248
7221                      (match_operand:SWIM248 1 "register_operand" "")
7222                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7223               (set (match_operand:SWIM248 3 "register_operand" "")
7224                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7225               (clobber (reg:CC FLAGS_REG))])])
7226
7227 ;; Split with 8bit unsigned divide:
7228 ;;      if (dividend an divisor are in [0-255])
7229 ;;         use 8bit unsigned integer divide
7230 ;;       else
7231 ;;         use original integer divide
7232 (define_split
7233   [(set (match_operand:SWI48 0 "register_operand" "")
7234         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7235                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7236    (set (match_operand:SWI48 1 "register_operand" "")
7237         (mod:SWI48 (match_dup 2) (match_dup 3)))
7238    (clobber (reg:CC FLAGS_REG))]
7239   "TARGET_USE_8BIT_IDIV
7240    && TARGET_QIMODE_MATH
7241    && can_create_pseudo_p ()
7242    && !optimize_insn_for_size_p ()"
7243   [(const_int 0)]
7244   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7245
7246 (define_insn_and_split "divmod<mode>4_1"
7247   [(set (match_operand:SWI48 0 "register_operand" "=a")
7248         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7249                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7250    (set (match_operand:SWI48 1 "register_operand" "=&d")
7251         (mod:SWI48 (match_dup 2) (match_dup 3)))
7252    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7253    (clobber (reg:CC FLAGS_REG))]
7254   ""
7255   "#"
7256   "reload_completed"
7257   [(parallel [(set (match_dup 1)
7258                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7259               (clobber (reg:CC FLAGS_REG))])
7260    (parallel [(set (match_dup 0)
7261                    (div:SWI48 (match_dup 2) (match_dup 3)))
7262               (set (match_dup 1)
7263                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7264               (use (match_dup 1))
7265               (clobber (reg:CC FLAGS_REG))])]
7266 {
7267   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7268
7269   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7270     operands[4] = operands[2];
7271   else
7272     {
7273       /* Avoid use of cltd in favor of a mov+shift.  */
7274       emit_move_insn (operands[1], operands[2]);
7275       operands[4] = operands[1];
7276     }
7277 }
7278   [(set_attr "type" "multi")
7279    (set_attr "mode" "<MODE>")])
7280
7281 (define_insn_and_split "*divmod<mode>4"
7282   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7283         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7284                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7285    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7286         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7287    (clobber (reg:CC FLAGS_REG))]
7288   ""
7289   "#"
7290   "reload_completed"
7291   [(parallel [(set (match_dup 1)
7292                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7293               (clobber (reg:CC FLAGS_REG))])
7294    (parallel [(set (match_dup 0)
7295                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7296               (set (match_dup 1)
7297                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7298               (use (match_dup 1))
7299               (clobber (reg:CC FLAGS_REG))])]
7300 {
7301   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7302
7303   if (<MODE>mode != HImode
7304       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7305     operands[4] = operands[2];
7306   else
7307     {
7308       /* Avoid use of cltd in favor of a mov+shift.  */
7309       emit_move_insn (operands[1], operands[2]);
7310       operands[4] = operands[1];
7311     }
7312 }
7313   [(set_attr "type" "multi")
7314    (set_attr "mode" "<MODE>")])
7315
7316 (define_insn "*divmod<mode>4_noext"
7317   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7318         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7319                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7320    (set (match_operand:SWIM248 1 "register_operand" "=d")
7321         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7322    (use (match_operand:SWIM248 4 "register_operand" "1"))
7323    (clobber (reg:CC FLAGS_REG))]
7324   ""
7325   "idiv{<imodesuffix>}\t%3"
7326   [(set_attr "type" "idiv")
7327    (set_attr "mode" "<MODE>")])
7328
7329 (define_expand "divmodqi4"
7330   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7331                    (div:QI
7332                      (match_operand:QI 1 "register_operand" "")
7333                      (match_operand:QI 2 "nonimmediate_operand" "")))
7334               (set (match_operand:QI 3 "register_operand" "")
7335                    (mod:QI (match_dup 1) (match_dup 2)))
7336               (clobber (reg:CC FLAGS_REG))])]
7337   "TARGET_QIMODE_MATH"
7338 {
7339   rtx div, mod, insn;
7340   rtx tmp0, tmp1;
7341   
7342   tmp0 = gen_reg_rtx (HImode);
7343   tmp1 = gen_reg_rtx (HImode);
7344
7345   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7346      in AX.  */
7347   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7348   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7349
7350   /* Extract remainder from AH.  */
7351   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7352   insn = emit_move_insn (operands[3], tmp1);
7353
7354   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7355   set_unique_reg_note (insn, REG_EQUAL, mod);
7356
7357   /* Extract quotient from AL.  */
7358   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7359
7360   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7361   set_unique_reg_note (insn, REG_EQUAL, div);
7362
7363   DONE;
7364 })
7365
7366 ;; Divide AX by r/m8, with result stored in
7367 ;; AL <- Quotient
7368 ;; AH <- Remainder
7369 ;; Change div/mod to HImode and extend the second argument to HImode
7370 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7371 ;; combine may fail.
7372 (define_insn "divmodhiqi3"
7373   [(set (match_operand:HI 0 "register_operand" "=a")
7374         (ior:HI
7375           (ashift:HI
7376             (zero_extend:HI
7377               (truncate:QI
7378                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7379                         (sign_extend:HI
7380                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7381             (const_int 8))
7382           (zero_extend:HI
7383             (truncate:QI
7384               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7385    (clobber (reg:CC FLAGS_REG))]
7386   "TARGET_QIMODE_MATH"
7387   "idiv{b}\t%2"
7388   [(set_attr "type" "idiv")
7389    (set_attr "mode" "QI")])
7390
7391 (define_expand "udivmod<mode>4"
7392   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7393                    (udiv:SWIM248
7394                      (match_operand:SWIM248 1 "register_operand" "")
7395                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7396               (set (match_operand:SWIM248 3 "register_operand" "")
7397                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7398               (clobber (reg:CC FLAGS_REG))])])
7399
7400 ;; Split with 8bit unsigned divide:
7401 ;;      if (dividend an divisor are in [0-255])
7402 ;;         use 8bit unsigned integer divide
7403 ;;       else
7404 ;;         use original integer divide
7405 (define_split
7406   [(set (match_operand:SWI48 0 "register_operand" "")
7407         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7408                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7409    (set (match_operand:SWI48 1 "register_operand" "")
7410         (umod:SWI48 (match_dup 2) (match_dup 3)))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "TARGET_USE_8BIT_IDIV
7413    && TARGET_QIMODE_MATH
7414    && can_create_pseudo_p ()
7415    && !optimize_insn_for_size_p ()"
7416   [(const_int 0)]
7417   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7418
7419 (define_insn_and_split "udivmod<mode>4_1"
7420   [(set (match_operand:SWI48 0 "register_operand" "=a")
7421         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7422                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7423    (set (match_operand:SWI48 1 "register_operand" "=&d")
7424         (umod:SWI48 (match_dup 2) (match_dup 3)))
7425    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7426    (clobber (reg:CC FLAGS_REG))]
7427   ""
7428   "#"
7429   "reload_completed"
7430   [(set (match_dup 1) (const_int 0))
7431    (parallel [(set (match_dup 0)
7432                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7433               (set (match_dup 1)
7434                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7435               (use (match_dup 1))
7436               (clobber (reg:CC FLAGS_REG))])]
7437   ""
7438   [(set_attr "type" "multi")
7439    (set_attr "mode" "<MODE>")])
7440
7441 (define_insn_and_split "*udivmod<mode>4"
7442   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7443         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7444                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7445    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7446         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7447    (clobber (reg:CC FLAGS_REG))]
7448   ""
7449   "#"
7450   "reload_completed"
7451   [(set (match_dup 1) (const_int 0))
7452    (parallel [(set (match_dup 0)
7453                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7454               (set (match_dup 1)
7455                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7456               (use (match_dup 1))
7457               (clobber (reg:CC FLAGS_REG))])]
7458   ""
7459   [(set_attr "type" "multi")
7460    (set_attr "mode" "<MODE>")])
7461
7462 (define_insn "*udivmod<mode>4_noext"
7463   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7464         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7465                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7466    (set (match_operand:SWIM248 1 "register_operand" "=d")
7467         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7468    (use (match_operand:SWIM248 4 "register_operand" "1"))
7469    (clobber (reg:CC FLAGS_REG))]
7470   ""
7471   "div{<imodesuffix>}\t%3"
7472   [(set_attr "type" "idiv")
7473    (set_attr "mode" "<MODE>")])
7474
7475 (define_expand "udivmodqi4"
7476   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7477                    (udiv:QI
7478                      (match_operand:QI 1 "register_operand" "")
7479                      (match_operand:QI 2 "nonimmediate_operand" "")))
7480               (set (match_operand:QI 3 "register_operand" "")
7481                    (umod:QI (match_dup 1) (match_dup 2)))
7482               (clobber (reg:CC FLAGS_REG))])]
7483   "TARGET_QIMODE_MATH"
7484 {
7485   rtx div, mod, insn;
7486   rtx tmp0, tmp1;
7487   
7488   tmp0 = gen_reg_rtx (HImode);
7489   tmp1 = gen_reg_rtx (HImode);
7490
7491   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7492      in AX.  */
7493   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7494   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7495
7496   /* Extract remainder from AH.  */
7497   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7498   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7499   insn = emit_move_insn (operands[3], tmp1);
7500
7501   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7502   set_unique_reg_note (insn, REG_EQUAL, mod);
7503
7504   /* Extract quotient from AL.  */
7505   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7506
7507   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7508   set_unique_reg_note (insn, REG_EQUAL, div);
7509
7510   DONE;
7511 })
7512
7513 (define_insn "udivmodhiqi3"
7514   [(set (match_operand:HI 0 "register_operand" "=a")
7515         (ior:HI
7516           (ashift:HI
7517             (zero_extend:HI
7518               (truncate:QI
7519                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7520                         (zero_extend:HI
7521                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7522             (const_int 8))
7523           (zero_extend:HI
7524             (truncate:QI
7525               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7526    (clobber (reg:CC FLAGS_REG))]
7527   "TARGET_QIMODE_MATH"
7528   "div{b}\t%2"
7529   [(set_attr "type" "idiv")
7530    (set_attr "mode" "QI")])
7531
7532 ;; We cannot use div/idiv for double division, because it causes
7533 ;; "division by zero" on the overflow and that's not what we expect
7534 ;; from truncate.  Because true (non truncating) double division is
7535 ;; never generated, we can't create this insn anyway.
7536 ;
7537 ;(define_insn ""
7538 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7539 ;       (truncate:SI
7540 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7541 ;                  (zero_extend:DI
7542 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7543 ;   (set (match_operand:SI 3 "register_operand" "=d")
7544 ;       (truncate:SI
7545 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7546 ;   (clobber (reg:CC FLAGS_REG))]
7547 ;  ""
7548 ;  "div{l}\t{%2, %0|%0, %2}"
7549 ;  [(set_attr "type" "idiv")])
7550 \f
7551 ;;- Logical AND instructions
7552
7553 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7554 ;; Note that this excludes ah.
7555
7556 (define_expand "testsi_ccno_1"
7557   [(set (reg:CCNO FLAGS_REG)
7558         (compare:CCNO
7559           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7560                   (match_operand:SI 1 "nonmemory_operand" ""))
7561           (const_int 0)))])
7562
7563 (define_expand "testqi_ccz_1"
7564   [(set (reg:CCZ FLAGS_REG)
7565         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7566                              (match_operand:QI 1 "nonmemory_operand" ""))
7567                  (const_int 0)))])
7568
7569 (define_expand "testdi_ccno_1"
7570   [(set (reg:CCNO FLAGS_REG)
7571         (compare:CCNO
7572           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7573                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7574           (const_int 0)))]
7575   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7576
7577 (define_insn "*testdi_1"
7578   [(set (reg FLAGS_REG)
7579         (compare
7580          (and:DI
7581           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7582           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7583          (const_int 0)))]
7584   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7585    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7586   "@
7587    test{l}\t{%k1, %k0|%k0, %k1}
7588    test{l}\t{%k1, %k0|%k0, %k1}
7589    test{q}\t{%1, %0|%0, %1}
7590    test{q}\t{%1, %0|%0, %1}
7591    test{q}\t{%1, %0|%0, %1}"
7592   [(set_attr "type" "test")
7593    (set_attr "modrm" "0,1,0,1,1")
7594    (set_attr "mode" "SI,SI,DI,DI,DI")])
7595
7596 (define_insn "*testqi_1_maybe_si"
7597   [(set (reg FLAGS_REG)
7598         (compare
7599           (and:QI
7600             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7601             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7602           (const_int 0)))]
7603    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7604     && ix86_match_ccmode (insn,
7605                          CONST_INT_P (operands[1])
7606                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7607 {
7608   if (which_alternative == 3)
7609     {
7610       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7611         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7612       return "test{l}\t{%1, %k0|%k0, %1}";
7613     }
7614   return "test{b}\t{%1, %0|%0, %1}";
7615 }
7616   [(set_attr "type" "test")
7617    (set_attr "modrm" "0,1,1,1")
7618    (set_attr "mode" "QI,QI,QI,SI")
7619    (set_attr "pent_pair" "uv,np,uv,np")])
7620
7621 (define_insn "*test<mode>_1"
7622   [(set (reg FLAGS_REG)
7623         (compare
7624          (and:SWI124
7625           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7626           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7627          (const_int 0)))]
7628   "ix86_match_ccmode (insn, CCNOmode)
7629    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7630   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7631   [(set_attr "type" "test")
7632    (set_attr "modrm" "0,1,1")
7633    (set_attr "mode" "<MODE>")
7634    (set_attr "pent_pair" "uv,np,uv")])
7635
7636 (define_expand "testqi_ext_ccno_0"
7637   [(set (reg:CCNO FLAGS_REG)
7638         (compare:CCNO
7639           (and:SI
7640             (zero_extract:SI
7641               (match_operand 0 "ext_register_operand" "")
7642               (const_int 8)
7643               (const_int 8))
7644             (match_operand 1 "const_int_operand" ""))
7645           (const_int 0)))])
7646
7647 (define_insn "*testqi_ext_0"
7648   [(set (reg FLAGS_REG)
7649         (compare
7650           (and:SI
7651             (zero_extract:SI
7652               (match_operand 0 "ext_register_operand" "Q")
7653               (const_int 8)
7654               (const_int 8))
7655             (match_operand 1 "const_int_operand" "n"))
7656           (const_int 0)))]
7657   "ix86_match_ccmode (insn, CCNOmode)"
7658   "test{b}\t{%1, %h0|%h0, %1}"
7659   [(set_attr "type" "test")
7660    (set_attr "mode" "QI")
7661    (set_attr "length_immediate" "1")
7662    (set_attr "modrm" "1")
7663    (set_attr "pent_pair" "np")])
7664
7665 (define_insn "*testqi_ext_1_rex64"
7666   [(set (reg FLAGS_REG)
7667         (compare
7668           (and:SI
7669             (zero_extract:SI
7670               (match_operand 0 "ext_register_operand" "Q")
7671               (const_int 8)
7672               (const_int 8))
7673             (zero_extend:SI
7674               (match_operand:QI 1 "register_operand" "Q")))
7675           (const_int 0)))]
7676   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7677   "test{b}\t{%1, %h0|%h0, %1}"
7678   [(set_attr "type" "test")
7679    (set_attr "mode" "QI")])
7680
7681 (define_insn "*testqi_ext_1"
7682   [(set (reg FLAGS_REG)
7683         (compare
7684           (and:SI
7685             (zero_extract:SI
7686               (match_operand 0 "ext_register_operand" "Q")
7687               (const_int 8)
7688               (const_int 8))
7689             (zero_extend:SI
7690               (match_operand:QI 1 "general_operand" "Qm")))
7691           (const_int 0)))]
7692   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7693   "test{b}\t{%1, %h0|%h0, %1}"
7694   [(set_attr "type" "test")
7695    (set_attr "mode" "QI")])
7696
7697 (define_insn "*testqi_ext_2"
7698   [(set (reg FLAGS_REG)
7699         (compare
7700           (and:SI
7701             (zero_extract:SI
7702               (match_operand 0 "ext_register_operand" "Q")
7703               (const_int 8)
7704               (const_int 8))
7705             (zero_extract:SI
7706               (match_operand 1 "ext_register_operand" "Q")
7707               (const_int 8)
7708               (const_int 8)))
7709           (const_int 0)))]
7710   "ix86_match_ccmode (insn, CCNOmode)"
7711   "test{b}\t{%h1, %h0|%h0, %h1}"
7712   [(set_attr "type" "test")
7713    (set_attr "mode" "QI")])
7714
7715 (define_insn "*testqi_ext_3_rex64"
7716   [(set (reg FLAGS_REG)
7717         (compare (zero_extract:DI
7718                    (match_operand 0 "nonimmediate_operand" "rm")
7719                    (match_operand:DI 1 "const_int_operand" "")
7720                    (match_operand:DI 2 "const_int_operand" ""))
7721                  (const_int 0)))]
7722   "TARGET_64BIT
7723    && ix86_match_ccmode (insn, CCNOmode)
7724    && INTVAL (operands[1]) > 0
7725    && INTVAL (operands[2]) >= 0
7726    /* Ensure that resulting mask is zero or sign extended operand.  */
7727    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7728        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7729            && INTVAL (operands[1]) > 32))
7730    && (GET_MODE (operands[0]) == SImode
7731        || GET_MODE (operands[0]) == DImode
7732        || GET_MODE (operands[0]) == HImode
7733        || GET_MODE (operands[0]) == QImode)"
7734   "#")
7735
7736 ;; Combine likes to form bit extractions for some tests.  Humor it.
7737 (define_insn "*testqi_ext_3"
7738   [(set (reg FLAGS_REG)
7739         (compare (zero_extract:SI
7740                    (match_operand 0 "nonimmediate_operand" "rm")
7741                    (match_operand:SI 1 "const_int_operand" "")
7742                    (match_operand:SI 2 "const_int_operand" ""))
7743                  (const_int 0)))]
7744   "ix86_match_ccmode (insn, CCNOmode)
7745    && INTVAL (operands[1]) > 0
7746    && INTVAL (operands[2]) >= 0
7747    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7748    && (GET_MODE (operands[0]) == SImode
7749        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7750        || GET_MODE (operands[0]) == HImode
7751        || GET_MODE (operands[0]) == QImode)"
7752   "#")
7753
7754 (define_split
7755   [(set (match_operand 0 "flags_reg_operand" "")
7756         (match_operator 1 "compare_operator"
7757           [(zero_extract
7758              (match_operand 2 "nonimmediate_operand" "")
7759              (match_operand 3 "const_int_operand" "")
7760              (match_operand 4 "const_int_operand" ""))
7761            (const_int 0)]))]
7762   "ix86_match_ccmode (insn, CCNOmode)"
7763   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7764 {
7765   rtx val = operands[2];
7766   HOST_WIDE_INT len = INTVAL (operands[3]);
7767   HOST_WIDE_INT pos = INTVAL (operands[4]);
7768   HOST_WIDE_INT mask;
7769   enum machine_mode mode, submode;
7770
7771   mode = GET_MODE (val);
7772   if (MEM_P (val))
7773     {
7774       /* ??? Combine likes to put non-volatile mem extractions in QImode
7775          no matter the size of the test.  So find a mode that works.  */
7776       if (! MEM_VOLATILE_P (val))
7777         {
7778           mode = smallest_mode_for_size (pos + len, MODE_INT);
7779           val = adjust_address (val, mode, 0);
7780         }
7781     }
7782   else if (GET_CODE (val) == SUBREG
7783            && (submode = GET_MODE (SUBREG_REG (val)),
7784                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7785            && pos + len <= GET_MODE_BITSIZE (submode)
7786            && GET_MODE_CLASS (submode) == MODE_INT)
7787     {
7788       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7789       mode = submode;
7790       val = SUBREG_REG (val);
7791     }
7792   else if (mode == HImode && pos + len <= 8)
7793     {
7794       /* Small HImode tests can be converted to QImode.  */
7795       mode = QImode;
7796       val = gen_lowpart (QImode, val);
7797     }
7798
7799   if (len == HOST_BITS_PER_WIDE_INT)
7800     mask = -1;
7801   else
7802     mask = ((HOST_WIDE_INT)1 << len) - 1;
7803   mask <<= pos;
7804
7805   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7806 })
7807
7808 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7809 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7810 ;; this is relatively important trick.
7811 ;; Do the conversion only post-reload to avoid limiting of the register class
7812 ;; to QI regs.
7813 (define_split
7814   [(set (match_operand 0 "flags_reg_operand" "")
7815         (match_operator 1 "compare_operator"
7816           [(and (match_operand 2 "register_operand" "")
7817                 (match_operand 3 "const_int_operand" ""))
7818            (const_int 0)]))]
7819    "reload_completed
7820     && QI_REG_P (operands[2])
7821     && GET_MODE (operands[2]) != QImode
7822     && ((ix86_match_ccmode (insn, CCZmode)
7823          && !(INTVAL (operands[3]) & ~(255 << 8)))
7824         || (ix86_match_ccmode (insn, CCNOmode)
7825             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7826   [(set (match_dup 0)
7827         (match_op_dup 1
7828           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7829                    (match_dup 3))
7830            (const_int 0)]))]
7831   "operands[2] = gen_lowpart (SImode, operands[2]);
7832    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7833
7834 (define_split
7835   [(set (match_operand 0 "flags_reg_operand" "")
7836         (match_operator 1 "compare_operator"
7837           [(and (match_operand 2 "nonimmediate_operand" "")
7838                 (match_operand 3 "const_int_operand" ""))
7839            (const_int 0)]))]
7840    "reload_completed
7841     && GET_MODE (operands[2]) != QImode
7842     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7843     && ((ix86_match_ccmode (insn, CCZmode)
7844          && !(INTVAL (operands[3]) & ~255))
7845         || (ix86_match_ccmode (insn, CCNOmode)
7846             && !(INTVAL (operands[3]) & ~127)))"
7847   [(set (match_dup 0)
7848         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7849                          (const_int 0)]))]
7850   "operands[2] = gen_lowpart (QImode, operands[2]);
7851    operands[3] = gen_lowpart (QImode, operands[3]);")
7852
7853 ;; %%% This used to optimize known byte-wide and operations to memory,
7854 ;; and sometimes to QImode registers.  If this is considered useful,
7855 ;; it should be done with splitters.
7856
7857 (define_expand "and<mode>3"
7858   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7859         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7860                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7861   ""
7862   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7863
7864 (define_insn "*anddi_1"
7865   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7866         (and:DI
7867          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7868          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7869    (clobber (reg:CC FLAGS_REG))]
7870   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7871 {
7872   switch (get_attr_type (insn))
7873     {
7874     case TYPE_IMOVX:
7875       {
7876         enum machine_mode mode;
7877
7878         gcc_assert (CONST_INT_P (operands[2]));
7879         if (INTVAL (operands[2]) == 0xff)
7880           mode = QImode;
7881         else
7882           {
7883             gcc_assert (INTVAL (operands[2]) == 0xffff);
7884             mode = HImode;
7885           }
7886
7887         operands[1] = gen_lowpart (mode, operands[1]);
7888         if (mode == QImode)
7889           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7890         else
7891           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7892       }
7893
7894     default:
7895       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7896       if (get_attr_mode (insn) == MODE_SI)
7897         return "and{l}\t{%k2, %k0|%k0, %k2}";
7898       else
7899         return "and{q}\t{%2, %0|%0, %2}";
7900     }
7901 }
7902   [(set_attr "type" "alu,alu,alu,imovx")
7903    (set_attr "length_immediate" "*,*,*,0")
7904    (set (attr "prefix_rex")
7905      (if_then_else
7906        (and (eq_attr "type" "imovx")
7907             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7908                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7909        (const_string "1")
7910        (const_string "*")))
7911    (set_attr "mode" "SI,DI,DI,SI")])
7912
7913 (define_insn "*andsi_1"
7914   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7915         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7916                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7917    (clobber (reg:CC FLAGS_REG))]
7918   "ix86_binary_operator_ok (AND, SImode, operands)"
7919 {
7920   switch (get_attr_type (insn))
7921     {
7922     case TYPE_IMOVX:
7923       {
7924         enum machine_mode mode;
7925
7926         gcc_assert (CONST_INT_P (operands[2]));
7927         if (INTVAL (operands[2]) == 0xff)
7928           mode = QImode;
7929         else
7930           {
7931             gcc_assert (INTVAL (operands[2]) == 0xffff);
7932             mode = HImode;
7933           }
7934
7935         operands[1] = gen_lowpart (mode, operands[1]);
7936         if (mode == QImode)
7937           return "movz{bl|x}\t{%1, %0|%0, %1}";
7938         else
7939           return "movz{wl|x}\t{%1, %0|%0, %1}";
7940       }
7941
7942     default:
7943       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7944       return "and{l}\t{%2, %0|%0, %2}";
7945     }
7946 }
7947   [(set_attr "type" "alu,alu,imovx")
7948    (set (attr "prefix_rex")
7949      (if_then_else
7950        (and (eq_attr "type" "imovx")
7951             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7952                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7953        (const_string "1")
7954        (const_string "*")))
7955    (set_attr "length_immediate" "*,*,0")
7956    (set_attr "mode" "SI")])
7957
7958 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7959 (define_insn "*andsi_1_zext"
7960   [(set (match_operand:DI 0 "register_operand" "=r")
7961         (zero_extend:DI
7962           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7963                   (match_operand:SI 2 "general_operand" "g"))))
7964    (clobber (reg:CC FLAGS_REG))]
7965   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7966   "and{l}\t{%2, %k0|%k0, %2}"
7967   [(set_attr "type" "alu")
7968    (set_attr "mode" "SI")])
7969
7970 (define_insn "*andhi_1"
7971   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7972         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7973                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7974    (clobber (reg:CC FLAGS_REG))]
7975   "ix86_binary_operator_ok (AND, HImode, operands)"
7976 {
7977   switch (get_attr_type (insn))
7978     {
7979     case TYPE_IMOVX:
7980       gcc_assert (CONST_INT_P (operands[2]));
7981       gcc_assert (INTVAL (operands[2]) == 0xff);
7982       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7983
7984     default:
7985       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7986
7987       return "and{w}\t{%2, %0|%0, %2}";
7988     }
7989 }
7990   [(set_attr "type" "alu,alu,imovx")
7991    (set_attr "length_immediate" "*,*,0")
7992    (set (attr "prefix_rex")
7993      (if_then_else
7994        (and (eq_attr "type" "imovx")
7995             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7996        (const_string "1")
7997        (const_string "*")))
7998    (set_attr "mode" "HI,HI,SI")])
7999
8000 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8001 (define_insn "*andqi_1"
8002   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8003         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8004                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8005    (clobber (reg:CC FLAGS_REG))]
8006   "ix86_binary_operator_ok (AND, QImode, operands)"
8007   "@
8008    and{b}\t{%2, %0|%0, %2}
8009    and{b}\t{%2, %0|%0, %2}
8010    and{l}\t{%k2, %k0|%k0, %k2}"
8011   [(set_attr "type" "alu")
8012    (set_attr "mode" "QI,QI,SI")])
8013
8014 (define_insn "*andqi_1_slp"
8015   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8016         (and:QI (match_dup 0)
8017                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8018    (clobber (reg:CC FLAGS_REG))]
8019   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8020    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8021   "and{b}\t{%1, %0|%0, %1}"
8022   [(set_attr "type" "alu1")
8023    (set_attr "mode" "QI")])
8024
8025 (define_split
8026   [(set (match_operand 0 "register_operand" "")
8027         (and (match_dup 0)
8028              (const_int -65536)))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8031     || optimize_function_for_size_p (cfun)"
8032   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8033   "operands[1] = gen_lowpart (HImode, operands[0]);")
8034
8035 (define_split
8036   [(set (match_operand 0 "ext_register_operand" "")
8037         (and (match_dup 0)
8038              (const_int -256)))
8039    (clobber (reg:CC FLAGS_REG))]
8040   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8041    && reload_completed"
8042   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8043   "operands[1] = gen_lowpart (QImode, operands[0]);")
8044
8045 (define_split
8046   [(set (match_operand 0 "ext_register_operand" "")
8047         (and (match_dup 0)
8048              (const_int -65281)))
8049    (clobber (reg:CC FLAGS_REG))]
8050   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8051    && reload_completed"
8052   [(parallel [(set (zero_extract:SI (match_dup 0)
8053                                     (const_int 8)
8054                                     (const_int 8))
8055                    (xor:SI
8056                      (zero_extract:SI (match_dup 0)
8057                                       (const_int 8)
8058                                       (const_int 8))
8059                      (zero_extract:SI (match_dup 0)
8060                                       (const_int 8)
8061                                       (const_int 8))))
8062               (clobber (reg:CC FLAGS_REG))])]
8063   "operands[0] = gen_lowpart (SImode, operands[0]);")
8064
8065 (define_insn "*anddi_2"
8066   [(set (reg FLAGS_REG)
8067         (compare
8068          (and:DI
8069           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8070           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8071          (const_int 0)))
8072    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8073         (and:DI (match_dup 1) (match_dup 2)))]
8074   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8075    && ix86_binary_operator_ok (AND, DImode, operands)"
8076   "@
8077    and{l}\t{%k2, %k0|%k0, %k2}
8078    and{q}\t{%2, %0|%0, %2}
8079    and{q}\t{%2, %0|%0, %2}"
8080   [(set_attr "type" "alu")
8081    (set_attr "mode" "SI,DI,DI")])
8082
8083 (define_insn "*andqi_2_maybe_si"
8084   [(set (reg FLAGS_REG)
8085         (compare (and:QI
8086                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8087                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8088                  (const_int 0)))
8089    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8090         (and:QI (match_dup 1) (match_dup 2)))]
8091   "ix86_binary_operator_ok (AND, QImode, operands)
8092    && ix86_match_ccmode (insn,
8093                          CONST_INT_P (operands[2])
8094                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8095 {
8096   if (which_alternative == 2)
8097     {
8098       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8099         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8100       return "and{l}\t{%2, %k0|%k0, %2}";
8101     }
8102   return "and{b}\t{%2, %0|%0, %2}";
8103 }
8104   [(set_attr "type" "alu")
8105    (set_attr "mode" "QI,QI,SI")])
8106
8107 (define_insn "*and<mode>_2"
8108   [(set (reg FLAGS_REG)
8109         (compare (and:SWI124
8110                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8111                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8112                  (const_int 0)))
8113    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8114         (and:SWI124 (match_dup 1) (match_dup 2)))]
8115   "ix86_match_ccmode (insn, CCNOmode)
8116    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8117   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8118   [(set_attr "type" "alu")
8119    (set_attr "mode" "<MODE>")])
8120
8121 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8122 (define_insn "*andsi_2_zext"
8123   [(set (reg FLAGS_REG)
8124         (compare (and:SI
8125                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8126                   (match_operand:SI 2 "general_operand" "g"))
8127                  (const_int 0)))
8128    (set (match_operand:DI 0 "register_operand" "=r")
8129         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8130   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8131    && ix86_binary_operator_ok (AND, SImode, operands)"
8132   "and{l}\t{%2, %k0|%k0, %2}"
8133   [(set_attr "type" "alu")
8134    (set_attr "mode" "SI")])
8135
8136 (define_insn "*andqi_2_slp"
8137   [(set (reg FLAGS_REG)
8138         (compare (and:QI
8139                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8140                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8141                  (const_int 0)))
8142    (set (strict_low_part (match_dup 0))
8143         (and:QI (match_dup 0) (match_dup 1)))]
8144   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8145    && ix86_match_ccmode (insn, CCNOmode)
8146    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8147   "and{b}\t{%1, %0|%0, %1}"
8148   [(set_attr "type" "alu1")
8149    (set_attr "mode" "QI")])
8150
8151 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8152 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8153 ;; for a QImode operand, which of course failed.
8154 (define_insn "andqi_ext_0"
8155   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8156                          (const_int 8)
8157                          (const_int 8))
8158         (and:SI
8159           (zero_extract:SI
8160             (match_operand 1 "ext_register_operand" "0")
8161             (const_int 8)
8162             (const_int 8))
8163           (match_operand 2 "const_int_operand" "n")))
8164    (clobber (reg:CC FLAGS_REG))]
8165   ""
8166   "and{b}\t{%2, %h0|%h0, %2}"
8167   [(set_attr "type" "alu")
8168    (set_attr "length_immediate" "1")
8169    (set_attr "modrm" "1")
8170    (set_attr "mode" "QI")])
8171
8172 ;; Generated by peephole translating test to and.  This shows up
8173 ;; often in fp comparisons.
8174 (define_insn "*andqi_ext_0_cc"
8175   [(set (reg FLAGS_REG)
8176         (compare
8177           (and:SI
8178             (zero_extract:SI
8179               (match_operand 1 "ext_register_operand" "0")
8180               (const_int 8)
8181               (const_int 8))
8182             (match_operand 2 "const_int_operand" "n"))
8183           (const_int 0)))
8184    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8185                          (const_int 8)
8186                          (const_int 8))
8187         (and:SI
8188           (zero_extract:SI
8189             (match_dup 1)
8190             (const_int 8)
8191             (const_int 8))
8192           (match_dup 2)))]
8193   "ix86_match_ccmode (insn, CCNOmode)"
8194   "and{b}\t{%2, %h0|%h0, %2}"
8195   [(set_attr "type" "alu")
8196    (set_attr "length_immediate" "1")
8197    (set_attr "modrm" "1")
8198    (set_attr "mode" "QI")])
8199
8200 (define_insn "*andqi_ext_1_rex64"
8201   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8202                          (const_int 8)
8203                          (const_int 8))
8204         (and:SI
8205           (zero_extract:SI
8206             (match_operand 1 "ext_register_operand" "0")
8207             (const_int 8)
8208             (const_int 8))
8209           (zero_extend:SI
8210             (match_operand 2 "ext_register_operand" "Q"))))
8211    (clobber (reg:CC FLAGS_REG))]
8212   "TARGET_64BIT"
8213   "and{b}\t{%2, %h0|%h0, %2}"
8214   [(set_attr "type" "alu")
8215    (set_attr "length_immediate" "0")
8216    (set_attr "mode" "QI")])
8217
8218 (define_insn "*andqi_ext_1"
8219   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8220                          (const_int 8)
8221                          (const_int 8))
8222         (and:SI
8223           (zero_extract:SI
8224             (match_operand 1 "ext_register_operand" "0")
8225             (const_int 8)
8226             (const_int 8))
8227           (zero_extend:SI
8228             (match_operand:QI 2 "general_operand" "Qm"))))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "!TARGET_64BIT"
8231   "and{b}\t{%2, %h0|%h0, %2}"
8232   [(set_attr "type" "alu")
8233    (set_attr "length_immediate" "0")
8234    (set_attr "mode" "QI")])
8235
8236 (define_insn "*andqi_ext_2"
8237   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8238                          (const_int 8)
8239                          (const_int 8))
8240         (and:SI
8241           (zero_extract:SI
8242             (match_operand 1 "ext_register_operand" "%0")
8243             (const_int 8)
8244             (const_int 8))
8245           (zero_extract:SI
8246             (match_operand 2 "ext_register_operand" "Q")
8247             (const_int 8)
8248             (const_int 8))))
8249    (clobber (reg:CC FLAGS_REG))]
8250   ""
8251   "and{b}\t{%h2, %h0|%h0, %h2}"
8252   [(set_attr "type" "alu")
8253    (set_attr "length_immediate" "0")
8254    (set_attr "mode" "QI")])
8255
8256 ;; Convert wide AND instructions with immediate operand to shorter QImode
8257 ;; equivalents when possible.
8258 ;; Don't do the splitting with memory operands, since it introduces risk
8259 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8260 ;; for size, but that can (should?) be handled by generic code instead.
8261 (define_split
8262   [(set (match_operand 0 "register_operand" "")
8263         (and (match_operand 1 "register_operand" "")
8264              (match_operand 2 "const_int_operand" "")))
8265    (clobber (reg:CC FLAGS_REG))]
8266    "reload_completed
8267     && QI_REG_P (operands[0])
8268     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8269     && !(~INTVAL (operands[2]) & ~(255 << 8))
8270     && GET_MODE (operands[0]) != QImode"
8271   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8272                    (and:SI (zero_extract:SI (match_dup 1)
8273                                             (const_int 8) (const_int 8))
8274                            (match_dup 2)))
8275               (clobber (reg:CC FLAGS_REG))])]
8276   "operands[0] = gen_lowpart (SImode, operands[0]);
8277    operands[1] = gen_lowpart (SImode, operands[1]);
8278    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8279
8280 ;; Since AND can be encoded with sign extended immediate, this is only
8281 ;; profitable when 7th bit is not set.
8282 (define_split
8283   [(set (match_operand 0 "register_operand" "")
8284         (and (match_operand 1 "general_operand" "")
8285              (match_operand 2 "const_int_operand" "")))
8286    (clobber (reg:CC FLAGS_REG))]
8287    "reload_completed
8288     && ANY_QI_REG_P (operands[0])
8289     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8290     && !(~INTVAL (operands[2]) & ~255)
8291     && !(INTVAL (operands[2]) & 128)
8292     && GET_MODE (operands[0]) != QImode"
8293   [(parallel [(set (strict_low_part (match_dup 0))
8294                    (and:QI (match_dup 1)
8295                            (match_dup 2)))
8296               (clobber (reg:CC FLAGS_REG))])]
8297   "operands[0] = gen_lowpart (QImode, operands[0]);
8298    operands[1] = gen_lowpart (QImode, operands[1]);
8299    operands[2] = gen_lowpart (QImode, operands[2]);")
8300 \f
8301 ;; Logical inclusive and exclusive OR instructions
8302
8303 ;; %%% This used to optimize known byte-wide and operations to memory.
8304 ;; If this is considered useful, it should be done with splitters.
8305
8306 (define_expand "<code><mode>3"
8307   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8308         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8309                      (match_operand:SWIM 2 "<general_operand>" "")))]
8310   ""
8311   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8312
8313 (define_insn "*<code><mode>_1"
8314   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8315         (any_or:SWI248
8316          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8317          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8318    (clobber (reg:CC FLAGS_REG))]
8319   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8320   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8321   [(set_attr "type" "alu")
8322    (set_attr "mode" "<MODE>")])
8323
8324 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8325 (define_insn "*<code>qi_1"
8326   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8327         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8328                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8329    (clobber (reg:CC FLAGS_REG))]
8330   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8331   "@
8332    <logic>{b}\t{%2, %0|%0, %2}
8333    <logic>{b}\t{%2, %0|%0, %2}
8334    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8335   [(set_attr "type" "alu")
8336    (set_attr "mode" "QI,QI,SI")])
8337
8338 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8339 (define_insn "*<code>si_1_zext"
8340   [(set (match_operand:DI 0 "register_operand" "=r")
8341         (zero_extend:DI
8342          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8343                     (match_operand:SI 2 "general_operand" "g"))))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8346   "<logic>{l}\t{%2, %k0|%k0, %2}"
8347   [(set_attr "type" "alu")
8348    (set_attr "mode" "SI")])
8349
8350 (define_insn "*<code>si_1_zext_imm"
8351   [(set (match_operand:DI 0 "register_operand" "=r")
8352         (any_or:DI
8353          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8354          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8355    (clobber (reg:CC FLAGS_REG))]
8356   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8357   "<logic>{l}\t{%2, %k0|%k0, %2}"
8358   [(set_attr "type" "alu")
8359    (set_attr "mode" "SI")])
8360
8361 (define_insn "*<code>qi_1_slp"
8362   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8363         (any_or:QI (match_dup 0)
8364                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8365    (clobber (reg:CC FLAGS_REG))]
8366   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8367    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8368   "<logic>{b}\t{%1, %0|%0, %1}"
8369   [(set_attr "type" "alu1")
8370    (set_attr "mode" "QI")])
8371
8372 (define_insn "*<code><mode>_2"
8373   [(set (reg FLAGS_REG)
8374         (compare (any_or:SWI
8375                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8376                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8377                  (const_int 0)))
8378    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8379         (any_or:SWI (match_dup 1) (match_dup 2)))]
8380   "ix86_match_ccmode (insn, CCNOmode)
8381    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8382   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8383   [(set_attr "type" "alu")
8384    (set_attr "mode" "<MODE>")])
8385
8386 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8387 ;; ??? Special case for immediate operand is missing - it is tricky.
8388 (define_insn "*<code>si_2_zext"
8389   [(set (reg FLAGS_REG)
8390         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8391                             (match_operand:SI 2 "general_operand" "g"))
8392                  (const_int 0)))
8393    (set (match_operand:DI 0 "register_operand" "=r")
8394         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8395   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8396    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8397   "<logic>{l}\t{%2, %k0|%k0, %2}"
8398   [(set_attr "type" "alu")
8399    (set_attr "mode" "SI")])
8400
8401 (define_insn "*<code>si_2_zext_imm"
8402   [(set (reg FLAGS_REG)
8403         (compare (any_or:SI
8404                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8405                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8406                  (const_int 0)))
8407    (set (match_operand:DI 0 "register_operand" "=r")
8408         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8409   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8410    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8411   "<logic>{l}\t{%2, %k0|%k0, %2}"
8412   [(set_attr "type" "alu")
8413    (set_attr "mode" "SI")])
8414
8415 (define_insn "*<code>qi_2_slp"
8416   [(set (reg FLAGS_REG)
8417         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8418                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8419                  (const_int 0)))
8420    (set (strict_low_part (match_dup 0))
8421         (any_or:QI (match_dup 0) (match_dup 1)))]
8422   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8423    && ix86_match_ccmode (insn, CCNOmode)
8424    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8425   "<logic>{b}\t{%1, %0|%0, %1}"
8426   [(set_attr "type" "alu1")
8427    (set_attr "mode" "QI")])
8428
8429 (define_insn "*<code><mode>_3"
8430   [(set (reg FLAGS_REG)
8431         (compare (any_or:SWI
8432                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8433                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8434                  (const_int 0)))
8435    (clobber (match_scratch:SWI 0 "=<r>"))]
8436   "ix86_match_ccmode (insn, CCNOmode)
8437    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8438   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8439   [(set_attr "type" "alu")
8440    (set_attr "mode" "<MODE>")])
8441
8442 (define_insn "*<code>qi_ext_0"
8443   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444                          (const_int 8)
8445                          (const_int 8))
8446         (any_or:SI
8447           (zero_extract:SI
8448             (match_operand 1 "ext_register_operand" "0")
8449             (const_int 8)
8450             (const_int 8))
8451           (match_operand 2 "const_int_operand" "n")))
8452    (clobber (reg:CC FLAGS_REG))]
8453   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8454   "<logic>{b}\t{%2, %h0|%h0, %2}"
8455   [(set_attr "type" "alu")
8456    (set_attr "length_immediate" "1")
8457    (set_attr "modrm" "1")
8458    (set_attr "mode" "QI")])
8459
8460 (define_insn "*<code>qi_ext_1_rex64"
8461   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462                          (const_int 8)
8463                          (const_int 8))
8464         (any_or:SI
8465           (zero_extract:SI
8466             (match_operand 1 "ext_register_operand" "0")
8467             (const_int 8)
8468             (const_int 8))
8469           (zero_extend:SI
8470             (match_operand 2 "ext_register_operand" "Q"))))
8471    (clobber (reg:CC FLAGS_REG))]
8472   "TARGET_64BIT
8473    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8474   "<logic>{b}\t{%2, %h0|%h0, %2}"
8475   [(set_attr "type" "alu")
8476    (set_attr "length_immediate" "0")
8477    (set_attr "mode" "QI")])
8478
8479 (define_insn "*<code>qi_ext_1"
8480   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8481                          (const_int 8)
8482                          (const_int 8))
8483         (any_or:SI
8484           (zero_extract:SI
8485             (match_operand 1 "ext_register_operand" "0")
8486             (const_int 8)
8487             (const_int 8))
8488           (zero_extend:SI
8489             (match_operand:QI 2 "general_operand" "Qm"))))
8490    (clobber (reg:CC FLAGS_REG))]
8491   "!TARGET_64BIT
8492    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8493   "<logic>{b}\t{%2, %h0|%h0, %2}"
8494   [(set_attr "type" "alu")
8495    (set_attr "length_immediate" "0")
8496    (set_attr "mode" "QI")])
8497
8498 (define_insn "*<code>qi_ext_2"
8499   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8500                          (const_int 8)
8501                          (const_int 8))
8502         (any_or:SI
8503           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8504                            (const_int 8)
8505                            (const_int 8))
8506           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8507                            (const_int 8)
8508                            (const_int 8))))
8509    (clobber (reg:CC FLAGS_REG))]
8510   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8511   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8512   [(set_attr "type" "alu")
8513    (set_attr "length_immediate" "0")
8514    (set_attr "mode" "QI")])
8515
8516 (define_split
8517   [(set (match_operand 0 "register_operand" "")
8518         (any_or (match_operand 1 "register_operand" "")
8519                 (match_operand 2 "const_int_operand" "")))
8520    (clobber (reg:CC FLAGS_REG))]
8521    "reload_completed
8522     && QI_REG_P (operands[0])
8523     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8524     && !(INTVAL (operands[2]) & ~(255 << 8))
8525     && GET_MODE (operands[0]) != QImode"
8526   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8527                    (any_or:SI (zero_extract:SI (match_dup 1)
8528                                                (const_int 8) (const_int 8))
8529                               (match_dup 2)))
8530               (clobber (reg:CC FLAGS_REG))])]
8531   "operands[0] = gen_lowpart (SImode, operands[0]);
8532    operands[1] = gen_lowpart (SImode, operands[1]);
8533    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8534
8535 ;; Since OR can be encoded with sign extended immediate, this is only
8536 ;; profitable when 7th bit is set.
8537 (define_split
8538   [(set (match_operand 0 "register_operand" "")
8539         (any_or (match_operand 1 "general_operand" "")
8540                 (match_operand 2 "const_int_operand" "")))
8541    (clobber (reg:CC FLAGS_REG))]
8542    "reload_completed
8543     && ANY_QI_REG_P (operands[0])
8544     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8545     && !(INTVAL (operands[2]) & ~255)
8546     && (INTVAL (operands[2]) & 128)
8547     && GET_MODE (operands[0]) != QImode"
8548   [(parallel [(set (strict_low_part (match_dup 0))
8549                    (any_or:QI (match_dup 1)
8550                               (match_dup 2)))
8551               (clobber (reg:CC FLAGS_REG))])]
8552   "operands[0] = gen_lowpart (QImode, operands[0]);
8553    operands[1] = gen_lowpart (QImode, operands[1]);
8554    operands[2] = gen_lowpart (QImode, operands[2]);")
8555
8556 (define_expand "xorqi_cc_ext_1"
8557   [(parallel [
8558      (set (reg:CCNO FLAGS_REG)
8559           (compare:CCNO
8560             (xor:SI
8561               (zero_extract:SI
8562                 (match_operand 1 "ext_register_operand" "")
8563                 (const_int 8)
8564                 (const_int 8))
8565               (match_operand:QI 2 "general_operand" ""))
8566             (const_int 0)))
8567      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8568                            (const_int 8)
8569                            (const_int 8))
8570           (xor:SI
8571             (zero_extract:SI
8572              (match_dup 1)
8573              (const_int 8)
8574              (const_int 8))
8575             (match_dup 2)))])])
8576
8577 (define_insn "*xorqi_cc_ext_1_rex64"
8578   [(set (reg FLAGS_REG)
8579         (compare
8580           (xor:SI
8581             (zero_extract:SI
8582               (match_operand 1 "ext_register_operand" "0")
8583               (const_int 8)
8584               (const_int 8))
8585             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8586           (const_int 0)))
8587    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8588                          (const_int 8)
8589                          (const_int 8))
8590         (xor:SI
8591           (zero_extract:SI
8592            (match_dup 1)
8593            (const_int 8)
8594            (const_int 8))
8595           (match_dup 2)))]
8596   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8597   "xor{b}\t{%2, %h0|%h0, %2}"
8598   [(set_attr "type" "alu")
8599    (set_attr "modrm" "1")
8600    (set_attr "mode" "QI")])
8601
8602 (define_insn "*xorqi_cc_ext_1"
8603   [(set (reg FLAGS_REG)
8604         (compare
8605           (xor:SI
8606             (zero_extract:SI
8607               (match_operand 1 "ext_register_operand" "0")
8608               (const_int 8)
8609               (const_int 8))
8610             (match_operand:QI 2 "general_operand" "qmn"))
8611           (const_int 0)))
8612    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8613                          (const_int 8)
8614                          (const_int 8))
8615         (xor:SI
8616           (zero_extract:SI
8617            (match_dup 1)
8618            (const_int 8)
8619            (const_int 8))
8620           (match_dup 2)))]
8621   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8622   "xor{b}\t{%2, %h0|%h0, %2}"
8623   [(set_attr "type" "alu")
8624    (set_attr "modrm" "1")
8625    (set_attr "mode" "QI")])
8626 \f
8627 ;; Negation instructions
8628
8629 (define_expand "neg<mode>2"
8630   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8631         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8632   ""
8633   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8634
8635 (define_insn_and_split "*neg<dwi>2_doubleword"
8636   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8637         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8638    (clobber (reg:CC FLAGS_REG))]
8639   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8640   "#"
8641   "reload_completed"
8642   [(parallel
8643     [(set (reg:CCZ FLAGS_REG)
8644           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8645      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8646    (parallel
8647     [(set (match_dup 2)
8648           (plus:DWIH (match_dup 3)
8649                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8650                                 (const_int 0))))
8651      (clobber (reg:CC FLAGS_REG))])
8652    (parallel
8653     [(set (match_dup 2)
8654           (neg:DWIH (match_dup 2)))
8655      (clobber (reg:CC FLAGS_REG))])]
8656   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8657
8658 (define_insn "*neg<mode>2_1"
8659   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8660         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8661    (clobber (reg:CC FLAGS_REG))]
8662   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8663   "neg{<imodesuffix>}\t%0"
8664   [(set_attr "type" "negnot")
8665    (set_attr "mode" "<MODE>")])
8666
8667 ;; Combine is quite creative about this pattern.
8668 (define_insn "*negsi2_1_zext"
8669   [(set (match_operand:DI 0 "register_operand" "=r")
8670         (lshiftrt:DI
8671           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8672                              (const_int 32)))
8673         (const_int 32)))
8674    (clobber (reg:CC FLAGS_REG))]
8675   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8676   "neg{l}\t%k0"
8677   [(set_attr "type" "negnot")
8678    (set_attr "mode" "SI")])
8679
8680 ;; The problem with neg is that it does not perform (compare x 0),
8681 ;; it really performs (compare 0 x), which leaves us with the zero
8682 ;; flag being the only useful item.
8683
8684 (define_insn "*neg<mode>2_cmpz"
8685   [(set (reg:CCZ FLAGS_REG)
8686         (compare:CCZ
8687           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8688                    (const_int 0)))
8689    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8690         (neg:SWI (match_dup 1)))]
8691   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8692   "neg{<imodesuffix>}\t%0"
8693   [(set_attr "type" "negnot")
8694    (set_attr "mode" "<MODE>")])
8695
8696 (define_insn "*negsi2_cmpz_zext"
8697   [(set (reg:CCZ FLAGS_REG)
8698         (compare:CCZ
8699           (lshiftrt:DI
8700             (neg:DI (ashift:DI
8701                       (match_operand:DI 1 "register_operand" "0")
8702                       (const_int 32)))
8703             (const_int 32))
8704           (const_int 0)))
8705    (set (match_operand:DI 0 "register_operand" "=r")
8706         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8707                                         (const_int 32)))
8708                      (const_int 32)))]
8709   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8710   "neg{l}\t%k0"
8711   [(set_attr "type" "negnot")
8712    (set_attr "mode" "SI")])
8713
8714 ;; Changing of sign for FP values is doable using integer unit too.
8715
8716 (define_expand "<code><mode>2"
8717   [(set (match_operand:X87MODEF 0 "register_operand" "")
8718         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8719   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8720   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8721
8722 (define_insn "*absneg<mode>2_mixed"
8723   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8724         (match_operator:MODEF 3 "absneg_operator"
8725           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8726    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8727    (clobber (reg:CC FLAGS_REG))]
8728   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8729   "#")
8730
8731 (define_insn "*absneg<mode>2_sse"
8732   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8733         (match_operator:MODEF 3 "absneg_operator"
8734           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8735    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8736    (clobber (reg:CC FLAGS_REG))]
8737   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8738   "#")
8739
8740 (define_insn "*absneg<mode>2_i387"
8741   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8742         (match_operator:X87MODEF 3 "absneg_operator"
8743           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8744    (use (match_operand 2 "" ""))
8745    (clobber (reg:CC FLAGS_REG))]
8746   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8747   "#")
8748
8749 (define_expand "<code>tf2"
8750   [(set (match_operand:TF 0 "register_operand" "")
8751         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8752   "TARGET_SSE2"
8753   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8754
8755 (define_insn "*absnegtf2_sse"
8756   [(set (match_operand:TF 0 "register_operand" "=x,x")
8757         (match_operator:TF 3 "absneg_operator"
8758           [(match_operand:TF 1 "register_operand" "0,x")]))
8759    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "TARGET_SSE2"
8762   "#")
8763
8764 ;; Splitters for fp abs and neg.
8765
8766 (define_split
8767   [(set (match_operand 0 "fp_register_operand" "")
8768         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8769    (use (match_operand 2 "" ""))
8770    (clobber (reg:CC FLAGS_REG))]
8771   "reload_completed"
8772   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8773
8774 (define_split
8775   [(set (match_operand 0 "register_operand" "")
8776         (match_operator 3 "absneg_operator"
8777           [(match_operand 1 "register_operand" "")]))
8778    (use (match_operand 2 "nonimmediate_operand" ""))
8779    (clobber (reg:CC FLAGS_REG))]
8780   "reload_completed && SSE_REG_P (operands[0])"
8781   [(set (match_dup 0) (match_dup 3))]
8782 {
8783   enum machine_mode mode = GET_MODE (operands[0]);
8784   enum machine_mode vmode = GET_MODE (operands[2]);
8785   rtx tmp;
8786
8787   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8788   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8789   if (operands_match_p (operands[0], operands[2]))
8790     {
8791       tmp = operands[1];
8792       operands[1] = operands[2];
8793       operands[2] = tmp;
8794     }
8795   if (GET_CODE (operands[3]) == ABS)
8796     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8797   else
8798     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8799   operands[3] = tmp;
8800 })
8801
8802 (define_split
8803   [(set (match_operand:SF 0 "register_operand" "")
8804         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8805    (use (match_operand:V4SF 2 "" ""))
8806    (clobber (reg:CC FLAGS_REG))]
8807   "reload_completed"
8808   [(parallel [(set (match_dup 0) (match_dup 1))
8809               (clobber (reg:CC FLAGS_REG))])]
8810 {
8811   rtx tmp;
8812   operands[0] = gen_lowpart (SImode, operands[0]);
8813   if (GET_CODE (operands[1]) == ABS)
8814     {
8815       tmp = gen_int_mode (0x7fffffff, SImode);
8816       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8817     }
8818   else
8819     {
8820       tmp = gen_int_mode (0x80000000, SImode);
8821       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8822     }
8823   operands[1] = tmp;
8824 })
8825
8826 (define_split
8827   [(set (match_operand:DF 0 "register_operand" "")
8828         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8829    (use (match_operand 2 "" ""))
8830    (clobber (reg:CC FLAGS_REG))]
8831   "reload_completed"
8832   [(parallel [(set (match_dup 0) (match_dup 1))
8833               (clobber (reg:CC FLAGS_REG))])]
8834 {
8835   rtx tmp;
8836   if (TARGET_64BIT)
8837     {
8838       tmp = gen_lowpart (DImode, operands[0]);
8839       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8840       operands[0] = tmp;
8841
8842       if (GET_CODE (operands[1]) == ABS)
8843         tmp = const0_rtx;
8844       else
8845         tmp = gen_rtx_NOT (DImode, tmp);
8846     }
8847   else
8848     {
8849       operands[0] = gen_highpart (SImode, operands[0]);
8850       if (GET_CODE (operands[1]) == ABS)
8851         {
8852           tmp = gen_int_mode (0x7fffffff, SImode);
8853           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8854         }
8855       else
8856         {
8857           tmp = gen_int_mode (0x80000000, SImode);
8858           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8859         }
8860     }
8861   operands[1] = tmp;
8862 })
8863
8864 (define_split
8865   [(set (match_operand:XF 0 "register_operand" "")
8866         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8867    (use (match_operand 2 "" ""))
8868    (clobber (reg:CC FLAGS_REG))]
8869   "reload_completed"
8870   [(parallel [(set (match_dup 0) (match_dup 1))
8871               (clobber (reg:CC FLAGS_REG))])]
8872 {
8873   rtx tmp;
8874   operands[0] = gen_rtx_REG (SImode,
8875                              true_regnum (operands[0])
8876                              + (TARGET_64BIT ? 1 : 2));
8877   if (GET_CODE (operands[1]) == ABS)
8878     {
8879       tmp = GEN_INT (0x7fff);
8880       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8881     }
8882   else
8883     {
8884       tmp = GEN_INT (0x8000);
8885       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8886     }
8887   operands[1] = tmp;
8888 })
8889
8890 ;; Conditionalize these after reload. If they match before reload, we
8891 ;; lose the clobber and ability to use integer instructions.
8892
8893 (define_insn "*<code><mode>2_1"
8894   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8895         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8896   "TARGET_80387
8897    && (reload_completed
8898        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8899   "f<absneg_mnemonic>"
8900   [(set_attr "type" "fsgn")
8901    (set_attr "mode" "<MODE>")])
8902
8903 (define_insn "*<code>extendsfdf2"
8904   [(set (match_operand:DF 0 "register_operand" "=f")
8905         (absneg:DF (float_extend:DF
8906                      (match_operand:SF 1 "register_operand" "0"))))]
8907   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8908   "f<absneg_mnemonic>"
8909   [(set_attr "type" "fsgn")
8910    (set_attr "mode" "DF")])
8911
8912 (define_insn "*<code>extendsfxf2"
8913   [(set (match_operand:XF 0 "register_operand" "=f")
8914         (absneg:XF (float_extend:XF
8915                      (match_operand:SF 1 "register_operand" "0"))))]
8916   "TARGET_80387"
8917   "f<absneg_mnemonic>"
8918   [(set_attr "type" "fsgn")
8919    (set_attr "mode" "XF")])
8920
8921 (define_insn "*<code>extenddfxf2"
8922   [(set (match_operand:XF 0 "register_operand" "=f")
8923         (absneg:XF (float_extend:XF
8924                      (match_operand:DF 1 "register_operand" "0"))))]
8925   "TARGET_80387"
8926   "f<absneg_mnemonic>"
8927   [(set_attr "type" "fsgn")
8928    (set_attr "mode" "XF")])
8929
8930 ;; Copysign instructions
8931
8932 (define_mode_iterator CSGNMODE [SF DF TF])
8933 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8934
8935 (define_expand "copysign<mode>3"
8936   [(match_operand:CSGNMODE 0 "register_operand" "")
8937    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8938    (match_operand:CSGNMODE 2 "register_operand" "")]
8939   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8940    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8941   "ix86_expand_copysign (operands); DONE;")
8942
8943 (define_insn_and_split "copysign<mode>3_const"
8944   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8945         (unspec:CSGNMODE
8946           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8947            (match_operand:CSGNMODE 2 "register_operand" "0")
8948            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8949           UNSPEC_COPYSIGN))]
8950   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8951    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8952   "#"
8953   "&& reload_completed"
8954   [(const_int 0)]
8955   "ix86_split_copysign_const (operands); DONE;")
8956
8957 (define_insn "copysign<mode>3_var"
8958   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8959         (unspec:CSGNMODE
8960           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8961            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8962            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8963            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8964           UNSPEC_COPYSIGN))
8965    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8966   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8967    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8968   "#")
8969
8970 (define_split
8971   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8972         (unspec:CSGNMODE
8973           [(match_operand:CSGNMODE 2 "register_operand" "")
8974            (match_operand:CSGNMODE 3 "register_operand" "")
8975            (match_operand:<CSGNVMODE> 4 "" "")
8976            (match_operand:<CSGNVMODE> 5 "" "")]
8977           UNSPEC_COPYSIGN))
8978    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8979   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8980     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8981    && reload_completed"
8982   [(const_int 0)]
8983   "ix86_split_copysign_var (operands); DONE;")
8984 \f
8985 ;; One complement instructions
8986
8987 (define_expand "one_cmpl<mode>2"
8988   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8989         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8990   ""
8991   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8992
8993 (define_insn "*one_cmpl<mode>2_1"
8994   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8995         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8996   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8997   "not{<imodesuffix>}\t%0"
8998   [(set_attr "type" "negnot")
8999    (set_attr "mode" "<MODE>")])
9000
9001 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9002 (define_insn "*one_cmplqi2_1"
9003   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9004         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9005   "ix86_unary_operator_ok (NOT, QImode, operands)"
9006   "@
9007    not{b}\t%0
9008    not{l}\t%k0"
9009   [(set_attr "type" "negnot")
9010    (set_attr "mode" "QI,SI")])
9011
9012 ;; ??? Currently never generated - xor is used instead.
9013 (define_insn "*one_cmplsi2_1_zext"
9014   [(set (match_operand:DI 0 "register_operand" "=r")
9015         (zero_extend:DI
9016           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9017   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9018   "not{l}\t%k0"
9019   [(set_attr "type" "negnot")
9020    (set_attr "mode" "SI")])
9021
9022 (define_insn "*one_cmpl<mode>2_2"
9023   [(set (reg FLAGS_REG)
9024         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9025                  (const_int 0)))
9026    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9027         (not:SWI (match_dup 1)))]
9028   "ix86_match_ccmode (insn, CCNOmode)
9029    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9030   "#"
9031   [(set_attr "type" "alu1")
9032    (set_attr "mode" "<MODE>")])
9033
9034 (define_split
9035   [(set (match_operand 0 "flags_reg_operand" "")
9036         (match_operator 2 "compare_operator"
9037           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9038            (const_int 0)]))
9039    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9040         (not:SWI (match_dup 3)))]
9041   "ix86_match_ccmode (insn, CCNOmode)"
9042   [(parallel [(set (match_dup 0)
9043                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9044                                     (const_int 0)]))
9045               (set (match_dup 1)
9046                    (xor:SWI (match_dup 3) (const_int -1)))])])
9047
9048 ;; ??? Currently never generated - xor is used instead.
9049 (define_insn "*one_cmplsi2_2_zext"
9050   [(set (reg FLAGS_REG)
9051         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9052                  (const_int 0)))
9053    (set (match_operand:DI 0 "register_operand" "=r")
9054         (zero_extend:DI (not:SI (match_dup 1))))]
9055   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9056    && ix86_unary_operator_ok (NOT, SImode, operands)"
9057   "#"
9058   [(set_attr "type" "alu1")
9059    (set_attr "mode" "SI")])
9060
9061 (define_split
9062   [(set (match_operand 0 "flags_reg_operand" "")
9063         (match_operator 2 "compare_operator"
9064           [(not:SI (match_operand:SI 3 "register_operand" ""))
9065            (const_int 0)]))
9066    (set (match_operand:DI 1 "register_operand" "")
9067         (zero_extend:DI (not:SI (match_dup 3))))]
9068   "ix86_match_ccmode (insn, CCNOmode)"
9069   [(parallel [(set (match_dup 0)
9070                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9071                                     (const_int 0)]))
9072               (set (match_dup 1)
9073                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9074 \f
9075 ;; Shift instructions
9076
9077 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9078 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9079 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9080 ;; from the assembler input.
9081 ;;
9082 ;; This instruction shifts the target reg/mem as usual, but instead of
9083 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9084 ;; is a left shift double, bits are taken from the high order bits of
9085 ;; reg, else if the insn is a shift right double, bits are taken from the
9086 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9087 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9088 ;;
9089 ;; Since sh[lr]d does not change the `reg' operand, that is done
9090 ;; separately, making all shifts emit pairs of shift double and normal
9091 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9092 ;; support a 63 bit shift, each shift where the count is in a reg expands
9093 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9094 ;;
9095 ;; If the shift count is a constant, we need never emit more than one
9096 ;; shift pair, instead using moves and sign extension for counts greater
9097 ;; than 31.
9098
9099 (define_expand "ashl<mode>3"
9100   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9101         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9102                       (match_operand:QI 2 "nonmemory_operand" "")))]
9103   ""
9104   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9105
9106 (define_insn "*ashl<mode>3_doubleword"
9107   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9108         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9109                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9110    (clobber (reg:CC FLAGS_REG))]
9111   ""
9112   "#"
9113   [(set_attr "type" "multi")])
9114
9115 (define_split
9116   [(set (match_operand:DWI 0 "register_operand" "")
9117         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9118                     (match_operand:QI 2 "nonmemory_operand" "")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9121   [(const_int 0)]
9122   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9123
9124 ;; By default we don't ask for a scratch register, because when DWImode
9125 ;; values are manipulated, registers are already at a premium.  But if
9126 ;; we have one handy, we won't turn it away.
9127
9128 (define_peephole2
9129   [(match_scratch:DWIH 3 "r")
9130    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9131                    (ashift:<DWI>
9132                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9133                      (match_operand:QI 2 "nonmemory_operand" "")))
9134               (clobber (reg:CC FLAGS_REG))])
9135    (match_dup 3)]
9136   "TARGET_CMOVE"
9137   [(const_int 0)]
9138   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9139
9140 (define_insn "x86_64_shld"
9141   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9142         (ior:DI (ashift:DI (match_dup 0)
9143                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9144                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9145                   (minus:QI (const_int 64) (match_dup 2)))))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "TARGET_64BIT"
9148   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9149   [(set_attr "type" "ishift")
9150    (set_attr "prefix_0f" "1")
9151    (set_attr "mode" "DI")
9152    (set_attr "athlon_decode" "vector")
9153    (set_attr "amdfam10_decode" "vector")
9154    (set_attr "bdver1_decode" "vector")])
9155
9156 (define_insn "x86_shld"
9157   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9158         (ior:SI (ashift:SI (match_dup 0)
9159                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9160                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9161                   (minus:QI (const_int 32) (match_dup 2)))))
9162    (clobber (reg:CC FLAGS_REG))]
9163   ""
9164   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9165   [(set_attr "type" "ishift")
9166    (set_attr "prefix_0f" "1")
9167    (set_attr "mode" "SI")
9168    (set_attr "pent_pair" "np")
9169    (set_attr "athlon_decode" "vector")
9170    (set_attr "amdfam10_decode" "vector")
9171    (set_attr "bdver1_decode" "vector")])
9172
9173 (define_expand "x86_shift<mode>_adj_1"
9174   [(set (reg:CCZ FLAGS_REG)
9175         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9176                              (match_dup 4))
9177                      (const_int 0)))
9178    (set (match_operand:SWI48 0 "register_operand" "")
9179         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9180                             (match_operand:SWI48 1 "register_operand" "")
9181                             (match_dup 0)))
9182    (set (match_dup 1)
9183         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9184                             (match_operand:SWI48 3 "register_operand" "r")
9185                             (match_dup 1)))]
9186   "TARGET_CMOVE"
9187   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9188
9189 (define_expand "x86_shift<mode>_adj_2"
9190   [(use (match_operand:SWI48 0 "register_operand" ""))
9191    (use (match_operand:SWI48 1 "register_operand" ""))
9192    (use (match_operand:QI 2 "register_operand" ""))]
9193   ""
9194 {
9195   rtx label = gen_label_rtx ();
9196   rtx tmp;
9197
9198   emit_insn (gen_testqi_ccz_1 (operands[2],
9199                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9200
9201   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9202   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9203   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9204                               gen_rtx_LABEL_REF (VOIDmode, label),
9205                               pc_rtx);
9206   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9207   JUMP_LABEL (tmp) = label;
9208
9209   emit_move_insn (operands[0], operands[1]);
9210   ix86_expand_clear (operands[1]);
9211
9212   emit_label (label);
9213   LABEL_NUSES (label) = 1;
9214
9215   DONE;
9216 })
9217
9218 ;; Avoid useless masking of count operand.
9219 (define_insn_and_split "*ashl<mode>3_mask"
9220   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9221         (ashift:SWI48
9222           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9223           (subreg:QI
9224             (and:SI
9225               (match_operand:SI 2 "nonimmediate_operand" "c")
9226               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9227    (clobber (reg:CC FLAGS_REG))]
9228   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9229    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9230       == GET_MODE_BITSIZE (<MODE>mode)-1"
9231   "#"
9232   "&& 1"
9233   [(parallel [(set (match_dup 0)
9234                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9235               (clobber (reg:CC FLAGS_REG))])]
9236 {
9237   if (can_create_pseudo_p ())
9238     operands [2] = force_reg (SImode, operands[2]);
9239
9240   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9241 }
9242   [(set_attr "type" "ishift")
9243    (set_attr "mode" "<MODE>")])
9244
9245 (define_insn "*ashl<mode>3_1"
9246   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9247         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9248                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9249    (clobber (reg:CC FLAGS_REG))]
9250   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9251 {
9252   switch (get_attr_type (insn))
9253     {
9254     case TYPE_LEA:
9255       return "#";
9256
9257     case TYPE_ALU:
9258       gcc_assert (operands[2] == const1_rtx);
9259       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9260       return "add{<imodesuffix>}\t%0, %0";
9261
9262     default:
9263       if (operands[2] == const1_rtx
9264           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265         return "sal{<imodesuffix>}\t%0";
9266       else
9267         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9268     }
9269 }
9270   [(set (attr "type")
9271      (cond [(eq_attr "alternative" "1")
9272               (const_string "lea")
9273             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9274                           (const_int 0))
9275                       (match_operand 0 "register_operand" ""))
9276                  (match_operand 2 "const1_operand" ""))
9277               (const_string "alu")
9278            ]
9279            (const_string "ishift")))
9280    (set (attr "length_immediate")
9281      (if_then_else
9282        (ior (eq_attr "type" "alu")
9283             (and (eq_attr "type" "ishift")
9284                  (and (match_operand 2 "const1_operand" "")
9285                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9286                           (const_int 0)))))
9287        (const_string "0")
9288        (const_string "*")))
9289    (set_attr "mode" "<MODE>")])
9290
9291 (define_insn "*ashlsi3_1_zext"
9292   [(set (match_operand:DI 0 "register_operand" "=r,r")
9293         (zero_extend:DI
9294           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9295                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9296    (clobber (reg:CC FLAGS_REG))]
9297   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9298 {
9299   switch (get_attr_type (insn))
9300     {
9301     case TYPE_LEA:
9302       return "#";
9303
9304     case TYPE_ALU:
9305       gcc_assert (operands[2] == const1_rtx);
9306       return "add{l}\t%k0, %k0";
9307
9308     default:
9309       if (operands[2] == const1_rtx
9310           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9311         return "sal{l}\t%k0";
9312       else
9313         return "sal{l}\t{%2, %k0|%k0, %2}";
9314     }
9315 }
9316   [(set (attr "type")
9317      (cond [(eq_attr "alternative" "1")
9318               (const_string "lea")
9319             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9320                      (const_int 0))
9321                  (match_operand 2 "const1_operand" ""))
9322               (const_string "alu")
9323            ]
9324            (const_string "ishift")))
9325    (set (attr "length_immediate")
9326      (if_then_else
9327        (ior (eq_attr "type" "alu")
9328             (and (eq_attr "type" "ishift")
9329                  (and (match_operand 2 "const1_operand" "")
9330                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9331                           (const_int 0)))))
9332        (const_string "0")
9333        (const_string "*")))
9334    (set_attr "mode" "SI")])
9335
9336 (define_insn "*ashlhi3_1"
9337   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9338         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9339                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9340    (clobber (reg:CC FLAGS_REG))]
9341   "TARGET_PARTIAL_REG_STALL
9342    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9343 {
9344   switch (get_attr_type (insn))
9345     {
9346     case TYPE_ALU:
9347       gcc_assert (operands[2] == const1_rtx);
9348       return "add{w}\t%0, %0";
9349
9350     default:
9351       if (operands[2] == const1_rtx
9352           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9353         return "sal{w}\t%0";
9354       else
9355         return "sal{w}\t{%2, %0|%0, %2}";
9356     }
9357 }
9358   [(set (attr "type")
9359      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9360                           (const_int 0))
9361                       (match_operand 0 "register_operand" ""))
9362                  (match_operand 2 "const1_operand" ""))
9363               (const_string "alu")
9364            ]
9365            (const_string "ishift")))
9366    (set (attr "length_immediate")
9367      (if_then_else
9368        (ior (eq_attr "type" "alu")
9369             (and (eq_attr "type" "ishift")
9370                  (and (match_operand 2 "const1_operand" "")
9371                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9372                           (const_int 0)))))
9373        (const_string "0")
9374        (const_string "*")))
9375    (set_attr "mode" "HI")])
9376
9377 (define_insn "*ashlhi3_1_lea"
9378   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9379         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9380                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9381    (clobber (reg:CC FLAGS_REG))]
9382   "!TARGET_PARTIAL_REG_STALL
9383    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9384 {
9385   switch (get_attr_type (insn))
9386     {
9387     case TYPE_LEA:
9388       return "#";
9389
9390     case TYPE_ALU:
9391       gcc_assert (operands[2] == const1_rtx);
9392       return "add{w}\t%0, %0";
9393
9394     default:
9395       if (operands[2] == const1_rtx
9396           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9397         return "sal{w}\t%0";
9398       else
9399         return "sal{w}\t{%2, %0|%0, %2}";
9400     }
9401 }
9402   [(set (attr "type")
9403      (cond [(eq_attr "alternative" "1")
9404               (const_string "lea")
9405             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9406                           (const_int 0))
9407                       (match_operand 0 "register_operand" ""))
9408                  (match_operand 2 "const1_operand" ""))
9409               (const_string "alu")
9410            ]
9411            (const_string "ishift")))
9412    (set (attr "length_immediate")
9413      (if_then_else
9414        (ior (eq_attr "type" "alu")
9415             (and (eq_attr "type" "ishift")
9416                  (and (match_operand 2 "const1_operand" "")
9417                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9418                           (const_int 0)))))
9419        (const_string "0")
9420        (const_string "*")))
9421    (set_attr "mode" "HI,SI")])
9422
9423 (define_insn "*ashlqi3_1"
9424   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9425         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9426                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "TARGET_PARTIAL_REG_STALL
9429    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9430 {
9431   switch (get_attr_type (insn))
9432     {
9433     case TYPE_ALU:
9434       gcc_assert (operands[2] == const1_rtx);
9435       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9436         return "add{l}\t%k0, %k0";
9437       else
9438         return "add{b}\t%0, %0";
9439
9440     default:
9441       if (operands[2] == const1_rtx
9442           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9443         {
9444           if (get_attr_mode (insn) == MODE_SI)
9445             return "sal{l}\t%k0";
9446           else
9447             return "sal{b}\t%0";
9448         }
9449       else
9450         {
9451           if (get_attr_mode (insn) == MODE_SI)
9452             return "sal{l}\t{%2, %k0|%k0, %2}";
9453           else
9454             return "sal{b}\t{%2, %0|%0, %2}";
9455         }
9456     }
9457 }
9458   [(set (attr "type")
9459      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9460                           (const_int 0))
9461                       (match_operand 0 "register_operand" ""))
9462                  (match_operand 2 "const1_operand" ""))
9463               (const_string "alu")
9464            ]
9465            (const_string "ishift")))
9466    (set (attr "length_immediate")
9467      (if_then_else
9468        (ior (eq_attr "type" "alu")
9469             (and (eq_attr "type" "ishift")
9470                  (and (match_operand 2 "const1_operand" "")
9471                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9472                           (const_int 0)))))
9473        (const_string "0")
9474        (const_string "*")))
9475    (set_attr "mode" "QI,SI")])
9476
9477 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9478 (define_insn "*ashlqi3_1_lea"
9479   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9480         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9481                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9482    (clobber (reg:CC FLAGS_REG))]
9483   "!TARGET_PARTIAL_REG_STALL
9484    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9485 {
9486   switch (get_attr_type (insn))
9487     {
9488     case TYPE_LEA:
9489       return "#";
9490
9491     case TYPE_ALU:
9492       gcc_assert (operands[2] == const1_rtx);
9493       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9494         return "add{l}\t%k0, %k0";
9495       else
9496         return "add{b}\t%0, %0";
9497
9498     default:
9499       if (operands[2] == const1_rtx
9500           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9501         {
9502           if (get_attr_mode (insn) == MODE_SI)
9503             return "sal{l}\t%k0";
9504           else
9505             return "sal{b}\t%0";
9506         }
9507       else
9508         {
9509           if (get_attr_mode (insn) == MODE_SI)
9510             return "sal{l}\t{%2, %k0|%k0, %2}";
9511           else
9512             return "sal{b}\t{%2, %0|%0, %2}";
9513         }
9514     }
9515 }
9516   [(set (attr "type")
9517      (cond [(eq_attr "alternative" "2")
9518               (const_string "lea")
9519             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9520                           (const_int 0))
9521                       (match_operand 0 "register_operand" ""))
9522                  (match_operand 2 "const1_operand" ""))
9523               (const_string "alu")
9524            ]
9525            (const_string "ishift")))
9526    (set (attr "length_immediate")
9527      (if_then_else
9528        (ior (eq_attr "type" "alu")
9529             (and (eq_attr "type" "ishift")
9530                  (and (match_operand 2 "const1_operand" "")
9531                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9532                           (const_int 0)))))
9533        (const_string "0")
9534        (const_string "*")))
9535    (set_attr "mode" "QI,SI,SI")])
9536
9537 (define_insn "*ashlqi3_1_slp"
9538   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9539         (ashift:QI (match_dup 0)
9540                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9541    (clobber (reg:CC FLAGS_REG))]
9542   "(optimize_function_for_size_p (cfun)
9543     || !TARGET_PARTIAL_FLAG_REG_STALL
9544     || (operands[1] == const1_rtx
9545         && (TARGET_SHIFT1
9546             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9547 {
9548   switch (get_attr_type (insn))
9549     {
9550     case TYPE_ALU:
9551       gcc_assert (operands[1] == const1_rtx);
9552       return "add{b}\t%0, %0";
9553
9554     default:
9555       if (operands[1] == const1_rtx
9556           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9557         return "sal{b}\t%0";
9558       else
9559         return "sal{b}\t{%1, %0|%0, %1}";
9560     }
9561 }
9562   [(set (attr "type")
9563      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9564                           (const_int 0))
9565                       (match_operand 0 "register_operand" ""))
9566                  (match_operand 1 "const1_operand" ""))
9567               (const_string "alu")
9568            ]
9569            (const_string "ishift1")))
9570    (set (attr "length_immediate")
9571      (if_then_else
9572        (ior (eq_attr "type" "alu")
9573             (and (eq_attr "type" "ishift1")
9574                  (and (match_operand 1 "const1_operand" "")
9575                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9576                           (const_int 0)))))
9577        (const_string "0")
9578        (const_string "*")))
9579    (set_attr "mode" "QI")])
9580
9581 ;; Convert lea to the lea pattern to avoid flags dependency.
9582 (define_split
9583   [(set (match_operand 0 "register_operand" "")
9584         (ashift (match_operand 1 "index_register_operand" "")
9585                 (match_operand:QI 2 "const_int_operand" "")))
9586    (clobber (reg:CC FLAGS_REG))]
9587   "reload_completed
9588    && true_regnum (operands[0]) != true_regnum (operands[1])"
9589   [(const_int 0)]
9590 {
9591   rtx pat;
9592   enum machine_mode mode = GET_MODE (operands[0]);
9593
9594   if (mode != Pmode)
9595     operands[1] = gen_lowpart (Pmode, operands[1]);
9596   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9597
9598   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9599
9600   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9601     operands[0] = gen_lowpart (SImode, operands[0]);
9602
9603   if (TARGET_64BIT && mode != Pmode)
9604     pat = gen_rtx_SUBREG (SImode, pat, 0);
9605
9606   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9607   DONE;
9608 })
9609
9610 ;; Convert lea to the lea pattern to avoid flags dependency.
9611 (define_split
9612   [(set (match_operand:DI 0 "register_operand" "")
9613         (zero_extend:DI
9614           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9615                      (match_operand:QI 2 "const_int_operand" ""))))
9616    (clobber (reg:CC FLAGS_REG))]
9617   "TARGET_64BIT && reload_completed
9618    && true_regnum (operands[0]) != true_regnum (operands[1])"
9619   [(set (match_dup 0)
9620         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9621 {
9622   operands[1] = gen_lowpart (DImode, operands[1]);
9623   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9624 })
9625
9626 ;; This pattern can't accept a variable shift count, since shifts by
9627 ;; zero don't affect the flags.  We assume that shifts by constant
9628 ;; zero are optimized away.
9629 (define_insn "*ashl<mode>3_cmp"
9630   [(set (reg FLAGS_REG)
9631         (compare
9632           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9633                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9634           (const_int 0)))
9635    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9636         (ashift:SWI (match_dup 1) (match_dup 2)))]
9637   "(optimize_function_for_size_p (cfun)
9638     || !TARGET_PARTIAL_FLAG_REG_STALL
9639     || (operands[2] == const1_rtx
9640         && (TARGET_SHIFT1
9641             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9642    && ix86_match_ccmode (insn, CCGOCmode)
9643    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9644 {
9645   switch (get_attr_type (insn))
9646     {
9647     case TYPE_ALU:
9648       gcc_assert (operands[2] == const1_rtx);
9649       return "add{<imodesuffix>}\t%0, %0";
9650
9651     default:
9652       if (operands[2] == const1_rtx
9653           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9654         return "sal{<imodesuffix>}\t%0";
9655       else
9656         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9657     }
9658 }
9659   [(set (attr "type")
9660      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9661                           (const_int 0))
9662                       (match_operand 0 "register_operand" ""))
9663                  (match_operand 2 "const1_operand" ""))
9664               (const_string "alu")
9665            ]
9666            (const_string "ishift")))
9667    (set (attr "length_immediate")
9668      (if_then_else
9669        (ior (eq_attr "type" "alu")
9670             (and (eq_attr "type" "ishift")
9671                  (and (match_operand 2 "const1_operand" "")
9672                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9673                           (const_int 0)))))
9674        (const_string "0")
9675        (const_string "*")))
9676    (set_attr "mode" "<MODE>")])
9677
9678 (define_insn "*ashlsi3_cmp_zext"
9679   [(set (reg FLAGS_REG)
9680         (compare
9681           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9682                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9683           (const_int 0)))
9684    (set (match_operand:DI 0 "register_operand" "=r")
9685         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9686   "TARGET_64BIT
9687    && (optimize_function_for_size_p (cfun)
9688        || !TARGET_PARTIAL_FLAG_REG_STALL
9689        || (operands[2] == const1_rtx
9690            && (TARGET_SHIFT1
9691                || TARGET_DOUBLE_WITH_ADD)))
9692    && ix86_match_ccmode (insn, CCGOCmode)
9693    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9694 {
9695   switch (get_attr_type (insn))
9696     {
9697     case TYPE_ALU:
9698       gcc_assert (operands[2] == const1_rtx);
9699       return "add{l}\t%k0, %k0";
9700
9701     default:
9702       if (operands[2] == const1_rtx
9703           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9704         return "sal{l}\t%k0";
9705       else
9706         return "sal{l}\t{%2, %k0|%k0, %2}";
9707     }
9708 }
9709   [(set (attr "type")
9710      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9711                      (const_int 0))
9712                  (match_operand 2 "const1_operand" ""))
9713               (const_string "alu")
9714            ]
9715            (const_string "ishift")))
9716    (set (attr "length_immediate")
9717      (if_then_else
9718        (ior (eq_attr "type" "alu")
9719             (and (eq_attr "type" "ishift")
9720                  (and (match_operand 2 "const1_operand" "")
9721                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9722                           (const_int 0)))))
9723        (const_string "0")
9724        (const_string "*")))
9725    (set_attr "mode" "SI")])
9726
9727 (define_insn "*ashl<mode>3_cconly"
9728   [(set (reg FLAGS_REG)
9729         (compare
9730           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9731                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9732           (const_int 0)))
9733    (clobber (match_scratch:SWI 0 "=<r>"))]
9734   "(optimize_function_for_size_p (cfun)
9735     || !TARGET_PARTIAL_FLAG_REG_STALL
9736     || (operands[2] == const1_rtx
9737         && (TARGET_SHIFT1
9738             || TARGET_DOUBLE_WITH_ADD)))
9739    && ix86_match_ccmode (insn, CCGOCmode)"
9740 {
9741   switch (get_attr_type (insn))
9742     {
9743     case TYPE_ALU:
9744       gcc_assert (operands[2] == const1_rtx);
9745       return "add{<imodesuffix>}\t%0, %0";
9746
9747     default:
9748       if (operands[2] == const1_rtx
9749           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9750         return "sal{<imodesuffix>}\t%0";
9751       else
9752         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9753     }
9754 }
9755   [(set (attr "type")
9756      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9757                           (const_int 0))
9758                       (match_operand 0 "register_operand" ""))
9759                  (match_operand 2 "const1_operand" ""))
9760               (const_string "alu")
9761            ]
9762            (const_string "ishift")))
9763    (set (attr "length_immediate")
9764      (if_then_else
9765        (ior (eq_attr "type" "alu")
9766             (and (eq_attr "type" "ishift")
9767                  (and (match_operand 2 "const1_operand" "")
9768                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9769                           (const_int 0)))))
9770        (const_string "0")
9771        (const_string "*")))
9772    (set_attr "mode" "<MODE>")])
9773
9774 ;; See comment above `ashl<mode>3' about how this works.
9775
9776 (define_expand "<shiftrt_insn><mode>3"
9777   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9778         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9779                            (match_operand:QI 2 "nonmemory_operand" "")))]
9780   ""
9781   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9782
9783 ;; Avoid useless masking of count operand.
9784 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9785   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9786         (any_shiftrt:SWI48
9787           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9788           (subreg:QI
9789             (and:SI
9790               (match_operand:SI 2 "nonimmediate_operand" "c")
9791               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9792    (clobber (reg:CC FLAGS_REG))]
9793   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9794    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9795       == GET_MODE_BITSIZE (<MODE>mode)-1"
9796   "#"
9797   "&& 1"
9798   [(parallel [(set (match_dup 0)
9799                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9800               (clobber (reg:CC FLAGS_REG))])]
9801 {
9802   if (can_create_pseudo_p ())
9803     operands [2] = force_reg (SImode, operands[2]);
9804
9805   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9806 }
9807   [(set_attr "type" "ishift")
9808    (set_attr "mode" "<MODE>")])
9809
9810 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9811   [(set (match_operand:DWI 0 "register_operand" "=r")
9812         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9813                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9814    (clobber (reg:CC FLAGS_REG))]
9815   ""
9816   "#"
9817   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9818   [(const_int 0)]
9819   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9820   [(set_attr "type" "multi")])
9821
9822 ;; By default we don't ask for a scratch register, because when DWImode
9823 ;; values are manipulated, registers are already at a premium.  But if
9824 ;; we have one handy, we won't turn it away.
9825
9826 (define_peephole2
9827   [(match_scratch:DWIH 3 "r")
9828    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9829                    (any_shiftrt:<DWI>
9830                      (match_operand:<DWI> 1 "register_operand" "")
9831                      (match_operand:QI 2 "nonmemory_operand" "")))
9832               (clobber (reg:CC FLAGS_REG))])
9833    (match_dup 3)]
9834   "TARGET_CMOVE"
9835   [(const_int 0)]
9836   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9837
9838 (define_insn "x86_64_shrd"
9839   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9840         (ior:DI (ashiftrt:DI (match_dup 0)
9841                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9842                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9843                   (minus:QI (const_int 64) (match_dup 2)))))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "TARGET_64BIT"
9846   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9847   [(set_attr "type" "ishift")
9848    (set_attr "prefix_0f" "1")
9849    (set_attr "mode" "DI")
9850    (set_attr "athlon_decode" "vector")
9851    (set_attr "amdfam10_decode" "vector")
9852    (set_attr "bdver1_decode" "vector")])
9853
9854 (define_insn "x86_shrd"
9855   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9856         (ior:SI (ashiftrt:SI (match_dup 0)
9857                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9858                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9859                   (minus:QI (const_int 32) (match_dup 2)))))
9860    (clobber (reg:CC FLAGS_REG))]
9861   ""
9862   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9863   [(set_attr "type" "ishift")
9864    (set_attr "prefix_0f" "1")
9865    (set_attr "mode" "SI")
9866    (set_attr "pent_pair" "np")
9867    (set_attr "athlon_decode" "vector")
9868    (set_attr "amdfam10_decode" "vector")
9869    (set_attr "bdver1_decode" "vector")])
9870
9871 (define_insn "ashrdi3_cvt"
9872   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9873         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9874                      (match_operand:QI 2 "const_int_operand" "")))
9875    (clobber (reg:CC FLAGS_REG))]
9876   "TARGET_64BIT && INTVAL (operands[2]) == 63
9877    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9878    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9879   "@
9880    {cqto|cqo}
9881    sar{q}\t{%2, %0|%0, %2}"
9882   [(set_attr "type" "imovx,ishift")
9883    (set_attr "prefix_0f" "0,*")
9884    (set_attr "length_immediate" "0,*")
9885    (set_attr "modrm" "0,1")
9886    (set_attr "mode" "DI")])
9887
9888 (define_insn "ashrsi3_cvt"
9889   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9890         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9891                      (match_operand:QI 2 "const_int_operand" "")))
9892    (clobber (reg:CC FLAGS_REG))]
9893   "INTVAL (operands[2]) == 31
9894    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9895    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9896   "@
9897    {cltd|cdq}
9898    sar{l}\t{%2, %0|%0, %2}"
9899   [(set_attr "type" "imovx,ishift")
9900    (set_attr "prefix_0f" "0,*")
9901    (set_attr "length_immediate" "0,*")
9902    (set_attr "modrm" "0,1")
9903    (set_attr "mode" "SI")])
9904
9905 (define_insn "*ashrsi3_cvt_zext"
9906   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9907         (zero_extend:DI
9908           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9909                        (match_operand:QI 2 "const_int_operand" ""))))
9910    (clobber (reg:CC FLAGS_REG))]
9911   "TARGET_64BIT && INTVAL (operands[2]) == 31
9912    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9913    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9914   "@
9915    {cltd|cdq}
9916    sar{l}\t{%2, %k0|%k0, %2}"
9917   [(set_attr "type" "imovx,ishift")
9918    (set_attr "prefix_0f" "0,*")
9919    (set_attr "length_immediate" "0,*")
9920    (set_attr "modrm" "0,1")
9921    (set_attr "mode" "SI")])
9922
9923 (define_expand "x86_shift<mode>_adj_3"
9924   [(use (match_operand:SWI48 0 "register_operand" ""))
9925    (use (match_operand:SWI48 1 "register_operand" ""))
9926    (use (match_operand:QI 2 "register_operand" ""))]
9927   ""
9928 {
9929   rtx label = gen_label_rtx ();
9930   rtx tmp;
9931
9932   emit_insn (gen_testqi_ccz_1 (operands[2],
9933                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9934
9935   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9936   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9937   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9938                               gen_rtx_LABEL_REF (VOIDmode, label),
9939                               pc_rtx);
9940   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9941   JUMP_LABEL (tmp) = label;
9942
9943   emit_move_insn (operands[0], operands[1]);
9944   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9945                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9946   emit_label (label);
9947   LABEL_NUSES (label) = 1;
9948
9949   DONE;
9950 })
9951
9952 (define_insn "*<shiftrt_insn><mode>3_1"
9953   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9954         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9955                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9956    (clobber (reg:CC FLAGS_REG))]
9957   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9958 {
9959   if (operands[2] == const1_rtx
9960       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9961     return "<shiftrt>{<imodesuffix>}\t%0";
9962   else
9963     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9964 }
9965   [(set_attr "type" "ishift")
9966    (set (attr "length_immediate")
9967      (if_then_else
9968        (and (match_operand 2 "const1_operand" "")
9969             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9970                 (const_int 0)))
9971        (const_string "0")
9972        (const_string "*")))
9973    (set_attr "mode" "<MODE>")])
9974
9975 (define_insn "*<shiftrt_insn>si3_1_zext"
9976   [(set (match_operand:DI 0 "register_operand" "=r")
9977         (zero_extend:DI
9978           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9979                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9980    (clobber (reg:CC FLAGS_REG))]
9981   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9982 {
9983   if (operands[2] == const1_rtx
9984       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9985     return "<shiftrt>{l}\t%k0";
9986   else
9987     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9988 }
9989   [(set_attr "type" "ishift")
9990    (set (attr "length_immediate")
9991      (if_then_else
9992        (and (match_operand 2 "const1_operand" "")
9993             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9994                 (const_int 0)))
9995        (const_string "0")
9996        (const_string "*")))
9997    (set_attr "mode" "SI")])
9998
9999 (define_insn "*<shiftrt_insn>qi3_1_slp"
10000   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10001         (any_shiftrt:QI (match_dup 0)
10002                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10003    (clobber (reg:CC FLAGS_REG))]
10004   "(optimize_function_for_size_p (cfun)
10005     || !TARGET_PARTIAL_REG_STALL
10006     || (operands[1] == const1_rtx
10007         && TARGET_SHIFT1))"
10008 {
10009   if (operands[1] == const1_rtx
10010       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10011     return "<shiftrt>{b}\t%0";
10012   else
10013     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10014 }
10015   [(set_attr "type" "ishift1")
10016    (set (attr "length_immediate")
10017      (if_then_else
10018        (and (match_operand 1 "const1_operand" "")
10019             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10020                 (const_int 0)))
10021        (const_string "0")
10022        (const_string "*")))
10023    (set_attr "mode" "QI")])
10024
10025 ;; This pattern can't accept a variable shift count, since shifts by
10026 ;; zero don't affect the flags.  We assume that shifts by constant
10027 ;; zero are optimized away.
10028 (define_insn "*<shiftrt_insn><mode>3_cmp"
10029   [(set (reg FLAGS_REG)
10030         (compare
10031           (any_shiftrt:SWI
10032             (match_operand:SWI 1 "nonimmediate_operand" "0")
10033             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10034           (const_int 0)))
10035    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10036         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10037   "(optimize_function_for_size_p (cfun)
10038     || !TARGET_PARTIAL_FLAG_REG_STALL
10039     || (operands[2] == const1_rtx
10040         && TARGET_SHIFT1))
10041    && ix86_match_ccmode (insn, CCGOCmode)
10042    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10043 {
10044   if (operands[2] == const1_rtx
10045       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10046     return "<shiftrt>{<imodesuffix>}\t%0";
10047   else
10048     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10049 }
10050   [(set_attr "type" "ishift")
10051    (set (attr "length_immediate")
10052      (if_then_else
10053        (and (match_operand 2 "const1_operand" "")
10054             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10055                 (const_int 0)))
10056        (const_string "0")
10057        (const_string "*")))
10058    (set_attr "mode" "<MODE>")])
10059
10060 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10061   [(set (reg FLAGS_REG)
10062         (compare
10063           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10064                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10065           (const_int 0)))
10066    (set (match_operand:DI 0 "register_operand" "=r")
10067         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10068   "TARGET_64BIT
10069    && (optimize_function_for_size_p (cfun)
10070        || !TARGET_PARTIAL_FLAG_REG_STALL
10071        || (operands[2] == const1_rtx
10072            && TARGET_SHIFT1))
10073    && ix86_match_ccmode (insn, CCGOCmode)
10074    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10075 {
10076   if (operands[2] == const1_rtx
10077       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10078     return "<shiftrt>{l}\t%k0";
10079   else
10080     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10081 }
10082   [(set_attr "type" "ishift")
10083    (set (attr "length_immediate")
10084      (if_then_else
10085        (and (match_operand 2 "const1_operand" "")
10086             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10087                 (const_int 0)))
10088        (const_string "0")
10089        (const_string "*")))
10090    (set_attr "mode" "SI")])
10091
10092 (define_insn "*<shiftrt_insn><mode>3_cconly"
10093   [(set (reg FLAGS_REG)
10094         (compare
10095           (any_shiftrt:SWI
10096             (match_operand:SWI 1 "register_operand" "0")
10097             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10098           (const_int 0)))
10099    (clobber (match_scratch:SWI 0 "=<r>"))]
10100   "(optimize_function_for_size_p (cfun)
10101     || !TARGET_PARTIAL_FLAG_REG_STALL
10102     || (operands[2] == const1_rtx
10103         && TARGET_SHIFT1))
10104    && ix86_match_ccmode (insn, CCGOCmode)"
10105 {
10106   if (operands[2] == const1_rtx
10107       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10108     return "<shiftrt>{<imodesuffix>}\t%0";
10109   else
10110     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10111 }
10112   [(set_attr "type" "ishift")
10113    (set (attr "length_immediate")
10114      (if_then_else
10115        (and (match_operand 2 "const1_operand" "")
10116             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10117                 (const_int 0)))
10118        (const_string "0")
10119        (const_string "*")))
10120    (set_attr "mode" "<MODE>")])
10121 \f
10122 ;; Rotate instructions
10123
10124 (define_expand "<rotate_insn>ti3"
10125   [(set (match_operand:TI 0 "register_operand" "")
10126         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10127                        (match_operand:QI 2 "nonmemory_operand" "")))]
10128   "TARGET_64BIT"
10129 {
10130   if (const_1_to_63_operand (operands[2], VOIDmode))
10131     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10132                 (operands[0], operands[1], operands[2]));
10133   else
10134     FAIL;
10135
10136   DONE;
10137 })
10138
10139 (define_expand "<rotate_insn>di3"
10140   [(set (match_operand:DI 0 "shiftdi_operand" "")
10141         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10142                        (match_operand:QI 2 "nonmemory_operand" "")))]
10143  ""
10144 {
10145   if (TARGET_64BIT)
10146     ix86_expand_binary_operator (<CODE>, DImode, operands);
10147   else if (const_1_to_31_operand (operands[2], VOIDmode))
10148     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10149                 (operands[0], operands[1], operands[2]));
10150   else
10151     FAIL;
10152
10153   DONE;
10154 })
10155
10156 (define_expand "<rotate_insn><mode>3"
10157   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10158         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10159                             (match_operand:QI 2 "nonmemory_operand" "")))]
10160   ""
10161   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10162
10163 ;; Avoid useless masking of count operand.
10164 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10165   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10166         (any_rotate:SWI48
10167           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10168           (subreg:QI
10169             (and:SI
10170               (match_operand:SI 2 "nonimmediate_operand" "c")
10171               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10172    (clobber (reg:CC FLAGS_REG))]
10173   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10174    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10175       == GET_MODE_BITSIZE (<MODE>mode)-1"
10176   "#"
10177   "&& 1"
10178   [(parallel [(set (match_dup 0)
10179                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10180               (clobber (reg:CC FLAGS_REG))])]
10181 {
10182   if (can_create_pseudo_p ())
10183     operands [2] = force_reg (SImode, operands[2]);
10184
10185   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10186 }
10187   [(set_attr "type" "rotate")
10188    (set_attr "mode" "<MODE>")])
10189
10190 ;; Implement rotation using two double-precision
10191 ;; shift instructions and a scratch register.
10192
10193 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10194  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10195        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10196                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10197   (clobber (reg:CC FLAGS_REG))
10198   (clobber (match_scratch:DWIH 3 "=&r"))]
10199  ""
10200  "#"
10201  "reload_completed"
10202  [(set (match_dup 3) (match_dup 4))
10203   (parallel
10204    [(set (match_dup 4)
10205          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10206                    (lshiftrt:DWIH (match_dup 5)
10207                                   (minus:QI (match_dup 6) (match_dup 2)))))
10208     (clobber (reg:CC FLAGS_REG))])
10209   (parallel
10210    [(set (match_dup 5)
10211          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10212                    (lshiftrt:DWIH (match_dup 3)
10213                                   (minus:QI (match_dup 6) (match_dup 2)))))
10214     (clobber (reg:CC FLAGS_REG))])]
10215 {
10216   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10217
10218   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10219 })
10220
10221 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10222  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10223        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10224                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10225   (clobber (reg:CC FLAGS_REG))
10226   (clobber (match_scratch:DWIH 3 "=&r"))]
10227  ""
10228  "#"
10229  "reload_completed"
10230  [(set (match_dup 3) (match_dup 4))
10231   (parallel
10232    [(set (match_dup 4)
10233          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10234                    (ashift:DWIH (match_dup 5)
10235                                 (minus:QI (match_dup 6) (match_dup 2)))))
10236     (clobber (reg:CC FLAGS_REG))])
10237   (parallel
10238    [(set (match_dup 5)
10239          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10240                    (ashift:DWIH (match_dup 3)
10241                                 (minus:QI (match_dup 6) (match_dup 2)))))
10242     (clobber (reg:CC FLAGS_REG))])]
10243 {
10244   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10245
10246   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10247 })
10248
10249 (define_insn "*<rotate_insn><mode>3_1"
10250   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10251         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10252                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10253    (clobber (reg:CC FLAGS_REG))]
10254   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10255 {
10256   if (operands[2] == const1_rtx
10257       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10258     return "<rotate>{<imodesuffix>}\t%0";
10259   else
10260     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10261 }
10262   [(set_attr "type" "rotate")
10263    (set (attr "length_immediate")
10264      (if_then_else
10265        (and (match_operand 2 "const1_operand" "")
10266             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10267                 (const_int 0)))
10268        (const_string "0")
10269        (const_string "*")))
10270    (set_attr "mode" "<MODE>")])
10271
10272 (define_insn "*<rotate_insn>si3_1_zext"
10273   [(set (match_operand:DI 0 "register_operand" "=r")
10274         (zero_extend:DI
10275           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10276                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10277    (clobber (reg:CC FLAGS_REG))]
10278   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10279 {
10280     if (operands[2] == const1_rtx
10281         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10282     return "<rotate>{l}\t%k0";
10283   else
10284     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10285 }
10286   [(set_attr "type" "rotate")
10287    (set (attr "length_immediate")
10288      (if_then_else
10289        (and (match_operand 2 "const1_operand" "")
10290             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10291                 (const_int 0)))
10292        (const_string "0")
10293        (const_string "*")))
10294    (set_attr "mode" "SI")])
10295
10296 (define_insn "*<rotate_insn>qi3_1_slp"
10297   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10298         (any_rotate:QI (match_dup 0)
10299                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "(optimize_function_for_size_p (cfun)
10302     || !TARGET_PARTIAL_REG_STALL
10303     || (operands[1] == const1_rtx
10304         && TARGET_SHIFT1))"
10305 {
10306   if (operands[1] == const1_rtx
10307       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10308     return "<rotate>{b}\t%0";
10309   else
10310     return "<rotate>{b}\t{%1, %0|%0, %1}";
10311 }
10312   [(set_attr "type" "rotate1")
10313    (set (attr "length_immediate")
10314      (if_then_else
10315        (and (match_operand 1 "const1_operand" "")
10316             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10317                 (const_int 0)))
10318        (const_string "0")
10319        (const_string "*")))
10320    (set_attr "mode" "QI")])
10321
10322 (define_split
10323  [(set (match_operand:HI 0 "register_operand" "")
10324        (any_rotate:HI (match_dup 0) (const_int 8)))
10325   (clobber (reg:CC FLAGS_REG))]
10326  "reload_completed
10327   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10328  [(parallel [(set (strict_low_part (match_dup 0))
10329                   (bswap:HI (match_dup 0)))
10330              (clobber (reg:CC FLAGS_REG))])])
10331 \f
10332 ;; Bit set / bit test instructions
10333
10334 (define_expand "extv"
10335   [(set (match_operand:SI 0 "register_operand" "")
10336         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10337                          (match_operand:SI 2 "const8_operand" "")
10338                          (match_operand:SI 3 "const8_operand" "")))]
10339   ""
10340 {
10341   /* Handle extractions from %ah et al.  */
10342   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10343     FAIL;
10344
10345   /* From mips.md: extract_bit_field doesn't verify that our source
10346      matches the predicate, so check it again here.  */
10347   if (! ext_register_operand (operands[1], VOIDmode))
10348     FAIL;
10349 })
10350
10351 (define_expand "extzv"
10352   [(set (match_operand:SI 0 "register_operand" "")
10353         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10354                          (match_operand:SI 2 "const8_operand" "")
10355                          (match_operand:SI 3 "const8_operand" "")))]
10356   ""
10357 {
10358   /* Handle extractions from %ah et al.  */
10359   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10360     FAIL;
10361
10362   /* From mips.md: extract_bit_field doesn't verify that our source
10363      matches the predicate, so check it again here.  */
10364   if (! ext_register_operand (operands[1], VOIDmode))
10365     FAIL;
10366 })
10367
10368 (define_expand "insv"
10369   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10370                       (match_operand 1 "const8_operand" "")
10371                       (match_operand 2 "const8_operand" ""))
10372         (match_operand 3 "register_operand" ""))]
10373   ""
10374 {
10375   rtx (*gen_mov_insv_1) (rtx, rtx);
10376
10377   /* Handle insertions to %ah et al.  */
10378   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10379     FAIL;
10380
10381   /* From mips.md: insert_bit_field doesn't verify that our source
10382      matches the predicate, so check it again here.  */
10383   if (! ext_register_operand (operands[0], VOIDmode))
10384     FAIL;
10385
10386   gen_mov_insv_1 = (TARGET_64BIT
10387                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10388
10389   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10390   DONE;
10391 })
10392
10393 ;; %%% bts, btr, btc, bt.
10394 ;; In general these instructions are *slow* when applied to memory,
10395 ;; since they enforce atomic operation.  When applied to registers,
10396 ;; it depends on the cpu implementation.  They're never faster than
10397 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10398 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10399 ;; within the instruction itself, so operating on bits in the high
10400 ;; 32-bits of a register becomes easier.
10401 ;;
10402 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10403 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10404 ;; negdf respectively, so they can never be disabled entirely.
10405
10406 (define_insn "*btsq"
10407   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10408                          (const_int 1)
10409                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10410         (const_int 1))
10411    (clobber (reg:CC FLAGS_REG))]
10412   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10413   "bts{q}\t{%1, %0|%0, %1}"
10414   [(set_attr "type" "alu1")
10415    (set_attr "prefix_0f" "1")
10416    (set_attr "mode" "DI")])
10417
10418 (define_insn "*btrq"
10419   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10420                          (const_int 1)
10421                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10422         (const_int 0))
10423    (clobber (reg:CC FLAGS_REG))]
10424   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10425   "btr{q}\t{%1, %0|%0, %1}"
10426   [(set_attr "type" "alu1")
10427    (set_attr "prefix_0f" "1")
10428    (set_attr "mode" "DI")])
10429
10430 (define_insn "*btcq"
10431   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10432                          (const_int 1)
10433                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10434         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10437   "btc{q}\t{%1, %0|%0, %1}"
10438   [(set_attr "type" "alu1")
10439    (set_attr "prefix_0f" "1")
10440    (set_attr "mode" "DI")])
10441
10442 ;; Allow Nocona to avoid these instructions if a register is available.
10443
10444 (define_peephole2
10445   [(match_scratch:DI 2 "r")
10446    (parallel [(set (zero_extract:DI
10447                      (match_operand:DI 0 "register_operand" "")
10448                      (const_int 1)
10449                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10450                    (const_int 1))
10451               (clobber (reg:CC FLAGS_REG))])]
10452   "TARGET_64BIT && !TARGET_USE_BT"
10453   [(const_int 0)]
10454 {
10455   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10456   rtx op1;
10457
10458   if (HOST_BITS_PER_WIDE_INT >= 64)
10459     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10460   else if (i < HOST_BITS_PER_WIDE_INT)
10461     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10462   else
10463     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10464
10465   op1 = immed_double_const (lo, hi, DImode);
10466   if (i >= 31)
10467     {
10468       emit_move_insn (operands[2], op1);
10469       op1 = operands[2];
10470     }
10471
10472   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10473   DONE;
10474 })
10475
10476 (define_peephole2
10477   [(match_scratch:DI 2 "r")
10478    (parallel [(set (zero_extract:DI
10479                      (match_operand:DI 0 "register_operand" "")
10480                      (const_int 1)
10481                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10482                    (const_int 0))
10483               (clobber (reg:CC FLAGS_REG))])]
10484   "TARGET_64BIT && !TARGET_USE_BT"
10485   [(const_int 0)]
10486 {
10487   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10488   rtx op1;
10489
10490   if (HOST_BITS_PER_WIDE_INT >= 64)
10491     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10492   else if (i < HOST_BITS_PER_WIDE_INT)
10493     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10494   else
10495     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10496
10497   op1 = immed_double_const (~lo, ~hi, DImode);
10498   if (i >= 32)
10499     {
10500       emit_move_insn (operands[2], op1);
10501       op1 = operands[2];
10502     }
10503
10504   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10505   DONE;
10506 })
10507
10508 (define_peephole2
10509   [(match_scratch:DI 2 "r")
10510    (parallel [(set (zero_extract:DI
10511                      (match_operand:DI 0 "register_operand" "")
10512                      (const_int 1)
10513                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10514               (not:DI (zero_extract:DI
10515                         (match_dup 0) (const_int 1) (match_dup 1))))
10516               (clobber (reg:CC FLAGS_REG))])]
10517   "TARGET_64BIT && !TARGET_USE_BT"
10518   [(const_int 0)]
10519 {
10520   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10521   rtx op1;
10522
10523   if (HOST_BITS_PER_WIDE_INT >= 64)
10524     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10525   else if (i < HOST_BITS_PER_WIDE_INT)
10526     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10527   else
10528     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10529
10530   op1 = immed_double_const (lo, hi, DImode);
10531   if (i >= 31)
10532     {
10533       emit_move_insn (operands[2], op1);
10534       op1 = operands[2];
10535     }
10536
10537   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10538   DONE;
10539 })
10540
10541 (define_insn "*bt<mode>"
10542   [(set (reg:CCC FLAGS_REG)
10543         (compare:CCC
10544           (zero_extract:SWI48
10545             (match_operand:SWI48 0 "register_operand" "r")
10546             (const_int 1)
10547             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10548           (const_int 0)))]
10549   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10550   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10551   [(set_attr "type" "alu1")
10552    (set_attr "prefix_0f" "1")
10553    (set_attr "mode" "<MODE>")])
10554 \f
10555 ;; Store-flag instructions.
10556
10557 ;; For all sCOND expanders, also expand the compare or test insn that
10558 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10559
10560 (define_insn_and_split "*setcc_di_1"
10561   [(set (match_operand:DI 0 "register_operand" "=q")
10562         (match_operator:DI 1 "ix86_comparison_operator"
10563           [(reg FLAGS_REG) (const_int 0)]))]
10564   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10565   "#"
10566   "&& reload_completed"
10567   [(set (match_dup 2) (match_dup 1))
10568    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10569 {
10570   PUT_MODE (operands[1], QImode);
10571   operands[2] = gen_lowpart (QImode, operands[0]);
10572 })
10573
10574 (define_insn_and_split "*setcc_si_1_and"
10575   [(set (match_operand:SI 0 "register_operand" "=q")
10576         (match_operator:SI 1 "ix86_comparison_operator"
10577           [(reg FLAGS_REG) (const_int 0)]))
10578    (clobber (reg:CC FLAGS_REG))]
10579   "!TARGET_PARTIAL_REG_STALL
10580    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10581   "#"
10582   "&& reload_completed"
10583   [(set (match_dup 2) (match_dup 1))
10584    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10585               (clobber (reg:CC FLAGS_REG))])]
10586 {
10587   PUT_MODE (operands[1], QImode);
10588   operands[2] = gen_lowpart (QImode, operands[0]);
10589 })
10590
10591 (define_insn_and_split "*setcc_si_1_movzbl"
10592   [(set (match_operand:SI 0 "register_operand" "=q")
10593         (match_operator:SI 1 "ix86_comparison_operator"
10594           [(reg FLAGS_REG) (const_int 0)]))]
10595   "!TARGET_PARTIAL_REG_STALL
10596    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10597   "#"
10598   "&& reload_completed"
10599   [(set (match_dup 2) (match_dup 1))
10600    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10601 {
10602   PUT_MODE (operands[1], QImode);
10603   operands[2] = gen_lowpart (QImode, operands[0]);
10604 })
10605
10606 (define_insn "*setcc_qi"
10607   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10608         (match_operator:QI 1 "ix86_comparison_operator"
10609           [(reg FLAGS_REG) (const_int 0)]))]
10610   ""
10611   "set%C1\t%0"
10612   [(set_attr "type" "setcc")
10613    (set_attr "mode" "QI")])
10614
10615 (define_insn "*setcc_qi_slp"
10616   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10617         (match_operator:QI 1 "ix86_comparison_operator"
10618           [(reg FLAGS_REG) (const_int 0)]))]
10619   ""
10620   "set%C1\t%0"
10621   [(set_attr "type" "setcc")
10622    (set_attr "mode" "QI")])
10623
10624 ;; In general it is not safe to assume too much about CCmode registers,
10625 ;; so simplify-rtx stops when it sees a second one.  Under certain
10626 ;; conditions this is safe on x86, so help combine not create
10627 ;;
10628 ;;      seta    %al
10629 ;;      testb   %al, %al
10630 ;;      sete    %al
10631
10632 (define_split
10633   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10634         (ne:QI (match_operator 1 "ix86_comparison_operator"
10635                  [(reg FLAGS_REG) (const_int 0)])
10636             (const_int 0)))]
10637   ""
10638   [(set (match_dup 0) (match_dup 1))]
10639   "PUT_MODE (operands[1], QImode);")
10640
10641 (define_split
10642   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10643         (ne:QI (match_operator 1 "ix86_comparison_operator"
10644                  [(reg FLAGS_REG) (const_int 0)])
10645             (const_int 0)))]
10646   ""
10647   [(set (match_dup 0) (match_dup 1))]
10648   "PUT_MODE (operands[1], QImode);")
10649
10650 (define_split
10651   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10652         (eq:QI (match_operator 1 "ix86_comparison_operator"
10653                  [(reg FLAGS_REG) (const_int 0)])
10654             (const_int 0)))]
10655   ""
10656   [(set (match_dup 0) (match_dup 1))]
10657 {
10658   rtx new_op1 = copy_rtx (operands[1]);
10659   operands[1] = new_op1;
10660   PUT_MODE (new_op1, QImode);
10661   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10662                                              GET_MODE (XEXP (new_op1, 0))));
10663
10664   /* Make sure that (a) the CCmode we have for the flags is strong
10665      enough for the reversed compare or (b) we have a valid FP compare.  */
10666   if (! ix86_comparison_operator (new_op1, VOIDmode))
10667     FAIL;
10668 })
10669
10670 (define_split
10671   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10672         (eq:QI (match_operator 1 "ix86_comparison_operator"
10673                  [(reg FLAGS_REG) (const_int 0)])
10674             (const_int 0)))]
10675   ""
10676   [(set (match_dup 0) (match_dup 1))]
10677 {
10678   rtx new_op1 = copy_rtx (operands[1]);
10679   operands[1] = new_op1;
10680   PUT_MODE (new_op1, QImode);
10681   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10682                                              GET_MODE (XEXP (new_op1, 0))));
10683
10684   /* Make sure that (a) the CCmode we have for the flags is strong
10685      enough for the reversed compare or (b) we have a valid FP compare.  */
10686   if (! ix86_comparison_operator (new_op1, VOIDmode))
10687     FAIL;
10688 })
10689
10690 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10691 ;; subsequent logical operations are used to imitate conditional moves.
10692 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10693 ;; it directly.
10694
10695 (define_insn "*avx_setcc<mode>"
10696   [(set (match_operand:MODEF 0 "register_operand" "=x")
10697         (match_operator:MODEF 1 "avx_comparison_float_operator"
10698           [(match_operand:MODEF 2 "register_operand" "x")
10699            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10700   "TARGET_AVX"
10701   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10702   [(set_attr "type" "ssecmp")
10703    (set_attr "prefix" "vex")
10704    (set_attr "length_immediate" "1")
10705    (set_attr "mode" "<MODE>")])
10706
10707 (define_insn "*sse_setcc<mode>"
10708   [(set (match_operand:MODEF 0 "register_operand" "=x")
10709         (match_operator:MODEF 1 "sse_comparison_operator"
10710           [(match_operand:MODEF 2 "register_operand" "0")
10711            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10712   "SSE_FLOAT_MODE_P (<MODE>mode)"
10713   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10714   [(set_attr "type" "ssecmp")
10715    (set_attr "length_immediate" "1")
10716    (set_attr "mode" "<MODE>")])
10717 \f
10718 ;; Basic conditional jump instructions.
10719 ;; We ignore the overflow flag for signed branch instructions.
10720
10721 (define_insn "*jcc_1"
10722   [(set (pc)
10723         (if_then_else (match_operator 1 "ix86_comparison_operator"
10724                                       [(reg FLAGS_REG) (const_int 0)])
10725                       (label_ref (match_operand 0 "" ""))
10726                       (pc)))]
10727   ""
10728   "%+j%C1\t%l0"
10729   [(set_attr "type" "ibr")
10730    (set_attr "modrm" "0")
10731    (set (attr "length")
10732            (if_then_else (and (ge (minus (match_dup 0) (pc))
10733                                   (const_int -126))
10734                               (lt (minus (match_dup 0) (pc))
10735                                   (const_int 128)))
10736              (const_int 2)
10737              (const_int 6)))])
10738
10739 (define_insn "*jcc_2"
10740   [(set (pc)
10741         (if_then_else (match_operator 1 "ix86_comparison_operator"
10742                                       [(reg FLAGS_REG) (const_int 0)])
10743                       (pc)
10744                       (label_ref (match_operand 0 "" ""))))]
10745   ""
10746   "%+j%c1\t%l0"
10747   [(set_attr "type" "ibr")
10748    (set_attr "modrm" "0")
10749    (set (attr "length")
10750            (if_then_else (and (ge (minus (match_dup 0) (pc))
10751                                   (const_int -126))
10752                               (lt (minus (match_dup 0) (pc))
10753                                   (const_int 128)))
10754              (const_int 2)
10755              (const_int 6)))])
10756
10757 ;; In general it is not safe to assume too much about CCmode registers,
10758 ;; so simplify-rtx stops when it sees a second one.  Under certain
10759 ;; conditions this is safe on x86, so help combine not create
10760 ;;
10761 ;;      seta    %al
10762 ;;      testb   %al, %al
10763 ;;      je      Lfoo
10764
10765 (define_split
10766   [(set (pc)
10767         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10768                                       [(reg FLAGS_REG) (const_int 0)])
10769                           (const_int 0))
10770                       (label_ref (match_operand 1 "" ""))
10771                       (pc)))]
10772   ""
10773   [(set (pc)
10774         (if_then_else (match_dup 0)
10775                       (label_ref (match_dup 1))
10776                       (pc)))]
10777   "PUT_MODE (operands[0], VOIDmode);")
10778
10779 (define_split
10780   [(set (pc)
10781         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10782                                       [(reg FLAGS_REG) (const_int 0)])
10783                           (const_int 0))
10784                       (label_ref (match_operand 1 "" ""))
10785                       (pc)))]
10786   ""
10787   [(set (pc)
10788         (if_then_else (match_dup 0)
10789                       (label_ref (match_dup 1))
10790                       (pc)))]
10791 {
10792   rtx new_op0 = copy_rtx (operands[0]);
10793   operands[0] = new_op0;
10794   PUT_MODE (new_op0, VOIDmode);
10795   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10796                                              GET_MODE (XEXP (new_op0, 0))));
10797
10798   /* Make sure that (a) the CCmode we have for the flags is strong
10799      enough for the reversed compare or (b) we have a valid FP compare.  */
10800   if (! ix86_comparison_operator (new_op0, VOIDmode))
10801     FAIL;
10802 })
10803
10804 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10805 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10806 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10807 ;; appropriate modulo of the bit offset value.
10808
10809 (define_insn_and_split "*jcc_bt<mode>"
10810   [(set (pc)
10811         (if_then_else (match_operator 0 "bt_comparison_operator"
10812                         [(zero_extract:SWI48
10813                            (match_operand:SWI48 1 "register_operand" "r")
10814                            (const_int 1)
10815                            (zero_extend:SI
10816                              (match_operand:QI 2 "register_operand" "r")))
10817                          (const_int 0)])
10818                       (label_ref (match_operand 3 "" ""))
10819                       (pc)))
10820    (clobber (reg:CC FLAGS_REG))]
10821   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10822   "#"
10823   "&& 1"
10824   [(set (reg:CCC FLAGS_REG)
10825         (compare:CCC
10826           (zero_extract:SWI48
10827             (match_dup 1)
10828             (const_int 1)
10829             (match_dup 2))
10830           (const_int 0)))
10831    (set (pc)
10832         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10833                       (label_ref (match_dup 3))
10834                       (pc)))]
10835 {
10836   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10837
10838   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10839 })
10840
10841 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10842 ;; also for DImode, this is what combine produces.
10843 (define_insn_and_split "*jcc_bt<mode>_mask"
10844   [(set (pc)
10845         (if_then_else (match_operator 0 "bt_comparison_operator"
10846                         [(zero_extract:SWI48
10847                            (match_operand:SWI48 1 "register_operand" "r")
10848                            (const_int 1)
10849                            (and:SI
10850                              (match_operand:SI 2 "register_operand" "r")
10851                              (match_operand:SI 3 "const_int_operand" "n")))])
10852                       (label_ref (match_operand 4 "" ""))
10853                       (pc)))
10854    (clobber (reg:CC FLAGS_REG))]
10855   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10856    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10857       == GET_MODE_BITSIZE (<MODE>mode)-1"
10858   "#"
10859   "&& 1"
10860   [(set (reg:CCC FLAGS_REG)
10861         (compare:CCC
10862           (zero_extract:SWI48
10863             (match_dup 1)
10864             (const_int 1)
10865             (match_dup 2))
10866           (const_int 0)))
10867    (set (pc)
10868         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10869                       (label_ref (match_dup 4))
10870                       (pc)))]
10871 {
10872   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10873
10874   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10875 })
10876
10877 (define_insn_and_split "*jcc_btsi_1"
10878   [(set (pc)
10879         (if_then_else (match_operator 0 "bt_comparison_operator"
10880                         [(and:SI
10881                            (lshiftrt:SI
10882                              (match_operand:SI 1 "register_operand" "r")
10883                              (match_operand:QI 2 "register_operand" "r"))
10884                            (const_int 1))
10885                          (const_int 0)])
10886                       (label_ref (match_operand 3 "" ""))
10887                       (pc)))
10888    (clobber (reg:CC FLAGS_REG))]
10889   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10890   "#"
10891   "&& 1"
10892   [(set (reg:CCC FLAGS_REG)
10893         (compare:CCC
10894           (zero_extract:SI
10895             (match_dup 1)
10896             (const_int 1)
10897             (match_dup 2))
10898           (const_int 0)))
10899    (set (pc)
10900         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10901                       (label_ref (match_dup 3))
10902                       (pc)))]
10903 {
10904   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10905
10906   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10907 })
10908
10909 ;; avoid useless masking of bit offset operand
10910 (define_insn_and_split "*jcc_btsi_mask_1"
10911   [(set (pc)
10912         (if_then_else
10913           (match_operator 0 "bt_comparison_operator"
10914             [(and:SI
10915                (lshiftrt:SI
10916                  (match_operand:SI 1 "register_operand" "r")
10917                  (subreg:QI
10918                    (and:SI
10919                      (match_operand:SI 2 "register_operand" "r")
10920                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10921                (const_int 1))
10922              (const_int 0)])
10923           (label_ref (match_operand 4 "" ""))
10924           (pc)))
10925    (clobber (reg:CC FLAGS_REG))]
10926   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10927    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10928   "#"
10929   "&& 1"
10930   [(set (reg:CCC FLAGS_REG)
10931         (compare:CCC
10932           (zero_extract:SI
10933             (match_dup 1)
10934             (const_int 1)
10935             (match_dup 2))
10936           (const_int 0)))
10937    (set (pc)
10938         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10939                       (label_ref (match_dup 4))
10940                       (pc)))]
10941   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10942
10943 ;; Define combination compare-and-branch fp compare instructions to help
10944 ;; combine.
10945
10946 (define_insn "*fp_jcc_1_387"
10947   [(set (pc)
10948         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10949                         [(match_operand 1 "register_operand" "f")
10950                          (match_operand 2 "nonimmediate_operand" "fm")])
10951           (label_ref (match_operand 3 "" ""))
10952           (pc)))
10953    (clobber (reg:CCFP FPSR_REG))
10954    (clobber (reg:CCFP FLAGS_REG))
10955    (clobber (match_scratch:HI 4 "=a"))]
10956   "TARGET_80387
10957    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10958    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10959    && SELECT_CC_MODE (GET_CODE (operands[0]),
10960                       operands[1], operands[2]) == CCFPmode
10961    && !TARGET_CMOVE"
10962   "#")
10963
10964 (define_insn "*fp_jcc_1r_387"
10965   [(set (pc)
10966         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10967                         [(match_operand 1 "register_operand" "f")
10968                          (match_operand 2 "nonimmediate_operand" "fm")])
10969           (pc)
10970           (label_ref (match_operand 3 "" ""))))
10971    (clobber (reg:CCFP FPSR_REG))
10972    (clobber (reg:CCFP FLAGS_REG))
10973    (clobber (match_scratch:HI 4 "=a"))]
10974   "TARGET_80387
10975    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10976    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10977    && SELECT_CC_MODE (GET_CODE (operands[0]),
10978                       operands[1], operands[2]) == CCFPmode
10979    && !TARGET_CMOVE"
10980   "#")
10981
10982 (define_insn "*fp_jcc_2_387"
10983   [(set (pc)
10984         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10985                         [(match_operand 1 "register_operand" "f")
10986                          (match_operand 2 "register_operand" "f")])
10987           (label_ref (match_operand 3 "" ""))
10988           (pc)))
10989    (clobber (reg:CCFP FPSR_REG))
10990    (clobber (reg:CCFP FLAGS_REG))
10991    (clobber (match_scratch:HI 4 "=a"))]
10992   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10993    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10994    && !TARGET_CMOVE"
10995   "#")
10996
10997 (define_insn "*fp_jcc_2r_387"
10998   [(set (pc)
10999         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11000                         [(match_operand 1 "register_operand" "f")
11001                          (match_operand 2 "register_operand" "f")])
11002           (pc)
11003           (label_ref (match_operand 3 "" ""))))
11004    (clobber (reg:CCFP FPSR_REG))
11005    (clobber (reg:CCFP FLAGS_REG))
11006    (clobber (match_scratch:HI 4 "=a"))]
11007   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11008    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11009    && !TARGET_CMOVE"
11010   "#")
11011
11012 (define_insn "*fp_jcc_3_387"
11013   [(set (pc)
11014         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11015                         [(match_operand 1 "register_operand" "f")
11016                          (match_operand 2 "const0_operand" "")])
11017           (label_ref (match_operand 3 "" ""))
11018           (pc)))
11019    (clobber (reg:CCFP FPSR_REG))
11020    (clobber (reg:CCFP FLAGS_REG))
11021    (clobber (match_scratch:HI 4 "=a"))]
11022   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11023    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11024    && SELECT_CC_MODE (GET_CODE (operands[0]),
11025                       operands[1], operands[2]) == CCFPmode
11026    && !TARGET_CMOVE"
11027   "#")
11028
11029 (define_split
11030   [(set (pc)
11031         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11032                         [(match_operand 1 "register_operand" "")
11033                          (match_operand 2 "nonimmediate_operand" "")])
11034           (match_operand 3 "" "")
11035           (match_operand 4 "" "")))
11036    (clobber (reg:CCFP FPSR_REG))
11037    (clobber (reg:CCFP FLAGS_REG))]
11038   "reload_completed"
11039   [(const_int 0)]
11040 {
11041   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11042                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11043   DONE;
11044 })
11045
11046 (define_split
11047   [(set (pc)
11048         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11049                         [(match_operand 1 "register_operand" "")
11050                          (match_operand 2 "general_operand" "")])
11051           (match_operand 3 "" "")
11052           (match_operand 4 "" "")))
11053    (clobber (reg:CCFP FPSR_REG))
11054    (clobber (reg:CCFP FLAGS_REG))
11055    (clobber (match_scratch:HI 5 "=a"))]
11056   "reload_completed"
11057   [(const_int 0)]
11058 {
11059   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11060                         operands[3], operands[4], operands[5], NULL_RTX);
11061   DONE;
11062 })
11063
11064 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11065 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11066 ;; with a precedence over other operators and is always put in the first
11067 ;; place. Swap condition and operands to match ficom instruction.
11068
11069 (define_insn "*fp_jcc_4_<mode>_387"
11070   [(set (pc)
11071         (if_then_else
11072           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11073             [(match_operator 1 "float_operator"
11074               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11075              (match_operand 3 "register_operand" "f,f")])
11076           (label_ref (match_operand 4 "" ""))
11077           (pc)))
11078    (clobber (reg:CCFP FPSR_REG))
11079    (clobber (reg:CCFP FLAGS_REG))
11080    (clobber (match_scratch:HI 5 "=a,a"))]
11081   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11082    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11083    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11084    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11085    && !TARGET_CMOVE"
11086   "#")
11087
11088 (define_split
11089   [(set (pc)
11090         (if_then_else
11091           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11092             [(match_operator 1 "float_operator"
11093               [(match_operand:X87MODEI12 2 "memory_operand" "")])
11094              (match_operand 3 "register_operand" "")])
11095           (match_operand 4 "" "")
11096           (match_operand 5 "" "")))
11097    (clobber (reg:CCFP FPSR_REG))
11098    (clobber (reg:CCFP FLAGS_REG))
11099    (clobber (match_scratch:HI 6 "=a"))]
11100   "reload_completed"
11101   [(const_int 0)]
11102 {
11103   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11104
11105   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11106                         operands[3], operands[7],
11107                         operands[4], operands[5], operands[6], NULL_RTX);
11108   DONE;
11109 })
11110
11111 ;; %%% Kill this when reload knows how to do it.
11112 (define_split
11113   [(set (pc)
11114         (if_then_else
11115           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11116             [(match_operator 1 "float_operator"
11117               [(match_operand:X87MODEI12 2 "register_operand" "")])
11118              (match_operand 3 "register_operand" "")])
11119           (match_operand 4 "" "")
11120           (match_operand 5 "" "")))
11121    (clobber (reg:CCFP FPSR_REG))
11122    (clobber (reg:CCFP FLAGS_REG))
11123    (clobber (match_scratch:HI 6 "=a"))]
11124   "reload_completed"
11125   [(const_int 0)]
11126 {
11127   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11128   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11129
11130   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11131                         operands[3], operands[7],
11132                         operands[4], operands[5], operands[6], operands[2]);
11133   DONE;
11134 })
11135 \f
11136 ;; Unconditional and other jump instructions
11137
11138 (define_insn "jump"
11139   [(set (pc)
11140         (label_ref (match_operand 0 "" "")))]
11141   ""
11142   "jmp\t%l0"
11143   [(set_attr "type" "ibr")
11144    (set (attr "length")
11145            (if_then_else (and (ge (minus (match_dup 0) (pc))
11146                                   (const_int -126))
11147                               (lt (minus (match_dup 0) (pc))
11148                                   (const_int 128)))
11149              (const_int 2)
11150              (const_int 5)))
11151    (set_attr "modrm" "0")])
11152
11153 (define_expand "indirect_jump"
11154   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11155   ""
11156   "")
11157
11158 (define_insn "*indirect_jump"
11159   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11160   ""
11161   "jmp\t%A0"
11162   [(set_attr "type" "ibr")
11163    (set_attr "length_immediate" "0")])
11164
11165 (define_expand "tablejump"
11166   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11167               (use (label_ref (match_operand 1 "" "")))])]
11168   ""
11169 {
11170   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11171      relative.  Convert the relative address to an absolute address.  */
11172   if (flag_pic)
11173     {
11174       rtx op0, op1;
11175       enum rtx_code code;
11176
11177       /* We can't use @GOTOFF for text labels on VxWorks;
11178          see gotoff_operand.  */
11179       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11180         {
11181           code = PLUS;
11182           op0 = operands[0];
11183           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11184         }
11185       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11186         {
11187           code = PLUS;
11188           op0 = operands[0];
11189           op1 = pic_offset_table_rtx;
11190         }
11191       else
11192         {
11193           code = MINUS;
11194           op0 = pic_offset_table_rtx;
11195           op1 = operands[0];
11196         }
11197
11198       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11199                                          OPTAB_DIRECT);
11200     }
11201 })
11202
11203 (define_insn "*tablejump_1"
11204   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11205    (use (label_ref (match_operand 1 "" "")))]
11206   ""
11207   "jmp\t%A0"
11208   [(set_attr "type" "ibr")
11209    (set_attr "length_immediate" "0")])
11210 \f
11211 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11212
11213 (define_peephole2
11214   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11215    (set (match_operand:QI 1 "register_operand" "")
11216         (match_operator:QI 2 "ix86_comparison_operator"
11217           [(reg FLAGS_REG) (const_int 0)]))
11218    (set (match_operand 3 "q_regs_operand" "")
11219         (zero_extend (match_dup 1)))]
11220   "(peep2_reg_dead_p (3, operands[1])
11221     || operands_match_p (operands[1], operands[3]))
11222    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11223   [(set (match_dup 4) (match_dup 0))
11224    (set (strict_low_part (match_dup 5))
11225         (match_dup 2))]
11226 {
11227   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11228   operands[5] = gen_lowpart (QImode, operands[3]);
11229   ix86_expand_clear (operands[3]);
11230 })
11231
11232 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11233
11234 (define_peephole2
11235   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11236    (set (match_operand:QI 1 "register_operand" "")
11237         (match_operator:QI 2 "ix86_comparison_operator"
11238           [(reg FLAGS_REG) (const_int 0)]))
11239    (parallel [(set (match_operand 3 "q_regs_operand" "")
11240                    (zero_extend (match_dup 1)))
11241               (clobber (reg:CC FLAGS_REG))])]
11242   "(peep2_reg_dead_p (3, operands[1])
11243     || operands_match_p (operands[1], operands[3]))
11244    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11245   [(set (match_dup 4) (match_dup 0))
11246    (set (strict_low_part (match_dup 5))
11247         (match_dup 2))]
11248 {
11249   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11250   operands[5] = gen_lowpart (QImode, operands[3]);
11251   ix86_expand_clear (operands[3]);
11252 })
11253 \f
11254 ;; Call instructions.
11255
11256 ;; The predicates normally associated with named expanders are not properly
11257 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11258 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11259
11260 ;; P6 processors will jump to the address after the decrement when %esp
11261 ;; is used as a call operand, so they will execute return address as a code.
11262 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11263  
11264 ;; Call subroutine returning no value.
11265
11266 (define_expand "call_pop"
11267   [(parallel [(call (match_operand:QI 0 "" "")
11268                     (match_operand:SI 1 "" ""))
11269               (set (reg:SI SP_REG)
11270                    (plus:SI (reg:SI SP_REG)
11271                             (match_operand:SI 3 "" "")))])]
11272   "!TARGET_64BIT"
11273 {
11274   ix86_expand_call (NULL, operands[0], operands[1],
11275                     operands[2], operands[3], 0);
11276   DONE;
11277 })
11278
11279 (define_insn_and_split "*call_pop_0_vzeroupper"
11280   [(parallel
11281     [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11282            (match_operand:SI 1 "" ""))
11283      (set (reg:SI SP_REG)
11284           (plus:SI (reg:SI SP_REG)
11285                    (match_operand:SI 2 "immediate_operand" "")))])
11286    (unspec [(match_operand 3 "const_int_operand" "")]
11287            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11288   "TARGET_VZEROUPPER && !TARGET_64BIT"
11289   "#"
11290   "&& reload_completed"
11291   [(const_int 0)]
11292   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11293   [(set_attr "type" "call")])
11294
11295 (define_insn "*call_pop_0"
11296   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11297          (match_operand:SI 1 "" ""))
11298    (set (reg:SI SP_REG)
11299         (plus:SI (reg:SI SP_REG)
11300                  (match_operand:SI 2 "immediate_operand" "")))]
11301   "!TARGET_64BIT"
11302 {
11303   if (SIBLING_CALL_P (insn))
11304     return "jmp\t%P0";
11305   else
11306     return "call\t%P0";
11307 }
11308   [(set_attr "type" "call")])
11309
11310 (define_insn_and_split "*call_pop_1_vzeroupper"
11311   [(parallel
11312     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11313            (match_operand:SI 1 "" ""))
11314      (set (reg:SI SP_REG)
11315           (plus:SI (reg:SI SP_REG)
11316                    (match_operand:SI 2 "immediate_operand" "i")))])
11317    (unspec [(match_operand 3 "const_int_operand" "")]
11318            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11319   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11320   "#"
11321   "&& reload_completed"
11322   [(const_int 0)]
11323   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11324   [(set_attr "type" "call")])
11325
11326 (define_insn "*call_pop_1"
11327   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11328          (match_operand:SI 1 "" ""))
11329    (set (reg:SI SP_REG)
11330         (plus:SI (reg:SI SP_REG)
11331                  (match_operand:SI 2 "immediate_operand" "i")))]
11332   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11333 {
11334   if (constant_call_address_operand (operands[0], Pmode))
11335     return "call\t%P0";
11336   return "call\t%A0";
11337 }
11338   [(set_attr "type" "call")])
11339
11340 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11341  [(parallel
11342    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11343            (match_operand:SI 1 "" ""))
11344      (set (reg:SI SP_REG)
11345           (plus:SI (reg:SI SP_REG)
11346                    (match_operand:SI 2 "immediate_operand" "i,i")))])
11347    (unspec [(match_operand 3 "const_int_operand" "")]
11348            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11349   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11350   "#"
11351   "&& reload_completed"
11352   [(const_int 0)]
11353   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11354   [(set_attr "type" "call")])
11355
11356 (define_insn "*sibcall_pop_1"
11357   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11358          (match_operand:SI 1 "" ""))
11359    (set (reg:SI SP_REG)
11360         (plus:SI (reg:SI SP_REG)
11361                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11362   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11363   "@
11364    jmp\t%P0
11365    jmp\t%A0"
11366   [(set_attr "type" "call")])
11367
11368 (define_expand "call"
11369   [(call (match_operand:QI 0 "" "")
11370          (match_operand 1 "" ""))
11371    (use (match_operand 2 "" ""))]
11372   ""
11373 {
11374   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11375   DONE;
11376 })
11377
11378 (define_expand "sibcall"
11379   [(call (match_operand:QI 0 "" "")
11380          (match_operand 1 "" ""))
11381    (use (match_operand 2 "" ""))]
11382   ""
11383 {
11384   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11385   DONE;
11386 })
11387
11388 (define_insn_and_split "*call_0_vzeroupper"
11389   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11390          (match_operand 1 "" ""))
11391    (unspec [(match_operand 2 "const_int_operand" "")]
11392            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11393   "TARGET_VZEROUPPER"
11394   "#"
11395   "&& reload_completed"
11396   [(const_int 0)]
11397   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11398   [(set_attr "type" "call")])
11399
11400 (define_insn "*call_0"
11401   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11402          (match_operand 1 "" ""))]
11403   ""
11404   { return ix86_output_call_insn (insn, operands[0], 0); }
11405   [(set_attr "type" "call")])
11406
11407 (define_insn_and_split "*call_1_vzeroupper"
11408   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11409          (match_operand 1 "" ""))
11410    (unspec [(match_operand 2 "const_int_operand" "")]
11411            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11412   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11413   "#"
11414   "&& reload_completed"
11415   [(const_int 0)]
11416   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11417   [(set_attr "type" "call")])
11418
11419 (define_insn "*call_1"
11420   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11421          (match_operand 1 "" ""))]
11422   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11423   { return ix86_output_call_insn (insn, operands[0], 0); }
11424   [(set_attr "type" "call")])
11425
11426 (define_insn_and_split "*sibcall_1_vzeroupper"
11427   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11428          (match_operand 1 "" ""))
11429    (unspec [(match_operand 2 "const_int_operand" "")]
11430            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11431   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11432   "#"
11433   "&& reload_completed"
11434   [(const_int 0)]
11435   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11436   [(set_attr "type" "call")])
11437
11438 (define_insn "*sibcall_1"
11439   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11440          (match_operand 1 "" ""))]
11441   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11442   { return ix86_output_call_insn (insn, operands[0], 0); }
11443   [(set_attr "type" "call")])
11444
11445 (define_insn_and_split "*call_1_rex64_vzeroupper"
11446   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11447          (match_operand 1 "" ""))
11448    (unspec [(match_operand 2 "const_int_operand" "")]
11449            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11450   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11451    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11452   "#"
11453   "&& reload_completed"
11454   [(const_int 0)]
11455   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11456   [(set_attr "type" "call")])
11457
11458 (define_insn "*call_1_rex64"
11459   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11460          (match_operand 1 "" ""))]
11461   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11462    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11463   { return ix86_output_call_insn (insn, operands[0], 0); }
11464   [(set_attr "type" "call")])
11465
11466 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11467   [(parallel
11468     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11469            (match_operand 1 "" ""))
11470      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11471      (clobber (reg:TI XMM6_REG))
11472      (clobber (reg:TI XMM7_REG))
11473      (clobber (reg:TI XMM8_REG))
11474      (clobber (reg:TI XMM9_REG))
11475      (clobber (reg:TI XMM10_REG))
11476      (clobber (reg:TI XMM11_REG))
11477      (clobber (reg:TI XMM12_REG))
11478      (clobber (reg:TI XMM13_REG))
11479      (clobber (reg:TI XMM14_REG))
11480      (clobber (reg:TI XMM15_REG))
11481      (clobber (reg:DI SI_REG))
11482      (clobber (reg:DI DI_REG))])
11483    (unspec [(match_operand 2 "const_int_operand" "")]
11484            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11485   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11486   "#"
11487   "&& reload_completed"
11488   [(const_int 0)]
11489   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11490   [(set_attr "type" "call")])
11491
11492 (define_insn "*call_1_rex64_ms_sysv"
11493   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11494          (match_operand 1 "" ""))
11495    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11496    (clobber (reg:TI XMM6_REG))
11497    (clobber (reg:TI XMM7_REG))
11498    (clobber (reg:TI XMM8_REG))
11499    (clobber (reg:TI XMM9_REG))
11500    (clobber (reg:TI XMM10_REG))
11501    (clobber (reg:TI XMM11_REG))
11502    (clobber (reg:TI XMM12_REG))
11503    (clobber (reg:TI XMM13_REG))
11504    (clobber (reg:TI XMM14_REG))
11505    (clobber (reg:TI XMM15_REG))
11506    (clobber (reg:DI SI_REG))
11507    (clobber (reg:DI DI_REG))]
11508   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11509   { return ix86_output_call_insn (insn, operands[0], 0); }
11510   [(set_attr "type" "call")])
11511
11512 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11513   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11514          (match_operand 1 "" ""))
11515    (unspec [(match_operand 2 "const_int_operand" "")]
11516            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11517   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11518   "#"
11519   "&& reload_completed"
11520   [(const_int 0)]
11521   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11522   [(set_attr "type" "call")])
11523
11524 (define_insn "*call_1_rex64_large"
11525   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11526          (match_operand 1 "" ""))]
11527   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11528   { return ix86_output_call_insn (insn, operands[0], 0); }
11529   [(set_attr "type" "call")])
11530
11531 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11532   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11533          (match_operand 1 "" ""))
11534    (unspec [(match_operand 2 "const_int_operand" "")]
11535            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11536   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11537   "#"
11538   "&& reload_completed"
11539   [(const_int 0)]
11540   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11541   [(set_attr "type" "call")])
11542
11543 (define_insn "*sibcall_1_rex64"
11544   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11545          (match_operand 1 "" ""))]
11546   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11547   { return ix86_output_call_insn (insn, operands[0], 0); }
11548   [(set_attr "type" "call")])
11549
11550 ;; Call subroutine, returning value in operand 0
11551 (define_expand "call_value_pop"
11552   [(parallel [(set (match_operand 0 "" "")
11553                    (call (match_operand:QI 1 "" "")
11554                          (match_operand:SI 2 "" "")))
11555               (set (reg:SI SP_REG)
11556                    (plus:SI (reg:SI SP_REG)
11557                             (match_operand:SI 4 "" "")))])]
11558   "!TARGET_64BIT"
11559 {
11560   ix86_expand_call (operands[0], operands[1], operands[2],
11561                     operands[3], operands[4], 0);
11562   DONE;
11563 })
11564
11565 (define_expand "call_value"
11566   [(set (match_operand 0 "" "")
11567         (call (match_operand:QI 1 "" "")
11568               (match_operand:SI 2 "" "")))
11569    (use (match_operand:SI 3 "" ""))]
11570   ;; Operand 3 is not used on the i386.
11571   ""
11572 {
11573   ix86_expand_call (operands[0], operands[1], operands[2],
11574                     operands[3], NULL, 0);
11575   DONE;
11576 })
11577
11578 (define_expand "sibcall_value"
11579   [(set (match_operand 0 "" "")
11580         (call (match_operand:QI 1 "" "")
11581               (match_operand:SI 2 "" "")))
11582    (use (match_operand:SI 3 "" ""))]
11583   ;; Operand 3 is not used on the i386.
11584   ""
11585 {
11586   ix86_expand_call (operands[0], operands[1], operands[2],
11587                     operands[3], NULL, 1);
11588   DONE;
11589 })
11590
11591 ;; Call subroutine returning any type.
11592
11593 (define_expand "untyped_call"
11594   [(parallel [(call (match_operand 0 "" "")
11595                     (const_int 0))
11596               (match_operand 1 "" "")
11597               (match_operand 2 "" "")])]
11598   ""
11599 {
11600   int i;
11601
11602   /* In order to give reg-stack an easier job in validating two
11603      coprocessor registers as containing a possible return value,
11604      simply pretend the untyped call returns a complex long double
11605      value. 
11606
11607      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11608      and should have the default ABI.  */
11609
11610   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11611                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11612                     operands[0], const0_rtx,
11613                     GEN_INT ((TARGET_64BIT
11614                               ? (ix86_abi == SYSV_ABI
11615                                  ? X86_64_SSE_REGPARM_MAX
11616                                  : X86_64_MS_SSE_REGPARM_MAX)
11617                               : X86_32_SSE_REGPARM_MAX)
11618                              - 1),
11619                     NULL, 0);
11620
11621   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11622     {
11623       rtx set = XVECEXP (operands[2], 0, i);
11624       emit_move_insn (SET_DEST (set), SET_SRC (set));
11625     }
11626
11627   /* The optimizer does not know that the call sets the function value
11628      registers we stored in the result block.  We avoid problems by
11629      claiming that all hard registers are used and clobbered at this
11630      point.  */
11631   emit_insn (gen_blockage ());
11632
11633   DONE;
11634 })
11635 \f
11636 ;; Prologue and epilogue instructions
11637
11638 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11639 ;; all of memory.  This blocks insns from being moved across this point.
11640
11641 (define_insn "blockage"
11642   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11643   ""
11644   ""
11645   [(set_attr "length" "0")])
11646
11647 ;; Do not schedule instructions accessing memory across this point.
11648
11649 (define_expand "memory_blockage"
11650   [(set (match_dup 0)
11651         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11652   ""
11653 {
11654   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11655   MEM_VOLATILE_P (operands[0]) = 1;
11656 })
11657
11658 (define_insn "*memory_blockage"
11659   [(set (match_operand:BLK 0 "" "")
11660         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11661   ""
11662   ""
11663   [(set_attr "length" "0")])
11664
11665 ;; As USE insns aren't meaningful after reload, this is used instead
11666 ;; to prevent deleting instructions setting registers for PIC code
11667 (define_insn "prologue_use"
11668   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11669   ""
11670   ""
11671   [(set_attr "length" "0")])
11672
11673 ;; Insn emitted into the body of a function to return from a function.
11674 ;; This is only done if the function's epilogue is known to be simple.
11675 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11676
11677 (define_expand "return"
11678   [(return)]
11679   "ix86_can_use_return_insn_p ()"
11680 {
11681   if (crtl->args.pops_args)
11682     {
11683       rtx popc = GEN_INT (crtl->args.pops_args);
11684       emit_jump_insn (gen_return_pop_internal (popc));
11685       DONE;
11686     }
11687 })
11688
11689 (define_insn "return_internal"
11690   [(return)]
11691   "reload_completed"
11692   "ret"
11693   [(set_attr "length" "1")
11694    (set_attr "atom_unit" "jeu")
11695    (set_attr "length_immediate" "0")
11696    (set_attr "modrm" "0")])
11697
11698 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11699 ;; instruction Athlon and K8 have.
11700
11701 (define_insn "return_internal_long"
11702   [(return)
11703    (unspec [(const_int 0)] UNSPEC_REP)]
11704   "reload_completed"
11705   "rep\;ret"
11706   [(set_attr "length" "2")
11707    (set_attr "atom_unit" "jeu")
11708    (set_attr "length_immediate" "0")
11709    (set_attr "prefix_rep" "1")
11710    (set_attr "modrm" "0")])
11711
11712 (define_insn "return_pop_internal"
11713   [(return)
11714    (use (match_operand:SI 0 "const_int_operand" ""))]
11715   "reload_completed"
11716   "ret\t%0"
11717   [(set_attr "length" "3")
11718    (set_attr "atom_unit" "jeu")
11719    (set_attr "length_immediate" "2")
11720    (set_attr "modrm" "0")])
11721
11722 (define_insn "return_indirect_internal"
11723   [(return)
11724    (use (match_operand:SI 0 "register_operand" "r"))]
11725   "reload_completed"
11726   "jmp\t%A0"
11727   [(set_attr "type" "ibr")
11728    (set_attr "length_immediate" "0")])
11729
11730 (define_insn "nop"
11731   [(const_int 0)]
11732   ""
11733   "nop"
11734   [(set_attr "length" "1")
11735    (set_attr "length_immediate" "0")
11736    (set_attr "modrm" "0")])
11737
11738 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11739 (define_insn "nops"
11740   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11741                     UNSPECV_NOPS)]
11742   "reload_completed"
11743 {
11744   int num = INTVAL (operands[0]);
11745
11746   gcc_assert (num >= 1 && num <= 8);
11747
11748   while (num--)
11749     fputs ("\tnop\n", asm_out_file);
11750
11751   return "";
11752 }
11753   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11754    (set_attr "length_immediate" "0")
11755    (set_attr "modrm" "0")])
11756
11757 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11758 ;; branch prediction penalty for the third jump in a 16-byte
11759 ;; block on K8.
11760
11761 (define_insn "pad"
11762   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11763   ""
11764 {
11765 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11766   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11767 #else
11768   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11769      The align insn is used to avoid 3 jump instructions in the row to improve
11770      branch prediction and the benefits hardly outweigh the cost of extra 8
11771      nops on the average inserted by full alignment pseudo operation.  */
11772 #endif
11773   return "";
11774 }
11775   [(set_attr "length" "16")])
11776
11777 (define_expand "prologue"
11778   [(const_int 0)]
11779   ""
11780   "ix86_expand_prologue (); DONE;")
11781
11782 (define_insn "set_got"
11783   [(set (match_operand:SI 0 "register_operand" "=r")
11784         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "!TARGET_64BIT"
11787   "* return output_set_got (operands[0], NULL_RTX);"
11788   [(set_attr "type" "multi")
11789    (set_attr "length" "12")])
11790
11791 (define_insn "set_got_labelled"
11792   [(set (match_operand:SI 0 "register_operand" "=r")
11793         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11794          UNSPEC_SET_GOT))
11795    (clobber (reg:CC FLAGS_REG))]
11796   "!TARGET_64BIT"
11797   "* return output_set_got (operands[0], operands[1]);"
11798   [(set_attr "type" "multi")
11799    (set_attr "length" "12")])
11800
11801 (define_insn "set_got_rex64"
11802   [(set (match_operand:DI 0 "register_operand" "=r")
11803         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11804   "TARGET_64BIT"
11805   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11806   [(set_attr "type" "lea")
11807    (set_attr "length_address" "4")
11808    (set_attr "mode" "DI")])
11809
11810 (define_insn "set_rip_rex64"
11811   [(set (match_operand:DI 0 "register_operand" "=r")
11812         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11813   "TARGET_64BIT"
11814   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11815   [(set_attr "type" "lea")
11816    (set_attr "length_address" "4")
11817    (set_attr "mode" "DI")])
11818
11819 (define_insn "set_got_offset_rex64"
11820   [(set (match_operand:DI 0 "register_operand" "=r")
11821         (unspec:DI
11822           [(label_ref (match_operand 1 "" ""))]
11823           UNSPEC_SET_GOT_OFFSET))]
11824   "TARGET_64BIT"
11825   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11826   [(set_attr "type" "imov")
11827    (set_attr "length_immediate" "0")
11828    (set_attr "length_address" "8")
11829    (set_attr "mode" "DI")])
11830
11831 (define_expand "epilogue"
11832   [(const_int 0)]
11833   ""
11834   "ix86_expand_epilogue (1); DONE;")
11835
11836 (define_expand "sibcall_epilogue"
11837   [(const_int 0)]
11838   ""
11839   "ix86_expand_epilogue (0); DONE;")
11840
11841 (define_expand "eh_return"
11842   [(use (match_operand 0 "register_operand" ""))]
11843   ""
11844 {
11845   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11846
11847   /* Tricky bit: we write the address of the handler to which we will
11848      be returning into someone else's stack frame, one word below the
11849      stack address we wish to restore.  */
11850   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11851   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11852   tmp = gen_rtx_MEM (Pmode, tmp);
11853   emit_move_insn (tmp, ra);
11854
11855   emit_jump_insn (gen_eh_return_internal ());
11856   emit_barrier ();
11857   DONE;
11858 })
11859
11860 (define_insn_and_split "eh_return_internal"
11861   [(eh_return)]
11862   ""
11863   "#"
11864   "epilogue_completed"
11865   [(const_int 0)]
11866   "ix86_expand_epilogue (2); DONE;")
11867
11868 (define_insn "leave"
11869   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11870    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11871    (clobber (mem:BLK (scratch)))]
11872   "!TARGET_64BIT"
11873   "leave"
11874   [(set_attr "type" "leave")])
11875
11876 (define_insn "leave_rex64"
11877   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11878    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11879    (clobber (mem:BLK (scratch)))]
11880   "TARGET_64BIT"
11881   "leave"
11882   [(set_attr "type" "leave")])
11883 \f
11884 ;; Handle -fsplit-stack.
11885
11886 (define_expand "split_stack_prologue"
11887   [(const_int 0)]
11888   ""
11889 {
11890   ix86_expand_split_stack_prologue ();
11891   DONE;
11892 })
11893
11894 ;; In order to support the call/return predictor, we use a return
11895 ;; instruction which the middle-end doesn't see.
11896 (define_insn "split_stack_return"
11897   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11898                      UNSPECV_SPLIT_STACK_RETURN)]
11899   ""
11900 {
11901   if (operands[0] == const0_rtx)
11902     return "ret";
11903   else
11904     return "ret\t%0";
11905 }
11906   [(set_attr "atom_unit" "jeu")
11907    (set_attr "modrm" "0")
11908    (set (attr "length")
11909         (if_then_else (match_operand:SI 0 "const0_operand" "")
11910                       (const_int 1)
11911                       (const_int 3)))
11912    (set (attr "length_immediate")
11913         (if_then_else (match_operand:SI 0 "const0_operand" "")
11914                       (const_int 0)
11915                       (const_int 2)))])
11916
11917 ;; If there are operand 0 bytes available on the stack, jump to
11918 ;; operand 1.
11919
11920 (define_expand "split_stack_space_check"
11921   [(set (pc) (if_then_else
11922               (ltu (minus (reg SP_REG)
11923                           (match_operand 0 "register_operand" ""))
11924                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11925               (label_ref (match_operand 1 "" ""))
11926               (pc)))]
11927   ""
11928 {
11929   rtx reg, size, limit;
11930
11931   reg = gen_reg_rtx (Pmode);
11932   size = force_reg (Pmode, operands[0]);
11933   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11934   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11935                           UNSPEC_STACK_CHECK);
11936   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11937   ix86_expand_branch (GEU, reg, limit, operands[1]);
11938
11939   DONE;
11940 })
11941 \f
11942 ;; Bit manipulation instructions.
11943
11944 (define_expand "ffs<mode>2"
11945   [(set (match_dup 2) (const_int -1))
11946    (parallel [(set (reg:CCZ FLAGS_REG)
11947                    (compare:CCZ
11948                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11949                      (const_int 0)))
11950               (set (match_operand:SWI48 0 "register_operand" "")
11951                    (ctz:SWI48 (match_dup 1)))])
11952    (set (match_dup 0) (if_then_else:SWI48
11953                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11954                         (match_dup 2)
11955                         (match_dup 0)))
11956    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11957               (clobber (reg:CC FLAGS_REG))])]
11958   ""
11959 {
11960   if (<MODE>mode == SImode && !TARGET_CMOVE)
11961     {
11962       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11963       DONE;
11964     }
11965   operands[2] = gen_reg_rtx (<MODE>mode);
11966 })
11967
11968 (define_insn_and_split "ffssi2_no_cmove"
11969   [(set (match_operand:SI 0 "register_operand" "=r")
11970         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11971    (clobber (match_scratch:SI 2 "=&q"))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "!TARGET_CMOVE"
11974   "#"
11975   "&& reload_completed"
11976   [(parallel [(set (reg:CCZ FLAGS_REG)
11977                    (compare:CCZ (match_dup 1) (const_int 0)))
11978               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11979    (set (strict_low_part (match_dup 3))
11980         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11981    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11982               (clobber (reg:CC FLAGS_REG))])
11983    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11984               (clobber (reg:CC FLAGS_REG))])
11985    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11986               (clobber (reg:CC FLAGS_REG))])]
11987 {
11988   operands[3] = gen_lowpart (QImode, operands[2]);
11989   ix86_expand_clear (operands[2]);
11990 })
11991
11992 (define_insn "*ffs<mode>_1"
11993   [(set (reg:CCZ FLAGS_REG)
11994         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11995                      (const_int 0)))
11996    (set (match_operand:SWI48 0 "register_operand" "=r")
11997         (ctz:SWI48 (match_dup 1)))]
11998   ""
11999   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12000   [(set_attr "type" "alu1")
12001    (set_attr "prefix_0f" "1")
12002    (set_attr "mode" "<MODE>")])
12003
12004 (define_insn "ctz<mode>2"
12005   [(set (match_operand:SWI248 0 "register_operand" "=r")
12006         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12007    (clobber (reg:CC FLAGS_REG))]
12008   ""
12009 {
12010   if (TARGET_BMI)
12011     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12012   else
12013     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12014 }
12015   [(set_attr "type" "alu1")
12016    (set_attr "prefix_0f" "1")
12017    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12018    (set_attr "mode" "<MODE>")])
12019
12020 (define_expand "clz<mode>2"
12021   [(parallel
12022      [(set (match_operand:SWI248 0 "register_operand" "")
12023            (minus:SWI248
12024              (match_dup 2)
12025              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12026       (clobber (reg:CC FLAGS_REG))])
12027    (parallel
12028      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12029       (clobber (reg:CC FLAGS_REG))])]
12030   ""
12031 {
12032   if (TARGET_ABM)
12033     {
12034       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12035       DONE;
12036     }
12037   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12038 })
12039
12040 (define_insn "clz<mode>2_abm"
12041   [(set (match_operand:SWI248 0 "register_operand" "=r")
12042         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   "TARGET_ABM || TARGET_BMI"
12045   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12046   [(set_attr "prefix_rep" "1")
12047    (set_attr "type" "bitmanip")
12048    (set_attr "mode" "<MODE>")])
12049
12050 ;; BMI instructions.
12051 (define_insn "*bmi_andn_<mode>"
12052   [(set (match_operand:SWI48 0 "register_operand" "=r")
12053         (and:SWI48
12054           (not:SWI48
12055             (match_operand:SWI48 1 "register_operand" "r"))
12056             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12057    (clobber (reg:CC FLAGS_REG))]
12058   "TARGET_BMI"
12059   "andn\t{%2, %1, %0|%0, %1, %2}"
12060   [(set_attr "type" "bitmanip")
12061    (set_attr "mode" "<MODE>")])
12062
12063 (define_insn "bmi_bextr_<mode>"
12064   [(set (match_operand:SWI48 0 "register_operand" "=r")
12065         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12066                        (match_operand:SWI48 2 "register_operand" "r")]
12067                        UNSPEC_BEXTR))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "TARGET_BMI"
12070   "bextr\t{%2, %1, %0|%0, %1, %2}"
12071   [(set_attr "type" "bitmanip")
12072    (set_attr "mode" "<MODE>")])
12073
12074 (define_insn "*bmi_blsi_<mode>"
12075   [(set (match_operand:SWI48 0 "register_operand" "=r")
12076         (and:SWI48
12077           (neg:SWI48
12078             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12079           (match_dup 1)))
12080    (clobber (reg:CC FLAGS_REG))]
12081   "TARGET_BMI"
12082   "blsi\t{%1, %0|%0, %1}"
12083   [(set_attr "type" "bitmanip")
12084    (set_attr "mode" "<MODE>")])
12085
12086 (define_insn "*bmi_blsmsk_<mode>"
12087   [(set (match_operand:SWI48 0 "register_operand" "=r")
12088         (xor:SWI48
12089           (plus:SWI48
12090             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12091             (const_int -1))
12092           (match_dup 1)))
12093    (clobber (reg:CC FLAGS_REG))]
12094   "TARGET_BMI"
12095   "blsmsk\t{%1, %0|%0, %1}"
12096   [(set_attr "type" "bitmanip")
12097    (set_attr "mode" "<MODE>")])
12098
12099 (define_insn "*bmi_blsr_<mode>"
12100   [(set (match_operand:SWI48 0 "register_operand" "=r")
12101         (and:SWI48
12102           (plus:SWI48
12103             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12104             (const_int -1))
12105           (match_dup 1)))
12106    (clobber (reg:CC FLAGS_REG))]
12107    "TARGET_BMI"
12108    "blsr\t{%1, %0|%0, %1}"
12109   [(set_attr "type" "bitmanip")
12110    (set_attr "mode" "<MODE>")])
12111
12112 ;; TBM instructions.
12113 (define_insn "tbm_bextri_<mode>"
12114   [(set (match_operand:SWI48 0 "register_operand" "=r")
12115         (zero_extract:SWI48
12116           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12117           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12118           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12119    (clobber (reg:CC FLAGS_REG))]
12120    "TARGET_TBM"
12121 {
12122   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12123   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12124 }
12125   [(set_attr "type" "bitmanip")
12126    (set_attr "mode" "<MODE>")])
12127
12128 (define_insn "*tbm_blcfill_<mode>"
12129   [(set (match_operand:SWI48 0 "register_operand" "=r")
12130         (and:SWI48
12131           (plus:SWI48
12132             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12133             (const_int 1))
12134           (match_dup 1)))
12135    (clobber (reg:CC FLAGS_REG))]
12136    "TARGET_TBM"
12137    "blcfill\t{%1, %0|%0, %1}"
12138   [(set_attr "type" "bitmanip")
12139    (set_attr "mode" "<MODE>")])
12140
12141 (define_insn "*tbm_blci_<mode>"
12142   [(set (match_operand:SWI48 0 "register_operand" "=r")
12143         (ior:SWI48
12144           (not:SWI48
12145             (plus:SWI48
12146               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12147               (const_int 1)))
12148           (match_dup 1)))
12149    (clobber (reg:CC FLAGS_REG))]
12150    "TARGET_TBM"
12151    "blci\t{%1, %0|%0, %1}"
12152   [(set_attr "type" "bitmanip")
12153    (set_attr "mode" "<MODE>")])
12154
12155 (define_insn "*tbm_blcic_<mode>"
12156   [(set (match_operand:SWI48 0 "register_operand" "=r")
12157         (and:SWI48
12158           (plus:SWI48
12159             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12160             (const_int 1))
12161           (not:SWI48
12162             (match_dup 1))))
12163    (clobber (reg:CC FLAGS_REG))]
12164    "TARGET_TBM"
12165    "blcic\t{%1, %0|%0, %1}"
12166   [(set_attr "type" "bitmanip")
12167    (set_attr "mode" "<MODE>")])
12168
12169 (define_insn "*tbm_blcmsk_<mode>"
12170   [(set (match_operand:SWI48 0 "register_operand" "=r")
12171         (xor:SWI48
12172           (plus:SWI48
12173             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12174             (const_int 1))
12175           (match_dup 1)))
12176    (clobber (reg:CC FLAGS_REG))]
12177    "TARGET_TBM"
12178    "blcmsk\t{%1, %0|%0, %1}"
12179   [(set_attr "type" "bitmanip")
12180    (set_attr "mode" "<MODE>")])
12181
12182 (define_insn "*tbm_blcs_<mode>"
12183   [(set (match_operand:SWI48 0 "register_operand" "=r")
12184         (ior:SWI48
12185           (plus:SWI48
12186             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12187             (const_int 1))
12188           (match_dup 1)))
12189    (clobber (reg:CC FLAGS_REG))]
12190    "TARGET_TBM"
12191    "blcs\t{%1, %0|%0, %1}"
12192   [(set_attr "type" "bitmanip")
12193    (set_attr "mode" "<MODE>")])
12194
12195 (define_insn "*tbm_blsfill_<mode>"
12196   [(set (match_operand:SWI48 0 "register_operand" "=r")
12197         (ior:SWI48
12198           (plus:SWI48
12199             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12200             (const_int -1))
12201           (match_dup 1)))
12202    (clobber (reg:CC FLAGS_REG))]
12203    "TARGET_TBM"
12204    "blsfill\t{%1, %0|%0, %1}"
12205   [(set_attr "type" "bitmanip")
12206    (set_attr "mode" "<MODE>")])
12207
12208 (define_insn "*tbm_blsic_<mode>"
12209   [(set (match_operand:SWI48 0 "register_operand" "=r")
12210         (ior:SWI48
12211           (plus:SWI48
12212             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12213             (const_int -1))
12214           (not:SWI48
12215             (match_dup 1))))
12216    (clobber (reg:CC FLAGS_REG))]
12217    "TARGET_TBM"
12218    "blsic\t{%1, %0|%0, %1}"
12219   [(set_attr "type" "bitmanip")
12220    (set_attr "mode" "<MODE>")])
12221
12222 (define_insn "*tbm_t1mskc_<mode>"
12223   [(set (match_operand:SWI48 0 "register_operand" "=r")
12224         (ior:SWI48
12225           (plus:SWI48
12226             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12227             (const_int 1))
12228           (not:SWI48
12229             (match_dup 1))))
12230    (clobber (reg:CC FLAGS_REG))]
12231    "TARGET_TBM"
12232    "t1mskc\t{%1, %0|%0, %1}"
12233   [(set_attr "type" "bitmanip")
12234    (set_attr "mode" "<MODE>")])
12235
12236 (define_insn "*tbm_tzmsk_<mode>"
12237   [(set (match_operand:SWI48 0 "register_operand" "=r")
12238         (and:SWI48
12239           (plus:SWI48
12240             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12241             (const_int -1))
12242           (not:SWI48
12243             (match_dup 1))))
12244    (clobber (reg:CC FLAGS_REG))]
12245    "TARGET_TBM"
12246    "tzmsk\t{%1, %0|%0, %1}"
12247   [(set_attr "type" "bitmanip")
12248    (set_attr "mode" "<MODE>")])
12249
12250 (define_insn "bsr_rex64"
12251   [(set (match_operand:DI 0 "register_operand" "=r")
12252         (minus:DI (const_int 63)
12253                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12254    (clobber (reg:CC FLAGS_REG))]
12255   "TARGET_64BIT"
12256   "bsr{q}\t{%1, %0|%0, %1}"
12257   [(set_attr "type" "alu1")
12258    (set_attr "prefix_0f" "1")
12259    (set_attr "mode" "DI")])
12260
12261 (define_insn "bsr"
12262   [(set (match_operand:SI 0 "register_operand" "=r")
12263         (minus:SI (const_int 31)
12264                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12265    (clobber (reg:CC FLAGS_REG))]
12266   ""
12267   "bsr{l}\t{%1, %0|%0, %1}"
12268   [(set_attr "type" "alu1")
12269    (set_attr "prefix_0f" "1")
12270    (set_attr "mode" "SI")])
12271
12272 (define_insn "*bsrhi"
12273   [(set (match_operand:HI 0 "register_operand" "=r")
12274         (minus:HI (const_int 15)
12275                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12276    (clobber (reg:CC FLAGS_REG))]
12277   ""
12278   "bsr{w}\t{%1, %0|%0, %1}"
12279   [(set_attr "type" "alu1")
12280    (set_attr "prefix_0f" "1")
12281    (set_attr "mode" "HI")])
12282
12283 (define_insn "popcount<mode>2"
12284   [(set (match_operand:SWI248 0 "register_operand" "=r")
12285         (popcount:SWI248
12286           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12287    (clobber (reg:CC FLAGS_REG))]
12288   "TARGET_POPCNT"
12289 {
12290 #if TARGET_MACHO
12291   return "popcnt\t{%1, %0|%0, %1}";
12292 #else
12293   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12294 #endif
12295 }
12296   [(set_attr "prefix_rep" "1")
12297    (set_attr "type" "bitmanip")
12298    (set_attr "mode" "<MODE>")])
12299
12300 (define_insn "*popcount<mode>2_cmp"
12301   [(set (reg FLAGS_REG)
12302         (compare
12303           (popcount:SWI248
12304             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12305           (const_int 0)))
12306    (set (match_operand:SWI248 0 "register_operand" "=r")
12307         (popcount:SWI248 (match_dup 1)))]
12308   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12309 {
12310 #if TARGET_MACHO
12311   return "popcnt\t{%1, %0|%0, %1}";
12312 #else
12313   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12314 #endif
12315 }
12316   [(set_attr "prefix_rep" "1")
12317    (set_attr "type" "bitmanip")
12318    (set_attr "mode" "<MODE>")])
12319
12320 (define_insn "*popcountsi2_cmp_zext"
12321   [(set (reg FLAGS_REG)
12322         (compare
12323           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12324           (const_int 0)))
12325    (set (match_operand:DI 0 "register_operand" "=r")
12326         (zero_extend:DI(popcount:SI (match_dup 1))))]
12327   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12328 {
12329 #if TARGET_MACHO
12330   return "popcnt\t{%1, %0|%0, %1}";
12331 #else
12332   return "popcnt{l}\t{%1, %0|%0, %1}";
12333 #endif
12334 }
12335   [(set_attr "prefix_rep" "1")
12336    (set_attr "type" "bitmanip")
12337    (set_attr "mode" "SI")])
12338
12339 (define_expand "bswap<mode>2"
12340   [(set (match_operand:SWI48 0 "register_operand" "")
12341         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12342   ""
12343 {
12344   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12345     {
12346       rtx x = operands[0];
12347
12348       emit_move_insn (x, operands[1]);
12349       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12350       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12351       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12352       DONE;
12353     }
12354 })
12355
12356 (define_insn "*bswap<mode>2_movbe"
12357   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12358         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12359   "TARGET_MOVBE
12360    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12361   "@
12362     bswap\t%0
12363     movbe\t{%1, %0|%0, %1}
12364     movbe\t{%1, %0|%0, %1}"
12365   [(set_attr "type" "bitmanip,imov,imov")
12366    (set_attr "modrm" "0,1,1")
12367    (set_attr "prefix_0f" "*,1,1")
12368    (set_attr "prefix_extra" "*,1,1")
12369    (set_attr "mode" "<MODE>")])
12370
12371 (define_insn "*bswap<mode>2_1"
12372   [(set (match_operand:SWI48 0 "register_operand" "=r")
12373         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12374   "TARGET_BSWAP"
12375   "bswap\t%0"
12376   [(set_attr "type" "bitmanip")
12377    (set_attr "modrm" "0")
12378    (set_attr "mode" "<MODE>")])
12379
12380 (define_insn "*bswaphi_lowpart_1"
12381   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12382         (bswap:HI (match_dup 0)))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12385   "@
12386     xchg{b}\t{%h0, %b0|%b0, %h0}
12387     rol{w}\t{$8, %0|%0, 8}"
12388   [(set_attr "length" "2,4")
12389    (set_attr "mode" "QI,HI")])
12390
12391 (define_insn "bswaphi_lowpart"
12392   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12393         (bswap:HI (match_dup 0)))
12394    (clobber (reg:CC FLAGS_REG))]
12395   ""
12396   "rol{w}\t{$8, %0|%0, 8}"
12397   [(set_attr "length" "4")
12398    (set_attr "mode" "HI")])
12399
12400 (define_expand "paritydi2"
12401   [(set (match_operand:DI 0 "register_operand" "")
12402         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12403   "! TARGET_POPCNT"
12404 {
12405   rtx scratch = gen_reg_rtx (QImode);
12406   rtx cond;
12407
12408   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12409                                 NULL_RTX, operands[1]));
12410
12411   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12412                          gen_rtx_REG (CCmode, FLAGS_REG),
12413                          const0_rtx);
12414   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12415
12416   if (TARGET_64BIT)
12417     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12418   else
12419     {
12420       rtx tmp = gen_reg_rtx (SImode);
12421
12422       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12423       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12424     }
12425   DONE;
12426 })
12427
12428 (define_expand "paritysi2"
12429   [(set (match_operand:SI 0 "register_operand" "")
12430         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12431   "! TARGET_POPCNT"
12432 {
12433   rtx scratch = gen_reg_rtx (QImode);
12434   rtx cond;
12435
12436   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12437
12438   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12439                          gen_rtx_REG (CCmode, FLAGS_REG),
12440                          const0_rtx);
12441   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12442
12443   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12444   DONE;
12445 })
12446
12447 (define_insn_and_split "paritydi2_cmp"
12448   [(set (reg:CC FLAGS_REG)
12449         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12450                    UNSPEC_PARITY))
12451    (clobber (match_scratch:DI 0 "=r"))
12452    (clobber (match_scratch:SI 1 "=&r"))
12453    (clobber (match_scratch:HI 2 "=Q"))]
12454   "! TARGET_POPCNT"
12455   "#"
12456   "&& reload_completed"
12457   [(parallel
12458      [(set (match_dup 1)
12459            (xor:SI (match_dup 1) (match_dup 4)))
12460       (clobber (reg:CC FLAGS_REG))])
12461    (parallel
12462      [(set (reg:CC FLAGS_REG)
12463            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12464       (clobber (match_dup 1))
12465       (clobber (match_dup 2))])]
12466 {
12467   operands[4] = gen_lowpart (SImode, operands[3]);
12468
12469   if (TARGET_64BIT)
12470     {
12471       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12472       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12473     }
12474   else
12475     operands[1] = gen_highpart (SImode, operands[3]);
12476 })
12477
12478 (define_insn_and_split "paritysi2_cmp"
12479   [(set (reg:CC FLAGS_REG)
12480         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12481                    UNSPEC_PARITY))
12482    (clobber (match_scratch:SI 0 "=r"))
12483    (clobber (match_scratch:HI 1 "=&Q"))]
12484   "! TARGET_POPCNT"
12485   "#"
12486   "&& reload_completed"
12487   [(parallel
12488      [(set (match_dup 1)
12489            (xor:HI (match_dup 1) (match_dup 3)))
12490       (clobber (reg:CC FLAGS_REG))])
12491    (parallel
12492      [(set (reg:CC FLAGS_REG)
12493            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12494       (clobber (match_dup 1))])]
12495 {
12496   operands[3] = gen_lowpart (HImode, operands[2]);
12497
12498   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12499   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12500 })
12501
12502 (define_insn "*parityhi2_cmp"
12503   [(set (reg:CC FLAGS_REG)
12504         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12505                    UNSPEC_PARITY))
12506    (clobber (match_scratch:HI 0 "=Q"))]
12507   "! TARGET_POPCNT"
12508   "xor{b}\t{%h0, %b0|%b0, %h0}"
12509   [(set_attr "length" "2")
12510    (set_attr "mode" "HI")])
12511 \f
12512 ;; Thread-local storage patterns for ELF.
12513 ;;
12514 ;; Note that these code sequences must appear exactly as shown
12515 ;; in order to allow linker relaxation.
12516
12517 (define_insn "*tls_global_dynamic_32_gnu"
12518   [(set (match_operand:SI 0 "register_operand" "=a")
12519         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12520                     (match_operand:SI 2 "tls_symbolic_operand" "")
12521                     (match_operand:SI 3 "call_insn_operand" "")]
12522                     UNSPEC_TLS_GD))
12523    (clobber (match_scratch:SI 4 "=d"))
12524    (clobber (match_scratch:SI 5 "=c"))
12525    (clobber (reg:CC FLAGS_REG))]
12526   "!TARGET_64BIT && TARGET_GNU_TLS"
12527   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12528   [(set_attr "type" "multi")
12529    (set_attr "length" "12")])
12530
12531 (define_expand "tls_global_dynamic_32"
12532   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12533                    (unspec:SI
12534                     [(match_dup 2)
12535                      (match_operand:SI 1 "tls_symbolic_operand" "")
12536                      (match_dup 3)]
12537                     UNSPEC_TLS_GD))
12538               (clobber (match_scratch:SI 4 ""))
12539               (clobber (match_scratch:SI 5 ""))
12540               (clobber (reg:CC FLAGS_REG))])]
12541   ""
12542 {
12543   if (flag_pic)
12544     operands[2] = pic_offset_table_rtx;
12545   else
12546     {
12547       operands[2] = gen_reg_rtx (Pmode);
12548       emit_insn (gen_set_got (operands[2]));
12549     }
12550   if (TARGET_GNU2_TLS)
12551     {
12552        emit_insn (gen_tls_dynamic_gnu2_32
12553                   (operands[0], operands[1], operands[2]));
12554        DONE;
12555     }
12556   operands[3] = ix86_tls_get_addr ();
12557 })
12558
12559 (define_insn "*tls_global_dynamic_64"
12560   [(set (match_operand:DI 0 "register_operand" "=a")
12561         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12562                  (match_operand:DI 3 "" "")))
12563    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12564               UNSPEC_TLS_GD)]
12565   "TARGET_64BIT"
12566   { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12567   [(set_attr "type" "multi")
12568    (set_attr "length" "16")])
12569
12570 (define_expand "tls_global_dynamic_64"
12571   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12572                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12573               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12574                          UNSPEC_TLS_GD)])]
12575   ""
12576 {
12577   if (TARGET_GNU2_TLS)
12578     {
12579        emit_insn (gen_tls_dynamic_gnu2_64
12580                   (operands[0], operands[1]));
12581        DONE;
12582     }
12583   operands[2] = ix86_tls_get_addr ();
12584 })
12585
12586 (define_insn "*tls_local_dynamic_base_32_gnu"
12587   [(set (match_operand:SI 0 "register_operand" "=a")
12588         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12589                     (match_operand:SI 2 "call_insn_operand" "")]
12590                    UNSPEC_TLS_LD_BASE))
12591    (clobber (match_scratch:SI 3 "=d"))
12592    (clobber (match_scratch:SI 4 "=c"))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "!TARGET_64BIT && TARGET_GNU_TLS"
12595   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12596   [(set_attr "type" "multi")
12597    (set_attr "length" "11")])
12598
12599 (define_expand "tls_local_dynamic_base_32"
12600   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12601                    (unspec:SI [(match_dup 1) (match_dup 2)]
12602                               UNSPEC_TLS_LD_BASE))
12603               (clobber (match_scratch:SI 3 ""))
12604               (clobber (match_scratch:SI 4 ""))
12605               (clobber (reg:CC FLAGS_REG))])]
12606   ""
12607 {
12608   if (flag_pic)
12609     operands[1] = pic_offset_table_rtx;
12610   else
12611     {
12612       operands[1] = gen_reg_rtx (Pmode);
12613       emit_insn (gen_set_got (operands[1]));
12614     }
12615   if (TARGET_GNU2_TLS)
12616     {
12617        emit_insn (gen_tls_dynamic_gnu2_32
12618                   (operands[0], ix86_tls_module_base (), operands[1]));
12619        DONE;
12620     }
12621   operands[2] = ix86_tls_get_addr ();
12622 })
12623
12624 (define_insn "*tls_local_dynamic_base_64"
12625   [(set (match_operand:DI 0 "register_operand" "=a")
12626         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12627                  (match_operand:DI 2 "" "")))
12628    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12629   "TARGET_64BIT"
12630   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12631   [(set_attr "type" "multi")
12632    (set_attr "length" "12")])
12633
12634 (define_expand "tls_local_dynamic_base_64"
12635   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12636                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12637               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12638   ""
12639 {
12640   if (TARGET_GNU2_TLS)
12641     {
12642        emit_insn (gen_tls_dynamic_gnu2_64
12643                   (operands[0], ix86_tls_module_base ()));
12644        DONE;
12645     }
12646   operands[1] = ix86_tls_get_addr ();
12647 })
12648
12649 ;; Local dynamic of a single variable is a lose.  Show combine how
12650 ;; to convert that back to global dynamic.
12651
12652 (define_insn_and_split "*tls_local_dynamic_32_once"
12653   [(set (match_operand:SI 0 "register_operand" "=a")
12654         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12655                              (match_operand:SI 2 "call_insn_operand" "")]
12656                             UNSPEC_TLS_LD_BASE)
12657                  (const:SI (unspec:SI
12658                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12659                             UNSPEC_DTPOFF))))
12660    (clobber (match_scratch:SI 4 "=d"))
12661    (clobber (match_scratch:SI 5 "=c"))
12662    (clobber (reg:CC FLAGS_REG))]
12663   ""
12664   "#"
12665   ""
12666   [(parallel [(set (match_dup 0)
12667                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12668                               UNSPEC_TLS_GD))
12669               (clobber (match_dup 4))
12670               (clobber (match_dup 5))
12671               (clobber (reg:CC FLAGS_REG))])])
12672
12673 ;; Segment register for the thread base ptr load
12674 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12675
12676 ;; Load and add the thread base pointer from %gs:0.
12677 (define_insn "*load_tp_<mode>"
12678   [(set (match_operand:P 0 "register_operand" "=r")
12679         (unspec:P [(const_int 0)] UNSPEC_TP))]
12680   ""
12681   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12682   [(set_attr "type" "imov")
12683    (set_attr "modrm" "0")
12684    (set_attr "length" "7")
12685    (set_attr "memory" "load")
12686    (set_attr "imm_disp" "false")])
12687
12688 (define_insn "*add_tp_<mode>"
12689   [(set (match_operand:P 0 "register_operand" "=r")
12690         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12691                 (match_operand:P 1 "register_operand" "0")))
12692    (clobber (reg:CC FLAGS_REG))]
12693   ""
12694   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12695   [(set_attr "type" "alu")
12696    (set_attr "modrm" "0")
12697    (set_attr "length" "7")
12698    (set_attr "memory" "load")
12699    (set_attr "imm_disp" "false")])
12700
12701 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12702 ;; %rax as destination of the initial executable code sequence.
12703 (define_insn "tls_initial_exec_64_sun"
12704   [(set (match_operand:DI 0 "register_operand" "=a")
12705         (unspec:DI
12706          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12707          UNSPEC_TLS_IE_SUN))
12708    (clobber (reg:CC FLAGS_REG))]
12709   "TARGET_64BIT && TARGET_SUN_TLS"
12710   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12711   [(set_attr "type" "multi")])
12712
12713 ;; GNU2 TLS patterns can be split.
12714
12715 (define_expand "tls_dynamic_gnu2_32"
12716   [(set (match_dup 3)
12717         (plus:SI (match_operand:SI 2 "register_operand" "")
12718                  (const:SI
12719                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12720                              UNSPEC_TLSDESC))))
12721    (parallel
12722     [(set (match_operand:SI 0 "register_operand" "")
12723           (unspec:SI [(match_dup 1) (match_dup 3)
12724                       (match_dup 2) (reg:SI SP_REG)]
12725                       UNSPEC_TLSDESC))
12726      (clobber (reg:CC FLAGS_REG))])]
12727   "!TARGET_64BIT && TARGET_GNU2_TLS"
12728 {
12729   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12730   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12731 })
12732
12733 (define_insn "*tls_dynamic_lea_32"
12734   [(set (match_operand:SI 0 "register_operand" "=r")
12735         (plus:SI (match_operand:SI 1 "register_operand" "b")
12736                  (const:SI
12737                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12738                               UNSPEC_TLSDESC))))]
12739   "!TARGET_64BIT && TARGET_GNU2_TLS"
12740   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12741   [(set_attr "type" "lea")
12742    (set_attr "mode" "SI")
12743    (set_attr "length" "6")
12744    (set_attr "length_address" "4")])
12745
12746 (define_insn "*tls_dynamic_call_32"
12747   [(set (match_operand:SI 0 "register_operand" "=a")
12748         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12749                     (match_operand:SI 2 "register_operand" "0")
12750                     ;; we have to make sure %ebx still points to the GOT
12751                     (match_operand:SI 3 "register_operand" "b")
12752                     (reg:SI SP_REG)]
12753                    UNSPEC_TLSDESC))
12754    (clobber (reg:CC FLAGS_REG))]
12755   "!TARGET_64BIT && TARGET_GNU2_TLS"
12756   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12757   [(set_attr "type" "call")
12758    (set_attr "length" "2")
12759    (set_attr "length_address" "0")])
12760
12761 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12762   [(set (match_operand:SI 0 "register_operand" "=&a")
12763         (plus:SI
12764          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12765                      (match_operand:SI 4 "" "")
12766                      (match_operand:SI 2 "register_operand" "b")
12767                      (reg:SI SP_REG)]
12768                     UNSPEC_TLSDESC)
12769          (const:SI (unspec:SI
12770                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12771                     UNSPEC_DTPOFF))))
12772    (clobber (reg:CC FLAGS_REG))]
12773   "!TARGET_64BIT && TARGET_GNU2_TLS"
12774   "#"
12775   ""
12776   [(set (match_dup 0) (match_dup 5))]
12777 {
12778   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12779   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12780 })
12781
12782 (define_expand "tls_dynamic_gnu2_64"
12783   [(set (match_dup 2)
12784         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12785                    UNSPEC_TLSDESC))
12786    (parallel
12787     [(set (match_operand:DI 0 "register_operand" "")
12788           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12789                      UNSPEC_TLSDESC))
12790      (clobber (reg:CC FLAGS_REG))])]
12791   "TARGET_64BIT && TARGET_GNU2_TLS"
12792 {
12793   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12794   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12795 })
12796
12797 (define_insn "*tls_dynamic_lea_64"
12798   [(set (match_operand:DI 0 "register_operand" "=r")
12799         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12800                    UNSPEC_TLSDESC))]
12801   "TARGET_64BIT && TARGET_GNU2_TLS"
12802   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12803   [(set_attr "type" "lea")
12804    (set_attr "mode" "DI")
12805    (set_attr "length" "7")
12806    (set_attr "length_address" "4")])
12807
12808 (define_insn "*tls_dynamic_call_64"
12809   [(set (match_operand:DI 0 "register_operand" "=a")
12810         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12811                     (match_operand:DI 2 "register_operand" "0")
12812                     (reg:DI SP_REG)]
12813                    UNSPEC_TLSDESC))
12814    (clobber (reg:CC FLAGS_REG))]
12815   "TARGET_64BIT && TARGET_GNU2_TLS"
12816   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12817   [(set_attr "type" "call")
12818    (set_attr "length" "2")
12819    (set_attr "length_address" "0")])
12820
12821 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12822   [(set (match_operand:DI 0 "register_operand" "=&a")
12823         (plus:DI
12824          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12825                      (match_operand:DI 3 "" "")
12826                      (reg:DI SP_REG)]
12827                     UNSPEC_TLSDESC)
12828          (const:DI (unspec:DI
12829                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12830                     UNSPEC_DTPOFF))))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "TARGET_64BIT && TARGET_GNU2_TLS"
12833   "#"
12834   ""
12835   [(set (match_dup 0) (match_dup 4))]
12836 {
12837   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12838   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12839 })
12840 \f
12841 ;; These patterns match the binary 387 instructions for addM3, subM3,
12842 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12843 ;; SFmode.  The first is the normal insn, the second the same insn but
12844 ;; with one operand a conversion, and the third the same insn but with
12845 ;; the other operand a conversion.  The conversion may be SFmode or
12846 ;; SImode if the target mode DFmode, but only SImode if the target mode
12847 ;; is SFmode.
12848
12849 ;; Gcc is slightly more smart about handling normal two address instructions
12850 ;; so use special patterns for add and mull.
12851
12852 (define_insn "*fop_<mode>_comm_mixed_avx"
12853   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12854         (match_operator:MODEF 3 "binary_fp_operator"
12855           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12856            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12857   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12858    && COMMUTATIVE_ARITH_P (operands[3])
12859    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12860   "* return output_387_binary_op (insn, operands);"
12861   [(set (attr "type")
12862         (if_then_else (eq_attr "alternative" "1")
12863            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12864               (const_string "ssemul")
12865               (const_string "sseadd"))
12866            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12867               (const_string "fmul")
12868               (const_string "fop"))))
12869    (set_attr "prefix" "orig,maybe_vex")
12870    (set_attr "mode" "<MODE>")])
12871
12872 (define_insn "*fop_<mode>_comm_mixed"
12873   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12874         (match_operator:MODEF 3 "binary_fp_operator"
12875           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12876            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12877   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12878    && COMMUTATIVE_ARITH_P (operands[3])
12879    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12880   "* return output_387_binary_op (insn, operands);"
12881   [(set (attr "type")
12882         (if_then_else (eq_attr "alternative" "1")
12883            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12884               (const_string "ssemul")
12885               (const_string "sseadd"))
12886            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12887               (const_string "fmul")
12888               (const_string "fop"))))
12889    (set_attr "mode" "<MODE>")])
12890
12891 (define_insn "*fop_<mode>_comm_avx"
12892   [(set (match_operand:MODEF 0 "register_operand" "=x")
12893         (match_operator:MODEF 3 "binary_fp_operator"
12894           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12895            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12896   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12897    && COMMUTATIVE_ARITH_P (operands[3])
12898    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12899   "* return output_387_binary_op (insn, operands);"
12900   [(set (attr "type")
12901         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12902            (const_string "ssemul")
12903            (const_string "sseadd")))
12904    (set_attr "prefix" "vex")
12905    (set_attr "mode" "<MODE>")])
12906
12907 (define_insn "*fop_<mode>_comm_sse"
12908   [(set (match_operand:MODEF 0 "register_operand" "=x")
12909         (match_operator:MODEF 3 "binary_fp_operator"
12910           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12911            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12912   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12913    && COMMUTATIVE_ARITH_P (operands[3])
12914    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12915   "* return output_387_binary_op (insn, operands);"
12916   [(set (attr "type")
12917         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12918            (const_string "ssemul")
12919            (const_string "sseadd")))
12920    (set_attr "mode" "<MODE>")])
12921
12922 (define_insn "*fop_<mode>_comm_i387"
12923   [(set (match_operand:MODEF 0 "register_operand" "=f")
12924         (match_operator:MODEF 3 "binary_fp_operator"
12925           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12926            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12927   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12928    && COMMUTATIVE_ARITH_P (operands[3])
12929    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12930   "* return output_387_binary_op (insn, operands);"
12931   [(set (attr "type")
12932         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12933            (const_string "fmul")
12934            (const_string "fop")))
12935    (set_attr "mode" "<MODE>")])
12936
12937 (define_insn "*fop_<mode>_1_mixed_avx"
12938   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12939         (match_operator:MODEF 3 "binary_fp_operator"
12940           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12941            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12942   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12943    && !COMMUTATIVE_ARITH_P (operands[3])
12944    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12945   "* return output_387_binary_op (insn, operands);"
12946   [(set (attr "type")
12947         (cond [(and (eq_attr "alternative" "2")
12948                     (match_operand:MODEF 3 "mult_operator" ""))
12949                  (const_string "ssemul")
12950                (and (eq_attr "alternative" "2")
12951                     (match_operand:MODEF 3 "div_operator" ""))
12952                  (const_string "ssediv")
12953                (eq_attr "alternative" "2")
12954                  (const_string "sseadd")
12955                (match_operand:MODEF 3 "mult_operator" "")
12956                  (const_string "fmul")
12957                (match_operand:MODEF 3 "div_operator" "")
12958                  (const_string "fdiv")
12959               ]
12960               (const_string "fop")))
12961    (set_attr "prefix" "orig,orig,maybe_vex")
12962    (set_attr "mode" "<MODE>")])
12963
12964 (define_insn "*fop_<mode>_1_mixed"
12965   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12966         (match_operator:MODEF 3 "binary_fp_operator"
12967           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12968            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12969   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12970    && !COMMUTATIVE_ARITH_P (operands[3])
12971    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12972   "* return output_387_binary_op (insn, operands);"
12973   [(set (attr "type")
12974         (cond [(and (eq_attr "alternative" "2")
12975                     (match_operand:MODEF 3 "mult_operator" ""))
12976                  (const_string "ssemul")
12977                (and (eq_attr "alternative" "2")
12978                     (match_operand:MODEF 3 "div_operator" ""))
12979                  (const_string "ssediv")
12980                (eq_attr "alternative" "2")
12981                  (const_string "sseadd")
12982                (match_operand:MODEF 3 "mult_operator" "")
12983                  (const_string "fmul")
12984                (match_operand:MODEF 3 "div_operator" "")
12985                  (const_string "fdiv")
12986               ]
12987               (const_string "fop")))
12988    (set_attr "mode" "<MODE>")])
12989
12990 (define_insn "*rcpsf2_sse"
12991   [(set (match_operand:SF 0 "register_operand" "=x")
12992         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12993                    UNSPEC_RCP))]
12994   "TARGET_SSE_MATH"
12995   "%vrcpss\t{%1, %d0|%d0, %1}"
12996   [(set_attr "type" "sse")
12997    (set_attr "atom_sse_attr" "rcp")
12998    (set_attr "prefix" "maybe_vex")
12999    (set_attr "mode" "SF")])
13000
13001 (define_insn "*fop_<mode>_1_avx"
13002   [(set (match_operand:MODEF 0 "register_operand" "=x")
13003         (match_operator:MODEF 3 "binary_fp_operator"
13004           [(match_operand:MODEF 1 "register_operand" "x")
13005            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13006   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13007    && !COMMUTATIVE_ARITH_P (operands[3])"
13008   "* return output_387_binary_op (insn, operands);"
13009   [(set (attr "type")
13010         (cond [(match_operand:MODEF 3 "mult_operator" "")
13011                  (const_string "ssemul")
13012                (match_operand:MODEF 3 "div_operator" "")
13013                  (const_string "ssediv")
13014               ]
13015               (const_string "sseadd")))
13016    (set_attr "prefix" "vex")
13017    (set_attr "mode" "<MODE>")])
13018
13019 (define_insn "*fop_<mode>_1_sse"
13020   [(set (match_operand:MODEF 0 "register_operand" "=x")
13021         (match_operator:MODEF 3 "binary_fp_operator"
13022           [(match_operand:MODEF 1 "register_operand" "0")
13023            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13024   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13025    && !COMMUTATIVE_ARITH_P (operands[3])"
13026   "* return output_387_binary_op (insn, operands);"
13027   [(set (attr "type")
13028         (cond [(match_operand:MODEF 3 "mult_operator" "")
13029                  (const_string "ssemul")
13030                (match_operand:MODEF 3 "div_operator" "")
13031                  (const_string "ssediv")
13032               ]
13033               (const_string "sseadd")))
13034    (set_attr "mode" "<MODE>")])
13035
13036 ;; This pattern is not fully shadowed by the pattern above.
13037 (define_insn "*fop_<mode>_1_i387"
13038   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13039         (match_operator:MODEF 3 "binary_fp_operator"
13040           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13041            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13042   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13043    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13044    && !COMMUTATIVE_ARITH_P (operands[3])
13045    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13046   "* return output_387_binary_op (insn, operands);"
13047   [(set (attr "type")
13048         (cond [(match_operand:MODEF 3 "mult_operator" "")
13049                  (const_string "fmul")
13050                (match_operand:MODEF 3 "div_operator" "")
13051                  (const_string "fdiv")
13052               ]
13053               (const_string "fop")))
13054    (set_attr "mode" "<MODE>")])
13055
13056 ;; ??? Add SSE splitters for these!
13057 (define_insn "*fop_<MODEF:mode>_2_i387"
13058   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13059         (match_operator:MODEF 3 "binary_fp_operator"
13060           [(float:MODEF
13061              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13062            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13063   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13064    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13065    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13066   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13067   [(set (attr "type")
13068         (cond [(match_operand:MODEF 3 "mult_operator" "")
13069                  (const_string "fmul")
13070                (match_operand:MODEF 3 "div_operator" "")
13071                  (const_string "fdiv")
13072               ]
13073               (const_string "fop")))
13074    (set_attr "fp_int_src" "true")
13075    (set_attr "mode" "<X87MODEI12:MODE>")])
13076
13077 (define_insn "*fop_<MODEF:mode>_3_i387"
13078   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13079         (match_operator:MODEF 3 "binary_fp_operator"
13080           [(match_operand:MODEF 1 "register_operand" "0,0")
13081            (float:MODEF
13082              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13083   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13084    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13085    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13086   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13087   [(set (attr "type")
13088         (cond [(match_operand:MODEF 3 "mult_operator" "")
13089                  (const_string "fmul")
13090                (match_operand:MODEF 3 "div_operator" "")
13091                  (const_string "fdiv")
13092               ]
13093               (const_string "fop")))
13094    (set_attr "fp_int_src" "true")
13095    (set_attr "mode" "<MODE>")])
13096
13097 (define_insn "*fop_df_4_i387"
13098   [(set (match_operand:DF 0 "register_operand" "=f,f")
13099         (match_operator:DF 3 "binary_fp_operator"
13100            [(float_extend:DF
13101              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13102             (match_operand:DF 2 "register_operand" "0,f")]))]
13103   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13104    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13105    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13106   "* return output_387_binary_op (insn, operands);"
13107   [(set (attr "type")
13108         (cond [(match_operand:DF 3 "mult_operator" "")
13109                  (const_string "fmul")
13110                (match_operand:DF 3 "div_operator" "")
13111                  (const_string "fdiv")
13112               ]
13113               (const_string "fop")))
13114    (set_attr "mode" "SF")])
13115
13116 (define_insn "*fop_df_5_i387"
13117   [(set (match_operand:DF 0 "register_operand" "=f,f")
13118         (match_operator:DF 3 "binary_fp_operator"
13119           [(match_operand:DF 1 "register_operand" "0,f")
13120            (float_extend:DF
13121             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13122   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13123    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13124   "* return output_387_binary_op (insn, operands);"
13125   [(set (attr "type")
13126         (cond [(match_operand:DF 3 "mult_operator" "")
13127                  (const_string "fmul")
13128                (match_operand:DF 3 "div_operator" "")
13129                  (const_string "fdiv")
13130               ]
13131               (const_string "fop")))
13132    (set_attr "mode" "SF")])
13133
13134 (define_insn "*fop_df_6_i387"
13135   [(set (match_operand:DF 0 "register_operand" "=f,f")
13136         (match_operator:DF 3 "binary_fp_operator"
13137           [(float_extend:DF
13138             (match_operand:SF 1 "register_operand" "0,f"))
13139            (float_extend:DF
13140             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13141   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13142    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13143   "* return output_387_binary_op (insn, operands);"
13144   [(set (attr "type")
13145         (cond [(match_operand:DF 3 "mult_operator" "")
13146                  (const_string "fmul")
13147                (match_operand:DF 3 "div_operator" "")
13148                  (const_string "fdiv")
13149               ]
13150               (const_string "fop")))
13151    (set_attr "mode" "SF")])
13152
13153 (define_insn "*fop_xf_comm_i387"
13154   [(set (match_operand:XF 0 "register_operand" "=f")
13155         (match_operator:XF 3 "binary_fp_operator"
13156                         [(match_operand:XF 1 "register_operand" "%0")
13157                          (match_operand:XF 2 "register_operand" "f")]))]
13158   "TARGET_80387
13159    && COMMUTATIVE_ARITH_P (operands[3])"
13160   "* return output_387_binary_op (insn, operands);"
13161   [(set (attr "type")
13162         (if_then_else (match_operand:XF 3 "mult_operator" "")
13163            (const_string "fmul")
13164            (const_string "fop")))
13165    (set_attr "mode" "XF")])
13166
13167 (define_insn "*fop_xf_1_i387"
13168   [(set (match_operand:XF 0 "register_operand" "=f,f")
13169         (match_operator:XF 3 "binary_fp_operator"
13170                         [(match_operand:XF 1 "register_operand" "0,f")
13171                          (match_operand:XF 2 "register_operand" "f,0")]))]
13172   "TARGET_80387
13173    && !COMMUTATIVE_ARITH_P (operands[3])"
13174   "* return output_387_binary_op (insn, operands);"
13175   [(set (attr "type")
13176         (cond [(match_operand:XF 3 "mult_operator" "")
13177                  (const_string "fmul")
13178                (match_operand:XF 3 "div_operator" "")
13179                  (const_string "fdiv")
13180               ]
13181               (const_string "fop")))
13182    (set_attr "mode" "XF")])
13183
13184 (define_insn "*fop_xf_2_i387"
13185   [(set (match_operand:XF 0 "register_operand" "=f,f")
13186         (match_operator:XF 3 "binary_fp_operator"
13187           [(float:XF
13188              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13189            (match_operand:XF 2 "register_operand" "0,0")]))]
13190   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13191   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13192   [(set (attr "type")
13193         (cond [(match_operand:XF 3 "mult_operator" "")
13194                  (const_string "fmul")
13195                (match_operand:XF 3 "div_operator" "")
13196                  (const_string "fdiv")
13197               ]
13198               (const_string "fop")))
13199    (set_attr "fp_int_src" "true")
13200    (set_attr "mode" "<MODE>")])
13201
13202 (define_insn "*fop_xf_3_i387"
13203   [(set (match_operand:XF 0 "register_operand" "=f,f")
13204         (match_operator:XF 3 "binary_fp_operator"
13205           [(match_operand:XF 1 "register_operand" "0,0")
13206            (float:XF
13207              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13208   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13209   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13210   [(set (attr "type")
13211         (cond [(match_operand:XF 3 "mult_operator" "")
13212                  (const_string "fmul")
13213                (match_operand:XF 3 "div_operator" "")
13214                  (const_string "fdiv")
13215               ]
13216               (const_string "fop")))
13217    (set_attr "fp_int_src" "true")
13218    (set_attr "mode" "<MODE>")])
13219
13220 (define_insn "*fop_xf_4_i387"
13221   [(set (match_operand:XF 0 "register_operand" "=f,f")
13222         (match_operator:XF 3 "binary_fp_operator"
13223            [(float_extend:XF
13224               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13225             (match_operand:XF 2 "register_operand" "0,f")]))]
13226   "TARGET_80387"
13227   "* return output_387_binary_op (insn, operands);"
13228   [(set (attr "type")
13229         (cond [(match_operand:XF 3 "mult_operator" "")
13230                  (const_string "fmul")
13231                (match_operand:XF 3 "div_operator" "")
13232                  (const_string "fdiv")
13233               ]
13234               (const_string "fop")))
13235    (set_attr "mode" "<MODE>")])
13236
13237 (define_insn "*fop_xf_5_i387"
13238   [(set (match_operand:XF 0 "register_operand" "=f,f")
13239         (match_operator:XF 3 "binary_fp_operator"
13240           [(match_operand:XF 1 "register_operand" "0,f")
13241            (float_extend:XF
13242              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13243   "TARGET_80387"
13244   "* return output_387_binary_op (insn, operands);"
13245   [(set (attr "type")
13246         (cond [(match_operand:XF 3 "mult_operator" "")
13247                  (const_string "fmul")
13248                (match_operand:XF 3 "div_operator" "")
13249                  (const_string "fdiv")
13250               ]
13251               (const_string "fop")))
13252    (set_attr "mode" "<MODE>")])
13253
13254 (define_insn "*fop_xf_6_i387"
13255   [(set (match_operand:XF 0 "register_operand" "=f,f")
13256         (match_operator:XF 3 "binary_fp_operator"
13257           [(float_extend:XF
13258              (match_operand:MODEF 1 "register_operand" "0,f"))
13259            (float_extend:XF
13260              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13261   "TARGET_80387"
13262   "* return output_387_binary_op (insn, operands);"
13263   [(set (attr "type")
13264         (cond [(match_operand:XF 3 "mult_operator" "")
13265                  (const_string "fmul")
13266                (match_operand:XF 3 "div_operator" "")
13267                  (const_string "fdiv")
13268               ]
13269               (const_string "fop")))
13270    (set_attr "mode" "<MODE>")])
13271
13272 (define_split
13273   [(set (match_operand 0 "register_operand" "")
13274         (match_operator 3 "binary_fp_operator"
13275            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13276             (match_operand 2 "register_operand" "")]))]
13277   "reload_completed
13278    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13279    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13280   [(const_int 0)]
13281 {
13282   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13283   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13284   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13285                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13286                                           GET_MODE (operands[3]),
13287                                           operands[4],
13288                                           operands[2])));
13289   ix86_free_from_memory (GET_MODE (operands[1]));
13290   DONE;
13291 })
13292
13293 (define_split
13294   [(set (match_operand 0 "register_operand" "")
13295         (match_operator 3 "binary_fp_operator"
13296            [(match_operand 1 "register_operand" "")
13297             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13298   "reload_completed
13299    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13300    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13301   [(const_int 0)]
13302 {
13303   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13304   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13305   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13306                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13307                                           GET_MODE (operands[3]),
13308                                           operands[1],
13309                                           operands[4])));
13310   ix86_free_from_memory (GET_MODE (operands[2]));
13311   DONE;
13312 })
13313 \f
13314 ;; FPU special functions.
13315
13316 ;; This pattern implements a no-op XFmode truncation for
13317 ;; all fancy i386 XFmode math functions.
13318
13319 (define_insn "truncxf<mode>2_i387_noop_unspec"
13320   [(set (match_operand:MODEF 0 "register_operand" "=f")
13321         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13322         UNSPEC_TRUNC_NOOP))]
13323   "TARGET_USE_FANCY_MATH_387"
13324   "* return output_387_reg_move (insn, operands);"
13325   [(set_attr "type" "fmov")
13326    (set_attr "mode" "<MODE>")])
13327
13328 (define_insn "sqrtxf2"
13329   [(set (match_operand:XF 0 "register_operand" "=f")
13330         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13331   "TARGET_USE_FANCY_MATH_387"
13332   "fsqrt"
13333   [(set_attr "type" "fpspc")
13334    (set_attr "mode" "XF")
13335    (set_attr "athlon_decode" "direct")
13336    (set_attr "amdfam10_decode" "direct")
13337    (set_attr "bdver1_decode" "direct")])
13338
13339 (define_insn "sqrt_extend<mode>xf2_i387"
13340   [(set (match_operand:XF 0 "register_operand" "=f")
13341         (sqrt:XF
13342           (float_extend:XF
13343             (match_operand:MODEF 1 "register_operand" "0"))))]
13344   "TARGET_USE_FANCY_MATH_387"
13345   "fsqrt"
13346   [(set_attr "type" "fpspc")
13347    (set_attr "mode" "XF")
13348    (set_attr "athlon_decode" "direct")
13349    (set_attr "amdfam10_decode" "direct")
13350    (set_attr "bdver1_decode" "direct")])
13351
13352 (define_insn "*rsqrtsf2_sse"
13353   [(set (match_operand:SF 0 "register_operand" "=x")
13354         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13355                    UNSPEC_RSQRT))]
13356   "TARGET_SSE_MATH"
13357   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13358   [(set_attr "type" "sse")
13359    (set_attr "atom_sse_attr" "rcp")
13360    (set_attr "prefix" "maybe_vex")
13361    (set_attr "mode" "SF")])
13362
13363 (define_expand "rsqrtsf2"
13364   [(set (match_operand:SF 0 "register_operand" "")
13365         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13366                    UNSPEC_RSQRT))]
13367   "TARGET_SSE_MATH"
13368 {
13369   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13370   DONE;
13371 })
13372
13373 (define_insn "*sqrt<mode>2_sse"
13374   [(set (match_operand:MODEF 0 "register_operand" "=x")
13375         (sqrt:MODEF
13376           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13377   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13378   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13379   [(set_attr "type" "sse")
13380    (set_attr "atom_sse_attr" "sqrt")
13381    (set_attr "prefix" "maybe_vex")
13382    (set_attr "mode" "<MODE>")
13383    (set_attr "athlon_decode" "*")
13384    (set_attr "amdfam10_decode" "*")
13385    (set_attr "bdver1_decode" "*")])
13386
13387 (define_expand "sqrt<mode>2"
13388   [(set (match_operand:MODEF 0 "register_operand" "")
13389         (sqrt:MODEF
13390           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13391   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13392    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13393 {
13394   if (<MODE>mode == SFmode
13395       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13396       && flag_finite_math_only && !flag_trapping_math
13397       && flag_unsafe_math_optimizations)
13398     {
13399       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13400       DONE;
13401     }
13402
13403   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13404     {
13405       rtx op0 = gen_reg_rtx (XFmode);
13406       rtx op1 = force_reg (<MODE>mode, operands[1]);
13407
13408       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13409       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13410       DONE;
13411    }
13412 })
13413
13414 (define_insn "fpremxf4_i387"
13415   [(set (match_operand:XF 0 "register_operand" "=f")
13416         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13417                     (match_operand:XF 3 "register_operand" "1")]
13418                    UNSPEC_FPREM_F))
13419    (set (match_operand:XF 1 "register_operand" "=u")
13420         (unspec:XF [(match_dup 2) (match_dup 3)]
13421                    UNSPEC_FPREM_U))
13422    (set (reg:CCFP FPSR_REG)
13423         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13424                      UNSPEC_C2_FLAG))]
13425   "TARGET_USE_FANCY_MATH_387"
13426   "fprem"
13427   [(set_attr "type" "fpspc")
13428    (set_attr "mode" "XF")])
13429
13430 (define_expand "fmodxf3"
13431   [(use (match_operand:XF 0 "register_operand" ""))
13432    (use (match_operand:XF 1 "general_operand" ""))
13433    (use (match_operand:XF 2 "general_operand" ""))]
13434   "TARGET_USE_FANCY_MATH_387"
13435 {
13436   rtx label = gen_label_rtx ();
13437
13438   rtx op1 = gen_reg_rtx (XFmode);
13439   rtx op2 = gen_reg_rtx (XFmode);
13440
13441   emit_move_insn (op2, operands[2]);
13442   emit_move_insn (op1, operands[1]);
13443
13444   emit_label (label);
13445   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13446   ix86_emit_fp_unordered_jump (label);
13447   LABEL_NUSES (label) = 1;
13448
13449   emit_move_insn (operands[0], op1);
13450   DONE;
13451 })
13452
13453 (define_expand "fmod<mode>3"
13454   [(use (match_operand:MODEF 0 "register_operand" ""))
13455    (use (match_operand:MODEF 1 "general_operand" ""))
13456    (use (match_operand:MODEF 2 "general_operand" ""))]
13457   "TARGET_USE_FANCY_MATH_387"
13458 {
13459   rtx (*gen_truncxf) (rtx, rtx);
13460
13461   rtx label = gen_label_rtx ();
13462
13463   rtx op1 = gen_reg_rtx (XFmode);
13464   rtx op2 = gen_reg_rtx (XFmode);
13465
13466   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13467   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13468
13469   emit_label (label);
13470   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13471   ix86_emit_fp_unordered_jump (label);
13472   LABEL_NUSES (label) = 1;
13473
13474   /* Truncate the result properly for strict SSE math.  */
13475   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13476       && !TARGET_MIX_SSE_I387)
13477     gen_truncxf = gen_truncxf<mode>2;
13478   else
13479     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13480
13481   emit_insn (gen_truncxf (operands[0], op1));
13482   DONE;
13483 })
13484
13485 (define_insn "fprem1xf4_i387"
13486   [(set (match_operand:XF 0 "register_operand" "=f")
13487         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13488                     (match_operand:XF 3 "register_operand" "1")]
13489                    UNSPEC_FPREM1_F))
13490    (set (match_operand:XF 1 "register_operand" "=u")
13491         (unspec:XF [(match_dup 2) (match_dup 3)]
13492                    UNSPEC_FPREM1_U))
13493    (set (reg:CCFP FPSR_REG)
13494         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13495                      UNSPEC_C2_FLAG))]
13496   "TARGET_USE_FANCY_MATH_387"
13497   "fprem1"
13498   [(set_attr "type" "fpspc")
13499    (set_attr "mode" "XF")])
13500
13501 (define_expand "remainderxf3"
13502   [(use (match_operand:XF 0 "register_operand" ""))
13503    (use (match_operand:XF 1 "general_operand" ""))
13504    (use (match_operand:XF 2 "general_operand" ""))]
13505   "TARGET_USE_FANCY_MATH_387"
13506 {
13507   rtx label = gen_label_rtx ();
13508
13509   rtx op1 = gen_reg_rtx (XFmode);
13510   rtx op2 = gen_reg_rtx (XFmode);
13511
13512   emit_move_insn (op2, operands[2]);
13513   emit_move_insn (op1, operands[1]);
13514
13515   emit_label (label);
13516   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13517   ix86_emit_fp_unordered_jump (label);
13518   LABEL_NUSES (label) = 1;
13519
13520   emit_move_insn (operands[0], op1);
13521   DONE;
13522 })
13523
13524 (define_expand "remainder<mode>3"
13525   [(use (match_operand:MODEF 0 "register_operand" ""))
13526    (use (match_operand:MODEF 1 "general_operand" ""))
13527    (use (match_operand:MODEF 2 "general_operand" ""))]
13528   "TARGET_USE_FANCY_MATH_387"
13529 {
13530   rtx (*gen_truncxf) (rtx, rtx);
13531
13532   rtx label = gen_label_rtx ();
13533
13534   rtx op1 = gen_reg_rtx (XFmode);
13535   rtx op2 = gen_reg_rtx (XFmode);
13536
13537   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13538   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13539
13540   emit_label (label);
13541
13542   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13543   ix86_emit_fp_unordered_jump (label);
13544   LABEL_NUSES (label) = 1;
13545
13546   /* Truncate the result properly for strict SSE math.  */
13547   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13548       && !TARGET_MIX_SSE_I387)
13549     gen_truncxf = gen_truncxf<mode>2;
13550   else
13551     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13552
13553   emit_insn (gen_truncxf (operands[0], op1));
13554   DONE;
13555 })
13556
13557 (define_insn "*sinxf2_i387"
13558   [(set (match_operand:XF 0 "register_operand" "=f")
13559         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13560   "TARGET_USE_FANCY_MATH_387
13561    && flag_unsafe_math_optimizations"
13562   "fsin"
13563   [(set_attr "type" "fpspc")
13564    (set_attr "mode" "XF")])
13565
13566 (define_insn "*sin_extend<mode>xf2_i387"
13567   [(set (match_operand:XF 0 "register_operand" "=f")
13568         (unspec:XF [(float_extend:XF
13569                       (match_operand:MODEF 1 "register_operand" "0"))]
13570                    UNSPEC_SIN))]
13571   "TARGET_USE_FANCY_MATH_387
13572    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13573        || TARGET_MIX_SSE_I387)
13574    && flag_unsafe_math_optimizations"
13575   "fsin"
13576   [(set_attr "type" "fpspc")
13577    (set_attr "mode" "XF")])
13578
13579 (define_insn "*cosxf2_i387"
13580   [(set (match_operand:XF 0 "register_operand" "=f")
13581         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13582   "TARGET_USE_FANCY_MATH_387
13583    && flag_unsafe_math_optimizations"
13584   "fcos"
13585   [(set_attr "type" "fpspc")
13586    (set_attr "mode" "XF")])
13587
13588 (define_insn "*cos_extend<mode>xf2_i387"
13589   [(set (match_operand:XF 0 "register_operand" "=f")
13590         (unspec:XF [(float_extend:XF
13591                       (match_operand:MODEF 1 "register_operand" "0"))]
13592                    UNSPEC_COS))]
13593   "TARGET_USE_FANCY_MATH_387
13594    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13595        || TARGET_MIX_SSE_I387)
13596    && flag_unsafe_math_optimizations"
13597   "fcos"
13598   [(set_attr "type" "fpspc")
13599    (set_attr "mode" "XF")])
13600
13601 ;; When sincos pattern is defined, sin and cos builtin functions will be
13602 ;; expanded to sincos pattern with one of its outputs left unused.
13603 ;; CSE pass will figure out if two sincos patterns can be combined,
13604 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13605 ;; depending on the unused output.
13606
13607 (define_insn "sincosxf3"
13608   [(set (match_operand:XF 0 "register_operand" "=f")
13609         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13610                    UNSPEC_SINCOS_COS))
13611    (set (match_operand:XF 1 "register_operand" "=u")
13612         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13613   "TARGET_USE_FANCY_MATH_387
13614    && flag_unsafe_math_optimizations"
13615   "fsincos"
13616   [(set_attr "type" "fpspc")
13617    (set_attr "mode" "XF")])
13618
13619 (define_split
13620   [(set (match_operand:XF 0 "register_operand" "")
13621         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13622                    UNSPEC_SINCOS_COS))
13623    (set (match_operand:XF 1 "register_operand" "")
13624         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13625   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13626    && !(reload_completed || reload_in_progress)"
13627   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13628
13629 (define_split
13630   [(set (match_operand:XF 0 "register_operand" "")
13631         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13632                    UNSPEC_SINCOS_COS))
13633    (set (match_operand:XF 1 "register_operand" "")
13634         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13635   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13636    && !(reload_completed || reload_in_progress)"
13637   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13638
13639 (define_insn "sincos_extend<mode>xf3_i387"
13640   [(set (match_operand:XF 0 "register_operand" "=f")
13641         (unspec:XF [(float_extend:XF
13642                       (match_operand:MODEF 2 "register_operand" "0"))]
13643                    UNSPEC_SINCOS_COS))
13644    (set (match_operand:XF 1 "register_operand" "=u")
13645         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13646   "TARGET_USE_FANCY_MATH_387
13647    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13648        || TARGET_MIX_SSE_I387)
13649    && flag_unsafe_math_optimizations"
13650   "fsincos"
13651   [(set_attr "type" "fpspc")
13652    (set_attr "mode" "XF")])
13653
13654 (define_split
13655   [(set (match_operand:XF 0 "register_operand" "")
13656         (unspec:XF [(float_extend:XF
13657                       (match_operand:MODEF 2 "register_operand" ""))]
13658                    UNSPEC_SINCOS_COS))
13659    (set (match_operand:XF 1 "register_operand" "")
13660         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13661   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13662    && !(reload_completed || reload_in_progress)"
13663   [(set (match_dup 1)
13664         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13665
13666 (define_split
13667   [(set (match_operand:XF 0 "register_operand" "")
13668         (unspec:XF [(float_extend:XF
13669                       (match_operand:MODEF 2 "register_operand" ""))]
13670                    UNSPEC_SINCOS_COS))
13671    (set (match_operand:XF 1 "register_operand" "")
13672         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13673   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13674    && !(reload_completed || reload_in_progress)"
13675   [(set (match_dup 0)
13676         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13677
13678 (define_expand "sincos<mode>3"
13679   [(use (match_operand:MODEF 0 "register_operand" ""))
13680    (use (match_operand:MODEF 1 "register_operand" ""))
13681    (use (match_operand:MODEF 2 "register_operand" ""))]
13682   "TARGET_USE_FANCY_MATH_387
13683    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13684        || TARGET_MIX_SSE_I387)
13685    && flag_unsafe_math_optimizations"
13686 {
13687   rtx op0 = gen_reg_rtx (XFmode);
13688   rtx op1 = gen_reg_rtx (XFmode);
13689
13690   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13691   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13692   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13693   DONE;
13694 })
13695
13696 (define_insn "fptanxf4_i387"
13697   [(set (match_operand:XF 0 "register_operand" "=f")
13698         (match_operand:XF 3 "const_double_operand" "F"))
13699    (set (match_operand:XF 1 "register_operand" "=u")
13700         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13701                    UNSPEC_TAN))]
13702   "TARGET_USE_FANCY_MATH_387
13703    && flag_unsafe_math_optimizations
13704    && standard_80387_constant_p (operands[3]) == 2"
13705   "fptan"
13706   [(set_attr "type" "fpspc")
13707    (set_attr "mode" "XF")])
13708
13709 (define_insn "fptan_extend<mode>xf4_i387"
13710   [(set (match_operand:MODEF 0 "register_operand" "=f")
13711         (match_operand:MODEF 3 "const_double_operand" "F"))
13712    (set (match_operand:XF 1 "register_operand" "=u")
13713         (unspec:XF [(float_extend:XF
13714                       (match_operand:MODEF 2 "register_operand" "0"))]
13715                    UNSPEC_TAN))]
13716   "TARGET_USE_FANCY_MATH_387
13717    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13718        || TARGET_MIX_SSE_I387)
13719    && flag_unsafe_math_optimizations
13720    && standard_80387_constant_p (operands[3]) == 2"
13721   "fptan"
13722   [(set_attr "type" "fpspc")
13723    (set_attr "mode" "XF")])
13724
13725 (define_expand "tanxf2"
13726   [(use (match_operand:XF 0 "register_operand" ""))
13727    (use (match_operand:XF 1 "register_operand" ""))]
13728   "TARGET_USE_FANCY_MATH_387
13729    && flag_unsafe_math_optimizations"
13730 {
13731   rtx one = gen_reg_rtx (XFmode);
13732   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13733
13734   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13735   DONE;
13736 })
13737
13738 (define_expand "tan<mode>2"
13739   [(use (match_operand:MODEF 0 "register_operand" ""))
13740    (use (match_operand:MODEF 1 "register_operand" ""))]
13741   "TARGET_USE_FANCY_MATH_387
13742    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13743        || TARGET_MIX_SSE_I387)
13744    && flag_unsafe_math_optimizations"
13745 {
13746   rtx op0 = gen_reg_rtx (XFmode);
13747
13748   rtx one = gen_reg_rtx (<MODE>mode);
13749   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13750
13751   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13752                                              operands[1], op2));
13753   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13754   DONE;
13755 })
13756
13757 (define_insn "*fpatanxf3_i387"
13758   [(set (match_operand:XF 0 "register_operand" "=f")
13759         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13760                     (match_operand:XF 2 "register_operand" "u")]
13761                    UNSPEC_FPATAN))
13762    (clobber (match_scratch:XF 3 "=2"))]
13763   "TARGET_USE_FANCY_MATH_387
13764    && flag_unsafe_math_optimizations"
13765   "fpatan"
13766   [(set_attr "type" "fpspc")
13767    (set_attr "mode" "XF")])
13768
13769 (define_insn "fpatan_extend<mode>xf3_i387"
13770   [(set (match_operand:XF 0 "register_operand" "=f")
13771         (unspec:XF [(float_extend:XF
13772                       (match_operand:MODEF 1 "register_operand" "0"))
13773                     (float_extend:XF
13774                       (match_operand:MODEF 2 "register_operand" "u"))]
13775                    UNSPEC_FPATAN))
13776    (clobber (match_scratch:XF 3 "=2"))]
13777   "TARGET_USE_FANCY_MATH_387
13778    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13779        || TARGET_MIX_SSE_I387)
13780    && flag_unsafe_math_optimizations"
13781   "fpatan"
13782   [(set_attr "type" "fpspc")
13783    (set_attr "mode" "XF")])
13784
13785 (define_expand "atan2xf3"
13786   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13787                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13788                                (match_operand:XF 1 "register_operand" "")]
13789                               UNSPEC_FPATAN))
13790               (clobber (match_scratch:XF 3 ""))])]
13791   "TARGET_USE_FANCY_MATH_387
13792    && flag_unsafe_math_optimizations")
13793
13794 (define_expand "atan2<mode>3"
13795   [(use (match_operand:MODEF 0 "register_operand" ""))
13796    (use (match_operand:MODEF 1 "register_operand" ""))
13797    (use (match_operand:MODEF 2 "register_operand" ""))]
13798   "TARGET_USE_FANCY_MATH_387
13799    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13800        || TARGET_MIX_SSE_I387)
13801    && flag_unsafe_math_optimizations"
13802 {
13803   rtx op0 = gen_reg_rtx (XFmode);
13804
13805   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13806   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13807   DONE;
13808 })
13809
13810 (define_expand "atanxf2"
13811   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13812                    (unspec:XF [(match_dup 2)
13813                                (match_operand:XF 1 "register_operand" "")]
13814                               UNSPEC_FPATAN))
13815               (clobber (match_scratch:XF 3 ""))])]
13816   "TARGET_USE_FANCY_MATH_387
13817    && flag_unsafe_math_optimizations"
13818 {
13819   operands[2] = gen_reg_rtx (XFmode);
13820   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13821 })
13822
13823 (define_expand "atan<mode>2"
13824   [(use (match_operand:MODEF 0 "register_operand" ""))
13825    (use (match_operand:MODEF 1 "register_operand" ""))]
13826   "TARGET_USE_FANCY_MATH_387
13827    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828        || TARGET_MIX_SSE_I387)
13829    && flag_unsafe_math_optimizations"
13830 {
13831   rtx op0 = gen_reg_rtx (XFmode);
13832
13833   rtx op2 = gen_reg_rtx (<MODE>mode);
13834   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13835
13836   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13837   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13838   DONE;
13839 })
13840
13841 (define_expand "asinxf2"
13842   [(set (match_dup 2)
13843         (mult:XF (match_operand:XF 1 "register_operand" "")
13844                  (match_dup 1)))
13845    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13846    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13847    (parallel [(set (match_operand:XF 0 "register_operand" "")
13848                    (unspec:XF [(match_dup 5) (match_dup 1)]
13849                               UNSPEC_FPATAN))
13850               (clobber (match_scratch:XF 6 ""))])]
13851   "TARGET_USE_FANCY_MATH_387
13852    && flag_unsafe_math_optimizations"
13853 {
13854   int i;
13855
13856   if (optimize_insn_for_size_p ())
13857     FAIL;
13858
13859   for (i = 2; i < 6; i++)
13860     operands[i] = gen_reg_rtx (XFmode);
13861
13862   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13863 })
13864
13865 (define_expand "asin<mode>2"
13866   [(use (match_operand:MODEF 0 "register_operand" ""))
13867    (use (match_operand:MODEF 1 "general_operand" ""))]
13868  "TARGET_USE_FANCY_MATH_387
13869    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13870        || TARGET_MIX_SSE_I387)
13871    && flag_unsafe_math_optimizations"
13872 {
13873   rtx op0 = gen_reg_rtx (XFmode);
13874   rtx op1 = gen_reg_rtx (XFmode);
13875
13876   if (optimize_insn_for_size_p ())
13877     FAIL;
13878
13879   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13880   emit_insn (gen_asinxf2 (op0, op1));
13881   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13882   DONE;
13883 })
13884
13885 (define_expand "acosxf2"
13886   [(set (match_dup 2)
13887         (mult:XF (match_operand:XF 1 "register_operand" "")
13888                  (match_dup 1)))
13889    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13890    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13891    (parallel [(set (match_operand:XF 0 "register_operand" "")
13892                    (unspec:XF [(match_dup 1) (match_dup 5)]
13893                               UNSPEC_FPATAN))
13894               (clobber (match_scratch:XF 6 ""))])]
13895   "TARGET_USE_FANCY_MATH_387
13896    && flag_unsafe_math_optimizations"
13897 {
13898   int i;
13899
13900   if (optimize_insn_for_size_p ())
13901     FAIL;
13902
13903   for (i = 2; i < 6; i++)
13904     operands[i] = gen_reg_rtx (XFmode);
13905
13906   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13907 })
13908
13909 (define_expand "acos<mode>2"
13910   [(use (match_operand:MODEF 0 "register_operand" ""))
13911    (use (match_operand:MODEF 1 "general_operand" ""))]
13912  "TARGET_USE_FANCY_MATH_387
13913    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914        || TARGET_MIX_SSE_I387)
13915    && flag_unsafe_math_optimizations"
13916 {
13917   rtx op0 = gen_reg_rtx (XFmode);
13918   rtx op1 = gen_reg_rtx (XFmode);
13919
13920   if (optimize_insn_for_size_p ())
13921     FAIL;
13922
13923   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13924   emit_insn (gen_acosxf2 (op0, op1));
13925   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13926   DONE;
13927 })
13928
13929 (define_insn "fyl2xxf3_i387"
13930   [(set (match_operand:XF 0 "register_operand" "=f")
13931         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13932                     (match_operand:XF 2 "register_operand" "u")]
13933                    UNSPEC_FYL2X))
13934    (clobber (match_scratch:XF 3 "=2"))]
13935   "TARGET_USE_FANCY_MATH_387
13936    && flag_unsafe_math_optimizations"
13937   "fyl2x"
13938   [(set_attr "type" "fpspc")
13939    (set_attr "mode" "XF")])
13940
13941 (define_insn "fyl2x_extend<mode>xf3_i387"
13942   [(set (match_operand:XF 0 "register_operand" "=f")
13943         (unspec:XF [(float_extend:XF
13944                       (match_operand:MODEF 1 "register_operand" "0"))
13945                     (match_operand:XF 2 "register_operand" "u")]
13946                    UNSPEC_FYL2X))
13947    (clobber (match_scratch:XF 3 "=2"))]
13948   "TARGET_USE_FANCY_MATH_387
13949    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13950        || TARGET_MIX_SSE_I387)
13951    && flag_unsafe_math_optimizations"
13952   "fyl2x"
13953   [(set_attr "type" "fpspc")
13954    (set_attr "mode" "XF")])
13955
13956 (define_expand "logxf2"
13957   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13958                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13959                                (match_dup 2)] UNSPEC_FYL2X))
13960               (clobber (match_scratch:XF 3 ""))])]
13961   "TARGET_USE_FANCY_MATH_387
13962    && flag_unsafe_math_optimizations"
13963 {
13964   operands[2] = gen_reg_rtx (XFmode);
13965   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13966 })
13967
13968 (define_expand "log<mode>2"
13969   [(use (match_operand:MODEF 0 "register_operand" ""))
13970    (use (match_operand:MODEF 1 "register_operand" ""))]
13971   "TARGET_USE_FANCY_MATH_387
13972    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13973        || TARGET_MIX_SSE_I387)
13974    && flag_unsafe_math_optimizations"
13975 {
13976   rtx op0 = gen_reg_rtx (XFmode);
13977
13978   rtx op2 = gen_reg_rtx (XFmode);
13979   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13980
13981   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13982   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13983   DONE;
13984 })
13985
13986 (define_expand "log10xf2"
13987   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13988                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13989                                (match_dup 2)] UNSPEC_FYL2X))
13990               (clobber (match_scratch:XF 3 ""))])]
13991   "TARGET_USE_FANCY_MATH_387
13992    && flag_unsafe_math_optimizations"
13993 {
13994   operands[2] = gen_reg_rtx (XFmode);
13995   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13996 })
13997
13998 (define_expand "log10<mode>2"
13999   [(use (match_operand:MODEF 0 "register_operand" ""))
14000    (use (match_operand:MODEF 1 "register_operand" ""))]
14001   "TARGET_USE_FANCY_MATH_387
14002    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14003        || TARGET_MIX_SSE_I387)
14004    && flag_unsafe_math_optimizations"
14005 {
14006   rtx op0 = gen_reg_rtx (XFmode);
14007
14008   rtx op2 = gen_reg_rtx (XFmode);
14009   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14010
14011   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14012   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14013   DONE;
14014 })
14015
14016 (define_expand "log2xf2"
14017   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14018                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14019                                (match_dup 2)] UNSPEC_FYL2X))
14020               (clobber (match_scratch:XF 3 ""))])]
14021   "TARGET_USE_FANCY_MATH_387
14022    && flag_unsafe_math_optimizations"
14023 {
14024   operands[2] = gen_reg_rtx (XFmode);
14025   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14026 })
14027
14028 (define_expand "log2<mode>2"
14029   [(use (match_operand:MODEF 0 "register_operand" ""))
14030    (use (match_operand:MODEF 1 "register_operand" ""))]
14031   "TARGET_USE_FANCY_MATH_387
14032    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14033        || TARGET_MIX_SSE_I387)
14034    && flag_unsafe_math_optimizations"
14035 {
14036   rtx op0 = gen_reg_rtx (XFmode);
14037
14038   rtx op2 = gen_reg_rtx (XFmode);
14039   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14040
14041   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14042   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14043   DONE;
14044 })
14045
14046 (define_insn "fyl2xp1xf3_i387"
14047   [(set (match_operand:XF 0 "register_operand" "=f")
14048         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14049                     (match_operand:XF 2 "register_operand" "u")]
14050                    UNSPEC_FYL2XP1))
14051    (clobber (match_scratch:XF 3 "=2"))]
14052   "TARGET_USE_FANCY_MATH_387
14053    && flag_unsafe_math_optimizations"
14054   "fyl2xp1"
14055   [(set_attr "type" "fpspc")
14056    (set_attr "mode" "XF")])
14057
14058 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14059   [(set (match_operand:XF 0 "register_operand" "=f")
14060         (unspec:XF [(float_extend:XF
14061                       (match_operand:MODEF 1 "register_operand" "0"))
14062                     (match_operand:XF 2 "register_operand" "u")]
14063                    UNSPEC_FYL2XP1))
14064    (clobber (match_scratch:XF 3 "=2"))]
14065   "TARGET_USE_FANCY_MATH_387
14066    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14067        || TARGET_MIX_SSE_I387)
14068    && flag_unsafe_math_optimizations"
14069   "fyl2xp1"
14070   [(set_attr "type" "fpspc")
14071    (set_attr "mode" "XF")])
14072
14073 (define_expand "log1pxf2"
14074   [(use (match_operand:XF 0 "register_operand" ""))
14075    (use (match_operand:XF 1 "register_operand" ""))]
14076   "TARGET_USE_FANCY_MATH_387
14077    && flag_unsafe_math_optimizations"
14078 {
14079   if (optimize_insn_for_size_p ())
14080     FAIL;
14081
14082   ix86_emit_i387_log1p (operands[0], operands[1]);
14083   DONE;
14084 })
14085
14086 (define_expand "log1p<mode>2"
14087   [(use (match_operand:MODEF 0 "register_operand" ""))
14088    (use (match_operand:MODEF 1 "register_operand" ""))]
14089   "TARGET_USE_FANCY_MATH_387
14090    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14091        || TARGET_MIX_SSE_I387)
14092    && flag_unsafe_math_optimizations"
14093 {
14094   rtx op0;
14095
14096   if (optimize_insn_for_size_p ())
14097     FAIL;
14098
14099   op0 = gen_reg_rtx (XFmode);
14100
14101   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14102
14103   ix86_emit_i387_log1p (op0, operands[1]);
14104   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14105   DONE;
14106 })
14107
14108 (define_insn "fxtractxf3_i387"
14109   [(set (match_operand:XF 0 "register_operand" "=f")
14110         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14111                    UNSPEC_XTRACT_FRACT))
14112    (set (match_operand:XF 1 "register_operand" "=u")
14113         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14114   "TARGET_USE_FANCY_MATH_387
14115    && flag_unsafe_math_optimizations"
14116   "fxtract"
14117   [(set_attr "type" "fpspc")
14118    (set_attr "mode" "XF")])
14119
14120 (define_insn "fxtract_extend<mode>xf3_i387"
14121   [(set (match_operand:XF 0 "register_operand" "=f")
14122         (unspec:XF [(float_extend:XF
14123                       (match_operand:MODEF 2 "register_operand" "0"))]
14124                    UNSPEC_XTRACT_FRACT))
14125    (set (match_operand:XF 1 "register_operand" "=u")
14126         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14127   "TARGET_USE_FANCY_MATH_387
14128    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14129        || TARGET_MIX_SSE_I387)
14130    && flag_unsafe_math_optimizations"
14131   "fxtract"
14132   [(set_attr "type" "fpspc")
14133    (set_attr "mode" "XF")])
14134
14135 (define_expand "logbxf2"
14136   [(parallel [(set (match_dup 2)
14137                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14138                               UNSPEC_XTRACT_FRACT))
14139               (set (match_operand:XF 0 "register_operand" "")
14140                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14141   "TARGET_USE_FANCY_MATH_387
14142    && flag_unsafe_math_optimizations"
14143   "operands[2] = gen_reg_rtx (XFmode);")
14144
14145 (define_expand "logb<mode>2"
14146   [(use (match_operand:MODEF 0 "register_operand" ""))
14147    (use (match_operand:MODEF 1 "register_operand" ""))]
14148   "TARGET_USE_FANCY_MATH_387
14149    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150        || TARGET_MIX_SSE_I387)
14151    && flag_unsafe_math_optimizations"
14152 {
14153   rtx op0 = gen_reg_rtx (XFmode);
14154   rtx op1 = gen_reg_rtx (XFmode);
14155
14156   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14157   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14158   DONE;
14159 })
14160
14161 (define_expand "ilogbxf2"
14162   [(use (match_operand:SI 0 "register_operand" ""))
14163    (use (match_operand:XF 1 "register_operand" ""))]
14164   "TARGET_USE_FANCY_MATH_387
14165    && flag_unsafe_math_optimizations"
14166 {
14167   rtx op0, op1;
14168
14169   if (optimize_insn_for_size_p ())
14170     FAIL;
14171
14172   op0 = gen_reg_rtx (XFmode);
14173   op1 = gen_reg_rtx (XFmode);
14174
14175   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14176   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14177   DONE;
14178 })
14179
14180 (define_expand "ilogb<mode>2"
14181   [(use (match_operand:SI 0 "register_operand" ""))
14182    (use (match_operand:MODEF 1 "register_operand" ""))]
14183   "TARGET_USE_FANCY_MATH_387
14184    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14185        || TARGET_MIX_SSE_I387)
14186    && flag_unsafe_math_optimizations"
14187 {
14188   rtx op0, op1;
14189
14190   if (optimize_insn_for_size_p ())
14191     FAIL;
14192
14193   op0 = gen_reg_rtx (XFmode);
14194   op1 = gen_reg_rtx (XFmode);
14195
14196   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14197   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14198   DONE;
14199 })
14200
14201 (define_insn "*f2xm1xf2_i387"
14202   [(set (match_operand:XF 0 "register_operand" "=f")
14203         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14204                    UNSPEC_F2XM1))]
14205   "TARGET_USE_FANCY_MATH_387
14206    && flag_unsafe_math_optimizations"
14207   "f2xm1"
14208   [(set_attr "type" "fpspc")
14209    (set_attr "mode" "XF")])
14210
14211 (define_insn "*fscalexf4_i387"
14212   [(set (match_operand:XF 0 "register_operand" "=f")
14213         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14214                     (match_operand:XF 3 "register_operand" "1")]
14215                    UNSPEC_FSCALE_FRACT))
14216    (set (match_operand:XF 1 "register_operand" "=u")
14217         (unspec:XF [(match_dup 2) (match_dup 3)]
14218                    UNSPEC_FSCALE_EXP))]
14219   "TARGET_USE_FANCY_MATH_387
14220    && flag_unsafe_math_optimizations"
14221   "fscale"
14222   [(set_attr "type" "fpspc")
14223    (set_attr "mode" "XF")])
14224
14225 (define_expand "expNcorexf3"
14226   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14227                                (match_operand:XF 2 "register_operand" "")))
14228    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14229    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14230    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14231    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14232    (parallel [(set (match_operand:XF 0 "register_operand" "")
14233                    (unspec:XF [(match_dup 8) (match_dup 4)]
14234                               UNSPEC_FSCALE_FRACT))
14235               (set (match_dup 9)
14236                    (unspec:XF [(match_dup 8) (match_dup 4)]
14237                               UNSPEC_FSCALE_EXP))])]
14238   "TARGET_USE_FANCY_MATH_387
14239    && flag_unsafe_math_optimizations"
14240 {
14241   int i;
14242
14243   if (optimize_insn_for_size_p ())
14244     FAIL;
14245
14246   for (i = 3; i < 10; i++)
14247     operands[i] = gen_reg_rtx (XFmode);
14248
14249   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14250 })
14251
14252 (define_expand "expxf2"
14253   [(use (match_operand:XF 0 "register_operand" ""))
14254    (use (match_operand:XF 1 "register_operand" ""))]
14255   "TARGET_USE_FANCY_MATH_387
14256    && flag_unsafe_math_optimizations"
14257 {
14258   rtx op2;
14259
14260   if (optimize_insn_for_size_p ())
14261     FAIL;
14262
14263   op2 = gen_reg_rtx (XFmode);
14264   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14265
14266   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14267   DONE;
14268 })
14269
14270 (define_expand "exp<mode>2"
14271   [(use (match_operand:MODEF 0 "register_operand" ""))
14272    (use (match_operand:MODEF 1 "general_operand" ""))]
14273  "TARGET_USE_FANCY_MATH_387
14274    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14275        || TARGET_MIX_SSE_I387)
14276    && flag_unsafe_math_optimizations"
14277 {
14278   rtx op0, op1;
14279
14280   if (optimize_insn_for_size_p ())
14281     FAIL;
14282
14283   op0 = gen_reg_rtx (XFmode);
14284   op1 = gen_reg_rtx (XFmode);
14285
14286   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14287   emit_insn (gen_expxf2 (op0, op1));
14288   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14289   DONE;
14290 })
14291
14292 (define_expand "exp10xf2"
14293   [(use (match_operand:XF 0 "register_operand" ""))
14294    (use (match_operand:XF 1 "register_operand" ""))]
14295   "TARGET_USE_FANCY_MATH_387
14296    && flag_unsafe_math_optimizations"
14297 {
14298   rtx op2;
14299
14300   if (optimize_insn_for_size_p ())
14301     FAIL;
14302
14303   op2 = gen_reg_rtx (XFmode);
14304   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14305
14306   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14307   DONE;
14308 })
14309
14310 (define_expand "exp10<mode>2"
14311   [(use (match_operand:MODEF 0 "register_operand" ""))
14312    (use (match_operand:MODEF 1 "general_operand" ""))]
14313  "TARGET_USE_FANCY_MATH_387
14314    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14315        || TARGET_MIX_SSE_I387)
14316    && flag_unsafe_math_optimizations"
14317 {
14318   rtx op0, op1;
14319
14320   if (optimize_insn_for_size_p ())
14321     FAIL;
14322
14323   op0 = gen_reg_rtx (XFmode);
14324   op1 = gen_reg_rtx (XFmode);
14325
14326   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14327   emit_insn (gen_exp10xf2 (op0, op1));
14328   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14329   DONE;
14330 })
14331
14332 (define_expand "exp2xf2"
14333   [(use (match_operand:XF 0 "register_operand" ""))
14334    (use (match_operand:XF 1 "register_operand" ""))]
14335   "TARGET_USE_FANCY_MATH_387
14336    && flag_unsafe_math_optimizations"
14337 {
14338   rtx op2;
14339
14340   if (optimize_insn_for_size_p ())
14341     FAIL;
14342
14343   op2 = gen_reg_rtx (XFmode);
14344   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14345
14346   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14347   DONE;
14348 })
14349
14350 (define_expand "exp2<mode>2"
14351   [(use (match_operand:MODEF 0 "register_operand" ""))
14352    (use (match_operand:MODEF 1 "general_operand" ""))]
14353  "TARGET_USE_FANCY_MATH_387
14354    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14355        || TARGET_MIX_SSE_I387)
14356    && flag_unsafe_math_optimizations"
14357 {
14358   rtx op0, op1;
14359
14360   if (optimize_insn_for_size_p ())
14361     FAIL;
14362
14363   op0 = gen_reg_rtx (XFmode);
14364   op1 = gen_reg_rtx (XFmode);
14365
14366   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14367   emit_insn (gen_exp2xf2 (op0, op1));
14368   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14369   DONE;
14370 })
14371
14372 (define_expand "expm1xf2"
14373   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14374                                (match_dup 2)))
14375    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14376    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14377    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14378    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14379    (parallel [(set (match_dup 7)
14380                    (unspec:XF [(match_dup 6) (match_dup 4)]
14381                               UNSPEC_FSCALE_FRACT))
14382               (set (match_dup 8)
14383                    (unspec:XF [(match_dup 6) (match_dup 4)]
14384                               UNSPEC_FSCALE_EXP))])
14385    (parallel [(set (match_dup 10)
14386                    (unspec:XF [(match_dup 9) (match_dup 8)]
14387                               UNSPEC_FSCALE_FRACT))
14388               (set (match_dup 11)
14389                    (unspec:XF [(match_dup 9) (match_dup 8)]
14390                               UNSPEC_FSCALE_EXP))])
14391    (set (match_dup 12) (minus:XF (match_dup 10)
14392                                  (float_extend:XF (match_dup 13))))
14393    (set (match_operand:XF 0 "register_operand" "")
14394         (plus:XF (match_dup 12) (match_dup 7)))]
14395   "TARGET_USE_FANCY_MATH_387
14396    && flag_unsafe_math_optimizations"
14397 {
14398   int i;
14399
14400   if (optimize_insn_for_size_p ())
14401     FAIL;
14402
14403   for (i = 2; i < 13; i++)
14404     operands[i] = gen_reg_rtx (XFmode);
14405
14406   operands[13]
14407     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14408
14409   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14410 })
14411
14412 (define_expand "expm1<mode>2"
14413   [(use (match_operand:MODEF 0 "register_operand" ""))
14414    (use (match_operand:MODEF 1 "general_operand" ""))]
14415  "TARGET_USE_FANCY_MATH_387
14416    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14417        || TARGET_MIX_SSE_I387)
14418    && flag_unsafe_math_optimizations"
14419 {
14420   rtx op0, op1;
14421
14422   if (optimize_insn_for_size_p ())
14423     FAIL;
14424
14425   op0 = gen_reg_rtx (XFmode);
14426   op1 = gen_reg_rtx (XFmode);
14427
14428   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14429   emit_insn (gen_expm1xf2 (op0, op1));
14430   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14431   DONE;
14432 })
14433
14434 (define_expand "ldexpxf3"
14435   [(set (match_dup 3)
14436         (float:XF (match_operand:SI 2 "register_operand" "")))
14437    (parallel [(set (match_operand:XF 0 " register_operand" "")
14438                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14439                                (match_dup 3)]
14440                               UNSPEC_FSCALE_FRACT))
14441               (set (match_dup 4)
14442                    (unspec:XF [(match_dup 1) (match_dup 3)]
14443                               UNSPEC_FSCALE_EXP))])]
14444   "TARGET_USE_FANCY_MATH_387
14445    && flag_unsafe_math_optimizations"
14446 {
14447   if (optimize_insn_for_size_p ())
14448     FAIL;
14449
14450   operands[3] = gen_reg_rtx (XFmode);
14451   operands[4] = gen_reg_rtx (XFmode);
14452 })
14453
14454 (define_expand "ldexp<mode>3"
14455   [(use (match_operand:MODEF 0 "register_operand" ""))
14456    (use (match_operand:MODEF 1 "general_operand" ""))
14457    (use (match_operand:SI 2 "register_operand" ""))]
14458  "TARGET_USE_FANCY_MATH_387
14459    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14460        || TARGET_MIX_SSE_I387)
14461    && flag_unsafe_math_optimizations"
14462 {
14463   rtx op0, op1;
14464
14465   if (optimize_insn_for_size_p ())
14466     FAIL;
14467
14468   op0 = gen_reg_rtx (XFmode);
14469   op1 = gen_reg_rtx (XFmode);
14470
14471   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14472   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14473   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14474   DONE;
14475 })
14476
14477 (define_expand "scalbxf3"
14478   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14479                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14480                                (match_operand:XF 2 "register_operand" "")]
14481                               UNSPEC_FSCALE_FRACT))
14482               (set (match_dup 3)
14483                    (unspec:XF [(match_dup 1) (match_dup 2)]
14484                               UNSPEC_FSCALE_EXP))])]
14485   "TARGET_USE_FANCY_MATH_387
14486    && flag_unsafe_math_optimizations"
14487 {
14488   if (optimize_insn_for_size_p ())
14489     FAIL;
14490
14491   operands[3] = gen_reg_rtx (XFmode);
14492 })
14493
14494 (define_expand "scalb<mode>3"
14495   [(use (match_operand:MODEF 0 "register_operand" ""))
14496    (use (match_operand:MODEF 1 "general_operand" ""))
14497    (use (match_operand:MODEF 2 "general_operand" ""))]
14498  "TARGET_USE_FANCY_MATH_387
14499    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14500        || TARGET_MIX_SSE_I387)
14501    && flag_unsafe_math_optimizations"
14502 {
14503   rtx op0, op1, op2;
14504
14505   if (optimize_insn_for_size_p ())
14506     FAIL;
14507
14508   op0 = gen_reg_rtx (XFmode);
14509   op1 = gen_reg_rtx (XFmode);
14510   op2 = gen_reg_rtx (XFmode);
14511
14512   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14513   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14514   emit_insn (gen_scalbxf3 (op0, op1, op2));
14515   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14516   DONE;
14517 })
14518
14519 (define_expand "significandxf2"
14520   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14521                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14522                               UNSPEC_XTRACT_FRACT))
14523               (set (match_dup 2)
14524                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14525   "TARGET_USE_FANCY_MATH_387
14526    && flag_unsafe_math_optimizations"
14527   "operands[2] = gen_reg_rtx (XFmode);")
14528
14529 (define_expand "significand<mode>2"
14530   [(use (match_operand:MODEF 0 "register_operand" ""))
14531    (use (match_operand:MODEF 1 "register_operand" ""))]
14532   "TARGET_USE_FANCY_MATH_387
14533    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14534        || TARGET_MIX_SSE_I387)
14535    && flag_unsafe_math_optimizations"
14536 {
14537   rtx op0 = gen_reg_rtx (XFmode);
14538   rtx op1 = gen_reg_rtx (XFmode);
14539
14540   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14541   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14542   DONE;
14543 })
14544 \f
14545
14546 (define_insn "sse4_1_round<mode>2"
14547   [(set (match_operand:MODEF 0 "register_operand" "=x")
14548         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14549                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14550                       UNSPEC_ROUND))]
14551   "TARGET_ROUND"
14552   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14553   [(set_attr "type" "ssecvt")
14554    (set_attr "prefix_extra" "1")
14555    (set_attr "prefix" "maybe_vex")
14556    (set_attr "mode" "<MODE>")])
14557
14558 (define_insn "rintxf2"
14559   [(set (match_operand:XF 0 "register_operand" "=f")
14560         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14561                    UNSPEC_FRNDINT))]
14562   "TARGET_USE_FANCY_MATH_387
14563    && flag_unsafe_math_optimizations"
14564   "frndint"
14565   [(set_attr "type" "fpspc")
14566    (set_attr "mode" "XF")])
14567
14568 (define_expand "rint<mode>2"
14569   [(use (match_operand:MODEF 0 "register_operand" ""))
14570    (use (match_operand:MODEF 1 "register_operand" ""))]
14571   "(TARGET_USE_FANCY_MATH_387
14572     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14573         || TARGET_MIX_SSE_I387)
14574     && flag_unsafe_math_optimizations)
14575    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14576        && !flag_trapping_math)"
14577 {
14578   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14579       && !flag_trapping_math)
14580     {
14581       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14582         FAIL;
14583       if (TARGET_ROUND)
14584         emit_insn (gen_sse4_1_round<mode>2
14585                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14586       else
14587         ix86_expand_rint (operand0, operand1);
14588     }
14589   else
14590     {
14591       rtx op0 = gen_reg_rtx (XFmode);
14592       rtx op1 = gen_reg_rtx (XFmode);
14593
14594       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14595       emit_insn (gen_rintxf2 (op0, op1));
14596
14597       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14598     }
14599   DONE;
14600 })
14601
14602 (define_expand "round<mode>2"
14603   [(match_operand:MODEF 0 "register_operand" "")
14604    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14605   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14606    && !flag_trapping_math && !flag_rounding_math"
14607 {
14608   if (optimize_insn_for_size_p ())
14609     FAIL;
14610   if (TARGET_64BIT || (<MODE>mode != DFmode))
14611     ix86_expand_round (operand0, operand1);
14612   else
14613     ix86_expand_rounddf_32 (operand0, operand1);
14614   DONE;
14615 })
14616
14617 (define_insn_and_split "*fistdi2_1"
14618   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14619         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14620                    UNSPEC_FIST))]
14621   "TARGET_USE_FANCY_MATH_387
14622    && can_create_pseudo_p ()"
14623   "#"
14624   "&& 1"
14625   [(const_int 0)]
14626 {
14627   if (memory_operand (operands[0], VOIDmode))
14628     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14629   else
14630     {
14631       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14632       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14633                                          operands[2]));
14634     }
14635   DONE;
14636 }
14637   [(set_attr "type" "fpspc")
14638    (set_attr "mode" "DI")])
14639
14640 (define_insn "fistdi2"
14641   [(set (match_operand:DI 0 "memory_operand" "=m")
14642         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14643                    UNSPEC_FIST))
14644    (clobber (match_scratch:XF 2 "=&1f"))]
14645   "TARGET_USE_FANCY_MATH_387"
14646   "* return output_fix_trunc (insn, operands, 0);"
14647   [(set_attr "type" "fpspc")
14648    (set_attr "mode" "DI")])
14649
14650 (define_insn "fistdi2_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))
14654    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14655    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14656   "TARGET_USE_FANCY_MATH_387"
14657   "#"
14658   [(set_attr "type" "fpspc")
14659    (set_attr "mode" "DI")])
14660
14661 (define_split
14662   [(set (match_operand:DI 0 "register_operand" "")
14663         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14664                    UNSPEC_FIST))
14665    (clobber (match_operand:DI 2 "memory_operand" ""))
14666    (clobber (match_scratch 3 ""))]
14667   "reload_completed"
14668   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14669               (clobber (match_dup 3))])
14670    (set (match_dup 0) (match_dup 2))])
14671
14672 (define_split
14673   [(set (match_operand:DI 0 "memory_operand" "")
14674         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14675                    UNSPEC_FIST))
14676    (clobber (match_operand:DI 2 "memory_operand" ""))
14677    (clobber (match_scratch 3 ""))]
14678   "reload_completed"
14679   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14680               (clobber (match_dup 3))])])
14681
14682 (define_insn_and_split "*fist<mode>2_1"
14683   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14684         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14685                            UNSPEC_FIST))]
14686   "TARGET_USE_FANCY_MATH_387
14687    && can_create_pseudo_p ()"
14688   "#"
14689   "&& 1"
14690   [(const_int 0)]
14691 {
14692   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14693   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14694                                         operands[2]));
14695   DONE;
14696 }
14697   [(set_attr "type" "fpspc")
14698    (set_attr "mode" "<MODE>")])
14699
14700 (define_insn "fist<mode>2"
14701   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14702         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14703                            UNSPEC_FIST))]
14704   "TARGET_USE_FANCY_MATH_387"
14705   "* return output_fix_trunc (insn, operands, 0);"
14706   [(set_attr "type" "fpspc")
14707    (set_attr "mode" "<MODE>")])
14708
14709 (define_insn "fist<mode>2_with_temp"
14710   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14711         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14712                            UNSPEC_FIST))
14713    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14714   "TARGET_USE_FANCY_MATH_387"
14715   "#"
14716   [(set_attr "type" "fpspc")
14717    (set_attr "mode" "<MODE>")])
14718
14719 (define_split
14720   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14721         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14722                            UNSPEC_FIST))
14723    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14724   "reload_completed"
14725   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14726    (set (match_dup 0) (match_dup 2))])
14727
14728 (define_split
14729   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14730         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14731                            UNSPEC_FIST))
14732    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14733   "reload_completed"
14734   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14735
14736 (define_expand "lrintxf<mode>2"
14737   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14738      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14739                       UNSPEC_FIST))]
14740   "TARGET_USE_FANCY_MATH_387")
14741
14742 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14743   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14744      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14745                         UNSPEC_FIX_NOTRUNC))]
14746   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14747    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14748
14749 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14750   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14751    (match_operand:MODEF 1 "register_operand" "")]
14752   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14753    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14754    && !flag_trapping_math && !flag_rounding_math"
14755 {
14756   if (optimize_insn_for_size_p ())
14757     FAIL;
14758   ix86_expand_lround (operand0, operand1);
14759   DONE;
14760 })
14761
14762 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14763 (define_insn_and_split "frndintxf2_floor"
14764   [(set (match_operand:XF 0 "register_operand" "")
14765         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14766          UNSPEC_FRNDINT_FLOOR))
14767    (clobber (reg:CC FLAGS_REG))]
14768   "TARGET_USE_FANCY_MATH_387
14769    && flag_unsafe_math_optimizations
14770    && can_create_pseudo_p ()"
14771   "#"
14772   "&& 1"
14773   [(const_int 0)]
14774 {
14775   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14776
14777   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14778   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14779
14780   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14781                                         operands[2], operands[3]));
14782   DONE;
14783 }
14784   [(set_attr "type" "frndint")
14785    (set_attr "i387_cw" "floor")
14786    (set_attr "mode" "XF")])
14787
14788 (define_insn "frndintxf2_floor_i387"
14789   [(set (match_operand:XF 0 "register_operand" "=f")
14790         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14791          UNSPEC_FRNDINT_FLOOR))
14792    (use (match_operand:HI 2 "memory_operand" "m"))
14793    (use (match_operand:HI 3 "memory_operand" "m"))]
14794   "TARGET_USE_FANCY_MATH_387
14795    && flag_unsafe_math_optimizations"
14796   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14797   [(set_attr "type" "frndint")
14798    (set_attr "i387_cw" "floor")
14799    (set_attr "mode" "XF")])
14800
14801 (define_expand "floorxf2"
14802   [(use (match_operand:XF 0 "register_operand" ""))
14803    (use (match_operand:XF 1 "register_operand" ""))]
14804   "TARGET_USE_FANCY_MATH_387
14805    && flag_unsafe_math_optimizations"
14806 {
14807   if (optimize_insn_for_size_p ())
14808     FAIL;
14809   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14810   DONE;
14811 })
14812
14813 (define_expand "floor<mode>2"
14814   [(use (match_operand:MODEF 0 "register_operand" ""))
14815    (use (match_operand:MODEF 1 "register_operand" ""))]
14816   "(TARGET_USE_FANCY_MATH_387
14817     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14818         || TARGET_MIX_SSE_I387)
14819     && flag_unsafe_math_optimizations)
14820    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14821        && !flag_trapping_math)"
14822 {
14823   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14824       && !flag_trapping_math
14825       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14826     {
14827       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14828         FAIL;
14829       if (TARGET_ROUND)
14830         emit_insn (gen_sse4_1_round<mode>2
14831                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14832       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14833         ix86_expand_floorceil (operand0, operand1, true);
14834       else
14835         ix86_expand_floorceildf_32 (operand0, operand1, true);
14836     }
14837   else
14838     {
14839       rtx op0, op1;
14840
14841       if (optimize_insn_for_size_p ())
14842         FAIL;
14843
14844       op0 = gen_reg_rtx (XFmode);
14845       op1 = gen_reg_rtx (XFmode);
14846       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14847       emit_insn (gen_frndintxf2_floor (op0, op1));
14848
14849       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14850     }
14851   DONE;
14852 })
14853
14854 (define_insn_and_split "*fist<mode>2_floor_1"
14855   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14856         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14857          UNSPEC_FIST_FLOOR))
14858    (clobber (reg:CC FLAGS_REG))]
14859   "TARGET_USE_FANCY_MATH_387
14860    && flag_unsafe_math_optimizations
14861    && can_create_pseudo_p ()"
14862   "#"
14863   "&& 1"
14864   [(const_int 0)]
14865 {
14866   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14867
14868   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14869   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14870   if (memory_operand (operands[0], VOIDmode))
14871     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14872                                       operands[2], operands[3]));
14873   else
14874     {
14875       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14876       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14877                                                   operands[2], operands[3],
14878                                                   operands[4]));
14879     }
14880   DONE;
14881 }
14882   [(set_attr "type" "fistp")
14883    (set_attr "i387_cw" "floor")
14884    (set_attr "mode" "<MODE>")])
14885
14886 (define_insn "fistdi2_floor"
14887   [(set (match_operand:DI 0 "memory_operand" "=m")
14888         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14889          UNSPEC_FIST_FLOOR))
14890    (use (match_operand:HI 2 "memory_operand" "m"))
14891    (use (match_operand:HI 3 "memory_operand" "m"))
14892    (clobber (match_scratch:XF 4 "=&1f"))]
14893   "TARGET_USE_FANCY_MATH_387
14894    && flag_unsafe_math_optimizations"
14895   "* return output_fix_trunc (insn, operands, 0);"
14896   [(set_attr "type" "fistp")
14897    (set_attr "i387_cw" "floor")
14898    (set_attr "mode" "DI")])
14899
14900 (define_insn "fistdi2_floor_with_temp"
14901   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14902         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14903          UNSPEC_FIST_FLOOR))
14904    (use (match_operand:HI 2 "memory_operand" "m,m"))
14905    (use (match_operand:HI 3 "memory_operand" "m,m"))
14906    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14907    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14908   "TARGET_USE_FANCY_MATH_387
14909    && flag_unsafe_math_optimizations"
14910   "#"
14911   [(set_attr "type" "fistp")
14912    (set_attr "i387_cw" "floor")
14913    (set_attr "mode" "DI")])
14914
14915 (define_split
14916   [(set (match_operand:DI 0 "register_operand" "")
14917         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14918          UNSPEC_FIST_FLOOR))
14919    (use (match_operand:HI 2 "memory_operand" ""))
14920    (use (match_operand:HI 3 "memory_operand" ""))
14921    (clobber (match_operand:DI 4 "memory_operand" ""))
14922    (clobber (match_scratch 5 ""))]
14923   "reload_completed"
14924   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14925               (use (match_dup 2))
14926               (use (match_dup 3))
14927               (clobber (match_dup 5))])
14928    (set (match_dup 0) (match_dup 4))])
14929
14930 (define_split
14931   [(set (match_operand:DI 0 "memory_operand" "")
14932         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14933          UNSPEC_FIST_FLOOR))
14934    (use (match_operand:HI 2 "memory_operand" ""))
14935    (use (match_operand:HI 3 "memory_operand" ""))
14936    (clobber (match_operand:DI 4 "memory_operand" ""))
14937    (clobber (match_scratch 5 ""))]
14938   "reload_completed"
14939   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14940               (use (match_dup 2))
14941               (use (match_dup 3))
14942               (clobber (match_dup 5))])])
14943
14944 (define_insn "fist<mode>2_floor"
14945   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14946         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14947          UNSPEC_FIST_FLOOR))
14948    (use (match_operand:HI 2 "memory_operand" "m"))
14949    (use (match_operand:HI 3 "memory_operand" "m"))]
14950   "TARGET_USE_FANCY_MATH_387
14951    && flag_unsafe_math_optimizations"
14952   "* return output_fix_trunc (insn, operands, 0);"
14953   [(set_attr "type" "fistp")
14954    (set_attr "i387_cw" "floor")
14955    (set_attr "mode" "<MODE>")])
14956
14957 (define_insn "fist<mode>2_floor_with_temp"
14958   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14959         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14960          UNSPEC_FIST_FLOOR))
14961    (use (match_operand:HI 2 "memory_operand" "m,m"))
14962    (use (match_operand:HI 3 "memory_operand" "m,m"))
14963    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14964   "TARGET_USE_FANCY_MATH_387
14965    && flag_unsafe_math_optimizations"
14966   "#"
14967   [(set_attr "type" "fistp")
14968    (set_attr "i387_cw" "floor")
14969    (set_attr "mode" "<MODE>")])
14970
14971 (define_split
14972   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14973         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14974          UNSPEC_FIST_FLOOR))
14975    (use (match_operand:HI 2 "memory_operand" ""))
14976    (use (match_operand:HI 3 "memory_operand" ""))
14977    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14978   "reload_completed"
14979   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14980                                   UNSPEC_FIST_FLOOR))
14981               (use (match_dup 2))
14982               (use (match_dup 3))])
14983    (set (match_dup 0) (match_dup 4))])
14984
14985 (define_split
14986   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14987         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14988          UNSPEC_FIST_FLOOR))
14989    (use (match_operand:HI 2 "memory_operand" ""))
14990    (use (match_operand:HI 3 "memory_operand" ""))
14991    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14992   "reload_completed"
14993   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14994                                   UNSPEC_FIST_FLOOR))
14995               (use (match_dup 2))
14996               (use (match_dup 3))])])
14997
14998 (define_expand "lfloorxf<mode>2"
14999   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15000                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15001                     UNSPEC_FIST_FLOOR))
15002               (clobber (reg:CC FLAGS_REG))])]
15003   "TARGET_USE_FANCY_MATH_387
15004    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15005    && flag_unsafe_math_optimizations")
15006
15007 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15008   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15009    (match_operand:MODEF 1 "register_operand" "")]
15010   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15011    && !flag_trapping_math"
15012 {
15013   if (TARGET_64BIT && optimize_insn_for_size_p ())
15014     FAIL;
15015   ix86_expand_lfloorceil (operand0, operand1, true);
15016   DONE;
15017 })
15018
15019 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15020 (define_insn_and_split "frndintxf2_ceil"
15021   [(set (match_operand:XF 0 "register_operand" "")
15022         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15023          UNSPEC_FRNDINT_CEIL))
15024    (clobber (reg:CC FLAGS_REG))]
15025   "TARGET_USE_FANCY_MATH_387
15026    && flag_unsafe_math_optimizations
15027    && can_create_pseudo_p ()"
15028   "#"
15029   "&& 1"
15030   [(const_int 0)]
15031 {
15032   ix86_optimize_mode_switching[I387_CEIL] = 1;
15033
15034   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15035   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15036
15037   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15038                                        operands[2], operands[3]));
15039   DONE;
15040 }
15041   [(set_attr "type" "frndint")
15042    (set_attr "i387_cw" "ceil")
15043    (set_attr "mode" "XF")])
15044
15045 (define_insn "frndintxf2_ceil_i387"
15046   [(set (match_operand:XF 0 "register_operand" "=f")
15047         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15048          UNSPEC_FRNDINT_CEIL))
15049    (use (match_operand:HI 2 "memory_operand" "m"))
15050    (use (match_operand:HI 3 "memory_operand" "m"))]
15051   "TARGET_USE_FANCY_MATH_387
15052    && flag_unsafe_math_optimizations"
15053   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15054   [(set_attr "type" "frndint")
15055    (set_attr "i387_cw" "ceil")
15056    (set_attr "mode" "XF")])
15057
15058 (define_expand "ceilxf2"
15059   [(use (match_operand:XF 0 "register_operand" ""))
15060    (use (match_operand:XF 1 "register_operand" ""))]
15061   "TARGET_USE_FANCY_MATH_387
15062    && flag_unsafe_math_optimizations"
15063 {
15064   if (optimize_insn_for_size_p ())
15065     FAIL;
15066   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15067   DONE;
15068 })
15069
15070 (define_expand "ceil<mode>2"
15071   [(use (match_operand:MODEF 0 "register_operand" ""))
15072    (use (match_operand:MODEF 1 "register_operand" ""))]
15073   "(TARGET_USE_FANCY_MATH_387
15074     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15075         || TARGET_MIX_SSE_I387)
15076     && flag_unsafe_math_optimizations)
15077    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15078        && !flag_trapping_math)"
15079 {
15080   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15081       && !flag_trapping_math
15082       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15083     {
15084       if (TARGET_ROUND)
15085         emit_insn (gen_sse4_1_round<mode>2
15086                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15087       else if (optimize_insn_for_size_p ())
15088         FAIL;
15089       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15090         ix86_expand_floorceil (operand0, operand1, false);
15091       else
15092         ix86_expand_floorceildf_32 (operand0, operand1, false);
15093     }
15094   else
15095     {
15096       rtx op0, op1;
15097
15098       if (optimize_insn_for_size_p ())
15099         FAIL;
15100
15101       op0 = gen_reg_rtx (XFmode);
15102       op1 = gen_reg_rtx (XFmode);
15103       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15104       emit_insn (gen_frndintxf2_ceil (op0, op1));
15105
15106       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15107     }
15108   DONE;
15109 })
15110
15111 (define_insn_and_split "*fist<mode>2_ceil_1"
15112   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15113         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15114          UNSPEC_FIST_CEIL))
15115    (clobber (reg:CC FLAGS_REG))]
15116   "TARGET_USE_FANCY_MATH_387
15117    && flag_unsafe_math_optimizations
15118    && can_create_pseudo_p ()"
15119   "#"
15120   "&& 1"
15121   [(const_int 0)]
15122 {
15123   ix86_optimize_mode_switching[I387_CEIL] = 1;
15124
15125   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15126   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15127   if (memory_operand (operands[0], VOIDmode))
15128     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15129                                      operands[2], operands[3]));
15130   else
15131     {
15132       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15133       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15134                                                  operands[2], operands[3],
15135                                                  operands[4]));
15136     }
15137   DONE;
15138 }
15139   [(set_attr "type" "fistp")
15140    (set_attr "i387_cw" "ceil")
15141    (set_attr "mode" "<MODE>")])
15142
15143 (define_insn "fistdi2_ceil"
15144   [(set (match_operand:DI 0 "memory_operand" "=m")
15145         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15146          UNSPEC_FIST_CEIL))
15147    (use (match_operand:HI 2 "memory_operand" "m"))
15148    (use (match_operand:HI 3 "memory_operand" "m"))
15149    (clobber (match_scratch:XF 4 "=&1f"))]
15150   "TARGET_USE_FANCY_MATH_387
15151    && flag_unsafe_math_optimizations"
15152   "* return output_fix_trunc (insn, operands, 0);"
15153   [(set_attr "type" "fistp")
15154    (set_attr "i387_cw" "ceil")
15155    (set_attr "mode" "DI")])
15156
15157 (define_insn "fistdi2_ceil_with_temp"
15158   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15159         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15160          UNSPEC_FIST_CEIL))
15161    (use (match_operand:HI 2 "memory_operand" "m,m"))
15162    (use (match_operand:HI 3 "memory_operand" "m,m"))
15163    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15164    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15165   "TARGET_USE_FANCY_MATH_387
15166    && flag_unsafe_math_optimizations"
15167   "#"
15168   [(set_attr "type" "fistp")
15169    (set_attr "i387_cw" "ceil")
15170    (set_attr "mode" "DI")])
15171
15172 (define_split
15173   [(set (match_operand:DI 0 "register_operand" "")
15174         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15175          UNSPEC_FIST_CEIL))
15176    (use (match_operand:HI 2 "memory_operand" ""))
15177    (use (match_operand:HI 3 "memory_operand" ""))
15178    (clobber (match_operand:DI 4 "memory_operand" ""))
15179    (clobber (match_scratch 5 ""))]
15180   "reload_completed"
15181   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15182               (use (match_dup 2))
15183               (use (match_dup 3))
15184               (clobber (match_dup 5))])
15185    (set (match_dup 0) (match_dup 4))])
15186
15187 (define_split
15188   [(set (match_operand:DI 0 "memory_operand" "")
15189         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15190          UNSPEC_FIST_CEIL))
15191    (use (match_operand:HI 2 "memory_operand" ""))
15192    (use (match_operand:HI 3 "memory_operand" ""))
15193    (clobber (match_operand:DI 4 "memory_operand" ""))
15194    (clobber (match_scratch 5 ""))]
15195   "reload_completed"
15196   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15197               (use (match_dup 2))
15198               (use (match_dup 3))
15199               (clobber (match_dup 5))])])
15200
15201 (define_insn "fist<mode>2_ceil"
15202   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15203         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15204          UNSPEC_FIST_CEIL))
15205    (use (match_operand:HI 2 "memory_operand" "m"))
15206    (use (match_operand:HI 3 "memory_operand" "m"))]
15207   "TARGET_USE_FANCY_MATH_387
15208    && flag_unsafe_math_optimizations"
15209   "* return output_fix_trunc (insn, operands, 0);"
15210   [(set_attr "type" "fistp")
15211    (set_attr "i387_cw" "ceil")
15212    (set_attr "mode" "<MODE>")])
15213
15214 (define_insn "fist<mode>2_ceil_with_temp"
15215   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15216         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15217          UNSPEC_FIST_CEIL))
15218    (use (match_operand:HI 2 "memory_operand" "m,m"))
15219    (use (match_operand:HI 3 "memory_operand" "m,m"))
15220    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15221   "TARGET_USE_FANCY_MATH_387
15222    && flag_unsafe_math_optimizations"
15223   "#"
15224   [(set_attr "type" "fistp")
15225    (set_attr "i387_cw" "ceil")
15226    (set_attr "mode" "<MODE>")])
15227
15228 (define_split
15229   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15230         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15231          UNSPEC_FIST_CEIL))
15232    (use (match_operand:HI 2 "memory_operand" ""))
15233    (use (match_operand:HI 3 "memory_operand" ""))
15234    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15235   "reload_completed"
15236   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15237                                   UNSPEC_FIST_CEIL))
15238               (use (match_dup 2))
15239               (use (match_dup 3))])
15240    (set (match_dup 0) (match_dup 4))])
15241
15242 (define_split
15243   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15244         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15245          UNSPEC_FIST_CEIL))
15246    (use (match_operand:HI 2 "memory_operand" ""))
15247    (use (match_operand:HI 3 "memory_operand" ""))
15248    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15249   "reload_completed"
15250   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15251                                   UNSPEC_FIST_CEIL))
15252               (use (match_dup 2))
15253               (use (match_dup 3))])])
15254
15255 (define_expand "lceilxf<mode>2"
15256   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15257                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15258                     UNSPEC_FIST_CEIL))
15259               (clobber (reg:CC FLAGS_REG))])]
15260   "TARGET_USE_FANCY_MATH_387
15261    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15262    && flag_unsafe_math_optimizations")
15263
15264 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15265   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15266    (match_operand:MODEF 1 "register_operand" "")]
15267   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15268    && !flag_trapping_math"
15269 {
15270   ix86_expand_lfloorceil (operand0, operand1, false);
15271   DONE;
15272 })
15273
15274 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15275 (define_insn_and_split "frndintxf2_trunc"
15276   [(set (match_operand:XF 0 "register_operand" "")
15277         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15278          UNSPEC_FRNDINT_TRUNC))
15279    (clobber (reg:CC FLAGS_REG))]
15280   "TARGET_USE_FANCY_MATH_387
15281    && flag_unsafe_math_optimizations
15282    && can_create_pseudo_p ()"
15283   "#"
15284   "&& 1"
15285   [(const_int 0)]
15286 {
15287   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15288
15289   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15290   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15291
15292   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15293                                         operands[2], operands[3]));
15294   DONE;
15295 }
15296   [(set_attr "type" "frndint")
15297    (set_attr "i387_cw" "trunc")
15298    (set_attr "mode" "XF")])
15299
15300 (define_insn "frndintxf2_trunc_i387"
15301   [(set (match_operand:XF 0 "register_operand" "=f")
15302         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15303          UNSPEC_FRNDINT_TRUNC))
15304    (use (match_operand:HI 2 "memory_operand" "m"))
15305    (use (match_operand:HI 3 "memory_operand" "m"))]
15306   "TARGET_USE_FANCY_MATH_387
15307    && flag_unsafe_math_optimizations"
15308   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15309   [(set_attr "type" "frndint")
15310    (set_attr "i387_cw" "trunc")
15311    (set_attr "mode" "XF")])
15312
15313 (define_expand "btruncxf2"
15314   [(use (match_operand:XF 0 "register_operand" ""))
15315    (use (match_operand:XF 1 "register_operand" ""))]
15316   "TARGET_USE_FANCY_MATH_387
15317    && flag_unsafe_math_optimizations"
15318 {
15319   if (optimize_insn_for_size_p ())
15320     FAIL;
15321   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15322   DONE;
15323 })
15324
15325 (define_expand "btrunc<mode>2"
15326   [(use (match_operand:MODEF 0 "register_operand" ""))
15327    (use (match_operand:MODEF 1 "register_operand" ""))]
15328   "(TARGET_USE_FANCY_MATH_387
15329     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15330         || TARGET_MIX_SSE_I387)
15331     && flag_unsafe_math_optimizations)
15332    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15333        && !flag_trapping_math)"
15334 {
15335   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15336       && !flag_trapping_math
15337       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15338     {
15339       if (TARGET_ROUND)
15340         emit_insn (gen_sse4_1_round<mode>2
15341                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15342       else if (optimize_insn_for_size_p ())
15343         FAIL;
15344       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15345         ix86_expand_trunc (operand0, operand1);
15346       else
15347         ix86_expand_truncdf_32 (operand0, operand1);
15348     }
15349   else
15350     {
15351       rtx op0, op1;
15352
15353       if (optimize_insn_for_size_p ())
15354         FAIL;
15355
15356       op0 = gen_reg_rtx (XFmode);
15357       op1 = gen_reg_rtx (XFmode);
15358       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15359       emit_insn (gen_frndintxf2_trunc (op0, op1));
15360
15361       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15362     }
15363   DONE;
15364 })
15365
15366 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15367 (define_insn_and_split "frndintxf2_mask_pm"
15368   [(set (match_operand:XF 0 "register_operand" "")
15369         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15370          UNSPEC_FRNDINT_MASK_PM))
15371    (clobber (reg:CC FLAGS_REG))]
15372   "TARGET_USE_FANCY_MATH_387
15373    && flag_unsafe_math_optimizations
15374    && can_create_pseudo_p ()"
15375   "#"
15376   "&& 1"
15377   [(const_int 0)]
15378 {
15379   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15380
15381   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15382   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15383
15384   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15385                                           operands[2], operands[3]));
15386   DONE;
15387 }
15388   [(set_attr "type" "frndint")
15389    (set_attr "i387_cw" "mask_pm")
15390    (set_attr "mode" "XF")])
15391
15392 (define_insn "frndintxf2_mask_pm_i387"
15393   [(set (match_operand:XF 0 "register_operand" "=f")
15394         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15395          UNSPEC_FRNDINT_MASK_PM))
15396    (use (match_operand:HI 2 "memory_operand" "m"))
15397    (use (match_operand:HI 3 "memory_operand" "m"))]
15398   "TARGET_USE_FANCY_MATH_387
15399    && flag_unsafe_math_optimizations"
15400   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15401   [(set_attr "type" "frndint")
15402    (set_attr "i387_cw" "mask_pm")
15403    (set_attr "mode" "XF")])
15404
15405 (define_expand "nearbyintxf2"
15406   [(use (match_operand:XF 0 "register_operand" ""))
15407    (use (match_operand:XF 1 "register_operand" ""))]
15408   "TARGET_USE_FANCY_MATH_387
15409    && flag_unsafe_math_optimizations"
15410 {
15411   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15412   DONE;
15413 })
15414
15415 (define_expand "nearbyint<mode>2"
15416   [(use (match_operand:MODEF 0 "register_operand" ""))
15417    (use (match_operand:MODEF 1 "register_operand" ""))]
15418   "TARGET_USE_FANCY_MATH_387
15419    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15420        || TARGET_MIX_SSE_I387)
15421    && flag_unsafe_math_optimizations"
15422 {
15423   rtx op0 = gen_reg_rtx (XFmode);
15424   rtx op1 = gen_reg_rtx (XFmode);
15425
15426   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15427   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15428
15429   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15430   DONE;
15431 })
15432
15433 (define_insn "fxam<mode>2_i387"
15434   [(set (match_operand:HI 0 "register_operand" "=a")
15435         (unspec:HI
15436           [(match_operand:X87MODEF 1 "register_operand" "f")]
15437           UNSPEC_FXAM))]
15438   "TARGET_USE_FANCY_MATH_387"
15439   "fxam\n\tfnstsw\t%0"
15440   [(set_attr "type" "multi")
15441    (set_attr "length" "4")
15442    (set_attr "unit" "i387")
15443    (set_attr "mode" "<MODE>")])
15444
15445 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15446   [(set (match_operand:HI 0 "register_operand" "")
15447         (unspec:HI
15448           [(match_operand:MODEF 1 "memory_operand" "")]
15449           UNSPEC_FXAM_MEM))]
15450   "TARGET_USE_FANCY_MATH_387
15451    && can_create_pseudo_p ()"
15452   "#"
15453   "&& 1"
15454   [(set (match_dup 2)(match_dup 1))
15455    (set (match_dup 0)
15456         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15457 {
15458   operands[2] = gen_reg_rtx (<MODE>mode);
15459
15460   MEM_VOLATILE_P (operands[1]) = 1;
15461 }
15462   [(set_attr "type" "multi")
15463    (set_attr "unit" "i387")
15464    (set_attr "mode" "<MODE>")])
15465
15466 (define_expand "isinfxf2"
15467   [(use (match_operand:SI 0 "register_operand" ""))
15468    (use (match_operand:XF 1 "register_operand" ""))]
15469   "TARGET_USE_FANCY_MATH_387
15470    && TARGET_C99_FUNCTIONS"
15471 {
15472   rtx mask = GEN_INT (0x45);
15473   rtx val = GEN_INT (0x05);
15474
15475   rtx cond;
15476
15477   rtx scratch = gen_reg_rtx (HImode);
15478   rtx res = gen_reg_rtx (QImode);
15479
15480   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15481
15482   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15483   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15484   cond = gen_rtx_fmt_ee (EQ, QImode,
15485                          gen_rtx_REG (CCmode, FLAGS_REG),
15486                          const0_rtx);
15487   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15488   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15489   DONE;
15490 })
15491
15492 (define_expand "isinf<mode>2"
15493   [(use (match_operand:SI 0 "register_operand" ""))
15494    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15495   "TARGET_USE_FANCY_MATH_387
15496    && TARGET_C99_FUNCTIONS
15497    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15498 {
15499   rtx mask = GEN_INT (0x45);
15500   rtx val = GEN_INT (0x05);
15501
15502   rtx cond;
15503
15504   rtx scratch = gen_reg_rtx (HImode);
15505   rtx res = gen_reg_rtx (QImode);
15506
15507   /* Remove excess precision by forcing value through memory. */
15508   if (memory_operand (operands[1], VOIDmode))
15509     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15510   else
15511     {
15512       enum ix86_stack_slot slot = (virtuals_instantiated
15513                                    ? SLOT_TEMP
15514                                    : SLOT_VIRTUAL);
15515       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15516
15517       emit_move_insn (temp, operands[1]);
15518       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15519     }
15520
15521   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15522   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15523   cond = gen_rtx_fmt_ee (EQ, QImode,
15524                          gen_rtx_REG (CCmode, FLAGS_REG),
15525                          const0_rtx);
15526   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15527   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15528   DONE;
15529 })
15530
15531 (define_expand "signbitxf2"
15532   [(use (match_operand:SI 0 "register_operand" ""))
15533    (use (match_operand:XF 1 "register_operand" ""))]
15534   "TARGET_USE_FANCY_MATH_387"
15535 {
15536   rtx scratch = gen_reg_rtx (HImode);
15537
15538   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15539   emit_insn (gen_andsi3 (operands[0],
15540              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15541   DONE;
15542 })
15543
15544 (define_insn "movmsk_df"
15545   [(set (match_operand:SI 0 "register_operand" "=r")
15546         (unspec:SI
15547           [(match_operand:DF 1 "register_operand" "x")]
15548           UNSPEC_MOVMSK))]
15549   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15550   "%vmovmskpd\t{%1, %0|%0, %1}"
15551   [(set_attr "type" "ssemov")
15552    (set_attr "prefix" "maybe_vex")
15553    (set_attr "mode" "DF")])
15554
15555 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15556 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15557 (define_expand "signbitdf2"
15558   [(use (match_operand:SI 0 "register_operand" ""))
15559    (use (match_operand:DF 1 "register_operand" ""))]
15560   "TARGET_USE_FANCY_MATH_387
15561    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15562 {
15563   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15564     {
15565       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15566       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15567     }
15568   else
15569     {
15570       rtx scratch = gen_reg_rtx (HImode);
15571
15572       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15573       emit_insn (gen_andsi3 (operands[0],
15574                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15575     }
15576   DONE;
15577 })
15578
15579 (define_expand "signbitsf2"
15580   [(use (match_operand:SI 0 "register_operand" ""))
15581    (use (match_operand:SF 1 "register_operand" ""))]
15582   "TARGET_USE_FANCY_MATH_387
15583    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15584 {
15585   rtx scratch = gen_reg_rtx (HImode);
15586
15587   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15588   emit_insn (gen_andsi3 (operands[0],
15589              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15590   DONE;
15591 })
15592 \f
15593 ;; Block operation instructions
15594
15595 (define_insn "cld"
15596   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15597   ""
15598   "cld"
15599   [(set_attr "length" "1")
15600    (set_attr "length_immediate" "0")
15601    (set_attr "modrm" "0")])
15602
15603 (define_expand "movmem<mode>"
15604   [(use (match_operand:BLK 0 "memory_operand" ""))
15605    (use (match_operand:BLK 1 "memory_operand" ""))
15606    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15607    (use (match_operand:SWI48 3 "const_int_operand" ""))
15608    (use (match_operand:SI 4 "const_int_operand" ""))
15609    (use (match_operand:SI 5 "const_int_operand" ""))]
15610   ""
15611 {
15612  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15613                          operands[4], operands[5]))
15614    DONE;
15615  else
15616    FAIL;
15617 })
15618
15619 ;; Most CPUs don't like single string operations
15620 ;; Handle this case here to simplify previous expander.
15621
15622 (define_expand "strmov"
15623   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15624    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15625    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15626               (clobber (reg:CC FLAGS_REG))])
15627    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15628               (clobber (reg:CC FLAGS_REG))])]
15629   ""
15630 {
15631   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15632
15633   /* If .md ever supports :P for Pmode, these can be directly
15634      in the pattern above.  */
15635   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15636   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15637
15638   /* Can't use this if the user has appropriated esi or edi.  */
15639   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15640       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15641     {
15642       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15643                                       operands[2], operands[3],
15644                                       operands[5], operands[6]));
15645       DONE;
15646     }
15647
15648   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15649 })
15650
15651 (define_expand "strmov_singleop"
15652   [(parallel [(set (match_operand 1 "memory_operand" "")
15653                    (match_operand 3 "memory_operand" ""))
15654               (set (match_operand 0 "register_operand" "")
15655                    (match_operand 4 "" ""))
15656               (set (match_operand 2 "register_operand" "")
15657                    (match_operand 5 "" ""))])]
15658   ""
15659   "ix86_current_function_needs_cld = 1;")
15660
15661 (define_insn "*strmovdi_rex_1"
15662   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15663         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15664    (set (match_operand:DI 0 "register_operand" "=D")
15665         (plus:DI (match_dup 2)
15666                  (const_int 8)))
15667    (set (match_operand:DI 1 "register_operand" "=S")
15668         (plus:DI (match_dup 3)
15669                  (const_int 8)))]
15670   "TARGET_64BIT"
15671   "movsq"
15672   [(set_attr "type" "str")
15673    (set_attr "memory" "both")
15674    (set_attr "mode" "DI")])
15675
15676 (define_insn "*strmovsi_1"
15677   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15678         (mem:SI (match_operand:P 3 "register_operand" "1")))
15679    (set (match_operand:P 0 "register_operand" "=D")
15680         (plus:P (match_dup 2)
15681                 (const_int 4)))
15682    (set (match_operand:P 1 "register_operand" "=S")
15683         (plus:P (match_dup 3)
15684                 (const_int 4)))]
15685   ""
15686   "movs{l|d}"
15687   [(set_attr "type" "str")
15688    (set_attr "memory" "both")
15689    (set_attr "mode" "SI")])
15690
15691 (define_insn "*strmovhi_1"
15692   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15693         (mem:HI (match_operand:P 3 "register_operand" "1")))
15694    (set (match_operand:P 0 "register_operand" "=D")
15695         (plus:P (match_dup 2)
15696                 (const_int 2)))
15697    (set (match_operand:P 1 "register_operand" "=S")
15698         (plus:P (match_dup 3)
15699                 (const_int 2)))]
15700   ""
15701   "movsw"
15702   [(set_attr "type" "str")
15703    (set_attr "memory" "both")
15704    (set_attr "mode" "HI")])
15705
15706 (define_insn "*strmovqi_1"
15707   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15708         (mem:QI (match_operand:P 3 "register_operand" "1")))
15709    (set (match_operand:P 0 "register_operand" "=D")
15710         (plus:P (match_dup 2)
15711                 (const_int 1)))
15712    (set (match_operand:P 1 "register_operand" "=S")
15713         (plus:P (match_dup 3)
15714                 (const_int 1)))]
15715   ""
15716   "movsb"
15717   [(set_attr "type" "str")
15718    (set_attr "memory" "both")
15719    (set (attr "prefix_rex")
15720         (if_then_else
15721           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15722           (const_string "0")
15723           (const_string "*")))
15724    (set_attr "mode" "QI")])
15725
15726 (define_expand "rep_mov"
15727   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15728               (set (match_operand 0 "register_operand" "")
15729                    (match_operand 5 "" ""))
15730               (set (match_operand 2 "register_operand" "")
15731                    (match_operand 6 "" ""))
15732               (set (match_operand 1 "memory_operand" "")
15733                    (match_operand 3 "memory_operand" ""))
15734               (use (match_dup 4))])]
15735   ""
15736   "ix86_current_function_needs_cld = 1;")
15737
15738 (define_insn "*rep_movdi_rex64"
15739   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15740    (set (match_operand:DI 0 "register_operand" "=D")
15741         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15742                             (const_int 3))
15743                  (match_operand:DI 3 "register_operand" "0")))
15744    (set (match_operand:DI 1 "register_operand" "=S")
15745         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15746                  (match_operand:DI 4 "register_operand" "1")))
15747    (set (mem:BLK (match_dup 3))
15748         (mem:BLK (match_dup 4)))
15749    (use (match_dup 5))]
15750   "TARGET_64BIT"
15751   "rep{%;} movsq"
15752   [(set_attr "type" "str")
15753    (set_attr "prefix_rep" "1")
15754    (set_attr "memory" "both")
15755    (set_attr "mode" "DI")])
15756
15757 (define_insn "*rep_movsi"
15758   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15759    (set (match_operand:P 0 "register_operand" "=D")
15760         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15761                           (const_int 2))
15762                  (match_operand:P 3 "register_operand" "0")))
15763    (set (match_operand:P 1 "register_operand" "=S")
15764         (plus:P (ashift:P (match_dup 5) (const_int 2))
15765                 (match_operand:P 4 "register_operand" "1")))
15766    (set (mem:BLK (match_dup 3))
15767         (mem:BLK (match_dup 4)))
15768    (use (match_dup 5))]
15769   ""
15770   "rep{%;} movs{l|d}"
15771   [(set_attr "type" "str")
15772    (set_attr "prefix_rep" "1")
15773    (set_attr "memory" "both")
15774    (set_attr "mode" "SI")])
15775
15776 (define_insn "*rep_movqi"
15777   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15778    (set (match_operand:P 0 "register_operand" "=D")
15779         (plus:P (match_operand:P 3 "register_operand" "0")
15780                 (match_operand:P 5 "register_operand" "2")))
15781    (set (match_operand:P 1 "register_operand" "=S")
15782         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15783    (set (mem:BLK (match_dup 3))
15784         (mem:BLK (match_dup 4)))
15785    (use (match_dup 5))]
15786   ""
15787   "rep{%;} movsb"
15788   [(set_attr "type" "str")
15789    (set_attr "prefix_rep" "1")
15790    (set_attr "memory" "both")
15791    (set_attr "mode" "QI")])
15792
15793 (define_expand "setmem<mode>"
15794    [(use (match_operand:BLK 0 "memory_operand" ""))
15795     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15796     (use (match_operand 2 "const_int_operand" ""))
15797     (use (match_operand 3 "const_int_operand" ""))
15798     (use (match_operand:SI 4 "const_int_operand" ""))
15799     (use (match_operand:SI 5 "const_int_operand" ""))]
15800   ""
15801 {
15802  if (ix86_expand_setmem (operands[0], operands[1],
15803                          operands[2], operands[3],
15804                          operands[4], operands[5]))
15805    DONE;
15806  else
15807    FAIL;
15808 })
15809
15810 ;; Most CPUs don't like single string operations
15811 ;; Handle this case here to simplify previous expander.
15812
15813 (define_expand "strset"
15814   [(set (match_operand 1 "memory_operand" "")
15815         (match_operand 2 "register_operand" ""))
15816    (parallel [(set (match_operand 0 "register_operand" "")
15817                    (match_dup 3))
15818               (clobber (reg:CC FLAGS_REG))])]
15819   ""
15820 {
15821   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15822     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15823
15824   /* If .md ever supports :P for Pmode, this can be directly
15825      in the pattern above.  */
15826   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15827                               GEN_INT (GET_MODE_SIZE (GET_MODE
15828                                                       (operands[2]))));
15829   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15830     {
15831       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15832                                       operands[3]));
15833       DONE;
15834     }
15835 })
15836
15837 (define_expand "strset_singleop"
15838   [(parallel [(set (match_operand 1 "memory_operand" "")
15839                    (match_operand 2 "register_operand" ""))
15840               (set (match_operand 0 "register_operand" "")
15841                    (match_operand 3 "" ""))])]
15842   ""
15843   "ix86_current_function_needs_cld = 1;")
15844
15845 (define_insn "*strsetdi_rex_1"
15846   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15847         (match_operand:DI 2 "register_operand" "a"))
15848    (set (match_operand:DI 0 "register_operand" "=D")
15849         (plus:DI (match_dup 1)
15850                  (const_int 8)))]
15851   "TARGET_64BIT"
15852   "stosq"
15853   [(set_attr "type" "str")
15854    (set_attr "memory" "store")
15855    (set_attr "mode" "DI")])
15856
15857 (define_insn "*strsetsi_1"
15858   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15859         (match_operand:SI 2 "register_operand" "a"))
15860    (set (match_operand:P 0 "register_operand" "=D")
15861         (plus:P (match_dup 1)
15862                 (const_int 4)))]
15863   ""
15864   "stos{l|d}"
15865   [(set_attr "type" "str")
15866    (set_attr "memory" "store")
15867    (set_attr "mode" "SI")])
15868
15869 (define_insn "*strsethi_1"
15870   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15871         (match_operand:HI 2 "register_operand" "a"))
15872    (set (match_operand:P 0 "register_operand" "=D")
15873         (plus:P (match_dup 1)
15874                 (const_int 2)))]
15875   ""
15876   "stosw"
15877   [(set_attr "type" "str")
15878    (set_attr "memory" "store")
15879    (set_attr "mode" "HI")])
15880
15881 (define_insn "*strsetqi_1"
15882   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15883         (match_operand:QI 2 "register_operand" "a"))
15884    (set (match_operand:P 0 "register_operand" "=D")
15885         (plus:P (match_dup 1)
15886                 (const_int 1)))]
15887   ""
15888   "stosb"
15889   [(set_attr "type" "str")
15890    (set_attr "memory" "store")
15891    (set (attr "prefix_rex")
15892         (if_then_else
15893           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15894           (const_string "0")
15895           (const_string "*")))
15896    (set_attr "mode" "QI")])
15897
15898 (define_expand "rep_stos"
15899   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15900               (set (match_operand 0 "register_operand" "")
15901                    (match_operand 4 "" ""))
15902               (set (match_operand 2 "memory_operand" "") (const_int 0))
15903               (use (match_operand 3 "register_operand" ""))
15904               (use (match_dup 1))])]
15905   ""
15906   "ix86_current_function_needs_cld = 1;")
15907
15908 (define_insn "*rep_stosdi_rex64"
15909   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15910    (set (match_operand:DI 0 "register_operand" "=D")
15911         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15912                             (const_int 3))
15913                  (match_operand:DI 3 "register_operand" "0")))
15914    (set (mem:BLK (match_dup 3))
15915         (const_int 0))
15916    (use (match_operand:DI 2 "register_operand" "a"))
15917    (use (match_dup 4))]
15918   "TARGET_64BIT"
15919   "rep{%;} stosq"
15920   [(set_attr "type" "str")
15921    (set_attr "prefix_rep" "1")
15922    (set_attr "memory" "store")
15923    (set_attr "mode" "DI")])
15924
15925 (define_insn "*rep_stossi"
15926   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15927    (set (match_operand:P 0 "register_operand" "=D")
15928         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15929                           (const_int 2))
15930                  (match_operand:P 3 "register_operand" "0")))
15931    (set (mem:BLK (match_dup 3))
15932         (const_int 0))
15933    (use (match_operand:SI 2 "register_operand" "a"))
15934    (use (match_dup 4))]
15935   ""
15936   "rep{%;} stos{l|d}"
15937   [(set_attr "type" "str")
15938    (set_attr "prefix_rep" "1")
15939    (set_attr "memory" "store")
15940    (set_attr "mode" "SI")])
15941
15942 (define_insn "*rep_stosqi"
15943   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15944    (set (match_operand:P 0 "register_operand" "=D")
15945         (plus:P (match_operand:P 3 "register_operand" "0")
15946                 (match_operand:P 4 "register_operand" "1")))
15947    (set (mem:BLK (match_dup 3))
15948         (const_int 0))
15949    (use (match_operand:QI 2 "register_operand" "a"))
15950    (use (match_dup 4))]
15951   ""
15952   "rep{%;} stosb"
15953   [(set_attr "type" "str")
15954    (set_attr "prefix_rep" "1")
15955    (set_attr "memory" "store")
15956    (set (attr "prefix_rex")
15957         (if_then_else
15958           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15959           (const_string "0")
15960           (const_string "*")))
15961    (set_attr "mode" "QI")])
15962
15963 (define_expand "cmpstrnsi"
15964   [(set (match_operand:SI 0 "register_operand" "")
15965         (compare:SI (match_operand:BLK 1 "general_operand" "")
15966                     (match_operand:BLK 2 "general_operand" "")))
15967    (use (match_operand 3 "general_operand" ""))
15968    (use (match_operand 4 "immediate_operand" ""))]
15969   ""
15970 {
15971   rtx addr1, addr2, out, outlow, count, countreg, align;
15972
15973   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15974     FAIL;
15975
15976   /* Can't use this if the user has appropriated esi or edi.  */
15977   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15978     FAIL;
15979
15980   out = operands[0];
15981   if (!REG_P (out))
15982     out = gen_reg_rtx (SImode);
15983
15984   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15985   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15986   if (addr1 != XEXP (operands[1], 0))
15987     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15988   if (addr2 != XEXP (operands[2], 0))
15989     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15990
15991   count = operands[3];
15992   countreg = ix86_zero_extend_to_Pmode (count);
15993
15994   /* %%% Iff we are testing strict equality, we can use known alignment
15995      to good advantage.  This may be possible with combine, particularly
15996      once cc0 is dead.  */
15997   align = operands[4];
15998
15999   if (CONST_INT_P (count))
16000     {
16001       if (INTVAL (count) == 0)
16002         {
16003           emit_move_insn (operands[0], const0_rtx);
16004           DONE;
16005         }
16006       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16007                                      operands[1], operands[2]));
16008     }
16009   else
16010     {
16011       rtx (*gen_cmp) (rtx, rtx);
16012
16013       gen_cmp = (TARGET_64BIT
16014                  ? gen_cmpdi_1 : gen_cmpsi_1);
16015
16016       emit_insn (gen_cmp (countreg, countreg));
16017       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16018                                   operands[1], operands[2]));
16019     }
16020
16021   outlow = gen_lowpart (QImode, out);
16022   emit_insn (gen_cmpintqi (outlow));
16023   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16024
16025   if (operands[0] != out)
16026     emit_move_insn (operands[0], out);
16027
16028   DONE;
16029 })
16030
16031 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16032
16033 (define_expand "cmpintqi"
16034   [(set (match_dup 1)
16035         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16036    (set (match_dup 2)
16037         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16038    (parallel [(set (match_operand:QI 0 "register_operand" "")
16039                    (minus:QI (match_dup 1)
16040                              (match_dup 2)))
16041               (clobber (reg:CC FLAGS_REG))])]
16042   ""
16043 {
16044   operands[1] = gen_reg_rtx (QImode);
16045   operands[2] = gen_reg_rtx (QImode);
16046 })
16047
16048 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16049 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16050
16051 (define_expand "cmpstrnqi_nz_1"
16052   [(parallel [(set (reg:CC FLAGS_REG)
16053                    (compare:CC (match_operand 4 "memory_operand" "")
16054                                (match_operand 5 "memory_operand" "")))
16055               (use (match_operand 2 "register_operand" ""))
16056               (use (match_operand:SI 3 "immediate_operand" ""))
16057               (clobber (match_operand 0 "register_operand" ""))
16058               (clobber (match_operand 1 "register_operand" ""))
16059               (clobber (match_dup 2))])]
16060   ""
16061   "ix86_current_function_needs_cld = 1;")
16062
16063 (define_insn "*cmpstrnqi_nz_1"
16064   [(set (reg:CC FLAGS_REG)
16065         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16066                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16067    (use (match_operand:P 6 "register_operand" "2"))
16068    (use (match_operand:SI 3 "immediate_operand" "i"))
16069    (clobber (match_operand:P 0 "register_operand" "=S"))
16070    (clobber (match_operand:P 1 "register_operand" "=D"))
16071    (clobber (match_operand:P 2 "register_operand" "=c"))]
16072   ""
16073   "repz{%;} cmpsb"
16074   [(set_attr "type" "str")
16075    (set_attr "mode" "QI")
16076    (set (attr "prefix_rex")
16077         (if_then_else
16078           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16079           (const_string "0")
16080           (const_string "*")))
16081    (set_attr "prefix_rep" "1")])
16082
16083 ;; The same, but the count is not known to not be zero.
16084
16085 (define_expand "cmpstrnqi_1"
16086   [(parallel [(set (reg:CC FLAGS_REG)
16087                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16088                                      (const_int 0))
16089                   (compare:CC (match_operand 4 "memory_operand" "")
16090                               (match_operand 5 "memory_operand" ""))
16091                   (const_int 0)))
16092               (use (match_operand:SI 3 "immediate_operand" ""))
16093               (use (reg:CC FLAGS_REG))
16094               (clobber (match_operand 0 "register_operand" ""))
16095               (clobber (match_operand 1 "register_operand" ""))
16096               (clobber (match_dup 2))])]
16097   ""
16098   "ix86_current_function_needs_cld = 1;")
16099
16100 (define_insn "*cmpstrnqi_1"
16101   [(set (reg:CC FLAGS_REG)
16102         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16103                              (const_int 0))
16104           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16105                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16106           (const_int 0)))
16107    (use (match_operand:SI 3 "immediate_operand" "i"))
16108    (use (reg:CC FLAGS_REG))
16109    (clobber (match_operand:P 0 "register_operand" "=S"))
16110    (clobber (match_operand:P 1 "register_operand" "=D"))
16111    (clobber (match_operand:P 2 "register_operand" "=c"))]
16112   ""
16113   "repz{%;} cmpsb"
16114   [(set_attr "type" "str")
16115    (set_attr "mode" "QI")
16116    (set (attr "prefix_rex")
16117         (if_then_else
16118           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16119           (const_string "0")
16120           (const_string "*")))
16121    (set_attr "prefix_rep" "1")])
16122
16123 (define_expand "strlen<mode>"
16124   [(set (match_operand:SWI48x 0 "register_operand" "")
16125         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16126                         (match_operand:QI 2 "immediate_operand" "")
16127                         (match_operand 3 "immediate_operand" "")]
16128                        UNSPEC_SCAS))]
16129   ""
16130 {
16131  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16132    DONE;
16133  else
16134    FAIL;
16135 })
16136
16137 (define_expand "strlenqi_1"
16138   [(parallel [(set (match_operand 0 "register_operand" "")
16139                    (match_operand 2 "" ""))
16140               (clobber (match_operand 1 "register_operand" ""))
16141               (clobber (reg:CC FLAGS_REG))])]
16142   ""
16143   "ix86_current_function_needs_cld = 1;")
16144
16145 (define_insn "*strlenqi_1"
16146   [(set (match_operand:P 0 "register_operand" "=&c")
16147         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16148                    (match_operand:QI 2 "register_operand" "a")
16149                    (match_operand:P 3 "immediate_operand" "i")
16150                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16151    (clobber (match_operand:P 1 "register_operand" "=D"))
16152    (clobber (reg:CC FLAGS_REG))]
16153   ""
16154   "repnz{%;} scasb"
16155   [(set_attr "type" "str")
16156    (set_attr "mode" "QI")
16157    (set (attr "prefix_rex")
16158         (if_then_else
16159           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16160           (const_string "0")
16161           (const_string "*")))
16162    (set_attr "prefix_rep" "1")])
16163
16164 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16165 ;; handled in combine, but it is not currently up to the task.
16166 ;; When used for their truth value, the cmpstrn* expanders generate
16167 ;; code like this:
16168 ;;
16169 ;;   repz cmpsb
16170 ;;   seta       %al
16171 ;;   setb       %dl
16172 ;;   cmpb       %al, %dl
16173 ;;   jcc        label
16174 ;;
16175 ;; The intermediate three instructions are unnecessary.
16176
16177 ;; This one handles cmpstrn*_nz_1...
16178 (define_peephole2
16179   [(parallel[
16180      (set (reg:CC FLAGS_REG)
16181           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16182                       (mem:BLK (match_operand 5 "register_operand" ""))))
16183      (use (match_operand 6 "register_operand" ""))
16184      (use (match_operand:SI 3 "immediate_operand" ""))
16185      (clobber (match_operand 0 "register_operand" ""))
16186      (clobber (match_operand 1 "register_operand" ""))
16187      (clobber (match_operand 2 "register_operand" ""))])
16188    (set (match_operand:QI 7 "register_operand" "")
16189         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16190    (set (match_operand:QI 8 "register_operand" "")
16191         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16192    (set (reg FLAGS_REG)
16193         (compare (match_dup 7) (match_dup 8)))
16194   ]
16195   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16196   [(parallel[
16197      (set (reg:CC FLAGS_REG)
16198           (compare:CC (mem:BLK (match_dup 4))
16199                       (mem:BLK (match_dup 5))))
16200      (use (match_dup 6))
16201      (use (match_dup 3))
16202      (clobber (match_dup 0))
16203      (clobber (match_dup 1))
16204      (clobber (match_dup 2))])])
16205
16206 ;; ...and this one handles cmpstrn*_1.
16207 (define_peephole2
16208   [(parallel[
16209      (set (reg:CC FLAGS_REG)
16210           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16211                                (const_int 0))
16212             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16213                         (mem:BLK (match_operand 5 "register_operand" "")))
16214             (const_int 0)))
16215      (use (match_operand:SI 3 "immediate_operand" ""))
16216      (use (reg:CC FLAGS_REG))
16217      (clobber (match_operand 0 "register_operand" ""))
16218      (clobber (match_operand 1 "register_operand" ""))
16219      (clobber (match_operand 2 "register_operand" ""))])
16220    (set (match_operand:QI 7 "register_operand" "")
16221         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16222    (set (match_operand:QI 8 "register_operand" "")
16223         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16224    (set (reg FLAGS_REG)
16225         (compare (match_dup 7) (match_dup 8)))
16226   ]
16227   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16228   [(parallel[
16229      (set (reg:CC FLAGS_REG)
16230           (if_then_else:CC (ne (match_dup 6)
16231                                (const_int 0))
16232             (compare:CC (mem:BLK (match_dup 4))
16233                         (mem:BLK (match_dup 5)))
16234             (const_int 0)))
16235      (use (match_dup 3))
16236      (use (reg:CC FLAGS_REG))
16237      (clobber (match_dup 0))
16238      (clobber (match_dup 1))
16239      (clobber (match_dup 2))])])
16240 \f
16241 ;; Conditional move instructions.
16242
16243 (define_expand "mov<mode>cc"
16244   [(set (match_operand:SWIM 0 "register_operand" "")
16245         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16246                            (match_operand:SWIM 2 "general_operand" "")
16247                            (match_operand:SWIM 3 "general_operand" "")))]
16248   ""
16249   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16250
16251 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16252 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16253 ;; So just document what we're doing explicitly.
16254
16255 (define_expand "x86_mov<mode>cc_0_m1"
16256   [(parallel
16257     [(set (match_operand:SWI48 0 "register_operand" "")
16258           (if_then_else:SWI48
16259             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16260              [(match_operand 1 "flags_reg_operand" "")
16261               (const_int 0)])
16262             (const_int -1)
16263             (const_int 0)))
16264      (clobber (reg:CC FLAGS_REG))])])
16265
16266 (define_insn "*x86_mov<mode>cc_0_m1"
16267   [(set (match_operand:SWI48 0 "register_operand" "=r")
16268         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16269                              [(reg FLAGS_REG) (const_int 0)])
16270           (const_int -1)
16271           (const_int 0)))
16272    (clobber (reg:CC FLAGS_REG))]
16273   ""
16274   "sbb{<imodesuffix>}\t%0, %0"
16275   ; Since we don't have the proper number of operands for an alu insn,
16276   ; fill in all the blanks.
16277   [(set_attr "type" "alu")
16278    (set_attr "use_carry" "1")
16279    (set_attr "pent_pair" "pu")
16280    (set_attr "memory" "none")
16281    (set_attr "imm_disp" "false")
16282    (set_attr "mode" "<MODE>")
16283    (set_attr "length_immediate" "0")])
16284
16285 (define_insn "*x86_mov<mode>cc_0_m1_se"
16286   [(set (match_operand:SWI48 0 "register_operand" "=r")
16287         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16288                              [(reg FLAGS_REG) (const_int 0)])
16289                             (const_int 1)
16290                             (const_int 0)))
16291    (clobber (reg:CC FLAGS_REG))]
16292   ""
16293   "sbb{<imodesuffix>}\t%0, %0"
16294   [(set_attr "type" "alu")
16295    (set_attr "use_carry" "1")
16296    (set_attr "pent_pair" "pu")
16297    (set_attr "memory" "none")
16298    (set_attr "imm_disp" "false")
16299    (set_attr "mode" "<MODE>")
16300    (set_attr "length_immediate" "0")])
16301
16302 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16303   [(set (match_operand:SWI48 0 "register_operand" "=r")
16304         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16305                     [(reg FLAGS_REG) (const_int 0)])))]
16306   ""
16307   "sbb{<imodesuffix>}\t%0, %0"
16308   [(set_attr "type" "alu")
16309    (set_attr "use_carry" "1")
16310    (set_attr "pent_pair" "pu")
16311    (set_attr "memory" "none")
16312    (set_attr "imm_disp" "false")
16313    (set_attr "mode" "<MODE>")
16314    (set_attr "length_immediate" "0")])
16315
16316 (define_insn "*mov<mode>cc_noc"
16317   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16318         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16319                                [(reg FLAGS_REG) (const_int 0)])
16320           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16321           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16322   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16323   "@
16324    cmov%O2%C1\t{%2, %0|%0, %2}
16325    cmov%O2%c1\t{%3, %0|%0, %3}"
16326   [(set_attr "type" "icmov")
16327    (set_attr "mode" "<MODE>")])
16328
16329 (define_insn_and_split "*movqicc_noc"
16330   [(set (match_operand:QI 0 "register_operand" "=r,r")
16331         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16332                            [(match_operand 4 "flags_reg_operand" "")
16333                             (const_int 0)])
16334                       (match_operand:QI 2 "register_operand" "r,0")
16335                       (match_operand:QI 3 "register_operand" "0,r")))]
16336   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16337   "#"
16338   "&& reload_completed"
16339   [(set (match_dup 0)
16340         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16341                       (match_dup 2)
16342                       (match_dup 3)))]
16343   "operands[0] = gen_lowpart (SImode, operands[0]);
16344    operands[2] = gen_lowpart (SImode, operands[2]);
16345    operands[3] = gen_lowpart (SImode, operands[3]);"
16346   [(set_attr "type" "icmov")
16347    (set_attr "mode" "SI")])
16348
16349 (define_expand "mov<mode>cc"
16350   [(set (match_operand:X87MODEF 0 "register_operand" "")
16351         (if_then_else:X87MODEF
16352           (match_operand 1 "ix86_fp_comparison_operator" "")
16353           (match_operand:X87MODEF 2 "register_operand" "")
16354           (match_operand:X87MODEF 3 "register_operand" "")))]
16355   "(TARGET_80387 && TARGET_CMOVE)
16356    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16357   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16358
16359 (define_insn "*movxfcc_1"
16360   [(set (match_operand:XF 0 "register_operand" "=f,f")
16361         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16362                                 [(reg FLAGS_REG) (const_int 0)])
16363                       (match_operand:XF 2 "register_operand" "f,0")
16364                       (match_operand:XF 3 "register_operand" "0,f")))]
16365   "TARGET_80387 && TARGET_CMOVE"
16366   "@
16367    fcmov%F1\t{%2, %0|%0, %2}
16368    fcmov%f1\t{%3, %0|%0, %3}"
16369   [(set_attr "type" "fcmov")
16370    (set_attr "mode" "XF")])
16371
16372 (define_insn "*movdfcc_1_rex64"
16373   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16374         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16375                                 [(reg FLAGS_REG) (const_int 0)])
16376                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16377                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16378   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16379    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16380   "@
16381    fcmov%F1\t{%2, %0|%0, %2}
16382    fcmov%f1\t{%3, %0|%0, %3}
16383    cmov%O2%C1\t{%2, %0|%0, %2}
16384    cmov%O2%c1\t{%3, %0|%0, %3}"
16385   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16386    (set_attr "mode" "DF,DF,DI,DI")])
16387
16388 (define_insn "*movdfcc_1"
16389   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16390         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16391                                 [(reg FLAGS_REG) (const_int 0)])
16392                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16393                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16394   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16395    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16396   "@
16397    fcmov%F1\t{%2, %0|%0, %2}
16398    fcmov%f1\t{%3, %0|%0, %3}
16399    #
16400    #"
16401   [(set_attr "type" "fcmov,fcmov,multi,multi")
16402    (set_attr "mode" "DF,DF,DI,DI")])
16403
16404 (define_split
16405   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16406         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16407                                 [(match_operand 4 "flags_reg_operand" "")
16408                                  (const_int 0)])
16409                       (match_operand:DF 2 "nonimmediate_operand" "")
16410                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16411   "!TARGET_64BIT && reload_completed"
16412   [(set (match_dup 2)
16413         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16414                       (match_dup 5)
16415                       (match_dup 6)))
16416    (set (match_dup 3)
16417         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16418                       (match_dup 7)
16419                       (match_dup 8)))]
16420 {
16421   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16422   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16423 })
16424
16425 (define_insn "*movsfcc_1_387"
16426   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16427         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16428                                 [(reg FLAGS_REG) (const_int 0)])
16429                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16430                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16431   "TARGET_80387 && TARGET_CMOVE
16432    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16433   "@
16434    fcmov%F1\t{%2, %0|%0, %2}
16435    fcmov%f1\t{%3, %0|%0, %3}
16436    cmov%O2%C1\t{%2, %0|%0, %2}
16437    cmov%O2%c1\t{%3, %0|%0, %3}"
16438   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16439    (set_attr "mode" "SF,SF,SI,SI")])
16440
16441 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16442 ;; the scalar versions to have only XMM registers as operands.
16443
16444 ;; XOP conditional move
16445 (define_insn "*xop_pcmov_<mode>"
16446   [(set (match_operand:MODEF 0 "register_operand" "=x")
16447         (if_then_else:MODEF
16448           (match_operand:MODEF 1 "register_operand" "x")
16449           (match_operand:MODEF 2 "register_operand" "x")
16450           (match_operand:MODEF 3 "register_operand" "x")))]
16451   "TARGET_XOP"
16452   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16453   [(set_attr "type" "sse4arg")])
16454
16455 ;; These versions of the min/max patterns are intentionally ignorant of
16456 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16457 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16458 ;; are undefined in this condition, we're certain this is correct.
16459
16460 (define_insn "*avx_<code><mode>3"
16461   [(set (match_operand:MODEF 0 "register_operand" "=x")
16462         (smaxmin:MODEF
16463           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16464           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16465   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16466   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16467   [(set_attr "type" "sseadd")
16468    (set_attr "prefix" "vex")
16469    (set_attr "mode" "<MODE>")])
16470
16471 (define_insn "<code><mode>3"
16472   [(set (match_operand:MODEF 0 "register_operand" "=x")
16473         (smaxmin:MODEF
16474           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16475           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16476   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16477   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16478   [(set_attr "type" "sseadd")
16479    (set_attr "mode" "<MODE>")])
16480
16481 ;; These versions of the min/max patterns implement exactly the operations
16482 ;;   min = (op1 < op2 ? op1 : op2)
16483 ;;   max = (!(op1 < op2) ? op1 : op2)
16484 ;; Their operands are not commutative, and thus they may be used in the
16485 ;; presence of -0.0 and NaN.
16486
16487 (define_insn "*avx_ieee_smin<mode>3"
16488   [(set (match_operand:MODEF 0 "register_operand" "=x")
16489         (unspec:MODEF
16490           [(match_operand:MODEF 1 "register_operand" "x")
16491            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16492          UNSPEC_IEEE_MIN))]
16493   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16494   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16495   [(set_attr "type" "sseadd")
16496    (set_attr "prefix" "vex")
16497    (set_attr "mode" "<MODE>")])
16498
16499 (define_insn "*ieee_smin<mode>3"
16500   [(set (match_operand:MODEF 0 "register_operand" "=x")
16501         (unspec:MODEF
16502           [(match_operand:MODEF 1 "register_operand" "0")
16503            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16504          UNSPEC_IEEE_MIN))]
16505   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16506   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16507   [(set_attr "type" "sseadd")
16508    (set_attr "mode" "<MODE>")])
16509
16510 (define_insn "*avx_ieee_smax<mode>3"
16511   [(set (match_operand:MODEF 0 "register_operand" "=x")
16512         (unspec:MODEF
16513           [(match_operand:MODEF 1 "register_operand" "0")
16514            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16515          UNSPEC_IEEE_MAX))]
16516   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16517   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16518   [(set_attr "type" "sseadd")
16519    (set_attr "prefix" "vex")
16520    (set_attr "mode" "<MODE>")])
16521
16522 (define_insn "*ieee_smax<mode>3"
16523   [(set (match_operand:MODEF 0 "register_operand" "=x")
16524         (unspec:MODEF
16525           [(match_operand:MODEF 1 "register_operand" "0")
16526            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16527          UNSPEC_IEEE_MAX))]
16528   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16529   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16530   [(set_attr "type" "sseadd")
16531    (set_attr "mode" "<MODE>")])
16532
16533 ;; Make two stack loads independent:
16534 ;;   fld aa              fld aa
16535 ;;   fld %st(0)     ->   fld bb
16536 ;;   fmul bb             fmul %st(1), %st
16537 ;;
16538 ;; Actually we only match the last two instructions for simplicity.
16539 (define_peephole2
16540   [(set (match_operand 0 "fp_register_operand" "")
16541         (match_operand 1 "fp_register_operand" ""))
16542    (set (match_dup 0)
16543         (match_operator 2 "binary_fp_operator"
16544            [(match_dup 0)
16545             (match_operand 3 "memory_operand" "")]))]
16546   "REGNO (operands[0]) != REGNO (operands[1])"
16547   [(set (match_dup 0) (match_dup 3))
16548    (set (match_dup 0) (match_dup 4))]
16549
16550   ;; The % modifier is not operational anymore in peephole2's, so we have to
16551   ;; swap the operands manually in the case of addition and multiplication.
16552   "if (COMMUTATIVE_ARITH_P (operands[2]))
16553      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16554                                    GET_MODE (operands[2]),
16555                                    operands[0], operands[1]);
16556    else
16557      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16558                                    GET_MODE (operands[2]),
16559                                    operands[1], operands[0]);")
16560
16561 ;; Conditional addition patterns
16562 (define_expand "add<mode>cc"
16563   [(match_operand:SWI 0 "register_operand" "")
16564    (match_operand 1 "ordered_comparison_operator" "")
16565    (match_operand:SWI 2 "register_operand" "")
16566    (match_operand:SWI 3 "const_int_operand" "")]
16567   ""
16568   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16569 \f
16570 ;; Misc patterns (?)
16571
16572 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16573 ;; Otherwise there will be nothing to keep
16574 ;;
16575 ;; [(set (reg ebp) (reg esp))]
16576 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16577 ;;  (clobber (eflags)]
16578 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16579 ;;
16580 ;; in proper program order.
16581
16582 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16583   [(set (match_operand:P 0 "register_operand" "=r,r")
16584         (plus:P (match_operand:P 1 "register_operand" "0,r")
16585                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16586    (clobber (reg:CC FLAGS_REG))
16587    (clobber (mem:BLK (scratch)))]
16588   ""
16589 {
16590   switch (get_attr_type (insn))
16591     {
16592     case TYPE_IMOV:
16593       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16594
16595     case TYPE_ALU:
16596       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16597       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16598         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16599
16600       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16601
16602     default:
16603       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16604       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16605     }
16606 }
16607   [(set (attr "type")
16608         (cond [(and (eq_attr "alternative" "0")
16609                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16610                  (const_string "alu")
16611                (match_operand:<MODE> 2 "const0_operand" "")
16612                  (const_string "imov")
16613               ]
16614               (const_string "lea")))
16615    (set (attr "length_immediate")
16616         (cond [(eq_attr "type" "imov")
16617                  (const_string "0")
16618                (and (eq_attr "type" "alu")
16619                     (match_operand 2 "const128_operand" ""))
16620                  (const_string "1")
16621               ]
16622               (const_string "*")))
16623    (set_attr "mode" "<MODE>")])
16624
16625 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16626   [(set (match_operand:P 0 "register_operand" "=r")
16627         (minus:P (match_operand:P 1 "register_operand" "0")
16628                  (match_operand:P 2 "register_operand" "r")))
16629    (clobber (reg:CC FLAGS_REG))
16630    (clobber (mem:BLK (scratch)))]
16631   ""
16632   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16633   [(set_attr "type" "alu")
16634    (set_attr "mode" "<MODE>")])
16635
16636 (define_insn "allocate_stack_worker_probe_<mode>"
16637   [(set (match_operand:P 0 "register_operand" "=a")
16638         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16639                             UNSPECV_STACK_PROBE))
16640    (clobber (reg:CC FLAGS_REG))]
16641   "ix86_target_stack_probe ()"
16642   "call\t___chkstk_ms"
16643   [(set_attr "type" "multi")
16644    (set_attr "length" "5")])
16645
16646 (define_expand "allocate_stack"
16647   [(match_operand 0 "register_operand" "")
16648    (match_operand 1 "general_operand" "")]
16649   "ix86_target_stack_probe ()"
16650 {
16651   rtx x;
16652
16653 #ifndef CHECK_STACK_LIMIT
16654 #define CHECK_STACK_LIMIT 0
16655 #endif
16656
16657   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16658       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16659     {
16660       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16661                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16662       if (x != stack_pointer_rtx)
16663         emit_move_insn (stack_pointer_rtx, x);
16664     }
16665   else
16666     {
16667       x = copy_to_mode_reg (Pmode, operands[1]);
16668       if (TARGET_64BIT)
16669         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16670       else
16671         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16672       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16673                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16674       if (x != stack_pointer_rtx)
16675         emit_move_insn (stack_pointer_rtx, x);
16676     }
16677
16678   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16679   DONE;
16680 })
16681
16682 ;; Use IOR for stack probes, this is shorter.
16683 (define_expand "probe_stack"
16684   [(match_operand 0 "memory_operand" "")]
16685   ""
16686 {
16687   rtx (*gen_ior3) (rtx, rtx, rtx);
16688
16689   gen_ior3 = (GET_MODE (operands[0]) == DImode
16690               ? gen_iordi3 : gen_iorsi3);
16691
16692   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16693   DONE;
16694 })
16695
16696 (define_insn "adjust_stack_and_probe<mode>"
16697   [(set (match_operand:P 0 "register_operand" "=r")
16698         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16699                             UNSPECV_PROBE_STACK_RANGE))
16700    (set (reg:P SP_REG)
16701         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16702    (clobber (reg:CC FLAGS_REG))
16703    (clobber (mem:BLK (scratch)))]
16704   ""
16705   "* return output_adjust_stack_and_probe (operands[0]);"
16706   [(set_attr "type" "multi")])
16707
16708 (define_insn "probe_stack_range<mode>"
16709   [(set (match_operand:P 0 "register_operand" "=r")
16710         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16711                             (match_operand:P 2 "const_int_operand" "n")]
16712                             UNSPECV_PROBE_STACK_RANGE))
16713    (clobber (reg:CC FLAGS_REG))]
16714   ""
16715   "* return output_probe_stack_range (operands[0], operands[2]);"
16716   [(set_attr "type" "multi")])
16717
16718 (define_expand "builtin_setjmp_receiver"
16719   [(label_ref (match_operand 0 "" ""))]
16720   "!TARGET_64BIT && flag_pic"
16721 {
16722 #if TARGET_MACHO
16723   if (TARGET_MACHO)
16724     {
16725       rtx xops[3];
16726       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16727       rtx label_rtx = gen_label_rtx ();
16728       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16729       xops[0] = xops[1] = picreg;
16730       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16731       ix86_expand_binary_operator (MINUS, SImode, xops);
16732     }
16733   else
16734 #endif
16735     emit_insn (gen_set_got (pic_offset_table_rtx));
16736   DONE;
16737 })
16738 \f
16739 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16740
16741 (define_split
16742   [(set (match_operand 0 "register_operand" "")
16743         (match_operator 3 "promotable_binary_operator"
16744            [(match_operand 1 "register_operand" "")
16745             (match_operand 2 "aligned_operand" "")]))
16746    (clobber (reg:CC FLAGS_REG))]
16747   "! TARGET_PARTIAL_REG_STALL && reload_completed
16748    && ((GET_MODE (operands[0]) == HImode
16749         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16750             /* ??? next two lines just !satisfies_constraint_K (...) */
16751             || !CONST_INT_P (operands[2])
16752             || satisfies_constraint_K (operands[2])))
16753        || (GET_MODE (operands[0]) == QImode
16754            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16755   [(parallel [(set (match_dup 0)
16756                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16757               (clobber (reg:CC FLAGS_REG))])]
16758   "operands[0] = gen_lowpart (SImode, operands[0]);
16759    operands[1] = gen_lowpart (SImode, operands[1]);
16760    if (GET_CODE (operands[3]) != ASHIFT)
16761      operands[2] = gen_lowpart (SImode, operands[2]);
16762    PUT_MODE (operands[3], SImode);")
16763
16764 ; Promote the QImode tests, as i386 has encoding of the AND
16765 ; instruction with 32-bit sign-extended immediate and thus the
16766 ; instruction size is unchanged, except in the %eax case for
16767 ; which it is increased by one byte, hence the ! optimize_size.
16768 (define_split
16769   [(set (match_operand 0 "flags_reg_operand" "")
16770         (match_operator 2 "compare_operator"
16771           [(and (match_operand 3 "aligned_operand" "")
16772                 (match_operand 4 "const_int_operand" ""))
16773            (const_int 0)]))
16774    (set (match_operand 1 "register_operand" "")
16775         (and (match_dup 3) (match_dup 4)))]
16776   "! TARGET_PARTIAL_REG_STALL && reload_completed
16777    && optimize_insn_for_speed_p ()
16778    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16779        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16780    /* Ensure that the operand will remain sign-extended immediate.  */
16781    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16782   [(parallel [(set (match_dup 0)
16783                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16784                                     (const_int 0)]))
16785               (set (match_dup 1)
16786                    (and:SI (match_dup 3) (match_dup 4)))])]
16787 {
16788   operands[4]
16789     = gen_int_mode (INTVAL (operands[4])
16790                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16791   operands[1] = gen_lowpart (SImode, operands[1]);
16792   operands[3] = gen_lowpart (SImode, operands[3]);
16793 })
16794
16795 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16796 ; the TEST instruction with 32-bit sign-extended immediate and thus
16797 ; the instruction size would at least double, which is not what we
16798 ; want even with ! optimize_size.
16799 (define_split
16800   [(set (match_operand 0 "flags_reg_operand" "")
16801         (match_operator 1 "compare_operator"
16802           [(and (match_operand:HI 2 "aligned_operand" "")
16803                 (match_operand:HI 3 "const_int_operand" ""))
16804            (const_int 0)]))]
16805   "! TARGET_PARTIAL_REG_STALL && reload_completed
16806    && ! TARGET_FAST_PREFIX
16807    && optimize_insn_for_speed_p ()
16808    /* Ensure that the operand will remain sign-extended immediate.  */
16809    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16810   [(set (match_dup 0)
16811         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16812                          (const_int 0)]))]
16813 {
16814   operands[3]
16815     = gen_int_mode (INTVAL (operands[3])
16816                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16817   operands[2] = gen_lowpart (SImode, operands[2]);
16818 })
16819
16820 (define_split
16821   [(set (match_operand 0 "register_operand" "")
16822         (neg (match_operand 1 "register_operand" "")))
16823    (clobber (reg:CC FLAGS_REG))]
16824   "! TARGET_PARTIAL_REG_STALL && reload_completed
16825    && (GET_MODE (operands[0]) == HImode
16826        || (GET_MODE (operands[0]) == QImode
16827            && (TARGET_PROMOTE_QImode
16828                || optimize_insn_for_size_p ())))"
16829   [(parallel [(set (match_dup 0)
16830                    (neg:SI (match_dup 1)))
16831               (clobber (reg:CC FLAGS_REG))])]
16832   "operands[0] = gen_lowpart (SImode, operands[0]);
16833    operands[1] = gen_lowpart (SImode, operands[1]);")
16834
16835 (define_split
16836   [(set (match_operand 0 "register_operand" "")
16837         (not (match_operand 1 "register_operand" "")))]
16838   "! TARGET_PARTIAL_REG_STALL && reload_completed
16839    && (GET_MODE (operands[0]) == HImode
16840        || (GET_MODE (operands[0]) == QImode
16841            && (TARGET_PROMOTE_QImode
16842                || optimize_insn_for_size_p ())))"
16843   [(set (match_dup 0)
16844         (not:SI (match_dup 1)))]
16845   "operands[0] = gen_lowpart (SImode, operands[0]);
16846    operands[1] = gen_lowpart (SImode, operands[1]);")
16847
16848 (define_split
16849   [(set (match_operand 0 "register_operand" "")
16850         (if_then_else (match_operator 1 "ordered_comparison_operator"
16851                                 [(reg FLAGS_REG) (const_int 0)])
16852                       (match_operand 2 "register_operand" "")
16853                       (match_operand 3 "register_operand" "")))]
16854   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16855    && (GET_MODE (operands[0]) == HImode
16856        || (GET_MODE (operands[0]) == QImode
16857            && (TARGET_PROMOTE_QImode
16858                || optimize_insn_for_size_p ())))"
16859   [(set (match_dup 0)
16860         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16861   "operands[0] = gen_lowpart (SImode, operands[0]);
16862    operands[2] = gen_lowpart (SImode, operands[2]);
16863    operands[3] = gen_lowpart (SImode, operands[3]);")
16864 \f
16865 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16866 ;; transform a complex memory operation into two memory to register operations.
16867
16868 ;; Don't push memory operands
16869 (define_peephole2
16870   [(set (match_operand:SWI 0 "push_operand" "")
16871         (match_operand:SWI 1 "memory_operand" ""))
16872    (match_scratch:SWI 2 "<r>")]
16873   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16874    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16875   [(set (match_dup 2) (match_dup 1))
16876    (set (match_dup 0) (match_dup 2))])
16877
16878 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16879 ;; SImode pushes.
16880 (define_peephole2
16881   [(set (match_operand:SF 0 "push_operand" "")
16882         (match_operand:SF 1 "memory_operand" ""))
16883    (match_scratch:SF 2 "r")]
16884   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16885    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16886   [(set (match_dup 2) (match_dup 1))
16887    (set (match_dup 0) (match_dup 2))])
16888
16889 ;; Don't move an immediate directly to memory when the instruction
16890 ;; gets too big.
16891 (define_peephole2
16892   [(match_scratch:SWI124 1 "<r>")
16893    (set (match_operand:SWI124 0 "memory_operand" "")
16894         (const_int 0))]
16895   "optimize_insn_for_speed_p ()
16896    && !TARGET_USE_MOV0
16897    && TARGET_SPLIT_LONG_MOVES
16898    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16899    && peep2_regno_dead_p (0, FLAGS_REG)"
16900   [(parallel [(set (match_dup 2) (const_int 0))
16901               (clobber (reg:CC FLAGS_REG))])
16902    (set (match_dup 0) (match_dup 1))]
16903   "operands[2] = gen_lowpart (SImode, operands[1]);")
16904
16905 (define_peephole2
16906   [(match_scratch:SWI124 2 "<r>")
16907    (set (match_operand:SWI124 0 "memory_operand" "")
16908         (match_operand:SWI124 1 "immediate_operand" ""))]
16909   "optimize_insn_for_speed_p ()
16910    && TARGET_SPLIT_LONG_MOVES
16911    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16912   [(set (match_dup 2) (match_dup 1))
16913    (set (match_dup 0) (match_dup 2))])
16914
16915 ;; Don't compare memory with zero, load and use a test instead.
16916 (define_peephole2
16917   [(set (match_operand 0 "flags_reg_operand" "")
16918         (match_operator 1 "compare_operator"
16919           [(match_operand:SI 2 "memory_operand" "")
16920            (const_int 0)]))
16921    (match_scratch:SI 3 "r")]
16922   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16923   [(set (match_dup 3) (match_dup 2))
16924    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16925
16926 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16927 ;; Don't split NOTs with a displacement operand, because resulting XOR
16928 ;; will not be pairable anyway.
16929 ;;
16930 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16931 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16932 ;; so this split helps here as well.
16933 ;;
16934 ;; Note: Can't do this as a regular split because we can't get proper
16935 ;; lifetime information then.
16936
16937 (define_peephole2
16938   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16939         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16940   "optimize_insn_for_speed_p ()
16941    && ((TARGET_NOT_UNPAIRABLE
16942         && (!MEM_P (operands[0])
16943             || !memory_displacement_operand (operands[0], <MODE>mode)))
16944        || (TARGET_NOT_VECTORMODE
16945            && long_memory_operand (operands[0], <MODE>mode)))
16946    && peep2_regno_dead_p (0, FLAGS_REG)"
16947   [(parallel [(set (match_dup 0)
16948                    (xor:SWI124 (match_dup 1) (const_int -1)))
16949               (clobber (reg:CC FLAGS_REG))])])
16950
16951 ;; Non pairable "test imm, reg" instructions can be translated to
16952 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16953 ;; byte opcode instead of two, have a short form for byte operands),
16954 ;; so do it for other CPUs as well.  Given that the value was dead,
16955 ;; this should not create any new dependencies.  Pass on the sub-word
16956 ;; versions if we're concerned about partial register stalls.
16957
16958 (define_peephole2
16959   [(set (match_operand 0 "flags_reg_operand" "")
16960         (match_operator 1 "compare_operator"
16961           [(and:SI (match_operand:SI 2 "register_operand" "")
16962                    (match_operand:SI 3 "immediate_operand" ""))
16963            (const_int 0)]))]
16964   "ix86_match_ccmode (insn, CCNOmode)
16965    && (true_regnum (operands[2]) != AX_REG
16966        || satisfies_constraint_K (operands[3]))
16967    && peep2_reg_dead_p (1, operands[2])"
16968   [(parallel
16969      [(set (match_dup 0)
16970            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16971                             (const_int 0)]))
16972       (set (match_dup 2)
16973            (and:SI (match_dup 2) (match_dup 3)))])])
16974
16975 ;; We don't need to handle HImode case, because it will be promoted to SImode
16976 ;; on ! TARGET_PARTIAL_REG_STALL
16977
16978 (define_peephole2
16979   [(set (match_operand 0 "flags_reg_operand" "")
16980         (match_operator 1 "compare_operator"
16981           [(and:QI (match_operand:QI 2 "register_operand" "")
16982                    (match_operand:QI 3 "immediate_operand" ""))
16983            (const_int 0)]))]
16984   "! TARGET_PARTIAL_REG_STALL
16985    && ix86_match_ccmode (insn, CCNOmode)
16986    && true_regnum (operands[2]) != AX_REG
16987    && peep2_reg_dead_p (1, operands[2])"
16988   [(parallel
16989      [(set (match_dup 0)
16990            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16991                             (const_int 0)]))
16992       (set (match_dup 2)
16993            (and:QI (match_dup 2) (match_dup 3)))])])
16994
16995 (define_peephole2
16996   [(set (match_operand 0 "flags_reg_operand" "")
16997         (match_operator 1 "compare_operator"
16998           [(and:SI
16999              (zero_extract:SI
17000                (match_operand 2 "ext_register_operand" "")
17001                (const_int 8)
17002                (const_int 8))
17003              (match_operand 3 "const_int_operand" ""))
17004            (const_int 0)]))]
17005   "! TARGET_PARTIAL_REG_STALL
17006    && ix86_match_ccmode (insn, CCNOmode)
17007    && true_regnum (operands[2]) != AX_REG
17008    && peep2_reg_dead_p (1, operands[2])"
17009   [(parallel [(set (match_dup 0)
17010                    (match_op_dup 1
17011                      [(and:SI
17012                         (zero_extract:SI
17013                           (match_dup 2)
17014                           (const_int 8)
17015                           (const_int 8))
17016                         (match_dup 3))
17017                       (const_int 0)]))
17018               (set (zero_extract:SI (match_dup 2)
17019                                     (const_int 8)
17020                                     (const_int 8))
17021                    (and:SI
17022                      (zero_extract:SI
17023                        (match_dup 2)
17024                        (const_int 8)
17025                        (const_int 8))
17026                      (match_dup 3)))])])
17027
17028 ;; Don't do logical operations with memory inputs.
17029 (define_peephole2
17030   [(match_scratch:SI 2 "r")
17031    (parallel [(set (match_operand:SI 0 "register_operand" "")
17032                    (match_operator:SI 3 "arith_or_logical_operator"
17033                      [(match_dup 0)
17034                       (match_operand:SI 1 "memory_operand" "")]))
17035               (clobber (reg:CC FLAGS_REG))])]
17036   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17037   [(set (match_dup 2) (match_dup 1))
17038    (parallel [(set (match_dup 0)
17039                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17040               (clobber (reg:CC FLAGS_REG))])])
17041
17042 (define_peephole2
17043   [(match_scratch:SI 2 "r")
17044    (parallel [(set (match_operand:SI 0 "register_operand" "")
17045                    (match_operator:SI 3 "arith_or_logical_operator"
17046                      [(match_operand:SI 1 "memory_operand" "")
17047                       (match_dup 0)]))
17048               (clobber (reg:CC FLAGS_REG))])]
17049   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17050   [(set (match_dup 2) (match_dup 1))
17051    (parallel [(set (match_dup 0)
17052                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17053               (clobber (reg:CC FLAGS_REG))])])
17054
17055 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17056 ;; refers to the destination of the load!
17057
17058 (define_peephole2
17059   [(set (match_operand:SI 0 "register_operand" "")
17060         (match_operand:SI 1 "register_operand" ""))
17061    (parallel [(set (match_dup 0)
17062                    (match_operator:SI 3 "commutative_operator"
17063                      [(match_dup 0)
17064                       (match_operand:SI 2 "memory_operand" "")]))
17065               (clobber (reg:CC FLAGS_REG))])]
17066   "REGNO (operands[0]) != REGNO (operands[1])
17067    && GENERAL_REGNO_P (REGNO (operands[0]))
17068    && GENERAL_REGNO_P (REGNO (operands[1]))"
17069   [(set (match_dup 0) (match_dup 4))
17070    (parallel [(set (match_dup 0)
17071                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17072               (clobber (reg:CC FLAGS_REG))])]
17073   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17074
17075 (define_peephole2
17076   [(set (match_operand 0 "register_operand" "")
17077         (match_operand 1 "register_operand" ""))
17078    (set (match_dup 0)
17079                    (match_operator 3 "commutative_operator"
17080                      [(match_dup 0)
17081                       (match_operand 2 "memory_operand" "")]))]
17082   "REGNO (operands[0]) != REGNO (operands[1])
17083    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17084        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17085   [(set (match_dup 0) (match_dup 2))
17086    (set (match_dup 0)
17087         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17088
17089 ; Don't do logical operations with memory outputs
17090 ;
17091 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17092 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17093 ; the same decoder scheduling characteristics as the original.
17094
17095 (define_peephole2
17096   [(match_scratch:SI 2 "r")
17097    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17098                    (match_operator:SI 3 "arith_or_logical_operator"
17099                      [(match_dup 0)
17100                       (match_operand:SI 1 "nonmemory_operand" "")]))
17101               (clobber (reg:CC FLAGS_REG))])]
17102   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17103    /* Do not split stack checking probes.  */
17104    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17105   [(set (match_dup 2) (match_dup 0))
17106    (parallel [(set (match_dup 2)
17107                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17108               (clobber (reg:CC FLAGS_REG))])
17109    (set (match_dup 0) (match_dup 2))])
17110
17111 (define_peephole2
17112   [(match_scratch:SI 2 "r")
17113    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17114                    (match_operator:SI 3 "arith_or_logical_operator"
17115                      [(match_operand:SI 1 "nonmemory_operand" "")
17116                       (match_dup 0)]))
17117               (clobber (reg:CC FLAGS_REG))])]
17118   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17119    /* Do not split stack checking probes.  */
17120    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17121   [(set (match_dup 2) (match_dup 0))
17122    (parallel [(set (match_dup 2)
17123                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17124               (clobber (reg:CC FLAGS_REG))])
17125    (set (match_dup 0) (match_dup 2))])
17126
17127 ;; Attempt to always use XOR for zeroing registers.
17128 (define_peephole2
17129   [(set (match_operand 0 "register_operand" "")
17130         (match_operand 1 "const0_operand" ""))]
17131   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17132    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17133    && GENERAL_REG_P (operands[0])
17134    && peep2_regno_dead_p (0, FLAGS_REG)"
17135   [(parallel [(set (match_dup 0) (const_int 0))
17136               (clobber (reg:CC FLAGS_REG))])]
17137   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17138
17139 (define_peephole2
17140   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17141         (const_int 0))]
17142   "(GET_MODE (operands[0]) == QImode
17143     || GET_MODE (operands[0]) == HImode)
17144    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17145    && peep2_regno_dead_p (0, FLAGS_REG)"
17146   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17147               (clobber (reg:CC FLAGS_REG))])])
17148
17149 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17150 (define_peephole2
17151   [(set (match_operand:SWI248 0 "register_operand" "")
17152         (const_int -1))]
17153   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17154    && peep2_regno_dead_p (0, FLAGS_REG)"
17155   [(parallel [(set (match_dup 0) (const_int -1))
17156               (clobber (reg:CC FLAGS_REG))])]
17157 {
17158   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17159     operands[0] = gen_lowpart (SImode, operands[0]);
17160 })
17161
17162 ;; Attempt to convert simple lea to add/shift.
17163 ;; These can be created by move expanders.
17164
17165 (define_peephole2
17166   [(set (match_operand:SWI48 0 "register_operand" "")
17167         (plus:SWI48 (match_dup 0)
17168                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17169   "peep2_regno_dead_p (0, FLAGS_REG)"
17170   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17171               (clobber (reg:CC FLAGS_REG))])])
17172
17173 (define_peephole2
17174   [(set (match_operand:SI 0 "register_operand" "")
17175         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17176                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17177   "TARGET_64BIT
17178    && peep2_regno_dead_p (0, FLAGS_REG)
17179    && REGNO (operands[0]) == REGNO (operands[1])"
17180   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17181               (clobber (reg:CC FLAGS_REG))])]
17182   "operands[2] = gen_lowpart (SImode, operands[2]);")
17183
17184 (define_peephole2
17185   [(set (match_operand:SWI48 0 "register_operand" "")
17186         (mult:SWI48 (match_dup 0)
17187                     (match_operand:SWI48 1 "const_int_operand" "")))]
17188   "exact_log2 (INTVAL (operands[1])) >= 0
17189    && peep2_regno_dead_p (0, FLAGS_REG)"
17190   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17191               (clobber (reg:CC FLAGS_REG))])]
17192   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17193
17194 (define_peephole2
17195   [(set (match_operand:SI 0 "register_operand" "")
17196         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17197                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17198   "TARGET_64BIT
17199    && exact_log2 (INTVAL (operands[2])) >= 0
17200    && REGNO (operands[0]) == REGNO (operands[1])
17201    && peep2_regno_dead_p (0, FLAGS_REG)"
17202   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17203               (clobber (reg:CC FLAGS_REG))])]
17204   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17205
17206 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17207 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17208 ;; On many CPUs it is also faster, since special hardware to avoid esp
17209 ;; dependencies is present.
17210
17211 ;; While some of these conversions may be done using splitters, we use
17212 ;; peepholes in order to allow combine_stack_adjustments pass to see
17213 ;; nonobfuscated RTL.
17214
17215 ;; Convert prologue esp subtractions to push.
17216 ;; We need register to push.  In order to keep verify_flow_info happy we have
17217 ;; two choices
17218 ;; - use scratch and clobber it in order to avoid dependencies
17219 ;; - use already live register
17220 ;; We can't use the second way right now, since there is no reliable way how to
17221 ;; verify that given register is live.  First choice will also most likely in
17222 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17223 ;; call clobbered registers are dead.  We may want to use base pointer as an
17224 ;; alternative when no register is available later.
17225
17226 (define_peephole2
17227   [(match_scratch:P 1 "r")
17228    (parallel [(set (reg:P SP_REG)
17229                    (plus:P (reg:P SP_REG)
17230                            (match_operand:P 0 "const_int_operand" "")))
17231               (clobber (reg:CC FLAGS_REG))
17232               (clobber (mem:BLK (scratch)))])]
17233   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17234    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17235   [(clobber (match_dup 1))
17236    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17237               (clobber (mem:BLK (scratch)))])])
17238
17239 (define_peephole2
17240   [(match_scratch:P 1 "r")
17241    (parallel [(set (reg:P SP_REG)
17242                    (plus:P (reg:P SP_REG)
17243                            (match_operand:P 0 "const_int_operand" "")))
17244               (clobber (reg:CC FLAGS_REG))
17245               (clobber (mem:BLK (scratch)))])]
17246   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17247    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17248   [(clobber (match_dup 1))
17249    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17250    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17251               (clobber (mem:BLK (scratch)))])])
17252
17253 ;; Convert esp subtractions to push.
17254 (define_peephole2
17255   [(match_scratch:P 1 "r")
17256    (parallel [(set (reg:P SP_REG)
17257                    (plus:P (reg:P SP_REG)
17258                            (match_operand:P 0 "const_int_operand" "")))
17259               (clobber (reg:CC FLAGS_REG))])]
17260   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17261    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17262   [(clobber (match_dup 1))
17263    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17264
17265 (define_peephole2
17266   [(match_scratch:P 1 "r")
17267    (parallel [(set (reg:P SP_REG)
17268                    (plus:P (reg:P SP_REG)
17269                            (match_operand:P 0 "const_int_operand" "")))
17270               (clobber (reg:CC FLAGS_REG))])]
17271   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17272    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17273   [(clobber (match_dup 1))
17274    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17275    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17276
17277 ;; Convert epilogue deallocator to pop.
17278 (define_peephole2
17279   [(match_scratch:P 1 "r")
17280    (parallel [(set (reg:P SP_REG)
17281                    (plus:P (reg:P SP_REG)
17282                            (match_operand:P 0 "const_int_operand" "")))
17283               (clobber (reg:CC FLAGS_REG))
17284               (clobber (mem:BLK (scratch)))])]
17285   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17286    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17287   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17288               (clobber (mem:BLK (scratch)))])])
17289
17290 ;; Two pops case is tricky, since pop causes dependency
17291 ;; on destination register.  We use two registers if available.
17292 (define_peephole2
17293   [(match_scratch:P 1 "r")
17294    (match_scratch:P 2 "r")
17295    (parallel [(set (reg:P SP_REG)
17296                    (plus:P (reg:P SP_REG)
17297                            (match_operand:P 0 "const_int_operand" "")))
17298               (clobber (reg:CC FLAGS_REG))
17299               (clobber (mem:BLK (scratch)))])]
17300   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17301    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17302   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17303               (clobber (mem:BLK (scratch)))])
17304    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17305
17306 (define_peephole2
17307   [(match_scratch:P 1 "r")
17308    (parallel [(set (reg:P SP_REG)
17309                    (plus:P (reg:P SP_REG)
17310                            (match_operand:P 0 "const_int_operand" "")))
17311               (clobber (reg:CC FLAGS_REG))
17312               (clobber (mem:BLK (scratch)))])]
17313   "optimize_insn_for_size_p ()
17314    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17315   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17316               (clobber (mem:BLK (scratch)))])
17317    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17318
17319 ;; Convert esp additions to pop.
17320 (define_peephole2
17321   [(match_scratch:P 1 "r")
17322    (parallel [(set (reg:P SP_REG)
17323                    (plus:P (reg:P SP_REG)
17324                            (match_operand:P 0 "const_int_operand" "")))
17325               (clobber (reg:CC FLAGS_REG))])]
17326   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17327   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17328
17329 ;; Two pops case is tricky, since pop causes dependency
17330 ;; on destination register.  We use two registers if available.
17331 (define_peephole2
17332   [(match_scratch:P 1 "r")
17333    (match_scratch:P 2 "r")
17334    (parallel [(set (reg:P SP_REG)
17335                    (plus:P (reg:P SP_REG)
17336                            (match_operand:P 0 "const_int_operand" "")))
17337               (clobber (reg:CC FLAGS_REG))])]
17338   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17339   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17340    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17341
17342 (define_peephole2
17343   [(match_scratch:P 1 "r")
17344    (parallel [(set (reg:P SP_REG)
17345                    (plus:P (reg:P SP_REG)
17346                            (match_operand:P 0 "const_int_operand" "")))
17347               (clobber (reg:CC FLAGS_REG))])]
17348   "optimize_insn_for_size_p ()
17349    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17350   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17351    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17352 \f
17353 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17354 ;; required and register dies.  Similarly for 128 to -128.
17355 (define_peephole2
17356   [(set (match_operand 0 "flags_reg_operand" "")
17357         (match_operator 1 "compare_operator"
17358           [(match_operand 2 "register_operand" "")
17359            (match_operand 3 "const_int_operand" "")]))]
17360   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17361      && incdec_operand (operands[3], GET_MODE (operands[3])))
17362     || (!TARGET_FUSE_CMP_AND_BRANCH
17363         && INTVAL (operands[3]) == 128))
17364    && ix86_match_ccmode (insn, CCGCmode)
17365    && peep2_reg_dead_p (1, operands[2])"
17366   [(parallel [(set (match_dup 0)
17367                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17368               (clobber (match_dup 2))])])
17369 \f
17370 ;; Convert imul by three, five and nine into lea
17371 (define_peephole2
17372   [(parallel
17373     [(set (match_operand:SWI48 0 "register_operand" "")
17374           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17375                       (match_operand:SWI48 2 "const_int_operand" "")))
17376      (clobber (reg:CC FLAGS_REG))])]
17377   "INTVAL (operands[2]) == 3
17378    || INTVAL (operands[2]) == 5
17379    || INTVAL (operands[2]) == 9"
17380   [(set (match_dup 0)
17381         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17382                     (match_dup 1)))]
17383   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17384
17385 (define_peephole2
17386   [(parallel
17387     [(set (match_operand:SWI48 0 "register_operand" "")
17388           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17389                       (match_operand:SWI48 2 "const_int_operand" "")))
17390      (clobber (reg:CC FLAGS_REG))])]
17391   "optimize_insn_for_speed_p ()
17392    && (INTVAL (operands[2]) == 3
17393        || INTVAL (operands[2]) == 5
17394        || INTVAL (operands[2]) == 9)"
17395   [(set (match_dup 0) (match_dup 1))
17396    (set (match_dup 0)
17397         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17398                     (match_dup 0)))]
17399   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17400
17401 ;; imul $32bit_imm, mem, reg is vector decoded, while
17402 ;; imul $32bit_imm, reg, reg is direct decoded.
17403 (define_peephole2
17404   [(match_scratch:SWI48 3 "r")
17405    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17406                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17407                                (match_operand:SWI48 2 "immediate_operand" "")))
17408               (clobber (reg:CC FLAGS_REG))])]
17409   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17410    && !satisfies_constraint_K (operands[2])"
17411   [(set (match_dup 3) (match_dup 1))
17412    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17413               (clobber (reg:CC FLAGS_REG))])])
17414
17415 (define_peephole2
17416   [(match_scratch:SI 3 "r")
17417    (parallel [(set (match_operand:DI 0 "register_operand" "")
17418                    (zero_extend:DI
17419                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17420                               (match_operand:SI 2 "immediate_operand" ""))))
17421               (clobber (reg:CC FLAGS_REG))])]
17422   "TARGET_64BIT
17423    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17424    && !satisfies_constraint_K (operands[2])"
17425   [(set (match_dup 3) (match_dup 1))
17426    (parallel [(set (match_dup 0)
17427                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17428               (clobber (reg:CC FLAGS_REG))])])
17429
17430 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17431 ;; Convert it into imul reg, reg
17432 ;; It would be better to force assembler to encode instruction using long
17433 ;; immediate, but there is apparently no way to do so.
17434 (define_peephole2
17435   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17436                    (mult:SWI248
17437                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17438                     (match_operand:SWI248 2 "const_int_operand" "")))
17439               (clobber (reg:CC FLAGS_REG))])
17440    (match_scratch:SWI248 3 "r")]
17441   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17442    && satisfies_constraint_K (operands[2])"
17443   [(set (match_dup 3) (match_dup 2))
17444    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17445               (clobber (reg:CC FLAGS_REG))])]
17446 {
17447   if (!rtx_equal_p (operands[0], operands[1]))
17448     emit_move_insn (operands[0], operands[1]);
17449 })
17450
17451 ;; After splitting up read-modify operations, array accesses with memory
17452 ;; operands might end up in form:
17453 ;;  sall    $2, %eax
17454 ;;  movl    4(%esp), %edx
17455 ;;  addl    %edx, %eax
17456 ;; instead of pre-splitting:
17457 ;;  sall    $2, %eax
17458 ;;  addl    4(%esp), %eax
17459 ;; Turn it into:
17460 ;;  movl    4(%esp), %edx
17461 ;;  leal    (%edx,%eax,4), %eax
17462
17463 (define_peephole2
17464   [(match_scratch:P 5 "r")
17465    (parallel [(set (match_operand 0 "register_operand" "")
17466                    (ashift (match_operand 1 "register_operand" "")
17467                            (match_operand 2 "const_int_operand" "")))
17468                (clobber (reg:CC FLAGS_REG))])
17469    (parallel [(set (match_operand 3 "register_operand" "")
17470                    (plus (match_dup 0)
17471                          (match_operand 4 "x86_64_general_operand" "")))
17472                    (clobber (reg:CC FLAGS_REG))])]
17473   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17474    /* Validate MODE for lea.  */
17475    && ((!TARGET_PARTIAL_REG_STALL
17476         && (GET_MODE (operands[0]) == QImode
17477             || GET_MODE (operands[0]) == HImode))
17478        || GET_MODE (operands[0]) == SImode
17479        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17480    && (rtx_equal_p (operands[0], operands[3])
17481        || peep2_reg_dead_p (2, operands[0]))
17482    /* We reorder load and the shift.  */
17483    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17484   [(set (match_dup 5) (match_dup 4))
17485    (set (match_dup 0) (match_dup 1))]
17486 {
17487   enum machine_mode op1mode = GET_MODE (operands[1]);
17488   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17489   int scale = 1 << INTVAL (operands[2]);
17490   rtx index = gen_lowpart (Pmode, operands[1]);
17491   rtx base = gen_lowpart (Pmode, operands[5]);
17492   rtx dest = gen_lowpart (mode, operands[3]);
17493
17494   operands[1] = gen_rtx_PLUS (Pmode, base,
17495                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17496   operands[5] = base;
17497   if (mode != Pmode)
17498     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17499   if (op1mode != Pmode)
17500     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17501   operands[0] = dest;
17502 })
17503 \f
17504 ;; Call-value patterns last so that the wildcard operand does not
17505 ;; disrupt insn-recog's switch tables.
17506
17507 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17508   [(parallel
17509     [(set (match_operand 0 "" "")
17510           (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17511                 (match_operand:SI 2 "" "")))
17512      (set (reg:SI SP_REG)
17513           (plus:SI (reg:SI SP_REG)
17514                    (match_operand:SI 3 "immediate_operand" "")))])
17515    (unspec [(match_operand 4 "const_int_operand" "")]
17516            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17517   "TARGET_VZEROUPPER && !TARGET_64BIT"
17518   "#"
17519   "&& reload_completed"
17520   [(const_int 0)]
17521   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17522   [(set_attr "type" "callv")])
17523
17524 (define_insn "*call_value_pop_0"
17525   [(set (match_operand 0 "" "")
17526         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17527               (match_operand:SI 2 "" "")))
17528    (set (reg:SI SP_REG)
17529         (plus:SI (reg:SI SP_REG)
17530                  (match_operand:SI 3 "immediate_operand" "")))]
17531   "!TARGET_64BIT"
17532   { return ix86_output_call_insn (insn, operands[1], 1); }
17533   [(set_attr "type" "callv")])
17534
17535 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17536   [(parallel
17537     [(set (match_operand 0 "" "")
17538           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17539                 (match_operand:SI 2 "" "")))
17540      (set (reg:SI SP_REG)
17541           (plus:SI (reg:SI SP_REG)
17542                    (match_operand:SI 3 "immediate_operand" "i")))])
17543    (unspec [(match_operand 4 "const_int_operand" "")]
17544            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17545   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17546   "#"
17547   "&& reload_completed"
17548   [(const_int 0)]
17549   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17550   [(set_attr "type" "callv")])
17551
17552 (define_insn "*call_value_pop_1"
17553   [(set (match_operand 0 "" "")
17554         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17555               (match_operand:SI 2 "" "")))
17556    (set (reg:SI SP_REG)
17557         (plus:SI (reg:SI SP_REG)
17558                  (match_operand:SI 3 "immediate_operand" "i")))]
17559   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17560   { return ix86_output_call_insn (insn, operands[1], 1); }
17561   [(set_attr "type" "callv")])
17562
17563 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17564  [(parallel
17565    [(set (match_operand 0 "" "")
17566           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17567                 (match_operand:SI 2 "" "")))
17568      (set (reg:SI SP_REG)
17569           (plus:SI (reg:SI SP_REG)
17570                    (match_operand:SI 3 "immediate_operand" "i,i")))])
17571    (unspec [(match_operand 4 "const_int_operand" "")]
17572            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17573   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17574   "#"
17575   "&& reload_completed"
17576   [(const_int 0)]
17577   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17578   [(set_attr "type" "callv")])
17579
17580 (define_insn "*sibcall_value_pop_1"
17581   [(set (match_operand 0 "" "")
17582         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17583               (match_operand:SI 2 "" "")))
17584    (set (reg:SI SP_REG)
17585         (plus:SI (reg:SI SP_REG)
17586                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17587   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17588   { return ix86_output_call_insn (insn, operands[1], 1); }
17589   [(set_attr "type" "callv")])
17590
17591 (define_insn_and_split "*call_value_0_vzeroupper"
17592   [(set (match_operand 0 "" "")
17593         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17594               (match_operand:SI 2 "" "")))
17595    (unspec [(match_operand 3 "const_int_operand" "")]
17596            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17597   "TARGET_VZEROUPPER && !TARGET_64BIT"
17598   "#"
17599   "&& reload_completed"
17600   [(const_int 0)]
17601   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17602   [(set_attr "type" "callv")])
17603
17604 (define_insn "*call_value_0"
17605   [(set (match_operand 0 "" "")
17606         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17607               (match_operand:SI 2 "" "")))]
17608   "!TARGET_64BIT"
17609   { return ix86_output_call_insn (insn, operands[1], 1); }
17610   [(set_attr "type" "callv")])
17611
17612 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17613   [(set (match_operand 0 "" "")
17614         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17615               (match_operand:DI 2 "const_int_operand" "")))
17616    (unspec [(match_operand 3 "const_int_operand" "")]
17617            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17618   "TARGET_VZEROUPPER && TARGET_64BIT"
17619   "#"
17620   "&& reload_completed"
17621   [(const_int 0)]
17622   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17623   [(set_attr "type" "callv")])
17624
17625 (define_insn "*call_value_0_rex64"
17626   [(set (match_operand 0 "" "")
17627         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17628               (match_operand:DI 2 "const_int_operand" "")))]
17629   "TARGET_64BIT"
17630   { return ix86_output_call_insn (insn, operands[1], 1); }
17631   [(set_attr "type" "callv")])
17632
17633 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17634   [(parallel
17635     [(set (match_operand 0 "" "")
17636           (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17637                 (match_operand:DI 2 "const_int_operand" "")))
17638      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17639      (clobber (reg:TI XMM6_REG))
17640      (clobber (reg:TI XMM7_REG))
17641      (clobber (reg:TI XMM8_REG))
17642      (clobber (reg:TI XMM9_REG))
17643      (clobber (reg:TI XMM10_REG))
17644      (clobber (reg:TI XMM11_REG))
17645      (clobber (reg:TI XMM12_REG))
17646      (clobber (reg:TI XMM13_REG))
17647      (clobber (reg:TI XMM14_REG))
17648      (clobber (reg:TI XMM15_REG))
17649      (clobber (reg:DI SI_REG))
17650      (clobber (reg:DI DI_REG))])
17651    (unspec [(match_operand 3 "const_int_operand" "")]
17652            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17653   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17654   "#"
17655   "&& reload_completed"
17656   [(const_int 0)]
17657   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17658   [(set_attr "type" "callv")])
17659
17660 (define_insn "*call_value_0_rex64_ms_sysv"
17661   [(set (match_operand 0 "" "")
17662         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17663               (match_operand:DI 2 "const_int_operand" "")))
17664    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17665    (clobber (reg:TI XMM6_REG))
17666    (clobber (reg:TI XMM7_REG))
17667    (clobber (reg:TI XMM8_REG))
17668    (clobber (reg:TI XMM9_REG))
17669    (clobber (reg:TI XMM10_REG))
17670    (clobber (reg:TI XMM11_REG))
17671    (clobber (reg:TI XMM12_REG))
17672    (clobber (reg:TI XMM13_REG))
17673    (clobber (reg:TI XMM14_REG))
17674    (clobber (reg:TI XMM15_REG))
17675    (clobber (reg:DI SI_REG))
17676    (clobber (reg:DI DI_REG))]
17677   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17678   { return ix86_output_call_insn (insn, operands[1], 1); }
17679   [(set_attr "type" "callv")])
17680
17681 (define_insn_and_split "*call_value_1_vzeroupper"
17682   [(set (match_operand 0 "" "")
17683         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17684               (match_operand:SI 2 "" "")))
17685    (unspec [(match_operand 3 "const_int_operand" "")]
17686            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17687   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17688   "#"
17689   "&& reload_completed"
17690   [(const_int 0)]
17691   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17692   [(set_attr "type" "callv")])
17693
17694 (define_insn "*call_value_1"
17695   [(set (match_operand 0 "" "")
17696         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17697               (match_operand:SI 2 "" "")))]
17698   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17699   { return ix86_output_call_insn (insn, operands[1], 1); }
17700   [(set_attr "type" "callv")])
17701
17702 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17703   [(set (match_operand 0 "" "")
17704         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17705               (match_operand:SI 2 "" "")))
17706    (unspec [(match_operand 3 "const_int_operand" "")]
17707            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17708   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17709   "#"
17710   "&& reload_completed"
17711   [(const_int 0)]
17712   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17713   [(set_attr "type" "callv")])
17714
17715 (define_insn "*sibcall_value_1"
17716   [(set (match_operand 0 "" "")
17717         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17718               (match_operand:SI 2 "" "")))]
17719   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17720   { return ix86_output_call_insn (insn, operands[1], 1); }
17721   [(set_attr "type" "callv")])
17722
17723 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17724   [(set (match_operand 0 "" "")
17725         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17726               (match_operand:DI 2 "" "")))
17727    (unspec [(match_operand 3 "const_int_operand" "")]
17728            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17729   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17730    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17731   "#"
17732   "&& reload_completed"
17733   [(const_int 0)]
17734   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17735   [(set_attr "type" "callv")])
17736
17737 (define_insn "*call_value_1_rex64"
17738   [(set (match_operand 0 "" "")
17739         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17740               (match_operand:DI 2 "" "")))]
17741   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17742    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17743   { return ix86_output_call_insn (insn, operands[1], 1); }
17744   [(set_attr "type" "callv")])
17745
17746 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17747   [(parallel
17748     [(set (match_operand 0 "" "")
17749           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17750                 (match_operand:DI 2 "" "")))
17751      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17752      (clobber (reg:TI XMM6_REG))
17753      (clobber (reg:TI XMM7_REG))
17754      (clobber (reg:TI XMM8_REG))
17755      (clobber (reg:TI XMM9_REG))
17756      (clobber (reg:TI XMM10_REG))
17757      (clobber (reg:TI XMM11_REG))
17758      (clobber (reg:TI XMM12_REG))
17759      (clobber (reg:TI XMM13_REG))
17760      (clobber (reg:TI XMM14_REG))
17761      (clobber (reg:TI XMM15_REG))
17762      (clobber (reg:DI SI_REG))
17763      (clobber (reg:DI DI_REG))])
17764    (unspec [(match_operand 3 "const_int_operand" "")]
17765            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17766   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17767   "#"
17768   "&& reload_completed"
17769   [(const_int 0)]
17770   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17771   [(set_attr "type" "callv")])
17772
17773 (define_insn "*call_value_1_rex64_ms_sysv"
17774   [(set (match_operand 0 "" "")
17775         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17776               (match_operand:DI 2 "" "")))
17777    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17778    (clobber (reg:TI XMM6_REG))
17779    (clobber (reg:TI XMM7_REG))
17780    (clobber (reg:TI XMM8_REG))
17781    (clobber (reg:TI XMM9_REG))
17782    (clobber (reg:TI XMM10_REG))
17783    (clobber (reg:TI XMM11_REG))
17784    (clobber (reg:TI XMM12_REG))
17785    (clobber (reg:TI XMM13_REG))
17786    (clobber (reg:TI XMM14_REG))
17787    (clobber (reg:TI XMM15_REG))
17788    (clobber (reg:DI SI_REG))
17789    (clobber (reg:DI DI_REG))]
17790   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17791   { return ix86_output_call_insn (insn, operands[1], 1); }
17792   [(set_attr "type" "callv")])
17793
17794 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17795   [(set (match_operand 0 "" "")
17796         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17797               (match_operand:DI 2 "" "")))
17798    (unspec [(match_operand 3 "const_int_operand" "")]
17799            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17800   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17801   "#"
17802   "&& reload_completed"
17803   [(const_int 0)]
17804   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17805   [(set_attr "type" "callv")])
17806
17807 (define_insn "*call_value_1_rex64_large"
17808   [(set (match_operand 0 "" "")
17809         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17810               (match_operand:DI 2 "" "")))]
17811   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17812   { return ix86_output_call_insn (insn, operands[1], 1); }
17813   [(set_attr "type" "callv")])
17814
17815 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17816   [(set (match_operand 0 "" "")
17817         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17818               (match_operand:DI 2 "" "")))
17819    (unspec [(match_operand 3 "const_int_operand" "")]
17820            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17821   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17822   "#"
17823   "&& reload_completed"
17824   [(const_int 0)]
17825   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17826   [(set_attr "type" "callv")])
17827
17828 (define_insn "*sibcall_value_1_rex64"
17829   [(set (match_operand 0 "" "")
17830         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17831               (match_operand:DI 2 "" "")))]
17832   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17833   { return ix86_output_call_insn (insn, operands[1], 1); }
17834   [(set_attr "type" "callv")])
17835 \f
17836 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17837 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17838 ;; caught for use by garbage collectors and the like.  Using an insn that
17839 ;; maps to SIGILL makes it more likely the program will rightfully die.
17840 ;; Keeping with tradition, "6" is in honor of #UD.
17841 (define_insn "trap"
17842   [(trap_if (const_int 1) (const_int 6))]
17843   ""
17844   { return ASM_SHORT "0x0b0f"; }
17845   [(set_attr "length" "2")])
17846
17847 (define_expand "prefetch"
17848   [(prefetch (match_operand 0 "address_operand" "")
17849              (match_operand:SI 1 "const_int_operand" "")
17850              (match_operand:SI 2 "const_int_operand" ""))]
17851   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17852 {
17853   int rw = INTVAL (operands[1]);
17854   int locality = INTVAL (operands[2]);
17855
17856   gcc_assert (rw == 0 || rw == 1);
17857   gcc_assert (locality >= 0 && locality <= 3);
17858   gcc_assert (GET_MODE (operands[0]) == Pmode
17859               || GET_MODE (operands[0]) == VOIDmode);
17860
17861   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17862      supported by SSE counterpart or the SSE prefetch is not available
17863      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17864      of locality.  */
17865   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17866     operands[2] = GEN_INT (3);
17867   else
17868     operands[1] = const0_rtx;
17869 })
17870
17871 (define_insn "*prefetch_sse_<mode>"
17872   [(prefetch (match_operand:P 0 "address_operand" "p")
17873              (const_int 0)
17874              (match_operand:SI 1 "const_int_operand" ""))]
17875   "TARGET_PREFETCH_SSE"
17876 {
17877   static const char * const patterns[4] = {
17878    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17879   };
17880
17881   int locality = INTVAL (operands[1]);
17882   gcc_assert (locality >= 0 && locality <= 3);
17883
17884   return patterns[locality];
17885 }
17886   [(set_attr "type" "sse")
17887    (set_attr "atom_sse_attr" "prefetch")
17888    (set (attr "length_address")
17889         (symbol_ref "memory_address_length (operands[0])"))
17890    (set_attr "memory" "none")])
17891
17892 (define_insn "*prefetch_3dnow_<mode>"
17893   [(prefetch (match_operand:P 0 "address_operand" "p")
17894              (match_operand:SI 1 "const_int_operand" "n")
17895              (const_int 3))]
17896   "TARGET_3DNOW"
17897 {
17898   if (INTVAL (operands[1]) == 0)
17899     return "prefetch\t%a0";
17900   else
17901     return "prefetchw\t%a0";
17902 }
17903   [(set_attr "type" "mmx")
17904    (set (attr "length_address")
17905         (symbol_ref "memory_address_length (operands[0])"))
17906    (set_attr "memory" "none")])
17907
17908 (define_expand "stack_protect_set"
17909   [(match_operand 0 "memory_operand" "")
17910    (match_operand 1 "memory_operand" "")]
17911   ""
17912 {
17913   rtx (*insn)(rtx, rtx);
17914
17915 #ifdef TARGET_THREAD_SSP_OFFSET
17916   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17917   insn = (TARGET_64BIT
17918           ? gen_stack_tls_protect_set_di
17919           : gen_stack_tls_protect_set_si);
17920 #else
17921   insn = (TARGET_64BIT
17922           ? gen_stack_protect_set_di
17923           : gen_stack_protect_set_si);
17924 #endif
17925
17926   emit_insn (insn (operands[0], operands[1]));
17927   DONE;
17928 })
17929
17930 (define_insn "stack_protect_set_<mode>"
17931   [(set (match_operand:P 0 "memory_operand" "=m")
17932         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17933    (set (match_scratch:P 2 "=&r") (const_int 0))
17934    (clobber (reg:CC FLAGS_REG))]
17935   ""
17936   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17937   [(set_attr "type" "multi")])
17938
17939 (define_insn "stack_tls_protect_set_<mode>"
17940   [(set (match_operand:P 0 "memory_operand" "=m")
17941         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17942                   UNSPEC_SP_TLS_SET))
17943    (set (match_scratch:P 2 "=&r") (const_int 0))
17944    (clobber (reg:CC FLAGS_REG))]
17945   ""
17946   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17947   [(set_attr "type" "multi")])
17948
17949 (define_expand "stack_protect_test"
17950   [(match_operand 0 "memory_operand" "")
17951    (match_operand 1 "memory_operand" "")
17952    (match_operand 2 "" "")]
17953   ""
17954 {
17955   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17956
17957   rtx (*insn)(rtx, rtx, rtx);
17958
17959 #ifdef TARGET_THREAD_SSP_OFFSET
17960   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17961   insn = (TARGET_64BIT
17962           ? gen_stack_tls_protect_test_di
17963           : gen_stack_tls_protect_test_si);
17964 #else
17965   insn = (TARGET_64BIT
17966           ? gen_stack_protect_test_di
17967           : gen_stack_protect_test_si);
17968 #endif
17969
17970   emit_insn (insn (flags, operands[0], operands[1]));
17971
17972   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17973                                   flags, const0_rtx, operands[2]));
17974   DONE;
17975 })
17976
17977 (define_insn "stack_protect_test_<mode>"
17978   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17979         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17980                      (match_operand:P 2 "memory_operand" "m")]
17981                     UNSPEC_SP_TEST))
17982    (clobber (match_scratch:P 3 "=&r"))]
17983   ""
17984   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17985   [(set_attr "type" "multi")])
17986
17987 (define_insn "stack_tls_protect_test_<mode>"
17988   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17989         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17990                      (match_operand:P 2 "const_int_operand" "i")]
17991                     UNSPEC_SP_TLS_TEST))
17992    (clobber (match_scratch:P 3 "=r"))]
17993   ""
17994   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17995   [(set_attr "type" "multi")])
17996
17997 (define_insn "sse4_2_crc32<mode>"
17998   [(set (match_operand:SI 0 "register_operand" "=r")
17999         (unspec:SI
18000           [(match_operand:SI 1 "register_operand" "0")
18001            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18002           UNSPEC_CRC32))]
18003   "TARGET_SSE4_2 || TARGET_CRC32"
18004   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18005   [(set_attr "type" "sselog1")
18006    (set_attr "prefix_rep" "1")
18007    (set_attr "prefix_extra" "1")
18008    (set (attr "prefix_data16")
18009      (if_then_else (match_operand:HI 2 "" "")
18010        (const_string "1")
18011        (const_string "*")))
18012    (set (attr "prefix_rex")
18013      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18014        (const_string "1")
18015        (const_string "*")))
18016    (set_attr "mode" "SI")])
18017
18018 (define_insn "sse4_2_crc32di"
18019   [(set (match_operand:DI 0 "register_operand" "=r")
18020         (unspec:DI
18021           [(match_operand:DI 1 "register_operand" "0")
18022            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18023           UNSPEC_CRC32))]
18024   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18025   "crc32{q}\t{%2, %0|%0, %2}"
18026   [(set_attr "type" "sselog1")
18027    (set_attr "prefix_rep" "1")
18028    (set_attr "prefix_extra" "1")
18029    (set_attr "mode" "DI")])
18030
18031 (define_expand "rdpmc"
18032   [(match_operand:DI 0 "register_operand" "")
18033    (match_operand:SI 1 "register_operand" "")]
18034   ""
18035 {
18036   rtx reg = gen_reg_rtx (DImode);
18037   rtx si;
18038
18039   /* Force operand 1 into ECX.  */
18040   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18041   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18042   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18043                                 UNSPECV_RDPMC);
18044
18045   if (TARGET_64BIT)
18046     {
18047       rtvec vec = rtvec_alloc (2);
18048       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18049       rtx upper = gen_reg_rtx (DImode);
18050       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18051                                         gen_rtvec (1, const0_rtx),
18052                                         UNSPECV_RDPMC);
18053       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18054       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18055       emit_insn (load);
18056       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18057                                    NULL, 1, OPTAB_DIRECT);
18058       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18059                                  OPTAB_DIRECT);
18060     }
18061   else
18062     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18063   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18064   DONE;
18065 })
18066
18067 (define_insn "*rdpmc"
18068   [(set (match_operand:DI 0 "register_operand" "=A")
18069         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18070                             UNSPECV_RDPMC))]
18071   "!TARGET_64BIT"
18072   "rdpmc"
18073   [(set_attr "type" "other")
18074    (set_attr "length" "2")])
18075
18076 (define_insn "*rdpmc_rex64"
18077   [(set (match_operand:DI 0 "register_operand" "=a")
18078         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18079                             UNSPECV_RDPMC))
18080   (set (match_operand:DI 1 "register_operand" "=d")
18081        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18082   "TARGET_64BIT"
18083   "rdpmc"
18084   [(set_attr "type" "other")
18085    (set_attr "length" "2")])
18086
18087 (define_expand "rdtsc"
18088   [(set (match_operand:DI 0 "register_operand" "")
18089         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18090   ""
18091 {
18092   if (TARGET_64BIT)
18093     {
18094       rtvec vec = rtvec_alloc (2);
18095       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18096       rtx upper = gen_reg_rtx (DImode);
18097       rtx lower = gen_reg_rtx (DImode);
18098       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18099                                          gen_rtvec (1, const0_rtx),
18100                                          UNSPECV_RDTSC);
18101       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18102       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18103       emit_insn (load);
18104       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18105                                    NULL, 1, OPTAB_DIRECT);
18106       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18107                                    OPTAB_DIRECT);
18108       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18109       DONE;
18110     }
18111 })
18112
18113 (define_insn "*rdtsc"
18114   [(set (match_operand:DI 0 "register_operand" "=A")
18115         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18116   "!TARGET_64BIT"
18117   "rdtsc"
18118   [(set_attr "type" "other")
18119    (set_attr "length" "2")])
18120
18121 (define_insn "*rdtsc_rex64"
18122   [(set (match_operand:DI 0 "register_operand" "=a")
18123         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18124    (set (match_operand:DI 1 "register_operand" "=d")
18125         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18126   "TARGET_64BIT"
18127   "rdtsc"
18128   [(set_attr "type" "other")
18129    (set_attr "length" "2")])
18130
18131 (define_expand "rdtscp"
18132   [(match_operand:DI 0 "register_operand" "")
18133    (match_operand:SI 1 "memory_operand" "")]
18134   ""
18135 {
18136   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18137                                     gen_rtvec (1, const0_rtx),
18138                                     UNSPECV_RDTSCP);
18139   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18140                                     gen_rtvec (1, const0_rtx),
18141                                     UNSPECV_RDTSCP);
18142   rtx reg = gen_reg_rtx (DImode);
18143   rtx tmp = gen_reg_rtx (SImode);
18144
18145   if (TARGET_64BIT)
18146     {
18147       rtvec vec = rtvec_alloc (3);
18148       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18149       rtx upper = gen_reg_rtx (DImode);
18150       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18151       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18152       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18153       emit_insn (load);
18154       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18155                                    NULL, 1, OPTAB_DIRECT);
18156       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18157                                  OPTAB_DIRECT);
18158     }
18159   else
18160     {
18161       rtvec vec = rtvec_alloc (2);
18162       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18163       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18164       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18165       emit_insn (load);
18166     }
18167   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18168   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18169   DONE;
18170 })
18171
18172 (define_insn "*rdtscp"
18173   [(set (match_operand:DI 0 "register_operand" "=A")
18174         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18175    (set (match_operand:SI 1 "register_operand" "=c")
18176         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18177   "!TARGET_64BIT"
18178   "rdtscp"
18179   [(set_attr "type" "other")
18180    (set_attr "length" "3")])
18181
18182 (define_insn "*rdtscp_rex64"
18183   [(set (match_operand:DI 0 "register_operand" "=a")
18184         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18185    (set (match_operand:DI 1 "register_operand" "=d")
18186         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18187    (set (match_operand:SI 2 "register_operand" "=c")
18188         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18189   "TARGET_64BIT"
18190   "rdtscp"
18191   [(set_attr "type" "other")
18192    (set_attr "length" "3")])
18193
18194 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18195 ;;
18196 ;; LWP instructions
18197 ;;
18198 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18199
18200 (define_expand "lwp_llwpcb"
18201   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18202                     UNSPECV_LLWP_INTRINSIC)]
18203   "TARGET_LWP")
18204
18205 (define_insn "*lwp_llwpcb<mode>1"
18206   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18207                     UNSPECV_LLWP_INTRINSIC)]
18208   "TARGET_LWP"
18209   "llwpcb\t%0"
18210   [(set_attr "type" "lwp")
18211    (set_attr "mode" "<MODE>")
18212    (set_attr "length" "5")])
18213
18214 (define_expand "lwp_slwpcb"
18215   [(set (match_operand 0 "register_operand" "=r")
18216         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18217   "TARGET_LWP"
18218 {
18219   if (TARGET_64BIT)
18220     emit_insn (gen_lwp_slwpcbdi (operands[0]));
18221   else
18222     emit_insn (gen_lwp_slwpcbsi (operands[0]));
18223   DONE;
18224 })
18225
18226 (define_insn "lwp_slwpcb<mode>"
18227   [(set (match_operand:P 0 "register_operand" "=r")
18228         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18229   "TARGET_LWP"
18230   "slwpcb\t%0"
18231   [(set_attr "type" "lwp")
18232    (set_attr "mode" "<MODE>")
18233    (set_attr "length" "5")])
18234
18235 (define_expand "lwp_lwpval<mode>3"
18236   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18237                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18238                      (match_operand:SI 3 "const_int_operand" "i")]
18239                     UNSPECV_LWPVAL_INTRINSIC)]
18240   "TARGET_LWP"
18241   "/* Avoid unused variable warning.  */
18242    (void) operand0;")
18243
18244 (define_insn "*lwp_lwpval<mode>3_1"
18245   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18246                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18247                      (match_operand:SI 2 "const_int_operand" "i")]
18248                     UNSPECV_LWPVAL_INTRINSIC)]
18249   "TARGET_LWP"
18250   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18251   [(set_attr "type" "lwp")
18252    (set_attr "mode" "<MODE>")
18253    (set (attr "length")
18254         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18255
18256 (define_expand "lwp_lwpins<mode>3"
18257   [(set (reg:CCC FLAGS_REG)
18258         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18259                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18260                               (match_operand:SI 3 "const_int_operand" "i")]
18261                              UNSPECV_LWPINS_INTRINSIC))
18262    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18263         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18264   "TARGET_LWP")
18265
18266 (define_insn "*lwp_lwpins<mode>3_1"
18267   [(set (reg:CCC FLAGS_REG)
18268         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18269                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18270                               (match_operand:SI 2 "const_int_operand" "i")]
18271                              UNSPECV_LWPINS_INTRINSIC))]
18272   "TARGET_LWP"
18273   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18274   [(set_attr "type" "lwp")
18275    (set_attr "mode" "<MODE>")
18276    (set (attr "length")
18277         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18278
18279 (define_insn "rdfsbase<mode>"
18280   [(set (match_operand:SWI48 0 "register_operand" "=r")
18281         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18282   "TARGET_64BIT && TARGET_FSGSBASE"
18283   "rdfsbase %0"
18284   [(set_attr "type" "other")
18285    (set_attr "prefix_extra" "2")])
18286
18287 (define_insn "rdgsbase<mode>"
18288   [(set (match_operand:SWI48 0 "register_operand" "=r")
18289         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18290   "TARGET_64BIT && TARGET_FSGSBASE"
18291   "rdgsbase %0"
18292   [(set_attr "type" "other")
18293    (set_attr "prefix_extra" "2")])
18294
18295 (define_insn "wrfsbase<mode>"
18296   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18297                     UNSPECV_WRFSBASE)]
18298   "TARGET_64BIT && TARGET_FSGSBASE"
18299   "wrfsbase %0"
18300   [(set_attr "type" "other")
18301    (set_attr "prefix_extra" "2")])
18302
18303 (define_insn "wrgsbase<mode>"
18304   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18305                     UNSPECV_WRGSBASE)]
18306   "TARGET_64BIT && TARGET_FSGSBASE"
18307   "wrgsbase %0"
18308   [(set_attr "type" "other")
18309    (set_attr "prefix_extra" "2")])
18310
18311 (define_insn "rdrand<mode>_1"
18312   [(set (match_operand:SWI248 0 "register_operand" "=r")
18313         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18314    (set (reg:CCC FLAGS_REG)
18315         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18316   "TARGET_RDRND"
18317   "rdrand\t%0"
18318   [(set_attr "type" "other")
18319    (set_attr "prefix_extra" "1")])
18320
18321 (include "mmx.md")
18322 (include "sse.md")
18323 (include "sync.md")