OSDN Git Service

* config/i386/i386.md (truncxf<mode>2): Fix indentation.
[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
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
80   ;; Prologue support
81   UNSPEC_STACK_ALLOC
82   UNSPEC_SET_GOT
83   UNSPEC_REG_SAVE
84   UNSPEC_DEF_CFA
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88
89   ;; TLS support
90   UNSPEC_TP
91   UNSPEC_TLS_GD
92   UNSPEC_TLS_LD_BASE
93   UNSPEC_TLSDESC
94
95   ;; Other random patterns
96   UNSPEC_SCAS
97   UNSPEC_FNSTSW
98   UNSPEC_SAHF
99   UNSPEC_PARITY
100   UNSPEC_FSTCW
101   UNSPEC_ADD_CARRY
102   UNSPEC_FLDCW
103   UNSPEC_REP
104   UNSPEC_LD_MPIC        ; load_macho_picbase
105   UNSPEC_TRUNC_NOOP
106
107   ;; For SSE/MMX support:
108   UNSPEC_FIX_NOTRUNC
109   UNSPEC_MASKMOV
110   UNSPEC_MOVMSK
111   UNSPEC_MOVNT
112   UNSPEC_MOVU
113   UNSPEC_RCP
114   UNSPEC_RSQRT
115   UNSPEC_SFENCE
116   UNSPEC_PFRCP
117   UNSPEC_PFRCPIT1
118   UNSPEC_PFRCPIT2
119   UNSPEC_PFRSQRT
120   UNSPEC_PFRSQIT1
121   UNSPEC_MFENCE
122   UNSPEC_LFENCE
123   UNSPEC_PSADBW
124   UNSPEC_LDDQU
125   UNSPEC_MS_TO_SYSV_CALL
126
127   ;; Generic math support
128   UNSPEC_COPYSIGN
129   UNSPEC_IEEE_MIN       ; not commutative
130   UNSPEC_IEEE_MAX       ; not commutative
131
132   ;; x87 Floating point
133   UNSPEC_SIN
134   UNSPEC_COS
135   UNSPEC_FPATAN
136   UNSPEC_FYL2X
137   UNSPEC_FYL2XP1
138   UNSPEC_FRNDINT
139   UNSPEC_FIST
140   UNSPEC_F2XM1
141   UNSPEC_TAN
142   UNSPEC_FXAM
143
144   ;; x87 Rounding
145   UNSPEC_FRNDINT_FLOOR
146   UNSPEC_FRNDINT_CEIL
147   UNSPEC_FRNDINT_TRUNC
148   UNSPEC_FRNDINT_MASK_PM
149   UNSPEC_FIST_FLOOR
150   UNSPEC_FIST_CEIL
151
152   ;; x87 Double output FP
153   UNSPEC_SINCOS_COS
154   UNSPEC_SINCOS_SIN
155   UNSPEC_XTRACT_FRACT
156   UNSPEC_XTRACT_EXP
157   UNSPEC_FSCALE_FRACT
158   UNSPEC_FSCALE_EXP
159   UNSPEC_FPREM_F
160   UNSPEC_FPREM_U
161   UNSPEC_FPREM1_F
162   UNSPEC_FPREM1_U
163
164   UNSPEC_C2_FLAG
165   UNSPEC_FXAM_MEM
166
167   ;; SSP patterns
168   UNSPEC_SP_SET
169   UNSPEC_SP_TEST
170   UNSPEC_SP_TLS_SET
171   UNSPEC_SP_TLS_TEST
172
173   ;; SSSE3
174   UNSPEC_PSHUFB
175   UNSPEC_PSIGN
176   UNSPEC_PALIGNR
177
178   ;; For SSE4A support
179   UNSPEC_EXTRQI
180   UNSPEC_EXTRQ
181   UNSPEC_INSERTQI
182   UNSPEC_INSERTQ
183
184   ;; For SSE4.1 support
185   UNSPEC_BLENDV
186   UNSPEC_INSERTPS
187   UNSPEC_DP
188   UNSPEC_MOVNTDQA
189   UNSPEC_MPSADBW
190   UNSPEC_PHMINPOSUW
191   UNSPEC_PTEST
192   UNSPEC_ROUND
193
194   ;; For SSE4.2 support
195   UNSPEC_CRC32
196   UNSPEC_PCMPESTR
197   UNSPEC_PCMPISTR
198
199   ;; For FMA4 support
200   UNSPEC_FMA4_INTRINSIC
201   UNSPEC_FMA4_FMADDSUB
202   UNSPEC_FMA4_FMSUBADD
203   UNSPEC_XOP_UNSIGNED_CMP
204   UNSPEC_XOP_TRUEFALSE
205   UNSPEC_XOP_PERMUTE
206   UNSPEC_FRCZ
207
208   ;; For AES support
209   UNSPEC_AESENC
210   UNSPEC_AESENCLAST
211   UNSPEC_AESDEC
212   UNSPEC_AESDECLAST
213   UNSPEC_AESIMC
214   UNSPEC_AESKEYGENASSIST
215
216   ;; For PCLMUL support
217   UNSPEC_PCLMUL
218
219   ;; For AVX support
220   UNSPEC_PCMP
221   UNSPEC_VPERMIL
222   UNSPEC_VPERMIL2
223   UNSPEC_VPERMIL2F128
224   UNSPEC_MASKLOAD
225   UNSPEC_MASKSTORE
226   UNSPEC_CAST
227   UNSPEC_VTESTP
228   UNSPEC_VCVTPH2PS
229   UNSPEC_VCVTPS2PH
230 ])
231
232 (define_c_enum "unspecv" [
233   UNSPECV_BLOCKAGE
234   UNSPECV_STACK_PROBE
235   UNSPECV_PROBE_STACK_RANGE
236   UNSPECV_EMMS
237   UNSPECV_LDMXCSR
238   UNSPECV_STMXCSR
239   UNSPECV_FEMMS
240   UNSPECV_CLFLUSH
241   UNSPECV_ALIGN
242   UNSPECV_MONITOR
243   UNSPECV_MWAIT
244   UNSPECV_CMPXCHG
245   UNSPECV_XCHG
246   UNSPECV_LOCK
247   UNSPECV_PROLOGUE_USE
248   UNSPECV_CLD
249   UNSPECV_VZEROALL
250   UNSPECV_VZEROUPPER
251   UNSPECV_RDTSC
252   UNSPECV_RDTSCP
253   UNSPECV_RDPMC
254   UNSPECV_LLWP_INTRINSIC
255   UNSPECV_SLWP_INTRINSIC
256   UNSPECV_LWPVAL_INTRINSIC
257   UNSPECV_LWPINS_INTRINSIC
258   UNSPECV_RDFSBASE
259   UNSPECV_RDGSBASE
260   UNSPECV_WRFSBASE
261   UNSPECV_WRGSBASE
262   UNSPECV_RDRAND
263 ])
264
265 ;; Constants to represent pcomtrue/pcomfalse variants
266 (define_constants
267   [(PCOM_FALSE                  0)
268    (PCOM_TRUE                   1)
269    (COM_FALSE_S                 2)
270    (COM_FALSE_P                 3)
271    (COM_TRUE_S                  4)
272    (COM_TRUE_P                  5)
273   ])
274
275 ;; Constants used in the XOP pperm instruction
276 (define_constants
277   [(PPERM_SRC                   0x00)   /* copy source */
278    (PPERM_INVERT                0x20)   /* invert source */
279    (PPERM_REVERSE               0x40)   /* bit reverse source */
280    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
281    (PPERM_ZERO                  0x80)   /* all 0's */
282    (PPERM_ONES                  0xa0)   /* all 1's */
283    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
284    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
285    (PPERM_SRC1                  0x00)   /* use first source byte */
286    (PPERM_SRC2                  0x10)   /* use second source byte */
287    ])
288
289 ;; Registers by name.
290 (define_constants
291   [(AX_REG                       0)
292    (DX_REG                       1)
293    (CX_REG                       2)
294    (BX_REG                       3)
295    (SI_REG                       4)
296    (DI_REG                       5)
297    (BP_REG                       6)
298    (SP_REG                       7)
299    (ST0_REG                      8)
300    (ST1_REG                      9)
301    (ST2_REG                     10)
302    (ST3_REG                     11)
303    (ST4_REG                     12)
304    (ST5_REG                     13)
305    (ST6_REG                     14)
306    (ST7_REG                     15)
307    (FLAGS_REG                   17)
308    (FPSR_REG                    18)
309    (FPCR_REG                    19)
310    (XMM0_REG                    21)
311    (XMM1_REG                    22)
312    (XMM2_REG                    23)
313    (XMM3_REG                    24)
314    (XMM4_REG                    25)
315    (XMM5_REG                    26)
316    (XMM6_REG                    27)
317    (XMM7_REG                    28)
318    (MM0_REG                     29)
319    (MM1_REG                     30)
320    (MM2_REG                     31)
321    (MM3_REG                     32)
322    (MM4_REG                     33)
323    (MM5_REG                     34)
324    (MM6_REG                     35)
325    (MM7_REG                     36)
326    (R8_REG                      37)
327    (R9_REG                      38)
328    (R10_REG                     39)
329    (R11_REG                     40)
330    (R12_REG                     41)
331    (R13_REG                     42)
332    (XMM8_REG                    45)
333    (XMM9_REG                    46)
334    (XMM10_REG                   47)
335    (XMM11_REG                   48)
336    (XMM12_REG                   49)
337    (XMM13_REG                   50)
338    (XMM14_REG                   51)
339    (XMM15_REG                   52)
340   ])
341
342 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
343 ;; from i386.c.
344
345 ;; In C guard expressions, put expressions which may be compile-time
346 ;; constants first.  This allows for better optimization.  For
347 ;; example, write "TARGET_64BIT && reload_completed", not
348 ;; "reload_completed && TARGET_64BIT".
349
350 \f
351 ;; Processor type.
352 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
353                     generic64,amdfam10,bdver1"
354   (const (symbol_ref "ix86_schedule")))
355
356 ;; A basic instruction type.  Refinements due to arguments to be
357 ;; provided in other attributes.
358 (define_attr "type"
359   "other,multi,
360    alu,alu1,negnot,imov,imovx,lea,
361    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
362    icmp,test,ibr,setcc,icmov,
363    push,pop,call,callv,leave,
364    str,bitmanip,
365    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
366    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
367    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
368    ssemuladd,sse4arg,lwp,
369    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
370   (const_string "other"))
371
372 ;; Main data type used by the insn
373 (define_attr "mode"
374   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
375   (const_string "unknown"))
376
377 ;; The CPU unit operations uses.
378 (define_attr "unit" "integer,i387,sse,mmx,unknown"
379   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
380            (const_string "i387")
381          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
382                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
383                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
384            (const_string "sse")
385          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
386            (const_string "mmx")
387          (eq_attr "type" "other")
388            (const_string "unknown")]
389          (const_string "integer")))
390
391 ;; The (bounding maximum) length of an instruction immediate.
392 (define_attr "length_immediate" ""
393   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
394                           bitmanip")
395            (const_int 0)
396          (eq_attr "unit" "i387,sse,mmx")
397            (const_int 0)
398          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
399                           imul,icmp,push,pop")
400            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
401          (eq_attr "type" "imov,test")
402            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
403          (eq_attr "type" "call")
404            (if_then_else (match_operand 0 "constant_call_address_operand" "")
405              (const_int 4)
406              (const_int 0))
407          (eq_attr "type" "callv")
408            (if_then_else (match_operand 1 "constant_call_address_operand" "")
409              (const_int 4)
410              (const_int 0))
411          ;; We don't know the size before shorten_branches.  Expect
412          ;; the instruction to fit for better scheduling.
413          (eq_attr "type" "ibr")
414            (const_int 1)
415          ]
416          (symbol_ref "/* Update immediate_length and other attributes! */
417                       gcc_unreachable (),1")))
418
419 ;; The (bounding maximum) length of an instruction address.
420 (define_attr "length_address" ""
421   (cond [(eq_attr "type" "str,other,multi,fxch")
422            (const_int 0)
423          (and (eq_attr "type" "call")
424               (match_operand 0 "constant_call_address_operand" ""))
425              (const_int 0)
426          (and (eq_attr "type" "callv")
427               (match_operand 1 "constant_call_address_operand" ""))
428              (const_int 0)
429          ]
430          (symbol_ref "ix86_attr_length_address_default (insn)")))
431
432 ;; Set when length prefix is used.
433 (define_attr "prefix_data16" ""
434   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
435            (const_int 0)
436          (eq_attr "mode" "HI")
437            (const_int 1)
438          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
439            (const_int 1)
440         ]
441         (const_int 0)))
442
443 ;; Set when string REP prefix is used.
444 (define_attr "prefix_rep" ""
445   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
446            (const_int 0)
447          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
448            (const_int 1)
449         ]
450         (const_int 0)))
451
452 ;; Set when 0f opcode prefix is used.
453 (define_attr "prefix_0f" ""
454   (if_then_else
455     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
456          (eq_attr "unit" "sse,mmx"))
457     (const_int 1)
458     (const_int 0)))
459
460 ;; Set when REX opcode prefix is used.
461 (define_attr "prefix_rex" ""
462   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
463            (const_int 0)
464          (and (eq_attr "mode" "DI")
465               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
466                    (eq_attr "unit" "!mmx")))
467            (const_int 1)
468          (and (eq_attr "mode" "QI")
469               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
470                   (const_int 0)))
471            (const_int 1)
472          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
473              (const_int 0))
474            (const_int 1)
475          (and (eq_attr "type" "imovx")
476               (match_operand:QI 1 "ext_QIreg_operand" ""))
477            (const_int 1)
478         ]
479         (const_int 0)))
480
481 ;; There are also additional prefixes in 3DNOW, SSSE3.
482 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
483 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
484 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
485 (define_attr "prefix_extra" ""
486   (cond [(eq_attr "type" "ssemuladd,sse4arg")
487            (const_int 2)
488          (eq_attr "type" "sseiadd1,ssecvt1")
489            (const_int 1)
490         ]
491         (const_int 0)))
492
493 ;; Prefix used: original, VEX or maybe VEX.
494 (define_attr "prefix" "orig,vex,maybe_vex"
495   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
496     (const_string "vex")
497     (const_string "orig")))
498
499 ;; VEX W bit is used.
500 (define_attr "prefix_vex_w" "" (const_int 0))
501
502 ;; The length of VEX prefix
503 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
504 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
505 ;; still prefix_0f 1, with prefix_extra 1.
506 (define_attr "length_vex" ""
507   (if_then_else (and (eq_attr "prefix_0f" "1")
508                      (eq_attr "prefix_extra" "0"))
509     (if_then_else (eq_attr "prefix_vex_w" "1")
510       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
511       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
512     (if_then_else (eq_attr "prefix_vex_w" "1")
513       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
514       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
515
516 ;; Set when modrm byte is used.
517 (define_attr "modrm" ""
518   (cond [(eq_attr "type" "str,leave")
519            (const_int 0)
520          (eq_attr "unit" "i387")
521            (const_int 0)
522          (and (eq_attr "type" "incdec")
523               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
524                    (ior (match_operand:SI 1 "register_operand" "")
525                         (match_operand:HI 1 "register_operand" ""))))
526            (const_int 0)
527          (and (eq_attr "type" "push")
528               (not (match_operand 1 "memory_operand" "")))
529            (const_int 0)
530          (and (eq_attr "type" "pop")
531               (not (match_operand 0 "memory_operand" "")))
532            (const_int 0)
533          (and (eq_attr "type" "imov")
534               (and (not (eq_attr "mode" "DI"))
535                    (ior (and (match_operand 0 "register_operand" "")
536                              (match_operand 1 "immediate_operand" ""))
537                         (ior (and (match_operand 0 "ax_reg_operand" "")
538                                   (match_operand 1 "memory_displacement_only_operand" ""))
539                              (and (match_operand 0 "memory_displacement_only_operand" "")
540                                   (match_operand 1 "ax_reg_operand" ""))))))
541            (const_int 0)
542          (and (eq_attr "type" "call")
543               (match_operand 0 "constant_call_address_operand" ""))
544              (const_int 0)
545          (and (eq_attr "type" "callv")
546               (match_operand 1 "constant_call_address_operand" ""))
547              (const_int 0)
548          (and (eq_attr "type" "alu,alu1,icmp,test")
549               (match_operand 0 "ax_reg_operand" ""))
550              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
551          ]
552          (const_int 1)))
553
554 ;; The (bounding maximum) length of an instruction in bytes.
555 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
556 ;; Later we may want to split them and compute proper length as for
557 ;; other insns.
558 (define_attr "length" ""
559   (cond [(eq_attr "type" "other,multi,fistp,frndint")
560            (const_int 16)
561          (eq_attr "type" "fcmp")
562            (const_int 4)
563          (eq_attr "unit" "i387")
564            (plus (const_int 2)
565                  (plus (attr "prefix_data16")
566                        (attr "length_address")))
567          (ior (eq_attr "prefix" "vex")
568               (and (eq_attr "prefix" "maybe_vex")
569                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
570            (plus (attr "length_vex")
571                  (plus (attr "length_immediate")
572                        (plus (attr "modrm")
573                              (attr "length_address"))))]
574          (plus (plus (attr "modrm")
575                      (plus (attr "prefix_0f")
576                            (plus (attr "prefix_rex")
577                                  (plus (attr "prefix_extra")
578                                        (const_int 1)))))
579                (plus (attr "prefix_rep")
580                      (plus (attr "prefix_data16")
581                            (plus (attr "length_immediate")
582                                  (attr "length_address")))))))
583
584 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
585 ;; `store' if there is a simple memory reference therein, or `unknown'
586 ;; if the instruction is complex.
587
588 (define_attr "memory" "none,load,store,both,unknown"
589   (cond [(eq_attr "type" "other,multi,str,lwp")
590            (const_string "unknown")
591          (eq_attr "type" "lea,fcmov,fpspc")
592            (const_string "none")
593          (eq_attr "type" "fistp,leave")
594            (const_string "both")
595          (eq_attr "type" "frndint")
596            (const_string "load")
597          (eq_attr "type" "push")
598            (if_then_else (match_operand 1 "memory_operand" "")
599              (const_string "both")
600              (const_string "store"))
601          (eq_attr "type" "pop")
602            (if_then_else (match_operand 0 "memory_operand" "")
603              (const_string "both")
604              (const_string "load"))
605          (eq_attr "type" "setcc")
606            (if_then_else (match_operand 0 "memory_operand" "")
607              (const_string "store")
608              (const_string "none"))
609          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
610            (if_then_else (ior (match_operand 0 "memory_operand" "")
611                               (match_operand 1 "memory_operand" ""))
612              (const_string "load")
613              (const_string "none"))
614          (eq_attr "type" "ibr")
615            (if_then_else (match_operand 0 "memory_operand" "")
616              (const_string "load")
617              (const_string "none"))
618          (eq_attr "type" "call")
619            (if_then_else (match_operand 0 "constant_call_address_operand" "")
620              (const_string "none")
621              (const_string "load"))
622          (eq_attr "type" "callv")
623            (if_then_else (match_operand 1 "constant_call_address_operand" "")
624              (const_string "none")
625              (const_string "load"))
626          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
627               (match_operand 1 "memory_operand" ""))
628            (const_string "both")
629          (and (match_operand 0 "memory_operand" "")
630               (match_operand 1 "memory_operand" ""))
631            (const_string "both")
632          (match_operand 0 "memory_operand" "")
633            (const_string "store")
634          (match_operand 1 "memory_operand" "")
635            (const_string "load")
636          (and (eq_attr "type"
637                  "!alu1,negnot,ishift1,
638                    imov,imovx,icmp,test,bitmanip,
639                    fmov,fcmp,fsgn,
640                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
641                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
642               (match_operand 2 "memory_operand" ""))
643            (const_string "load")
644          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
645               (match_operand 3 "memory_operand" ""))
646            (const_string "load")
647         ]
648         (const_string "none")))
649
650 ;; Indicates if an instruction has both an immediate and a displacement.
651
652 (define_attr "imm_disp" "false,true,unknown"
653   (cond [(eq_attr "type" "other,multi")
654            (const_string "unknown")
655          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
656               (and (match_operand 0 "memory_displacement_operand" "")
657                    (match_operand 1 "immediate_operand" "")))
658            (const_string "true")
659          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
660               (and (match_operand 0 "memory_displacement_operand" "")
661                    (match_operand 2 "immediate_operand" "")))
662            (const_string "true")
663         ]
664         (const_string "false")))
665
666 ;; Indicates if an FP operation has an integer source.
667
668 (define_attr "fp_int_src" "false,true"
669   (const_string "false"))
670
671 ;; Defines rounding mode of an FP operation.
672
673 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
674   (const_string "any"))
675
676 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
677 (define_attr "use_carry" "0,1" (const_string "0"))
678
679 ;; Define attribute to indicate unaligned ssemov insns
680 (define_attr "movu" "0,1" (const_string "0"))
681
682 ;; Describe a user's asm statement.
683 (define_asm_attributes
684   [(set_attr "length" "128")
685    (set_attr "type" "multi")])
686
687 (define_code_iterator plusminus [plus minus])
688
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698   [(plus "add") (ss_plus "adds") (us_plus "addus")
699    (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701   [(plus "adc") (minus "sbb")])
702
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705                         (minus "") (ss_minus "") (us_minus "")])
706
707 ;; Mapping of signed max and min
708 (define_code_iterator smaxmin [smax smin])
709
710 ;; Mapping of unsigned max and min
711 (define_code_iterator umaxmin [umax umin])
712
713 ;; Mapping of signed/unsigned max and min
714 (define_code_iterator maxmin [smax smin umax umin])
715
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718                               (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727
728 ;; Mapping of shift-right operators
729 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730
731 ;; Base name for define_insn
732 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733
734 ;; Base name for insn mnemonic.
735 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736
737 ;; Mapping of rotate operators
738 (define_code_iterator any_rotate [rotate rotatert])
739
740 ;; Base name for define_insn
741 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742
743 ;; Base name for insn mnemonic.
744 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745
746 ;; Mapping of abs neg operators
747 (define_code_iterator absneg [abs neg])
748
749 ;; Base name for x87 insn mnemonic.
750 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751
752 ;; Used in signed and unsigned widening multiplications.
753 (define_code_iterator any_extend [sign_extend zero_extend])
754
755 ;; Various insn prefixes for signed and unsigned operations.
756 (define_code_attr u [(sign_extend "") (zero_extend "u")
757                      (div "") (udiv "u")])
758 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759
760 ;; Used in signed and unsigned divisions.
761 (define_code_iterator any_div [div udiv])
762
763 ;; Instruction prefix for signed and unsigned operations.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
765                              (div "i") (udiv "")])
766
767 ;; 64bit single word integer modes.
768 (define_mode_iterator SWI1248x [QI HI SI DI])
769
770 ;; 64bit single word integer modes without QImode and HImode.
771 (define_mode_iterator SWI48x [SI DI])
772
773 ;; Single word integer modes.
774 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
775
776 ;; Single word integer modes without SImode and DImode.
777 (define_mode_iterator SWI12 [QI HI])
778
779 ;; Single word integer modes without DImode.
780 (define_mode_iterator SWI124 [QI HI SI])
781
782 ;; Single word integer modes without QImode and DImode.
783 (define_mode_iterator SWI24 [HI SI])
784
785 ;; Single word integer modes without QImode.
786 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
787
788 ;; Single word integer modes without QImode and HImode.
789 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
790
791 ;; All math-dependant single and double word integer modes.
792 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
793                              (HI "TARGET_HIMODE_MATH")
794                              SI DI (TI "TARGET_64BIT")])
795
796 ;; Math-dependant single word integer modes.
797 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
798                             (HI "TARGET_HIMODE_MATH")
799                             SI (DI "TARGET_64BIT")])
800
801 ;; Math-dependant single word integer modes without DImode.
802 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
803                                (HI "TARGET_HIMODE_MATH")
804                                SI])
805
806 ;; Math-dependant single word integer modes without QImode.
807 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
808                                SI (DI "TARGET_64BIT")])
809
810 ;; Double word integer modes.
811 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
812                            (TI "TARGET_64BIT")])
813
814 ;; Double word integer modes as mode attribute.
815 (define_mode_attr DWI [(SI "DI") (DI "TI")])
816 (define_mode_attr dwi [(SI "di") (DI "ti")])
817
818 ;; Half mode for double word integer modes.
819 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
820                             (DI "TARGET_64BIT")])
821
822 ;; Instruction suffix for integer modes.
823 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
824
825 ;; Pointer size prefix for integer modes (Intel asm dialect)
826 (define_mode_attr iptrsize [(QI "BYTE")
827                             (HI "WORD")
828                             (SI "DWORD")
829                             (DI "QWORD")])
830
831 ;; Register class for integer modes.
832 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
833
834 ;; Immediate operand constraint for integer modes.
835 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
836
837 ;; General operand constraint for word modes.
838 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
839
840 ;; Immediate operand constraint for double integer modes.
841 (define_mode_attr di [(SI "iF") (DI "e")])
842
843 ;; Immediate operand constraint for shifts.
844 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
845
846 ;; General operand predicate for integer modes.
847 (define_mode_attr general_operand
848         [(QI "general_operand")
849          (HI "general_operand")
850          (SI "general_operand")
851          (DI "x86_64_general_operand")
852          (TI "x86_64_general_operand")])
853
854 ;; General sign/zero extend operand predicate for integer modes.
855 (define_mode_attr general_szext_operand
856         [(QI "general_operand")
857          (HI "general_operand")
858          (SI "general_operand")
859          (DI "x86_64_szext_general_operand")])
860
861 ;; Immediate operand predicate for integer modes.
862 (define_mode_attr immediate_operand
863         [(QI "immediate_operand")
864          (HI "immediate_operand")
865          (SI "immediate_operand")
866          (DI "x86_64_immediate_operand")])
867
868 ;; Nonmemory operand predicate for integer modes.
869 (define_mode_attr nonmemory_operand
870         [(QI "nonmemory_operand")
871          (HI "nonmemory_operand")
872          (SI "nonmemory_operand")
873          (DI "x86_64_nonmemory_operand")])
874
875 ;; Operand predicate for shifts.
876 (define_mode_attr shift_operand
877         [(QI "nonimmediate_operand")
878          (HI "nonimmediate_operand")
879          (SI "nonimmediate_operand")
880          (DI "shiftdi_operand")
881          (TI "register_operand")])
882
883 ;; Operand predicate for shift argument.
884 (define_mode_attr shift_immediate_operand
885         [(QI "const_1_to_31_operand")
886          (HI "const_1_to_31_operand")
887          (SI "const_1_to_31_operand")
888          (DI "const_1_to_63_operand")])
889
890 ;; Input operand predicate for arithmetic left shifts.
891 (define_mode_attr ashl_input_operand
892         [(QI "nonimmediate_operand")
893          (HI "nonimmediate_operand")
894          (SI "nonimmediate_operand")
895          (DI "ashldi_input_operand")
896          (TI "reg_or_pm1_operand")])
897
898 ;; SSE and x87 SFmode and DFmode floating point modes
899 (define_mode_iterator MODEF [SF DF])
900
901 ;; All x87 floating point modes
902 (define_mode_iterator X87MODEF [SF DF XF])
903
904 ;; All integer modes handled by x87 fisttp operator.
905 (define_mode_iterator X87MODEI [HI SI DI])
906
907 ;; All integer modes handled by integer x87 operators.
908 (define_mode_iterator X87MODEI12 [HI SI])
909
910 ;; All integer modes handled by SSE cvtts?2si* operators.
911 (define_mode_iterator SSEMODEI24 [SI DI])
912
913 ;; SSE asm suffix for floating point modes
914 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
915
916 ;; SSE vector mode corresponding to a scalar mode
917 (define_mode_attr ssevecmode
918   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
919
920 ;; Instruction suffix for REX 64bit operators.
921 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
922
923 ;; This mode iterator allows :P to be used for patterns that operate on
924 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
925 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
926 \f
927 ;; Scheduling descriptions
928
929 (include "pentium.md")
930 (include "ppro.md")
931 (include "k6.md")
932 (include "athlon.md")
933 (include "geode.md")
934 (include "atom.md")
935
936 \f
937 ;; Operand and operator predicates and constraints
938
939 (include "predicates.md")
940 (include "constraints.md")
941
942 \f
943 ;; Compare and branch/compare and store instructions.
944
945 (define_expand "cbranch<mode>4"
946   [(set (reg:CC FLAGS_REG)
947         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
948                     (match_operand:SDWIM 2 "<general_operand>" "")))
949    (set (pc) (if_then_else
950                (match_operator 0 "ordered_comparison_operator"
951                 [(reg:CC FLAGS_REG) (const_int 0)])
952                (label_ref (match_operand 3 "" ""))
953                (pc)))]
954   ""
955 {
956   if (MEM_P (operands[1]) && MEM_P (operands[2]))
957     operands[1] = force_reg (<MODE>mode, operands[1]);
958   ix86_expand_branch (GET_CODE (operands[0]),
959                       operands[1], operands[2], operands[3]);
960   DONE;
961 })
962
963 (define_expand "cstore<mode>4"
964   [(set (reg:CC FLAGS_REG)
965         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
966                     (match_operand:SWIM 3 "<general_operand>" "")))
967    (set (match_operand:QI 0 "register_operand" "")
968         (match_operator 1 "ordered_comparison_operator"
969           [(reg:CC FLAGS_REG) (const_int 0)]))]
970   ""
971 {
972   if (MEM_P (operands[2]) && MEM_P (operands[3]))
973     operands[2] = force_reg (<MODE>mode, operands[2]);
974   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
975                      operands[2], operands[3]);
976   DONE;
977 })
978
979 (define_expand "cmp<mode>_1"
980   [(set (reg:CC FLAGS_REG)
981         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
982                     (match_operand:SWI48 1 "<general_operand>" "")))]
983   ""
984   "")
985
986 (define_insn "*cmp<mode>_ccno_1"
987   [(set (reg FLAGS_REG)
988         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
989                  (match_operand:SWI 1 "const0_operand" "")))]
990   "ix86_match_ccmode (insn, CCNOmode)"
991   "@
992    test{<imodesuffix>}\t%0, %0
993    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
994   [(set_attr "type" "test,icmp")
995    (set_attr "length_immediate" "0,1")
996    (set_attr "mode" "<MODE>")])
997
998 (define_insn "*cmp<mode>_1"
999   [(set (reg FLAGS_REG)
1000         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1001                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1002   "ix86_match_ccmode (insn, CCmode)"
1003   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1004   [(set_attr "type" "icmp")
1005    (set_attr "mode" "<MODE>")])
1006
1007 (define_insn "*cmp<mode>_minus_1"
1008   [(set (reg FLAGS_REG)
1009         (compare
1010           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1011                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1012           (const_int 0)))]
1013   "ix86_match_ccmode (insn, CCGOCmode)"
1014   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1015   [(set_attr "type" "icmp")
1016    (set_attr "mode" "<MODE>")])
1017
1018 (define_insn "*cmpqi_ext_1"
1019   [(set (reg FLAGS_REG)
1020         (compare
1021           (match_operand:QI 0 "general_operand" "Qm")
1022           (subreg:QI
1023             (zero_extract:SI
1024               (match_operand 1 "ext_register_operand" "Q")
1025               (const_int 8)
1026               (const_int 8)) 0)))]
1027   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1028   "cmp{b}\t{%h1, %0|%0, %h1}"
1029   [(set_attr "type" "icmp")
1030    (set_attr "mode" "QI")])
1031
1032 (define_insn "*cmpqi_ext_1_rex64"
1033   [(set (reg FLAGS_REG)
1034         (compare
1035           (match_operand:QI 0 "register_operand" "Q")
1036           (subreg:QI
1037             (zero_extract:SI
1038               (match_operand 1 "ext_register_operand" "Q")
1039               (const_int 8)
1040               (const_int 8)) 0)))]
1041   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1042   "cmp{b}\t{%h1, %0|%0, %h1}"
1043   [(set_attr "type" "icmp")
1044    (set_attr "mode" "QI")])
1045
1046 (define_insn "*cmpqi_ext_2"
1047   [(set (reg FLAGS_REG)
1048         (compare
1049           (subreg:QI
1050             (zero_extract:SI
1051               (match_operand 0 "ext_register_operand" "Q")
1052               (const_int 8)
1053               (const_int 8)) 0)
1054           (match_operand:QI 1 "const0_operand" "")))]
1055   "ix86_match_ccmode (insn, CCNOmode)"
1056   "test{b}\t%h0, %h0"
1057   [(set_attr "type" "test")
1058    (set_attr "length_immediate" "0")
1059    (set_attr "mode" "QI")])
1060
1061 (define_expand "cmpqi_ext_3"
1062   [(set (reg:CC FLAGS_REG)
1063         (compare:CC
1064           (subreg:QI
1065             (zero_extract:SI
1066               (match_operand 0 "ext_register_operand" "")
1067               (const_int 8)
1068               (const_int 8)) 0)
1069           (match_operand:QI 1 "immediate_operand" "")))]
1070   ""
1071   "")
1072
1073 (define_insn "*cmpqi_ext_3_insn"
1074   [(set (reg FLAGS_REG)
1075         (compare
1076           (subreg:QI
1077             (zero_extract:SI
1078               (match_operand 0 "ext_register_operand" "Q")
1079               (const_int 8)
1080               (const_int 8)) 0)
1081           (match_operand:QI 1 "general_operand" "Qmn")))]
1082   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1083   "cmp{b}\t{%1, %h0|%h0, %1}"
1084   [(set_attr "type" "icmp")
1085    (set_attr "modrm" "1")
1086    (set_attr "mode" "QI")])
1087
1088 (define_insn "*cmpqi_ext_3_insn_rex64"
1089   [(set (reg FLAGS_REG)
1090         (compare
1091           (subreg:QI
1092             (zero_extract:SI
1093               (match_operand 0 "ext_register_operand" "Q")
1094               (const_int 8)
1095               (const_int 8)) 0)
1096           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1097   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1098   "cmp{b}\t{%1, %h0|%h0, %1}"
1099   [(set_attr "type" "icmp")
1100    (set_attr "modrm" "1")
1101    (set_attr "mode" "QI")])
1102
1103 (define_insn "*cmpqi_ext_4"
1104   [(set (reg FLAGS_REG)
1105         (compare
1106           (subreg:QI
1107             (zero_extract:SI
1108               (match_operand 0 "ext_register_operand" "Q")
1109               (const_int 8)
1110               (const_int 8)) 0)
1111           (subreg:QI
1112             (zero_extract:SI
1113               (match_operand 1 "ext_register_operand" "Q")
1114               (const_int 8)
1115               (const_int 8)) 0)))]
1116   "ix86_match_ccmode (insn, CCmode)"
1117   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1118   [(set_attr "type" "icmp")
1119    (set_attr "mode" "QI")])
1120
1121 ;; These implement float point compares.
1122 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1123 ;; which would allow mix and match FP modes on the compares.  Which is what
1124 ;; the old patterns did, but with many more of them.
1125
1126 (define_expand "cbranchxf4"
1127   [(set (reg:CC FLAGS_REG)
1128         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1129                     (match_operand:XF 2 "nonmemory_operand" "")))
1130    (set (pc) (if_then_else
1131               (match_operator 0 "ix86_fp_comparison_operator"
1132                [(reg:CC FLAGS_REG)
1133                 (const_int 0)])
1134               (label_ref (match_operand 3 "" ""))
1135               (pc)))]
1136   "TARGET_80387"
1137 {
1138   ix86_expand_branch (GET_CODE (operands[0]),
1139                       operands[1], operands[2], operands[3]);
1140   DONE;
1141 })
1142
1143 (define_expand "cstorexf4"
1144   [(set (reg:CC FLAGS_REG)
1145         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1146                     (match_operand:XF 3 "nonmemory_operand" "")))
1147    (set (match_operand:QI 0 "register_operand" "")
1148               (match_operator 1 "ix86_fp_comparison_operator"
1149                [(reg:CC FLAGS_REG)
1150                 (const_int 0)]))]
1151   "TARGET_80387"
1152 {
1153   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1154                      operands[2], operands[3]);
1155   DONE;
1156 })
1157
1158 (define_expand "cbranch<mode>4"
1159   [(set (reg:CC FLAGS_REG)
1160         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1161                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1162    (set (pc) (if_then_else
1163               (match_operator 0 "ix86_fp_comparison_operator"
1164                [(reg:CC FLAGS_REG)
1165                 (const_int 0)])
1166               (label_ref (match_operand 3 "" ""))
1167               (pc)))]
1168   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1169 {
1170   ix86_expand_branch (GET_CODE (operands[0]),
1171                       operands[1], operands[2], operands[3]);
1172   DONE;
1173 })
1174
1175 (define_expand "cstore<mode>4"
1176   [(set (reg:CC FLAGS_REG)
1177         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1178                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1179    (set (match_operand:QI 0 "register_operand" "")
1180               (match_operator 1 "ix86_fp_comparison_operator"
1181                [(reg:CC FLAGS_REG)
1182                 (const_int 0)]))]
1183   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1184 {
1185   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186                      operands[2], operands[3]);
1187   DONE;
1188 })
1189
1190 (define_expand "cbranchcc4"
1191   [(set (pc) (if_then_else
1192               (match_operator 0 "comparison_operator"
1193                [(match_operand 1 "flags_reg_operand" "")
1194                 (match_operand 2 "const0_operand" "")])
1195               (label_ref (match_operand 3 "" ""))
1196               (pc)))]
1197   ""
1198 {
1199   ix86_expand_branch (GET_CODE (operands[0]),
1200                       operands[1], operands[2], operands[3]);
1201   DONE;
1202 })
1203
1204 (define_expand "cstorecc4"
1205   [(set (match_operand:QI 0 "register_operand" "")
1206               (match_operator 1 "comparison_operator"
1207                [(match_operand 2 "flags_reg_operand" "")
1208                 (match_operand 3 "const0_operand" "")]))]
1209   ""
1210 {
1211   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212                      operands[2], operands[3]);
1213   DONE;
1214 })
1215
1216
1217 ;; FP compares, step 1:
1218 ;; Set the FP condition codes.
1219 ;;
1220 ;; CCFPmode     compare with exceptions
1221 ;; CCFPUmode    compare with no exceptions
1222
1223 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1224 ;; used to manage the reg stack popping would not be preserved.
1225
1226 (define_insn "*cmpfp_0"
1227   [(set (match_operand:HI 0 "register_operand" "=a")
1228         (unspec:HI
1229           [(compare:CCFP
1230              (match_operand 1 "register_operand" "f")
1231              (match_operand 2 "const0_operand" ""))]
1232         UNSPEC_FNSTSW))]
1233   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1234    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1235   "* return output_fp_compare (insn, operands, 0, 0);"
1236   [(set_attr "type" "multi")
1237    (set_attr "unit" "i387")
1238    (set (attr "mode")
1239      (cond [(match_operand:SF 1 "" "")
1240               (const_string "SF")
1241             (match_operand:DF 1 "" "")
1242               (const_string "DF")
1243            ]
1244            (const_string "XF")))])
1245
1246 (define_insn_and_split "*cmpfp_0_cc"
1247   [(set (reg:CCFP FLAGS_REG)
1248         (compare:CCFP
1249           (match_operand 1 "register_operand" "f")
1250           (match_operand 2 "const0_operand" "")))
1251    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1252   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1253    && TARGET_SAHF && !TARGET_CMOVE
1254    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1255   "#"
1256   "&& reload_completed"
1257   [(set (match_dup 0)
1258         (unspec:HI
1259           [(compare:CCFP (match_dup 1)(match_dup 2))]
1260         UNSPEC_FNSTSW))
1261    (set (reg:CC FLAGS_REG)
1262         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1263   ""
1264   [(set_attr "type" "multi")
1265    (set_attr "unit" "i387")
1266    (set (attr "mode")
1267      (cond [(match_operand:SF 1 "" "")
1268               (const_string "SF")
1269             (match_operand:DF 1 "" "")
1270               (const_string "DF")
1271            ]
1272            (const_string "XF")))])
1273
1274 (define_insn "*cmpfp_xf"
1275   [(set (match_operand:HI 0 "register_operand" "=a")
1276         (unspec:HI
1277           [(compare:CCFP
1278              (match_operand:XF 1 "register_operand" "f")
1279              (match_operand:XF 2 "register_operand" "f"))]
1280           UNSPEC_FNSTSW))]
1281   "TARGET_80387"
1282   "* return output_fp_compare (insn, operands, 0, 0);"
1283   [(set_attr "type" "multi")
1284    (set_attr "unit" "i387")
1285    (set_attr "mode" "XF")])
1286
1287 (define_insn_and_split "*cmpfp_xf_cc"
1288   [(set (reg:CCFP FLAGS_REG)
1289         (compare:CCFP
1290           (match_operand:XF 1 "register_operand" "f")
1291           (match_operand:XF 2 "register_operand" "f")))
1292    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1293   "TARGET_80387
1294    && TARGET_SAHF && !TARGET_CMOVE"
1295   "#"
1296   "&& reload_completed"
1297   [(set (match_dup 0)
1298         (unspec:HI
1299           [(compare:CCFP (match_dup 1)(match_dup 2))]
1300         UNSPEC_FNSTSW))
1301    (set (reg:CC FLAGS_REG)
1302         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1303   ""
1304   [(set_attr "type" "multi")
1305    (set_attr "unit" "i387")
1306    (set_attr "mode" "XF")])
1307
1308 (define_insn "*cmpfp_<mode>"
1309   [(set (match_operand:HI 0 "register_operand" "=a")
1310         (unspec:HI
1311           [(compare:CCFP
1312              (match_operand:MODEF 1 "register_operand" "f")
1313              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1314           UNSPEC_FNSTSW))]
1315   "TARGET_80387"
1316   "* return output_fp_compare (insn, operands, 0, 0);"
1317   [(set_attr "type" "multi")
1318    (set_attr "unit" "i387")
1319    (set_attr "mode" "<MODE>")])
1320
1321 (define_insn_and_split "*cmpfp_<mode>_cc"
1322   [(set (reg:CCFP FLAGS_REG)
1323         (compare:CCFP
1324           (match_operand:MODEF 1 "register_operand" "f")
1325           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1326    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1327   "TARGET_80387
1328    && TARGET_SAHF && !TARGET_CMOVE"
1329   "#"
1330   "&& reload_completed"
1331   [(set (match_dup 0)
1332         (unspec:HI
1333           [(compare:CCFP (match_dup 1)(match_dup 2))]
1334         UNSPEC_FNSTSW))
1335    (set (reg:CC FLAGS_REG)
1336         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1337   ""
1338   [(set_attr "type" "multi")
1339    (set_attr "unit" "i387")
1340    (set_attr "mode" "<MODE>")])
1341
1342 (define_insn "*cmpfp_u"
1343   [(set (match_operand:HI 0 "register_operand" "=a")
1344         (unspec:HI
1345           [(compare:CCFPU
1346              (match_operand 1 "register_operand" "f")
1347              (match_operand 2 "register_operand" "f"))]
1348           UNSPEC_FNSTSW))]
1349   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1350    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1351   "* return output_fp_compare (insn, operands, 0, 1);"
1352   [(set_attr "type" "multi")
1353    (set_attr "unit" "i387")
1354    (set (attr "mode")
1355      (cond [(match_operand:SF 1 "" "")
1356               (const_string "SF")
1357             (match_operand:DF 1 "" "")
1358               (const_string "DF")
1359            ]
1360            (const_string "XF")))])
1361
1362 (define_insn_and_split "*cmpfp_u_cc"
1363   [(set (reg:CCFPU FLAGS_REG)
1364         (compare:CCFPU
1365           (match_operand 1 "register_operand" "f")
1366           (match_operand 2 "register_operand" "f")))
1367    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1368   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1369    && TARGET_SAHF && !TARGET_CMOVE
1370    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1371   "#"
1372   "&& reload_completed"
1373   [(set (match_dup 0)
1374         (unspec:HI
1375           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1376         UNSPEC_FNSTSW))
1377    (set (reg:CC FLAGS_REG)
1378         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1379   ""
1380   [(set_attr "type" "multi")
1381    (set_attr "unit" "i387")
1382    (set (attr "mode")
1383      (cond [(match_operand:SF 1 "" "")
1384               (const_string "SF")
1385             (match_operand:DF 1 "" "")
1386               (const_string "DF")
1387            ]
1388            (const_string "XF")))])
1389
1390 (define_insn "*cmpfp_<mode>"
1391   [(set (match_operand:HI 0 "register_operand" "=a")
1392         (unspec:HI
1393           [(compare:CCFP
1394              (match_operand 1 "register_operand" "f")
1395              (match_operator 3 "float_operator"
1396                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1397           UNSPEC_FNSTSW))]
1398   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1400    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1401   "* return output_fp_compare (insn, operands, 0, 0);"
1402   [(set_attr "type" "multi")
1403    (set_attr "unit" "i387")
1404    (set_attr "fp_int_src" "true")
1405    (set_attr "mode" "<MODE>")])
1406
1407 (define_insn_and_split "*cmpfp_<mode>_cc"
1408   [(set (reg:CCFP FLAGS_REG)
1409         (compare:CCFP
1410           (match_operand 1 "register_operand" "f")
1411           (match_operator 3 "float_operator"
1412             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1413    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1414   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1415    && TARGET_SAHF && !TARGET_CMOVE
1416    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1417    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1418   "#"
1419   "&& reload_completed"
1420   [(set (match_dup 0)
1421         (unspec:HI
1422           [(compare:CCFP
1423              (match_dup 1)
1424              (match_op_dup 3 [(match_dup 2)]))]
1425         UNSPEC_FNSTSW))
1426    (set (reg:CC FLAGS_REG)
1427         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1428   ""
1429   [(set_attr "type" "multi")
1430    (set_attr "unit" "i387")
1431    (set_attr "fp_int_src" "true")
1432    (set_attr "mode" "<MODE>")])
1433
1434 ;; FP compares, step 2
1435 ;; Move the fpsw to ax.
1436
1437 (define_insn "x86_fnstsw_1"
1438   [(set (match_operand:HI 0 "register_operand" "=a")
1439         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1440   "TARGET_80387"
1441   "fnstsw\t%0"
1442   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1443    (set_attr "mode" "SI")
1444    (set_attr "unit" "i387")])
1445
1446 ;; FP compares, step 3
1447 ;; Get ax into flags, general case.
1448
1449 (define_insn "x86_sahf_1"
1450   [(set (reg:CC FLAGS_REG)
1451         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1452                    UNSPEC_SAHF))]
1453   "TARGET_SAHF"
1454 {
1455 #ifndef HAVE_AS_IX86_SAHF
1456   if (TARGET_64BIT)
1457     return ASM_BYTE "0x9e";
1458   else
1459 #endif
1460   return "sahf";
1461 }
1462   [(set_attr "length" "1")
1463    (set_attr "athlon_decode" "vector")
1464    (set_attr "amdfam10_decode" "direct")
1465    (set_attr "mode" "SI")])
1466
1467 ;; Pentium Pro can do steps 1 through 3 in one go.
1468 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1469 (define_insn "*cmpfp_i_mixed"
1470   [(set (reg:CCFP FLAGS_REG)
1471         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1472                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1473   "TARGET_MIX_SSE_I387
1474    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1475    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1476   "* return output_fp_compare (insn, operands, 1, 0);"
1477   [(set_attr "type" "fcmp,ssecomi")
1478    (set_attr "prefix" "orig,maybe_vex")
1479    (set (attr "mode")
1480      (if_then_else (match_operand:SF 1 "" "")
1481         (const_string "SF")
1482         (const_string "DF")))
1483    (set (attr "prefix_rep")
1484         (if_then_else (eq_attr "type" "ssecomi")
1485                       (const_string "0")
1486                       (const_string "*")))
1487    (set (attr "prefix_data16")
1488         (cond [(eq_attr "type" "fcmp")
1489                  (const_string "*")
1490                (eq_attr "mode" "DF")
1491                  (const_string "1")
1492               ]
1493               (const_string "0")))
1494    (set_attr "athlon_decode" "vector")
1495    (set_attr "amdfam10_decode" "direct")])
1496
1497 (define_insn "*cmpfp_i_sse"
1498   [(set (reg:CCFP FLAGS_REG)
1499         (compare:CCFP (match_operand 0 "register_operand" "x")
1500                       (match_operand 1 "nonimmediate_operand" "xm")))]
1501   "TARGET_SSE_MATH
1502    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1503    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1504   "* return output_fp_compare (insn, operands, 1, 0);"
1505   [(set_attr "type" "ssecomi")
1506    (set_attr "prefix" "maybe_vex")
1507    (set (attr "mode")
1508      (if_then_else (match_operand:SF 1 "" "")
1509         (const_string "SF")
1510         (const_string "DF")))
1511    (set_attr "prefix_rep" "0")
1512    (set (attr "prefix_data16")
1513         (if_then_else (eq_attr "mode" "DF")
1514                       (const_string "1")
1515                       (const_string "0")))
1516    (set_attr "athlon_decode" "vector")
1517    (set_attr "amdfam10_decode" "direct")])
1518
1519 (define_insn "*cmpfp_i_i387"
1520   [(set (reg:CCFP FLAGS_REG)
1521         (compare:CCFP (match_operand 0 "register_operand" "f")
1522                       (match_operand 1 "register_operand" "f")))]
1523   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1524    && TARGET_CMOVE
1525    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1526    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527   "* return output_fp_compare (insn, operands, 1, 0);"
1528   [(set_attr "type" "fcmp")
1529    (set (attr "mode")
1530      (cond [(match_operand:SF 1 "" "")
1531               (const_string "SF")
1532             (match_operand:DF 1 "" "")
1533               (const_string "DF")
1534            ]
1535            (const_string "XF")))
1536    (set_attr "athlon_decode" "vector")
1537    (set_attr "amdfam10_decode" "direct")])
1538
1539 (define_insn "*cmpfp_iu_mixed"
1540   [(set (reg:CCFPU FLAGS_REG)
1541         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1542                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1543   "TARGET_MIX_SSE_I387
1544    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1545    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1546   "* return output_fp_compare (insn, operands, 1, 1);"
1547   [(set_attr "type" "fcmp,ssecomi")
1548    (set_attr "prefix" "orig,maybe_vex")
1549    (set (attr "mode")
1550      (if_then_else (match_operand:SF 1 "" "")
1551         (const_string "SF")
1552         (const_string "DF")))
1553    (set (attr "prefix_rep")
1554         (if_then_else (eq_attr "type" "ssecomi")
1555                       (const_string "0")
1556                       (const_string "*")))
1557    (set (attr "prefix_data16")
1558         (cond [(eq_attr "type" "fcmp")
1559                  (const_string "*")
1560                (eq_attr "mode" "DF")
1561                  (const_string "1")
1562               ]
1563               (const_string "0")))
1564    (set_attr "athlon_decode" "vector")
1565    (set_attr "amdfam10_decode" "direct")])
1566
1567 (define_insn "*cmpfp_iu_sse"
1568   [(set (reg:CCFPU FLAGS_REG)
1569         (compare:CCFPU (match_operand 0 "register_operand" "x")
1570                        (match_operand 1 "nonimmediate_operand" "xm")))]
1571   "TARGET_SSE_MATH
1572    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1573    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574   "* return output_fp_compare (insn, operands, 1, 1);"
1575   [(set_attr "type" "ssecomi")
1576    (set_attr "prefix" "maybe_vex")
1577    (set (attr "mode")
1578      (if_then_else (match_operand:SF 1 "" "")
1579         (const_string "SF")
1580         (const_string "DF")))
1581    (set_attr "prefix_rep" "0")
1582    (set (attr "prefix_data16")
1583         (if_then_else (eq_attr "mode" "DF")
1584                       (const_string "1")
1585                       (const_string "0")))
1586    (set_attr "athlon_decode" "vector")
1587    (set_attr "amdfam10_decode" "direct")])
1588
1589 (define_insn "*cmpfp_iu_387"
1590   [(set (reg:CCFPU FLAGS_REG)
1591         (compare:CCFPU (match_operand 0 "register_operand" "f")
1592                        (match_operand 1 "register_operand" "f")))]
1593   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1594    && TARGET_CMOVE
1595    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1596    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1597   "* return output_fp_compare (insn, operands, 1, 1);"
1598   [(set_attr "type" "fcmp")
1599    (set (attr "mode")
1600      (cond [(match_operand:SF 1 "" "")
1601               (const_string "SF")
1602             (match_operand:DF 1 "" "")
1603               (const_string "DF")
1604            ]
1605            (const_string "XF")))
1606    (set_attr "athlon_decode" "vector")
1607    (set_attr "amdfam10_decode" "direct")])
1608 \f
1609 ;; Push/pop instructions.
1610
1611 (define_insn "*pushdi2_rex64"
1612   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1613         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1614   "TARGET_64BIT"
1615   "@
1616    push{q}\t%1
1617    #"
1618   [(set_attr "type" "push,multi")
1619    (set_attr "mode" "DI")])
1620
1621 ;; Convert impossible pushes of immediate to existing instructions.
1622 ;; First try to get scratch register and go through it.  In case this
1623 ;; fails, push sign extended lower part first and then overwrite
1624 ;; upper part by 32bit move.
1625 (define_peephole2
1626   [(match_scratch:DI 2 "r")
1627    (set (match_operand:DI 0 "push_operand" "")
1628         (match_operand:DI 1 "immediate_operand" ""))]
1629   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1630    && !x86_64_immediate_operand (operands[1], DImode)"
1631   [(set (match_dup 2) (match_dup 1))
1632    (set (match_dup 0) (match_dup 2))])
1633
1634 ;; We need to define this as both peepholer and splitter for case
1635 ;; peephole2 pass is not run.
1636 ;; "&& 1" is needed to keep it from matching the previous pattern.
1637 (define_peephole2
1638   [(set (match_operand:DI 0 "push_operand" "")
1639         (match_operand:DI 1 "immediate_operand" ""))]
1640   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1641    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1642   [(set (match_dup 0) (match_dup 1))
1643    (set (match_dup 2) (match_dup 3))]
1644 {
1645   split_di (&operands[1], 1, &operands[2], &operands[3]);
1646
1647   operands[1] = gen_lowpart (DImode, operands[2]);
1648   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1649                                                    GEN_INT (4)));
1650 })
1651
1652 (define_split
1653   [(set (match_operand:DI 0 "push_operand" "")
1654         (match_operand:DI 1 "immediate_operand" ""))]
1655   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1656                     ? epilogue_completed : reload_completed)
1657    && !symbolic_operand (operands[1], DImode)
1658    && !x86_64_immediate_operand (operands[1], DImode)"
1659   [(set (match_dup 0) (match_dup 1))
1660    (set (match_dup 2) (match_dup 3))]
1661 {
1662   split_di (&operands[1], 1, &operands[2], &operands[3]);
1663
1664   operands[1] = gen_lowpart (DImode, operands[2]);
1665   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1666                                                    GEN_INT (4)));
1667 })
1668
1669 (define_insn "*pushdi2"
1670   [(set (match_operand:DI 0 "push_operand" "=<")
1671         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1672   "!TARGET_64BIT"
1673   "#")
1674
1675 (define_split
1676   [(set (match_operand:DI 0 "push_operand" "")
1677         (match_operand:DI 1 "general_operand" ""))]
1678   "!TARGET_64BIT && reload_completed
1679    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1680   [(const_int 0)]
1681   "ix86_split_long_move (operands); DONE;")
1682
1683 (define_insn "*pushsi2"
1684   [(set (match_operand:SI 0 "push_operand" "=<")
1685         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1686   "!TARGET_64BIT"
1687   "push{l}\t%1"
1688   [(set_attr "type" "push")
1689    (set_attr "mode" "SI")])
1690
1691 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1692 ;; "push a byte/word".  But actually we use pushl, which has the effect
1693 ;; of rounding the amount pushed up to a word.
1694
1695 ;; For TARGET_64BIT we always round up to 8 bytes.
1696 (define_insn "*push<mode>2_rex64"
1697   [(set (match_operand:SWI124 0 "push_operand" "=X")
1698         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1699   "TARGET_64BIT"
1700   "push{q}\t%q1"
1701   [(set_attr "type" "push")
1702    (set_attr "mode" "DI")])
1703
1704 (define_insn "*push<mode>2"
1705   [(set (match_operand:SWI12 0 "push_operand" "=X")
1706         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1707   "!TARGET_64BIT"
1708   "push{l}\t%k1"
1709   [(set_attr "type" "push")
1710    (set_attr "mode" "SI")])
1711
1712 (define_insn "*push<mode>2_prologue"
1713   [(set (match_operand:P 0 "push_operand" "=<")
1714         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1715    (clobber (mem:BLK (scratch)))]
1716   ""
1717   "push{<imodesuffix>}\t%1"
1718   [(set_attr "type" "push")
1719    (set_attr "mode" "<MODE>")])
1720
1721 (define_insn "*pop<mode>1"
1722   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1723         (match_operand:P 1 "pop_operand" ">"))]
1724   ""
1725   "pop{<imodesuffix>}\t%0"
1726   [(set_attr "type" "pop")
1727    (set_attr "mode" "<MODE>")])
1728
1729 (define_insn "*pop<mode>1_epilogue"
1730   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1731         (match_operand:P 1 "pop_operand" ">"))
1732    (clobber (mem:BLK (scratch)))]
1733   ""
1734   "pop{<imodesuffix>}\t%0"
1735   [(set_attr "type" "pop")
1736    (set_attr "mode" "<MODE>")])
1737 \f
1738 ;; Move instructions.
1739
1740 (define_expand "movoi"
1741   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1742         (match_operand:OI 1 "general_operand" ""))]
1743   "TARGET_AVX"
1744   "ix86_expand_move (OImode, operands); DONE;")
1745
1746 (define_expand "movti"
1747   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1748         (match_operand:TI 1 "nonimmediate_operand" ""))]
1749   "TARGET_64BIT || TARGET_SSE"
1750 {
1751   if (TARGET_64BIT)
1752     ix86_expand_move (TImode, operands);
1753   else if (push_operand (operands[0], TImode))
1754     ix86_expand_push (TImode, operands[1]);
1755   else
1756     ix86_expand_vector_move (TImode, operands);
1757   DONE;
1758 })
1759
1760 ;; This expands to what emit_move_complex would generate if we didn't
1761 ;; have a movti pattern.  Having this avoids problems with reload on
1762 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1763 ;; to have around all the time.
1764 (define_expand "movcdi"
1765   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1766         (match_operand:CDI 1 "general_operand" ""))]
1767   ""
1768 {
1769   if (push_operand (operands[0], CDImode))
1770     emit_move_complex_push (CDImode, operands[0], operands[1]);
1771   else
1772     emit_move_complex_parts (operands[0], operands[1]);
1773   DONE;
1774 })
1775
1776 (define_expand "mov<mode>"
1777   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1778         (match_operand:SWI1248x 1 "general_operand" ""))]
1779   ""
1780   "ix86_expand_move (<MODE>mode, operands); DONE;")
1781
1782 (define_insn "*mov<mode>_xor"
1783   [(set (match_operand:SWI48 0 "register_operand" "=r")
1784         (match_operand:SWI48 1 "const0_operand" ""))
1785    (clobber (reg:CC FLAGS_REG))]
1786   "reload_completed"
1787   "xor{l}\t%k0, %k0"
1788   [(set_attr "type" "alu1")
1789    (set_attr "mode" "SI")
1790    (set_attr "length_immediate" "0")])
1791
1792 (define_insn "*mov<mode>_or"
1793   [(set (match_operand:SWI48 0 "register_operand" "=r")
1794         (match_operand:SWI48 1 "const_int_operand" ""))
1795    (clobber (reg:CC FLAGS_REG))]
1796   "reload_completed
1797    && operands[1] == constm1_rtx"
1798   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1799   [(set_attr "type" "alu1")
1800    (set_attr "mode" "<MODE>")
1801    (set_attr "length_immediate" "1")])
1802
1803 (define_insn "*movoi_internal_avx"
1804   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1805         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1806   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1807 {
1808   switch (which_alternative)
1809     {
1810     case 0:
1811       return "vxorps\t%0, %0, %0";
1812     case 1:
1813     case 2:
1814       if (misaligned_operand (operands[0], OImode)
1815           || misaligned_operand (operands[1], OImode))
1816         return "vmovdqu\t{%1, %0|%0, %1}";
1817       else
1818         return "vmovdqa\t{%1, %0|%0, %1}";
1819     default:
1820       gcc_unreachable ();
1821     }
1822 }
1823   [(set_attr "type" "sselog1,ssemov,ssemov")
1824    (set_attr "prefix" "vex")
1825    (set_attr "mode" "OI")])
1826
1827 (define_insn "*movti_internal_rex64"
1828   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1829         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1830   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1831 {
1832   switch (which_alternative)
1833     {
1834     case 0:
1835     case 1:
1836       return "#";
1837     case 2:
1838       if (get_attr_mode (insn) == MODE_V4SF)
1839         return "%vxorps\t%0, %d0";
1840       else
1841         return "%vpxor\t%0, %d0";
1842     case 3:
1843     case 4:
1844       /* TDmode values are passed as TImode on the stack.  Moving them
1845          to stack may result in unaligned memory access.  */
1846       if (misaligned_operand (operands[0], TImode)
1847           || misaligned_operand (operands[1], TImode))
1848         {
1849           if (get_attr_mode (insn) == MODE_V4SF)
1850             return "%vmovups\t{%1, %0|%0, %1}";
1851          else
1852            return "%vmovdqu\t{%1, %0|%0, %1}";
1853         }
1854       else
1855         {
1856           if (get_attr_mode (insn) == MODE_V4SF)
1857             return "%vmovaps\t{%1, %0|%0, %1}";
1858          else
1859            return "%vmovdqa\t{%1, %0|%0, %1}";
1860         }
1861     default:
1862       gcc_unreachable ();
1863     }
1864 }
1865   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1866    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1867    (set (attr "mode")
1868         (cond [(eq_attr "alternative" "2,3")
1869                  (if_then_else
1870                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1871                        (const_int 0))
1872                    (const_string "V4SF")
1873                    (const_string "TI"))
1874                (eq_attr "alternative" "4")
1875                  (if_then_else
1876                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1877                             (const_int 0))
1878                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1879                             (const_int 0)))
1880                    (const_string "V4SF")
1881                    (const_string "TI"))]
1882                (const_string "DI")))])
1883
1884 (define_split
1885   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1886         (match_operand:TI 1 "general_operand" ""))]
1887   "reload_completed
1888    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1889   [(const_int 0)]
1890   "ix86_split_long_move (operands); DONE;")
1891
1892 (define_insn "*movti_internal_sse"
1893   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1894         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1895   "TARGET_SSE && !TARGET_64BIT
1896    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1897 {
1898   switch (which_alternative)
1899     {
1900     case 0:
1901       if (get_attr_mode (insn) == MODE_V4SF)
1902         return "%vxorps\t%0, %d0";
1903       else
1904         return "%vpxor\t%0, %d0";
1905     case 1:
1906     case 2:
1907       /* TDmode values are passed as TImode on the stack.  Moving them
1908          to stack may result in unaligned memory access.  */
1909       if (misaligned_operand (operands[0], TImode)
1910           || misaligned_operand (operands[1], TImode))
1911         {
1912           if (get_attr_mode (insn) == MODE_V4SF)
1913             return "%vmovups\t{%1, %0|%0, %1}";
1914          else
1915            return "%vmovdqu\t{%1, %0|%0, %1}";
1916         }
1917       else
1918         {
1919           if (get_attr_mode (insn) == MODE_V4SF)
1920             return "%vmovaps\t{%1, %0|%0, %1}";
1921          else
1922            return "%vmovdqa\t{%1, %0|%0, %1}";
1923         }
1924     default:
1925       gcc_unreachable ();
1926     }
1927 }
1928   [(set_attr "type" "sselog1,ssemov,ssemov")
1929    (set_attr "prefix" "maybe_vex")
1930    (set (attr "mode")
1931         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1932                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1933                         (const_int 0)))
1934                  (const_string "V4SF")
1935                (and (eq_attr "alternative" "2")
1936                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1937                         (const_int 0)))
1938                  (const_string "V4SF")]
1939               (const_string "TI")))])
1940
1941 (define_insn "*movdi_internal_rex64"
1942   [(set (match_operand:DI 0 "nonimmediate_operand"
1943           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1944         (match_operand:DI 1 "general_operand"
1945           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1946   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 {
1948   switch (get_attr_type (insn))
1949     {
1950     case TYPE_SSECVT:
1951       if (SSE_REG_P (operands[0]))
1952         return "movq2dq\t{%1, %0|%0, %1}";
1953       else
1954         return "movdq2q\t{%1, %0|%0, %1}";
1955
1956     case TYPE_SSEMOV:
1957       if (TARGET_AVX)
1958         {
1959           if (get_attr_mode (insn) == MODE_TI)
1960             return "vmovdqa\t{%1, %0|%0, %1}";
1961           else
1962             return "vmovq\t{%1, %0|%0, %1}";
1963         }
1964
1965       if (get_attr_mode (insn) == MODE_TI)
1966         return "movdqa\t{%1, %0|%0, %1}";
1967       /* FALLTHRU */
1968
1969     case TYPE_MMXMOV:
1970       /* Moves from and into integer register is done using movd
1971          opcode with REX prefix.  */
1972       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1973         return "movd\t{%1, %0|%0, %1}";
1974       return "movq\t{%1, %0|%0, %1}";
1975
1976     case TYPE_SSELOG1:
1977       return "%vpxor\t%0, %d0";
1978
1979     case TYPE_MMX:
1980       return "pxor\t%0, %0";
1981
1982     case TYPE_MULTI:
1983       return "#";
1984
1985     case TYPE_LEA:
1986       return "lea{q}\t{%a1, %0|%0, %a1}";
1987
1988     default:
1989       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1990       if (get_attr_mode (insn) == MODE_SI)
1991         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1992       else if (which_alternative == 2)
1993         return "movabs{q}\t{%1, %0|%0, %1}";
1994       else
1995         return "mov{q}\t{%1, %0|%0, %1}";
1996     }
1997 }
1998   [(set (attr "type")
1999      (cond [(eq_attr "alternative" "5")
2000               (const_string "mmx")
2001             (eq_attr "alternative" "6,7,8,9,10")
2002               (const_string "mmxmov")
2003             (eq_attr "alternative" "11")
2004               (const_string "sselog1")
2005             (eq_attr "alternative" "12,13,14,15,16")
2006               (const_string "ssemov")
2007             (eq_attr "alternative" "17,18")
2008               (const_string "ssecvt")
2009             (eq_attr "alternative" "4")
2010               (const_string "multi")
2011             (match_operand:DI 1 "pic_32bit_operand" "")
2012               (const_string "lea")
2013            ]
2014            (const_string "imov")))
2015    (set (attr "modrm")
2016      (if_then_else
2017        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2018          (const_string "0")
2019          (const_string "*")))
2020    (set (attr "length_immediate")
2021      (if_then_else
2022        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2023          (const_string "8")
2024          (const_string "*")))
2025    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2026    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2027    (set (attr "prefix")
2028      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2029        (const_string "maybe_vex")
2030        (const_string "orig")))
2031    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2032
2033 ;; Convert impossible stores of immediate to existing instructions.
2034 ;; First try to get scratch register and go through it.  In case this
2035 ;; fails, move by 32bit parts.
2036 (define_peephole2
2037   [(match_scratch:DI 2 "r")
2038    (set (match_operand:DI 0 "memory_operand" "")
2039         (match_operand:DI 1 "immediate_operand" ""))]
2040   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2041    && !x86_64_immediate_operand (operands[1], DImode)"
2042   [(set (match_dup 2) (match_dup 1))
2043    (set (match_dup 0) (match_dup 2))])
2044
2045 ;; We need to define this as both peepholer and splitter for case
2046 ;; peephole2 pass is not run.
2047 ;; "&& 1" is needed to keep it from matching the previous pattern.
2048 (define_peephole2
2049   [(set (match_operand:DI 0 "memory_operand" "")
2050         (match_operand:DI 1 "immediate_operand" ""))]
2051   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2052    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2053   [(set (match_dup 2) (match_dup 3))
2054    (set (match_dup 4) (match_dup 5))]
2055   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2056
2057 (define_split
2058   [(set (match_operand:DI 0 "memory_operand" "")
2059         (match_operand:DI 1 "immediate_operand" ""))]
2060   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2061                     ? epilogue_completed : reload_completed)
2062    && !symbolic_operand (operands[1], DImode)
2063    && !x86_64_immediate_operand (operands[1], DImode)"
2064   [(set (match_dup 2) (match_dup 3))
2065    (set (match_dup 4) (match_dup 5))]
2066   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2067
2068 (define_insn "*movdi_internal"
2069   [(set (match_operand:DI 0 "nonimmediate_operand"
2070                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2071         (match_operand:DI 1 "general_operand"
2072                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2073   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2074   "@
2075    #
2076    #
2077    pxor\t%0, %0
2078    movq\t{%1, %0|%0, %1}
2079    movq\t{%1, %0|%0, %1}
2080    %vpxor\t%0, %d0
2081    %vmovq\t{%1, %0|%0, %1}
2082    %vmovdqa\t{%1, %0|%0, %1}
2083    %vmovq\t{%1, %0|%0, %1}
2084    xorps\t%0, %0
2085    movlps\t{%1, %0|%0, %1}
2086    movaps\t{%1, %0|%0, %1}
2087    movlps\t{%1, %0|%0, %1}"
2088   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2089    (set (attr "prefix")
2090      (if_then_else (eq_attr "alternative" "5,6,7,8")
2091        (const_string "vex")
2092        (const_string "orig")))
2093    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2094
2095 (define_split
2096   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2097         (match_operand:DI 1 "general_operand" ""))]
2098   "!TARGET_64BIT && reload_completed
2099    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2100    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2101   [(const_int 0)]
2102   "ix86_split_long_move (operands); DONE;")
2103
2104 (define_insn "*movsi_internal"
2105   [(set (match_operand:SI 0 "nonimmediate_operand"
2106                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2107         (match_operand:SI 1 "general_operand"
2108                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2109   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2110 {
2111   switch (get_attr_type (insn))
2112     {
2113     case TYPE_SSELOG1:
2114       if (get_attr_mode (insn) == MODE_TI)
2115         return "%vpxor\t%0, %d0";
2116       return "%vxorps\t%0, %d0";
2117
2118     case TYPE_SSEMOV:
2119       switch (get_attr_mode (insn))
2120         {
2121         case MODE_TI:
2122           return "%vmovdqa\t{%1, %0|%0, %1}";
2123         case MODE_V4SF:
2124           return "%vmovaps\t{%1, %0|%0, %1}";
2125         case MODE_SI:
2126           return "%vmovd\t{%1, %0|%0, %1}";
2127         case MODE_SF:
2128           return "%vmovss\t{%1, %0|%0, %1}";
2129         default:
2130           gcc_unreachable ();
2131         }
2132
2133     case TYPE_MMX:
2134       return "pxor\t%0, %0";
2135
2136     case TYPE_MMXMOV:
2137       if (get_attr_mode (insn) == MODE_DI)
2138         return "movq\t{%1, %0|%0, %1}";
2139       return "movd\t{%1, %0|%0, %1}";
2140
2141     case TYPE_LEA:
2142       return "lea{l}\t{%a1, %0|%0, %a1}";
2143
2144     default:
2145       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2146       return "mov{l}\t{%1, %0|%0, %1}";
2147     }
2148 }
2149   [(set (attr "type")
2150      (cond [(eq_attr "alternative" "2")
2151               (const_string "mmx")
2152             (eq_attr "alternative" "3,4,5")
2153               (const_string "mmxmov")
2154             (eq_attr "alternative" "6")
2155               (const_string "sselog1")
2156             (eq_attr "alternative" "7,8,9,10,11")
2157               (const_string "ssemov")
2158             (match_operand:DI 1 "pic_32bit_operand" "")
2159               (const_string "lea")
2160            ]
2161            (const_string "imov")))
2162    (set (attr "prefix")
2163      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2164        (const_string "orig")
2165        (const_string "maybe_vex")))
2166    (set (attr "prefix_data16")
2167      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2168        (const_string "1")
2169        (const_string "*")))
2170    (set (attr "mode")
2171      (cond [(eq_attr "alternative" "2,3")
2172               (const_string "DI")
2173             (eq_attr "alternative" "6,7")
2174               (if_then_else
2175                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2176                 (const_string "V4SF")
2177                 (const_string "TI"))
2178             (and (eq_attr "alternative" "8,9,10,11")
2179                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2180               (const_string "SF")
2181            ]
2182            (const_string "SI")))])
2183
2184 (define_insn "*movhi_internal"
2185   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2186         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2187   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2188 {
2189   switch (get_attr_type (insn))
2190     {
2191     case TYPE_IMOVX:
2192       /* movzwl is faster than movw on p2 due to partial word stalls,
2193          though not as fast as an aligned movl.  */
2194       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2195     default:
2196       if (get_attr_mode (insn) == MODE_SI)
2197         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2198       else
2199         return "mov{w}\t{%1, %0|%0, %1}";
2200     }
2201 }
2202   [(set (attr "type")
2203      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2204                 (const_int 0))
2205               (const_string "imov")
2206             (and (eq_attr "alternative" "0")
2207                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2208                           (const_int 0))
2209                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2210                           (const_int 0))))
2211               (const_string "imov")
2212             (and (eq_attr "alternative" "1,2")
2213                  (match_operand:HI 1 "aligned_operand" ""))
2214               (const_string "imov")
2215             (and (ne (symbol_ref "TARGET_MOVX")
2216                      (const_int 0))
2217                  (eq_attr "alternative" "0,2"))
2218               (const_string "imovx")
2219            ]
2220            (const_string "imov")))
2221     (set (attr "mode")
2222       (cond [(eq_attr "type" "imovx")
2223                (const_string "SI")
2224              (and (eq_attr "alternative" "1,2")
2225                   (match_operand:HI 1 "aligned_operand" ""))
2226                (const_string "SI")
2227              (and (eq_attr "alternative" "0")
2228                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2229                            (const_int 0))
2230                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2231                            (const_int 0))))
2232                (const_string "SI")
2233             ]
2234             (const_string "HI")))])
2235
2236 ;; Situation is quite tricky about when to choose full sized (SImode) move
2237 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2238 ;; partial register dependency machines (such as AMD Athlon), where QImode
2239 ;; moves issue extra dependency and for partial register stalls machines
2240 ;; that don't use QImode patterns (and QImode move cause stall on the next
2241 ;; instruction).
2242 ;;
2243 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2244 ;; register stall machines with, where we use QImode instructions, since
2245 ;; partial register stall can be caused there.  Then we use movzx.
2246 (define_insn "*movqi_internal"
2247   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2248         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2249   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2250 {
2251   switch (get_attr_type (insn))
2252     {
2253     case TYPE_IMOVX:
2254       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2255       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2256     default:
2257       if (get_attr_mode (insn) == MODE_SI)
2258         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2259       else
2260         return "mov{b}\t{%1, %0|%0, %1}";
2261     }
2262 }
2263   [(set (attr "type")
2264      (cond [(and (eq_attr "alternative" "5")
2265                  (not (match_operand:QI 1 "aligned_operand" "")))
2266               (const_string "imovx")
2267             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2268                 (const_int 0))
2269               (const_string "imov")
2270             (and (eq_attr "alternative" "3")
2271                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2272                           (const_int 0))
2273                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2274                           (const_int 0))))
2275               (const_string "imov")
2276             (eq_attr "alternative" "3,5")
2277               (const_string "imovx")
2278             (and (ne (symbol_ref "TARGET_MOVX")
2279                      (const_int 0))
2280                  (eq_attr "alternative" "2"))
2281               (const_string "imovx")
2282            ]
2283            (const_string "imov")))
2284    (set (attr "mode")
2285       (cond [(eq_attr "alternative" "3,4,5")
2286                (const_string "SI")
2287              (eq_attr "alternative" "6")
2288                (const_string "QI")
2289              (eq_attr "type" "imovx")
2290                (const_string "SI")
2291              (and (eq_attr "type" "imov")
2292                   (and (eq_attr "alternative" "0,1")
2293                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2294                                 (const_int 0))
2295                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2296                                      (const_int 0))
2297                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2298                                      (const_int 0))))))
2299                (const_string "SI")
2300              ;; Avoid partial register stalls when not using QImode arithmetic
2301              (and (eq_attr "type" "imov")
2302                   (and (eq_attr "alternative" "0,1")
2303                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2304                                 (const_int 0))
2305                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2306                                 (const_int 0)))))
2307                (const_string "SI")
2308            ]
2309            (const_string "QI")))])
2310
2311 ;; Stores and loads of ax to arbitrary constant address.
2312 ;; We fake an second form of instruction to force reload to load address
2313 ;; into register when rax is not available
2314 (define_insn "*movabs<mode>_1"
2315   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2316         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2317   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2318   "@
2319    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2320    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2321   [(set_attr "type" "imov")
2322    (set_attr "modrm" "0,*")
2323    (set_attr "length_address" "8,0")
2324    (set_attr "length_immediate" "0,*")
2325    (set_attr "memory" "store")
2326    (set_attr "mode" "<MODE>")])
2327
2328 (define_insn "*movabs<mode>_2"
2329   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2330         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2331   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2332   "@
2333    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2334    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2335   [(set_attr "type" "imov")
2336    (set_attr "modrm" "0,*")
2337    (set_attr "length_address" "8,0")
2338    (set_attr "length_immediate" "0")
2339    (set_attr "memory" "load")
2340    (set_attr "mode" "<MODE>")])
2341
2342 (define_insn "*swap<mode>"
2343   [(set (match_operand:SWI48 0 "register_operand" "+r")
2344         (match_operand:SWI48 1 "register_operand" "+r"))
2345    (set (match_dup 1)
2346         (match_dup 0))]
2347   ""
2348   "xchg{<imodesuffix>}\t%1, %0"
2349   [(set_attr "type" "imov")
2350    (set_attr "mode" "<MODE>")
2351    (set_attr "pent_pair" "np")
2352    (set_attr "athlon_decode" "vector")
2353    (set_attr "amdfam10_decode" "double")])
2354
2355 (define_insn "*swap<mode>_1"
2356   [(set (match_operand:SWI12 0 "register_operand" "+r")
2357         (match_operand:SWI12 1 "register_operand" "+r"))
2358    (set (match_dup 1)
2359         (match_dup 0))]
2360   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2361   "xchg{l}\t%k1, %k0"
2362   [(set_attr "type" "imov")
2363    (set_attr "mode" "SI")
2364    (set_attr "pent_pair" "np")
2365    (set_attr "athlon_decode" "vector")
2366    (set_attr "amdfam10_decode" "double")])
2367
2368 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2369 ;; is disabled for AMDFAM10
2370 (define_insn "*swap<mode>_2"
2371   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2372         (match_operand:SWI12 1 "register_operand" "+<r>"))
2373    (set (match_dup 1)
2374         (match_dup 0))]
2375   "TARGET_PARTIAL_REG_STALL"
2376   "xchg{<imodesuffix>}\t%1, %0"
2377   [(set_attr "type" "imov")
2378    (set_attr "mode" "<MODE>")
2379    (set_attr "pent_pair" "np")
2380    (set_attr "athlon_decode" "vector")])
2381
2382 (define_expand "movstrict<mode>"
2383   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2384         (match_operand:SWI12 1 "general_operand" ""))]
2385   ""
2386 {
2387   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2388     FAIL;
2389   /* Don't generate memory->memory moves, go through a register */
2390   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2391     operands[1] = force_reg (<MODE>mode, operands[1]);
2392 })
2393
2394 (define_insn "*movstrict<mode>_1"
2395   [(set (strict_low_part
2396           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2397         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2398   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2399    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2400   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2401   [(set_attr "type" "imov")
2402    (set_attr "mode" "<MODE>")])
2403
2404 (define_insn "*movstrict<mode>_xor"
2405   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2406         (match_operand:SWI12 1 "const0_operand" ""))
2407    (clobber (reg:CC FLAGS_REG))]
2408   "reload_completed"
2409   "xor{<imodesuffix>}\t%0, %0"
2410   [(set_attr "type" "alu1")
2411    (set_attr "mode" "<MODE>")
2412    (set_attr "length_immediate" "0")])
2413
2414 (define_insn "*mov<mode>_extv_1"
2415   [(set (match_operand:SWI24 0 "register_operand" "=R")
2416         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2417                             (const_int 8)
2418                             (const_int 8)))]
2419   ""
2420   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2421   [(set_attr "type" "imovx")
2422    (set_attr "mode" "SI")])
2423
2424 (define_insn "*movqi_extv_1_rex64"
2425   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2426         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2427                          (const_int 8)
2428                          (const_int 8)))]
2429   "TARGET_64BIT"
2430 {
2431   switch (get_attr_type (insn))
2432     {
2433     case TYPE_IMOVX:
2434       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2435     default:
2436       return "mov{b}\t{%h1, %0|%0, %h1}";
2437     }
2438 }
2439   [(set (attr "type")
2440      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2441                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2442                              (ne (symbol_ref "TARGET_MOVX")
2443                                  (const_int 0))))
2444         (const_string "imovx")
2445         (const_string "imov")))
2446    (set (attr "mode")
2447      (if_then_else (eq_attr "type" "imovx")
2448         (const_string "SI")
2449         (const_string "QI")))])
2450
2451 (define_insn "*movqi_extv_1"
2452   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2453         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2454                          (const_int 8)
2455                          (const_int 8)))]
2456   "!TARGET_64BIT"
2457 {
2458   switch (get_attr_type (insn))
2459     {
2460     case TYPE_IMOVX:
2461       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2462     default:
2463       return "mov{b}\t{%h1, %0|%0, %h1}";
2464     }
2465 }
2466   [(set (attr "type")
2467      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2468                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2469                              (ne (symbol_ref "TARGET_MOVX")
2470                                  (const_int 0))))
2471         (const_string "imovx")
2472         (const_string "imov")))
2473    (set (attr "mode")
2474      (if_then_else (eq_attr "type" "imovx")
2475         (const_string "SI")
2476         (const_string "QI")))])
2477
2478 (define_insn "*mov<mode>_extzv_1"
2479   [(set (match_operand:SWI48 0 "register_operand" "=R")
2480         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2481                             (const_int 8)
2482                             (const_int 8)))]
2483   ""
2484   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2485   [(set_attr "type" "imovx")
2486    (set_attr "mode" "SI")])
2487
2488 (define_insn "*movqi_extzv_2_rex64"
2489   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2490         (subreg:QI
2491           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2492                            (const_int 8)
2493                            (const_int 8)) 0))]
2494   "TARGET_64BIT"
2495 {
2496   switch (get_attr_type (insn))
2497     {
2498     case TYPE_IMOVX:
2499       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2500     default:
2501       return "mov{b}\t{%h1, %0|%0, %h1}";
2502     }
2503 }
2504   [(set (attr "type")
2505      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2506                         (ne (symbol_ref "TARGET_MOVX")
2507                             (const_int 0)))
2508         (const_string "imovx")
2509         (const_string "imov")))
2510    (set (attr "mode")
2511      (if_then_else (eq_attr "type" "imovx")
2512         (const_string "SI")
2513         (const_string "QI")))])
2514
2515 (define_insn "*movqi_extzv_2"
2516   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2517         (subreg:QI
2518           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2519                            (const_int 8)
2520                            (const_int 8)) 0))]
2521   "!TARGET_64BIT"
2522 {
2523   switch (get_attr_type (insn))
2524     {
2525     case TYPE_IMOVX:
2526       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2527     default:
2528       return "mov{b}\t{%h1, %0|%0, %h1}";
2529     }
2530 }
2531   [(set (attr "type")
2532      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2533                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2534                              (ne (symbol_ref "TARGET_MOVX")
2535                                  (const_int 0))))
2536         (const_string "imovx")
2537         (const_string "imov")))
2538    (set (attr "mode")
2539      (if_then_else (eq_attr "type" "imovx")
2540         (const_string "SI")
2541         (const_string "QI")))])
2542
2543 (define_expand "mov<mode>_insv_1"
2544   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2545                             (const_int 8)
2546                             (const_int 8))
2547         (match_operand:SWI48 1 "nonmemory_operand" ""))]
2548   ""
2549   "")
2550
2551 (define_insn "*mov<mode>_insv_1_rex64"
2552   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2553                              (const_int 8)
2554                              (const_int 8))
2555         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2556   "TARGET_64BIT"
2557   "mov{b}\t{%b1, %h0|%h0, %b1}"
2558   [(set_attr "type" "imov")
2559    (set_attr "mode" "QI")])
2560
2561 (define_insn "*movsi_insv_1"
2562   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2563                          (const_int 8)
2564                          (const_int 8))
2565         (match_operand:SI 1 "general_operand" "Qmn"))]
2566   "!TARGET_64BIT"
2567   "mov{b}\t{%b1, %h0|%h0, %b1}"
2568   [(set_attr "type" "imov")
2569    (set_attr "mode" "QI")])
2570
2571 (define_insn "*movqi_insv_2"
2572   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2573                          (const_int 8)
2574                          (const_int 8))
2575         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2576                      (const_int 8)))]
2577   ""
2578   "mov{b}\t{%h1, %h0|%h0, %h1}"
2579   [(set_attr "type" "imov")
2580    (set_attr "mode" "QI")])
2581 \f
2582 ;; Floating point push instructions.
2583
2584 (define_insn "*pushtf"
2585   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2586         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2587   "TARGET_SSE2"
2588 {
2589   /* This insn should be already split before reg-stack.  */
2590   gcc_unreachable ();
2591 }
2592   [(set_attr "type" "multi")
2593    (set_attr "unit" "sse,*,*")
2594    (set_attr "mode" "TF,SI,SI")])
2595
2596 (define_split
2597   [(set (match_operand:TF 0 "push_operand" "")
2598         (match_operand:TF 1 "sse_reg_operand" ""))]
2599   "TARGET_SSE2 && reload_completed"
2600   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2601    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2602
2603 (define_split
2604   [(set (match_operand:TF 0 "push_operand" "")
2605         (match_operand:TF 1 "general_operand" ""))]
2606   "TARGET_SSE2 && reload_completed
2607    && !SSE_REG_P (operands[1])"
2608   [(const_int 0)]
2609   "ix86_split_long_move (operands); DONE;")
2610
2611 (define_insn "*pushxf"
2612   [(set (match_operand:XF 0 "push_operand" "=<,<")
2613         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2614   "optimize_function_for_speed_p (cfun)"
2615 {
2616   /* This insn should be already split before reg-stack.  */
2617   gcc_unreachable ();
2618 }
2619   [(set_attr "type" "multi")
2620    (set_attr "unit" "i387,*")
2621    (set_attr "mode" "XF,SI")])
2622
2623 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2624 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2625 ;; Pushing using integer instructions is longer except for constants
2626 ;; and direct memory references (assuming that any given constant is pushed
2627 ;; only once, but this ought to be handled elsewhere).
2628
2629 (define_insn "*pushxf_nointeger"
2630   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2631         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2632   "optimize_function_for_size_p (cfun)"
2633 {
2634   /* This insn should be already split before reg-stack.  */
2635   gcc_unreachable ();
2636 }
2637   [(set_attr "type" "multi")
2638    (set_attr "unit" "i387,*,*")
2639    (set_attr "mode" "XF,SI,SI")])
2640
2641 (define_split
2642   [(set (match_operand:XF 0 "push_operand" "")
2643         (match_operand:XF 1 "fp_register_operand" ""))]
2644   "reload_completed"
2645   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2646    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2647   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2648
2649 (define_split
2650   [(set (match_operand:XF 0 "push_operand" "")
2651         (match_operand:XF 1 "general_operand" ""))]
2652   "reload_completed
2653    && !FP_REG_P (operands[1])"
2654   [(const_int 0)]
2655   "ix86_split_long_move (operands); DONE;")
2656
2657 (define_insn "*pushdf"
2658   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2659         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2660   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2661 {
2662   /* This insn should be already split before reg-stack.  */
2663   gcc_unreachable ();
2664 }
2665   [(set_attr "type" "multi")
2666    (set_attr "unit" "i387,*,*")
2667    (set_attr "mode" "DF,SI,DF")])
2668
2669 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2670 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2671 ;; On the average, pushdf using integers can be still shorter.  Allow this
2672 ;; pattern for optimize_size too.
2673
2674 (define_insn "*pushdf_nointeger"
2675   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2676         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2677   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2678 {
2679   /* This insn should be already split before reg-stack.  */
2680   gcc_unreachable ();
2681 }
2682   [(set_attr "type" "multi")
2683    (set_attr "unit" "i387,*,*,*")
2684    (set_attr "mode" "DF,SI,SI,DF")])
2685
2686 ;; %%% Kill this when call knows how to work this out.
2687 (define_split
2688   [(set (match_operand:DF 0 "push_operand" "")
2689         (match_operand:DF 1 "any_fp_register_operand" ""))]
2690   "reload_completed"
2691   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2692    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2693
2694 (define_split
2695   [(set (match_operand:DF 0 "push_operand" "")
2696         (match_operand:DF 1 "general_operand" ""))]
2697   "reload_completed
2698    && !ANY_FP_REG_P (operands[1])"
2699   [(const_int 0)]
2700   "ix86_split_long_move (operands); DONE;")
2701
2702 (define_insn "*pushsf_rex64"
2703   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2704         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2705   "TARGET_64BIT"
2706 {
2707   /* Anything else should be already split before reg-stack.  */
2708   gcc_assert (which_alternative == 1);
2709   return "push{q}\t%q1";
2710 }
2711   [(set_attr "type" "multi,push,multi")
2712    (set_attr "unit" "i387,*,*")
2713    (set_attr "mode" "SF,DI,SF")])
2714
2715 (define_insn "*pushsf"
2716   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2717         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2718   "!TARGET_64BIT"
2719 {
2720   /* Anything else should be already split before reg-stack.  */
2721   gcc_assert (which_alternative == 1);
2722   return "push{l}\t%1";
2723 }
2724   [(set_attr "type" "multi,push,multi")
2725    (set_attr "unit" "i387,*,*")
2726    (set_attr "mode" "SF,SI,SF")])
2727
2728 (define_split
2729   [(set (match_operand:SF 0 "push_operand" "")
2730         (match_operand:SF 1 "memory_operand" ""))]
2731   "reload_completed
2732    && MEM_P (operands[1])
2733    && (operands[2] = find_constant_src (insn))"
2734   [(set (match_dup 0)
2735         (match_dup 2))])
2736
2737 ;; %%% Kill this when call knows how to work this out.
2738 (define_split
2739   [(set (match_operand:SF 0 "push_operand" "")
2740         (match_operand:SF 1 "any_fp_register_operand" ""))]
2741   "reload_completed"
2742   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2743    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2744   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2745 \f
2746 ;; Floating point move instructions.
2747
2748 (define_expand "movtf"
2749   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2750         (match_operand:TF 1 "nonimmediate_operand" ""))]
2751   "TARGET_SSE2"
2752 {
2753   ix86_expand_move (TFmode, operands);
2754   DONE;
2755 })
2756
2757 (define_expand "mov<mode>"
2758   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2759         (match_operand:X87MODEF 1 "general_operand" ""))]
2760   ""
2761   "ix86_expand_move (<MODE>mode, operands); DONE;")
2762
2763 (define_insn "*movtf_internal"
2764   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2765         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2766   "TARGET_SSE2
2767    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2768 {
2769   switch (which_alternative)
2770     {
2771     case 0:
2772     case 1:
2773       if (get_attr_mode (insn) == MODE_V4SF)
2774         return "%vmovaps\t{%1, %0|%0, %1}";
2775       else
2776         return "%vmovdqa\t{%1, %0|%0, %1}";
2777     case 2:
2778       if (get_attr_mode (insn) == MODE_V4SF)
2779         return "%vxorps\t%0, %d0";
2780       else
2781         return "%vpxor\t%0, %d0";
2782     case 3:
2783     case 4:
2784         return "#";
2785     default:
2786       gcc_unreachable ();
2787     }
2788 }
2789   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2790    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2791    (set (attr "mode")
2792         (cond [(eq_attr "alternative" "0,2")
2793                  (if_then_else
2794                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2795                        (const_int 0))
2796                    (const_string "V4SF")
2797                    (const_string "TI"))
2798                (eq_attr "alternative" "1")
2799                  (if_then_else
2800                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2801                             (const_int 0))
2802                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2803                             (const_int 0)))
2804                    (const_string "V4SF")
2805                    (const_string "TI"))]
2806                (const_string "DI")))])
2807
2808 (define_split
2809   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2810         (match_operand:TF 1 "general_operand" ""))]
2811   "reload_completed
2812    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2813   [(const_int 0)]
2814   "ix86_split_long_move (operands); DONE;")
2815
2816 (define_insn "*movxf_internal"
2817   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2818         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2819   "optimize_function_for_speed_p (cfun)
2820    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821    && (reload_in_progress || reload_completed
2822        || GET_CODE (operands[1]) != CONST_DOUBLE
2823        || memory_operand (operands[0], XFmode))"
2824 {
2825   switch (which_alternative)
2826     {
2827     case 0:
2828     case 1:
2829       return output_387_reg_move (insn, operands);
2830
2831     case 2:
2832       return standard_80387_constant_opcode (operands[1]);
2833
2834     case 3: case 4:
2835       return "#";
2836
2837     default:
2838       gcc_unreachable ();
2839     }
2840 }
2841   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842    (set_attr "mode" "XF,XF,XF,SI,SI")])
2843
2844 ;; Do not use integer registers when optimizing for size
2845 (define_insn "*movxf_internal_nointeger"
2846   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2847         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2848   "optimize_function_for_size_p (cfun)
2849    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2850    && (reload_in_progress || reload_completed
2851        || standard_80387_constant_p (operands[1])
2852        || GET_CODE (operands[1]) != CONST_DOUBLE
2853        || memory_operand (operands[0], XFmode))"
2854 {
2855   switch (which_alternative)
2856     {
2857     case 0:
2858     case 1:
2859       return output_387_reg_move (insn, operands);
2860
2861     case 2:
2862       return standard_80387_constant_opcode (operands[1]);
2863
2864     case 3: case 4:
2865       return "#";
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 (define_split
2874   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2875         (match_operand:XF 1 "general_operand" ""))]
2876   "reload_completed
2877    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2878    && ! (FP_REG_P (operands[0]) ||
2879          (GET_CODE (operands[0]) == SUBREG
2880           && FP_REG_P (SUBREG_REG (operands[0]))))
2881    && ! (FP_REG_P (operands[1]) ||
2882          (GET_CODE (operands[1]) == SUBREG
2883           && FP_REG_P (SUBREG_REG (operands[1]))))"
2884   [(const_int 0)]
2885   "ix86_split_long_move (operands); DONE;")
2886
2887 (define_insn "*movdf_internal_rex64"
2888   [(set (match_operand:DF 0 "nonimmediate_operand"
2889                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2890         (match_operand:DF 1 "general_operand"
2891                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2892   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2893    && (reload_in_progress || reload_completed
2894        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2895        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2896            && optimize_function_for_size_p (cfun)
2897            && standard_80387_constant_p (operands[1]))
2898        || GET_CODE (operands[1]) != CONST_DOUBLE
2899        || memory_operand (operands[0], DFmode))"
2900 {
2901   switch (which_alternative)
2902     {
2903     case 0:
2904     case 1:
2905       return output_387_reg_move (insn, operands);
2906
2907     case 2:
2908       return standard_80387_constant_opcode (operands[1]);
2909
2910     case 3:
2911     case 4:
2912       return "#";
2913
2914     case 5:
2915       switch (get_attr_mode (insn))
2916         {
2917         case MODE_V4SF:
2918           return "%vxorps\t%0, %d0";
2919         case MODE_V2DF:
2920           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2921             return "%vxorps\t%0, %d0";
2922           else
2923             return "%vxorpd\t%0, %d0";
2924         case MODE_TI:
2925           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2926             return "%vxorps\t%0, %d0";
2927           else
2928             return "%vpxor\t%0, %d0";
2929         default:
2930           gcc_unreachable ();
2931         }
2932     case 6:
2933     case 7:
2934     case 8:
2935       switch (get_attr_mode (insn))
2936         {
2937         case MODE_V4SF:
2938           return "%vmovaps\t{%1, %0|%0, %1}";
2939         case MODE_V2DF:
2940           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941             return "%vmovaps\t{%1, %0|%0, %1}";
2942           else
2943             return "%vmovapd\t{%1, %0|%0, %1}";
2944         case MODE_TI:
2945           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946             return "%vmovaps\t{%1, %0|%0, %1}";
2947           else
2948             return "%vmovdqa\t{%1, %0|%0, %1}";
2949         case MODE_DI:
2950           return "%vmovq\t{%1, %0|%0, %1}";
2951         case MODE_DF:
2952           if (TARGET_AVX)
2953             {
2954               if (REG_P (operands[0]) && REG_P (operands[1]))
2955                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2956               else
2957                 return "vmovsd\t{%1, %0|%0, %1}";
2958             }
2959           else
2960             return "movsd\t{%1, %0|%0, %1}";
2961         case MODE_V1DF:
2962           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2963         case MODE_V2SF:
2964           return "%vmovlps\t{%1, %d0|%d0, %1}";
2965         default:
2966           gcc_unreachable ();
2967         }
2968
2969     case 9:
2970     case 10:
2971     return "%vmovd\t{%1, %0|%0, %1}";
2972
2973     default:
2974       gcc_unreachable();
2975     }
2976 }
2977   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2978    (set (attr "prefix")
2979      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2980        (const_string "orig")
2981        (const_string "maybe_vex")))
2982    (set (attr "prefix_data16")
2983      (if_then_else (eq_attr "mode" "V1DF")
2984        (const_string "1")
2985        (const_string "*")))
2986    (set (attr "mode")
2987         (cond [(eq_attr "alternative" "0,1,2")
2988                  (const_string "DF")
2989                (eq_attr "alternative" "3,4,9,10")
2990                  (const_string "DI")
2991
2992                /* For SSE1, we have many fewer alternatives.  */
2993                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2994                  (cond [(eq_attr "alternative" "5,6")
2995                           (const_string "V4SF")
2996                        ]
2997                    (const_string "V2SF"))
2998
2999                /* xorps is one byte shorter.  */
3000                (eq_attr "alternative" "5")
3001                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3002                             (const_int 0))
3003                           (const_string "V4SF")
3004                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3005                             (const_int 0))
3006                           (const_string "TI")
3007                        ]
3008                        (const_string "V2DF"))
3009
3010                /* For architectures resolving dependencies on
3011                   whole SSE registers use APD move to break dependency
3012                   chains, otherwise use short move to avoid extra work.
3013
3014                   movaps encodes one byte shorter.  */
3015                (eq_attr "alternative" "6")
3016                  (cond
3017                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3018                         (const_int 0))
3019                       (const_string "V4SF")
3020                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3021                         (const_int 0))
3022                       (const_string "V2DF")
3023                    ]
3024                    (const_string "DF"))
3025                /* For architectures resolving dependencies on register
3026                   parts we may avoid extra work to zero out upper part
3027                   of register.  */
3028                (eq_attr "alternative" "7")
3029                  (if_then_else
3030                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3031                        (const_int 0))
3032                    (const_string "V1DF")
3033                    (const_string "DF"))
3034               ]
3035               (const_string "DF")))])
3036
3037 (define_insn "*movdf_internal"
3038   [(set (match_operand:DF 0 "nonimmediate_operand"
3039                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3040         (match_operand:DF 1 "general_operand"
3041                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3042   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3043    && optimize_function_for_speed_p (cfun)
3044    && TARGET_INTEGER_DFMODE_MOVES
3045    && (reload_in_progress || reload_completed
3046        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3047        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3048            && optimize_function_for_size_p (cfun)
3049            && standard_80387_constant_p (operands[1]))
3050        || GET_CODE (operands[1]) != CONST_DOUBLE
3051        || memory_operand (operands[0], DFmode))"
3052 {
3053   switch (which_alternative)
3054     {
3055     case 0:
3056     case 1:
3057       return output_387_reg_move (insn, operands);
3058
3059     case 2:
3060       return standard_80387_constant_opcode (operands[1]);
3061
3062     case 3:
3063     case 4:
3064       return "#";
3065
3066     case 5:
3067       switch (get_attr_mode (insn))
3068         {
3069         case MODE_V4SF:
3070           return "xorps\t%0, %0";
3071         case MODE_V2DF:
3072           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3073             return "xorps\t%0, %0";
3074           else
3075             return "xorpd\t%0, %0";
3076         case MODE_TI:
3077           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3078             return "xorps\t%0, %0";
3079           else
3080             return "pxor\t%0, %0";
3081         default:
3082           gcc_unreachable ();
3083         }
3084     case 6:
3085     case 7:
3086     case 8:
3087       switch (get_attr_mode (insn))
3088         {
3089         case MODE_V4SF:
3090           return "movaps\t{%1, %0|%0, %1}";
3091         case MODE_V2DF:
3092           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093             return "movaps\t{%1, %0|%0, %1}";
3094           else
3095             return "movapd\t{%1, %0|%0, %1}";
3096         case MODE_TI:
3097           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3098             return "movaps\t{%1, %0|%0, %1}";
3099           else
3100             return "movdqa\t{%1, %0|%0, %1}";
3101         case MODE_DI:
3102           return "movq\t{%1, %0|%0, %1}";
3103         case MODE_DF:
3104           return "movsd\t{%1, %0|%0, %1}";
3105         case MODE_V1DF:
3106           return "movlpd\t{%1, %0|%0, %1}";
3107         case MODE_V2SF:
3108           return "movlps\t{%1, %0|%0, %1}";
3109         default:
3110           gcc_unreachable ();
3111         }
3112
3113     default:
3114       gcc_unreachable();
3115     }
3116 }
3117   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3118    (set (attr "prefix_data16")
3119      (if_then_else (eq_attr "mode" "V1DF")
3120        (const_string "1")
3121        (const_string "*")))
3122    (set (attr "mode")
3123         (cond [(eq_attr "alternative" "0,1,2")
3124                  (const_string "DF")
3125                (eq_attr "alternative" "3,4")
3126                  (const_string "SI")
3127
3128                /* For SSE1, we have many fewer alternatives.  */
3129                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3130                  (cond [(eq_attr "alternative" "5,6")
3131                           (const_string "V4SF")
3132                        ]
3133                    (const_string "V2SF"))
3134
3135                /* xorps is one byte shorter.  */
3136                (eq_attr "alternative" "5")
3137                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3138                             (const_int 0))
3139                           (const_string "V4SF")
3140                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3141                             (const_int 0))
3142                           (const_string "TI")
3143                        ]
3144                        (const_string "V2DF"))
3145
3146                /* For architectures resolving dependencies on
3147                   whole SSE registers use APD move to break dependency
3148                   chains, otherwise use short move to avoid extra work.
3149
3150                   movaps encodes one byte shorter.  */
3151                (eq_attr "alternative" "6")
3152                  (cond
3153                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3154                         (const_int 0))
3155                       (const_string "V4SF")
3156                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3157                         (const_int 0))
3158                       (const_string "V2DF")
3159                    ]
3160                    (const_string "DF"))
3161                /* For architectures resolving dependencies on register
3162                   parts we may avoid extra work to zero out upper part
3163                   of register.  */
3164                (eq_attr "alternative" "7")
3165                  (if_then_else
3166                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3167                        (const_int 0))
3168                    (const_string "V1DF")
3169                    (const_string "DF"))
3170               ]
3171               (const_string "DF")))])
3172
3173 ;; Moving is usually shorter when only FP registers are used. This separate
3174 ;; movdf pattern avoids the use of integer registers for FP operations
3175 ;; when optimizing for size.
3176
3177 (define_insn "*movdf_internal_nointeger"
3178   [(set (match_operand:DF 0 "nonimmediate_operand"
3179                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3180         (match_operand:DF 1 "general_operand"
3181                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3182   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3183    && ((optimize_function_for_size_p (cfun)
3184        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3185    && (reload_in_progress || reload_completed
3186        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3187        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3188            && optimize_function_for_size_p (cfun)
3189            && !memory_operand (operands[0], DFmode)
3190            && standard_80387_constant_p (operands[1]))
3191        || GET_CODE (operands[1]) != CONST_DOUBLE
3192        || ((optimize_function_for_size_p (cfun)
3193             || !TARGET_MEMORY_MISMATCH_STALL
3194             || reload_in_progress || reload_completed)
3195            && memory_operand (operands[0], DFmode)))"
3196 {
3197   switch (which_alternative)
3198     {
3199     case 0:
3200     case 1:
3201       return output_387_reg_move (insn, operands);
3202
3203     case 2:
3204       return standard_80387_constant_opcode (operands[1]);
3205
3206     case 3:
3207     case 4:
3208       return "#";
3209
3210     case 5:
3211       switch (get_attr_mode (insn))
3212         {
3213         case MODE_V4SF:
3214           return "%vxorps\t%0, %d0";
3215         case MODE_V2DF:
3216           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3217             return "%vxorps\t%0, %d0";
3218           else
3219             return "%vxorpd\t%0, %d0";
3220         case MODE_TI:
3221           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3222             return "%vxorps\t%0, %d0";
3223           else
3224             return "%vpxor\t%0, %d0";
3225         default:
3226           gcc_unreachable ();
3227         }
3228     case 6:
3229     case 7:
3230     case 8:
3231       switch (get_attr_mode (insn))
3232         {
3233         case MODE_V4SF:
3234           return "%vmovaps\t{%1, %0|%0, %1}";
3235         case MODE_V2DF:
3236           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3237             return "%vmovaps\t{%1, %0|%0, %1}";
3238           else
3239             return "%vmovapd\t{%1, %0|%0, %1}";
3240         case MODE_TI:
3241           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3242             return "%vmovaps\t{%1, %0|%0, %1}";
3243           else
3244             return "%vmovdqa\t{%1, %0|%0, %1}";
3245         case MODE_DI:
3246           return "%vmovq\t{%1, %0|%0, %1}";
3247         case MODE_DF:
3248           if (TARGET_AVX)
3249             {
3250               if (REG_P (operands[0]) && REG_P (operands[1]))
3251                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3252               else
3253                 return "vmovsd\t{%1, %0|%0, %1}";
3254             }
3255           else
3256             return "movsd\t{%1, %0|%0, %1}";
3257         case MODE_V1DF:
3258           if (TARGET_AVX)
3259             {
3260               if (REG_P (operands[0]))
3261                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3262               else
3263                 return "vmovlpd\t{%1, %0|%0, %1}";
3264             }
3265           else
3266             return "movlpd\t{%1, %0|%0, %1}";
3267         case MODE_V2SF:
3268           if (TARGET_AVX)
3269             {
3270               if (REG_P (operands[0]))
3271                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3272               else
3273                 return "vmovlps\t{%1, %0|%0, %1}";
3274             }
3275           else
3276             return "movlps\t{%1, %0|%0, %1}";
3277         default:
3278           gcc_unreachable ();
3279         }
3280
3281     default:
3282       gcc_unreachable ();
3283     }
3284 }
3285   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3286    (set (attr "prefix")
3287      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3288        (const_string "orig")
3289        (const_string "maybe_vex")))
3290    (set (attr "prefix_data16")
3291      (if_then_else (eq_attr "mode" "V1DF")
3292        (const_string "1")
3293        (const_string "*")))
3294    (set (attr "mode")
3295         (cond [(eq_attr "alternative" "0,1,2")
3296                  (const_string "DF")
3297                (eq_attr "alternative" "3,4")
3298                  (const_string "SI")
3299
3300                /* For SSE1, we have many fewer alternatives.  */
3301                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3302                  (cond [(eq_attr "alternative" "5,6")
3303                           (const_string "V4SF")
3304                        ]
3305                    (const_string "V2SF"))
3306
3307                /* xorps is one byte shorter.  */
3308                (eq_attr "alternative" "5")
3309                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3310                             (const_int 0))
3311                           (const_string "V4SF")
3312                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3313                             (const_int 0))
3314                           (const_string "TI")
3315                        ]
3316                        (const_string "V2DF"))
3317
3318                /* For architectures resolving dependencies on
3319                   whole SSE registers use APD move to break dependency
3320                   chains, otherwise use short move to avoid extra work.
3321
3322                   movaps encodes one byte shorter.  */
3323                (eq_attr "alternative" "6")
3324                  (cond
3325                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3326                         (const_int 0))
3327                       (const_string "V4SF")
3328                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3329                         (const_int 0))
3330                       (const_string "V2DF")
3331                    ]
3332                    (const_string "DF"))
3333                /* For architectures resolving dependencies on register
3334                   parts we may avoid extra work to zero out upper part
3335                   of register.  */
3336                (eq_attr "alternative" "7")
3337                  (if_then_else
3338                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3339                        (const_int 0))
3340                    (const_string "V1DF")
3341                    (const_string "DF"))
3342               ]
3343               (const_string "DF")))])
3344
3345 (define_split
3346   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3347         (match_operand:DF 1 "general_operand" ""))]
3348   "reload_completed
3349    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3350    && ! (ANY_FP_REG_P (operands[0]) ||
3351          (GET_CODE (operands[0]) == SUBREG
3352           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3353    && ! (ANY_FP_REG_P (operands[1]) ||
3354          (GET_CODE (operands[1]) == SUBREG
3355           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3356   [(const_int 0)]
3357   "ix86_split_long_move (operands); DONE;")
3358
3359 (define_insn "*movsf_internal"
3360   [(set (match_operand:SF 0 "nonimmediate_operand"
3361           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3362         (match_operand:SF 1 "general_operand"
3363           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3364   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3365    && (reload_in_progress || reload_completed
3366        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3367        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3368            && standard_80387_constant_p (operands[1]))
3369        || GET_CODE (operands[1]) != CONST_DOUBLE
3370        || memory_operand (operands[0], SFmode))"
3371 {
3372   switch (which_alternative)
3373     {
3374     case 0:
3375     case 1:
3376       return output_387_reg_move (insn, operands);
3377
3378     case 2:
3379       return standard_80387_constant_opcode (operands[1]);
3380
3381     case 3:
3382     case 4:
3383       return "mov{l}\t{%1, %0|%0, %1}";
3384     case 5:
3385       if (get_attr_mode (insn) == MODE_TI)
3386         return "%vpxor\t%0, %d0";
3387       else
3388         return "%vxorps\t%0, %d0";
3389     case 6:
3390       if (get_attr_mode (insn) == MODE_V4SF)
3391         return "%vmovaps\t{%1, %0|%0, %1}";
3392       else
3393         return "%vmovss\t{%1, %d0|%d0, %1}";
3394     case 7:
3395       if (TARGET_AVX)
3396         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3397                                    : "vmovss\t{%1, %0|%0, %1}";
3398       else
3399         return "movss\t{%1, %0|%0, %1}";
3400     case 8:
3401       return "%vmovss\t{%1, %0|%0, %1}";
3402
3403     case 9: case 10: case 14: case 15:
3404       return "movd\t{%1, %0|%0, %1}";
3405     case 12: case 13:
3406       return "%vmovd\t{%1, %0|%0, %1}";
3407
3408     case 11:
3409       return "movq\t{%1, %0|%0, %1}";
3410
3411     default:
3412       gcc_unreachable ();
3413     }
3414 }
3415   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3416    (set (attr "prefix")
3417      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3418        (const_string "maybe_vex")
3419        (const_string "orig")))
3420    (set (attr "mode")
3421         (cond [(eq_attr "alternative" "3,4,9,10")
3422                  (const_string "SI")
3423                (eq_attr "alternative" "5")
3424                  (if_then_else
3425                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3426                                  (const_int 0))
3427                              (ne (symbol_ref "TARGET_SSE2")
3428                                  (const_int 0)))
3429                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3430                             (const_int 0)))
3431                    (const_string "TI")
3432                    (const_string "V4SF"))
3433                /* For architectures resolving dependencies on
3434                   whole SSE registers use APS move to break dependency
3435                   chains, otherwise use short move to avoid extra work.
3436
3437                   Do the same for architectures resolving dependencies on
3438                   the parts.  While in DF mode it is better to always handle
3439                   just register parts, the SF mode is different due to lack
3440                   of instructions to load just part of the register.  It is
3441                   better to maintain the whole registers in single format
3442                   to avoid problems on using packed logical operations.  */
3443                (eq_attr "alternative" "6")
3444                  (if_then_else
3445                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3446                             (const_int 0))
3447                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3448                             (const_int 0)))
3449                    (const_string "V4SF")
3450                    (const_string "SF"))
3451                (eq_attr "alternative" "11")
3452                  (const_string "DI")]
3453                (const_string "SF")))])
3454
3455 (define_split
3456   [(set (match_operand 0 "register_operand" "")
3457         (match_operand 1 "memory_operand" ""))]
3458   "reload_completed
3459    && MEM_P (operands[1])
3460    && (GET_MODE (operands[0]) == TFmode
3461        || GET_MODE (operands[0]) == XFmode
3462        || GET_MODE (operands[0]) == DFmode
3463        || GET_MODE (operands[0]) == SFmode)
3464    && (operands[2] = find_constant_src (insn))"
3465   [(set (match_dup 0) (match_dup 2))]
3466 {
3467   rtx c = operands[2];
3468   rtx r = operands[0];
3469
3470   if (GET_CODE (r) == SUBREG)
3471     r = SUBREG_REG (r);
3472
3473   if (SSE_REG_P (r))
3474     {
3475       if (!standard_sse_constant_p (c))
3476         FAIL;
3477     }
3478   else if (FP_REG_P (r))
3479     {
3480       if (!standard_80387_constant_p (c))
3481         FAIL;
3482     }
3483   else if (MMX_REG_P (r))
3484     FAIL;
3485 })
3486
3487 (define_split
3488   [(set (match_operand 0 "register_operand" "")
3489         (float_extend (match_operand 1 "memory_operand" "")))]
3490   "reload_completed
3491    && MEM_P (operands[1])
3492    && (GET_MODE (operands[0]) == TFmode
3493        || GET_MODE (operands[0]) == XFmode
3494        || GET_MODE (operands[0]) == DFmode
3495        || GET_MODE (operands[0]) == SFmode)
3496    && (operands[2] = find_constant_src (insn))"
3497   [(set (match_dup 0) (match_dup 2))]
3498 {
3499   rtx c = operands[2];
3500   rtx r = operands[0];
3501
3502   if (GET_CODE (r) == SUBREG)
3503     r = SUBREG_REG (r);
3504
3505   if (SSE_REG_P (r))
3506     {
3507       if (!standard_sse_constant_p (c))
3508         FAIL;
3509     }
3510   else if (FP_REG_P (r))
3511     {
3512       if (!standard_80387_constant_p (c))
3513         FAIL;
3514     }
3515   else if (MMX_REG_P (r))
3516     FAIL;
3517 })
3518
3519 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3520 (define_split
3521   [(set (match_operand:X87MODEF 0 "register_operand" "")
3522         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3523   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3524    && (standard_80387_constant_p (operands[1]) == 8
3525        || standard_80387_constant_p (operands[1]) == 9)"
3526   [(set (match_dup 0)(match_dup 1))
3527    (set (match_dup 0)
3528         (neg:X87MODEF (match_dup 0)))]
3529 {
3530   REAL_VALUE_TYPE r;
3531
3532   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3533   if (real_isnegzero (&r))
3534     operands[1] = CONST0_RTX (<MODE>mode);
3535   else
3536     operands[1] = CONST1_RTX (<MODE>mode);
3537 })
3538
3539 (define_insn "swapxf"
3540   [(set (match_operand:XF 0 "register_operand" "+f")
3541         (match_operand:XF 1 "register_operand" "+f"))
3542    (set (match_dup 1)
3543         (match_dup 0))]
3544   "TARGET_80387"
3545 {
3546   if (STACK_TOP_P (operands[0]))
3547     return "fxch\t%1";
3548   else
3549     return "fxch\t%0";
3550 }
3551   [(set_attr "type" "fxch")
3552    (set_attr "mode" "XF")])
3553
3554 (define_insn "*swap<mode>"
3555   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3556         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3557    (set (match_dup 1)
3558         (match_dup 0))]
3559   "TARGET_80387 || reload_completed"
3560 {
3561   if (STACK_TOP_P (operands[0]))
3562     return "fxch\t%1";
3563   else
3564     return "fxch\t%0";
3565 }
3566   [(set_attr "type" "fxch")
3567    (set_attr "mode" "<MODE>")])
3568 \f
3569 ;; Zero extension instructions
3570
3571 (define_expand "zero_extendsidi2"
3572   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3573         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3574   ""
3575 {
3576   if (!TARGET_64BIT)
3577     {
3578       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3579       DONE;
3580     }
3581 })
3582
3583 (define_insn "*zero_extendsidi2_rex64"
3584   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3585         (zero_extend:DI
3586          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3587   "TARGET_64BIT"
3588   "@
3589    mov\t{%k1, %k0|%k0, %k1}
3590    #
3591    movd\t{%1, %0|%0, %1}
3592    movd\t{%1, %0|%0, %1}
3593    %vmovd\t{%1, %0|%0, %1}
3594    %vmovd\t{%1, %0|%0, %1}"
3595   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3596    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3597    (set_attr "prefix_0f" "0,*,*,*,*,*")
3598    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3599
3600 (define_split
3601   [(set (match_operand:DI 0 "memory_operand" "")
3602         (zero_extend:DI (match_dup 0)))]
3603   "TARGET_64BIT"
3604   [(set (match_dup 4) (const_int 0))]
3605   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3606
3607 ;; %%% Kill me once multi-word ops are sane.
3608 (define_insn "zero_extendsidi2_1"
3609   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3610         (zero_extend:DI
3611          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3612    (clobber (reg:CC FLAGS_REG))]
3613   "!TARGET_64BIT"
3614   "@
3615    #
3616    #
3617    #
3618    movd\t{%1, %0|%0, %1}
3619    movd\t{%1, %0|%0, %1}
3620    %vmovd\t{%1, %0|%0, %1}
3621    %vmovd\t{%1, %0|%0, %1}"
3622   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3623    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3624    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3625
3626 (define_split
3627   [(set (match_operand:DI 0 "register_operand" "")
3628         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3629    (clobber (reg:CC FLAGS_REG))]
3630   "!TARGET_64BIT && reload_completed
3631    && true_regnum (operands[0]) == true_regnum (operands[1])"
3632   [(set (match_dup 4) (const_int 0))]
3633   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3634
3635 (define_split
3636   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3637         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3638    (clobber (reg:CC FLAGS_REG))]
3639   "!TARGET_64BIT && reload_completed
3640    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3641   [(set (match_dup 3) (match_dup 1))
3642    (set (match_dup 4) (const_int 0))]
3643   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3644
3645 (define_insn "zero_extend<mode>di2"
3646   [(set (match_operand:DI 0 "register_operand" "=r")
3647         (zero_extend:DI
3648          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3649   "TARGET_64BIT"
3650   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3651   [(set_attr "type" "imovx")
3652    (set_attr "mode" "SI")])
3653
3654 (define_expand "zero_extendhisi2"
3655   [(set (match_operand:SI 0 "register_operand" "")
3656         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3657   ""
3658 {
3659   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3660     {
3661       operands[1] = force_reg (HImode, operands[1]);
3662       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3663       DONE;
3664     }
3665 })
3666
3667 (define_insn_and_split "zero_extendhisi2_and"
3668   [(set (match_operand:SI 0 "register_operand" "=r")
3669         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3670    (clobber (reg:CC FLAGS_REG))]
3671   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3672   "#"
3673   "&& reload_completed"
3674   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3675               (clobber (reg:CC FLAGS_REG))])]
3676   ""
3677   [(set_attr "type" "alu1")
3678    (set_attr "mode" "SI")])
3679
3680 (define_insn "*zero_extendhisi2_movzwl"
3681   [(set (match_operand:SI 0 "register_operand" "=r")
3682         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683   "!TARGET_ZERO_EXTEND_WITH_AND
3684    || optimize_function_for_size_p (cfun)"
3685   "movz{wl|x}\t{%1, %0|%0, %1}"
3686   [(set_attr "type" "imovx")
3687    (set_attr "mode" "SI")])
3688
3689 (define_expand "zero_extendqi<mode>2"
3690   [(parallel
3691     [(set (match_operand:SWI24 0 "register_operand" "")
3692           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3693      (clobber (reg:CC FLAGS_REG))])]
3694   ""
3695   "")
3696
3697 (define_insn "*zero_extendqi<mode>2_and"
3698   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3699         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3700    (clobber (reg:CC FLAGS_REG))]
3701   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3702   "#"
3703   [(set_attr "type" "alu1")
3704    (set_attr "mode" "<MODE>")])
3705
3706 ;; When source and destination does not overlap, clear destination
3707 ;; first and then do the movb
3708 (define_split
3709   [(set (match_operand:SWI24 0 "register_operand" "")
3710         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3711    (clobber (reg:CC FLAGS_REG))]
3712   "reload_completed
3713    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3714    && ANY_QI_REG_P (operands[0])
3715    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3716    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3717   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3718 {
3719   operands[2] = gen_lowpart (QImode, operands[0]);
3720   ix86_expand_clear (operands[0]);
3721 })
3722
3723 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3724   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3725         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3726    (clobber (reg:CC FLAGS_REG))]
3727   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3728   "#"
3729   [(set_attr "type" "imovx,alu1")
3730    (set_attr "mode" "<MODE>")])
3731
3732 ;; For the movzbl case strip only the clobber
3733 (define_split
3734   [(set (match_operand:SWI24 0 "register_operand" "")
3735         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3736    (clobber (reg:CC FLAGS_REG))]
3737   "reload_completed
3738    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3739    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3740   [(set (match_dup 0)
3741         (zero_extend:SWI24 (match_dup 1)))])
3742
3743 ; zero extend to SImode to avoid partial register stalls
3744 (define_insn "*zero_extendqi<mode>2_movzbl"
3745   [(set (match_operand:SWI24 0 "register_operand" "=r")
3746         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3747   "reload_completed
3748    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3749   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3750   [(set_attr "type" "imovx")
3751    (set_attr "mode" "SI")])
3752
3753 ;; Rest is handled by single and.
3754 (define_split
3755   [(set (match_operand:SWI24 0 "register_operand" "")
3756         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3757    (clobber (reg:CC FLAGS_REG))]
3758   "reload_completed
3759    && true_regnum (operands[0]) == true_regnum (operands[1])"
3760   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3761               (clobber (reg:CC FLAGS_REG))])])
3762 \f
3763 ;; Sign extension instructions
3764
3765 (define_expand "extendsidi2"
3766   [(set (match_operand:DI 0 "register_operand" "")
3767         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3768   ""
3769 {
3770   if (!TARGET_64BIT)
3771     {
3772       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3773       DONE;
3774     }
3775 })
3776
3777 (define_insn "*extendsidi2_rex64"
3778   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3779         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3780   "TARGET_64BIT"
3781   "@
3782    {cltq|cdqe}
3783    movs{lq|x}\t{%1, %0|%0, %1}"
3784   [(set_attr "type" "imovx")
3785    (set_attr "mode" "DI")
3786    (set_attr "prefix_0f" "0")
3787    (set_attr "modrm" "0,1")])
3788
3789 (define_insn "extendsidi2_1"
3790   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3791         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3792    (clobber (reg:CC FLAGS_REG))
3793    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3794   "!TARGET_64BIT"
3795   "#")
3796
3797 ;; Extend to memory case when source register does die.
3798 (define_split
3799   [(set (match_operand:DI 0 "memory_operand" "")
3800         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3801    (clobber (reg:CC FLAGS_REG))
3802    (clobber (match_operand:SI 2 "register_operand" ""))]
3803   "(reload_completed
3804     && dead_or_set_p (insn, operands[1])
3805     && !reg_mentioned_p (operands[1], operands[0]))"
3806   [(set (match_dup 3) (match_dup 1))
3807    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3808               (clobber (reg:CC FLAGS_REG))])
3809    (set (match_dup 4) (match_dup 1))]
3810   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3811
3812 ;; Extend to memory case when source register does not die.
3813 (define_split
3814   [(set (match_operand:DI 0 "memory_operand" "")
3815         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3816    (clobber (reg:CC FLAGS_REG))
3817    (clobber (match_operand:SI 2 "register_operand" ""))]
3818   "reload_completed"
3819   [(const_int 0)]
3820 {
3821   split_di (&operands[0], 1, &operands[3], &operands[4]);
3822
3823   emit_move_insn (operands[3], operands[1]);
3824
3825   /* Generate a cltd if possible and doing so it profitable.  */
3826   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3827       && true_regnum (operands[1]) == AX_REG
3828       && true_regnum (operands[2]) == DX_REG)
3829     {
3830       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3831     }
3832   else
3833     {
3834       emit_move_insn (operands[2], operands[1]);
3835       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3836     }
3837   emit_move_insn (operands[4], operands[2]);
3838   DONE;
3839 })
3840
3841 ;; Extend to register case.  Optimize case where source and destination
3842 ;; registers match and cases where we can use cltd.
3843 (define_split
3844   [(set (match_operand:DI 0 "register_operand" "")
3845         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3846    (clobber (reg:CC FLAGS_REG))
3847    (clobber (match_scratch:SI 2 ""))]
3848   "reload_completed"
3849   [(const_int 0)]
3850 {
3851   split_di (&operands[0], 1, &operands[3], &operands[4]);
3852
3853   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3854     emit_move_insn (operands[3], operands[1]);
3855
3856   /* Generate a cltd if possible and doing so it profitable.  */
3857   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3858       && true_regnum (operands[3]) == AX_REG
3859       && true_regnum (operands[4]) == DX_REG)
3860     {
3861       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3862       DONE;
3863     }
3864
3865   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3866     emit_move_insn (operands[4], operands[1]);
3867
3868   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3869   DONE;
3870 })
3871
3872 (define_insn "extend<mode>di2"
3873   [(set (match_operand:DI 0 "register_operand" "=r")
3874         (sign_extend:DI
3875          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3876   "TARGET_64BIT"
3877   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3878   [(set_attr "type" "imovx")
3879    (set_attr "mode" "DI")])
3880
3881 (define_insn "extendhisi2"
3882   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3883         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3884   ""
3885 {
3886   switch (get_attr_prefix_0f (insn))
3887     {
3888     case 0:
3889       return "{cwtl|cwde}";
3890     default:
3891       return "movs{wl|x}\t{%1, %0|%0, %1}";
3892     }
3893 }
3894   [(set_attr "type" "imovx")
3895    (set_attr "mode" "SI")
3896    (set (attr "prefix_0f")
3897      ;; movsx is short decodable while cwtl is vector decoded.
3898      (if_then_else (and (eq_attr "cpu" "!k6")
3899                         (eq_attr "alternative" "0"))
3900         (const_string "0")
3901         (const_string "1")))
3902    (set (attr "modrm")
3903      (if_then_else (eq_attr "prefix_0f" "0")
3904         (const_string "0")
3905         (const_string "1")))])
3906
3907 (define_insn "*extendhisi2_zext"
3908   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3909         (zero_extend:DI
3910          (sign_extend:SI
3911           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3912   "TARGET_64BIT"
3913 {
3914   switch (get_attr_prefix_0f (insn))
3915     {
3916     case 0:
3917       return "{cwtl|cwde}";
3918     default:
3919       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3920     }
3921 }
3922   [(set_attr "type" "imovx")
3923    (set_attr "mode" "SI")
3924    (set (attr "prefix_0f")
3925      ;; movsx is short decodable while cwtl is vector decoded.
3926      (if_then_else (and (eq_attr "cpu" "!k6")
3927                         (eq_attr "alternative" "0"))
3928         (const_string "0")
3929         (const_string "1")))
3930    (set (attr "modrm")
3931      (if_then_else (eq_attr "prefix_0f" "0")
3932         (const_string "0")
3933         (const_string "1")))])
3934
3935 (define_insn "extendqisi2"
3936   [(set (match_operand:SI 0 "register_operand" "=r")
3937         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3938   ""
3939   "movs{bl|x}\t{%1, %0|%0, %1}"
3940    [(set_attr "type" "imovx")
3941     (set_attr "mode" "SI")])
3942
3943 (define_insn "*extendqisi2_zext"
3944   [(set (match_operand:DI 0 "register_operand" "=r")
3945         (zero_extend:DI
3946           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3947   "TARGET_64BIT"
3948   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3949    [(set_attr "type" "imovx")
3950     (set_attr "mode" "SI")])
3951
3952 (define_insn "extendqihi2"
3953   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3954         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3955   ""
3956 {
3957   switch (get_attr_prefix_0f (insn))
3958     {
3959     case 0:
3960       return "{cbtw|cbw}";
3961     default:
3962       return "movs{bw|x}\t{%1, %0|%0, %1}";
3963     }
3964 }
3965   [(set_attr "type" "imovx")
3966    (set_attr "mode" "HI")
3967    (set (attr "prefix_0f")
3968      ;; movsx is short decodable while cwtl is vector decoded.
3969      (if_then_else (and (eq_attr "cpu" "!k6")
3970                         (eq_attr "alternative" "0"))
3971         (const_string "0")
3972         (const_string "1")))
3973    (set (attr "modrm")
3974      (if_then_else (eq_attr "prefix_0f" "0")
3975         (const_string "0")
3976         (const_string "1")))])
3977 \f
3978 ;; Conversions between float and double.
3979
3980 ;; These are all no-ops in the model used for the 80387.
3981 ;; So just emit moves.
3982
3983 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3984 (define_split
3985   [(set (match_operand:DF 0 "push_operand" "")
3986         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3987   "reload_completed"
3988   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3989    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3990
3991 (define_split
3992   [(set (match_operand:XF 0 "push_operand" "")
3993         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3994   "reload_completed"
3995   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3996    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3997   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3998
3999 (define_expand "extendsfdf2"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4001         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4002   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4003 {
4004   /* ??? Needed for compress_float_constant since all fp constants
4005      are LEGITIMATE_CONSTANT_P.  */
4006   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4007     {
4008       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4009           && standard_80387_constant_p (operands[1]) > 0)
4010         {
4011           operands[1] = simplify_const_unary_operation
4012             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4013           emit_move_insn_1 (operands[0], operands[1]);
4014           DONE;
4015         }
4016       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4017     }
4018 })
4019
4020 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4021    cvtss2sd:
4022       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4023       cvtps2pd xmm2,xmm1
4024    We do the conversion post reload to avoid producing of 128bit spills
4025    that might lead to ICE on 32bit target.  The sequence unlikely combine
4026    anyway.  */
4027 (define_split
4028   [(set (match_operand:DF 0 "register_operand" "")
4029         (float_extend:DF
4030           (match_operand:SF 1 "nonimmediate_operand" "")))]
4031   "TARGET_USE_VECTOR_FP_CONVERTS
4032    && optimize_insn_for_speed_p ()
4033    && reload_completed && SSE_REG_P (operands[0])"
4034    [(set (match_dup 2)
4035          (float_extend:V2DF
4036            (vec_select:V2SF
4037              (match_dup 3)
4038              (parallel [(const_int 0) (const_int 1)]))))]
4039 {
4040   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4041   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4042   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4043      Try to avoid move when unpacking can be done in source.  */
4044   if (REG_P (operands[1]))
4045     {
4046       /* If it is unsafe to overwrite upper half of source, we need
4047          to move to destination and unpack there.  */
4048       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4049            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4050           && true_regnum (operands[0]) != true_regnum (operands[1]))
4051         {
4052           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4053           emit_move_insn (tmp, operands[1]);
4054         }
4055       else
4056         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4057       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4058                                              operands[3]));
4059     }
4060   else
4061     emit_insn (gen_vec_setv4sf_0 (operands[3],
4062                                   CONST0_RTX (V4SFmode), operands[1]));
4063 })
4064
4065 (define_insn "*extendsfdf2_mixed"
4066   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4067         (float_extend:DF
4068           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4069   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4070 {
4071   switch (which_alternative)
4072     {
4073     case 0:
4074     case 1:
4075       return output_387_reg_move (insn, operands);
4076
4077     case 2:
4078       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4079
4080     default:
4081       gcc_unreachable ();
4082     }
4083 }
4084   [(set_attr "type" "fmov,fmov,ssecvt")
4085    (set_attr "prefix" "orig,orig,maybe_vex")
4086    (set_attr "mode" "SF,XF,DF")])
4087
4088 (define_insn "*extendsfdf2_sse"
4089   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4090         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4091   "TARGET_SSE2 && TARGET_SSE_MATH"
4092   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4093   [(set_attr "type" "ssecvt")
4094    (set_attr "prefix" "maybe_vex")
4095    (set_attr "mode" "DF")])
4096
4097 (define_insn "*extendsfdf2_i387"
4098   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4099         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4100   "TARGET_80387"
4101   "* return output_387_reg_move (insn, operands);"
4102   [(set_attr "type" "fmov")
4103    (set_attr "mode" "SF,XF")])
4104
4105 (define_expand "extend<mode>xf2"
4106   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4107         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4108   "TARGET_80387"
4109 {
4110   /* ??? Needed for compress_float_constant since all fp constants
4111      are LEGITIMATE_CONSTANT_P.  */
4112   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4113     {
4114       if (standard_80387_constant_p (operands[1]) > 0)
4115         {
4116           operands[1] = simplify_const_unary_operation
4117             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4118           emit_move_insn_1 (operands[0], operands[1]);
4119           DONE;
4120         }
4121       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4122     }
4123 })
4124
4125 (define_insn "*extend<mode>xf2_i387"
4126   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4127         (float_extend:XF
4128           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4129   "TARGET_80387"
4130   "* return output_387_reg_move (insn, operands);"
4131   [(set_attr "type" "fmov")
4132    (set_attr "mode" "<MODE>,XF")])
4133
4134 ;; %%% This seems bad bad news.
4135 ;; This cannot output into an f-reg because there is no way to be sure
4136 ;; of truncating in that case.  Otherwise this is just like a simple move
4137 ;; insn.  So we pretend we can output to a reg in order to get better
4138 ;; register preferencing, but we really use a stack slot.
4139
4140 ;; Conversion from DFmode to SFmode.
4141
4142 (define_expand "truncdfsf2"
4143   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4144         (float_truncate:SF
4145           (match_operand:DF 1 "nonimmediate_operand" "")))]
4146   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4147 {
4148   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4149     ;
4150   else if (flag_unsafe_math_optimizations)
4151     ;
4152   else
4153     {
4154       enum ix86_stack_slot slot = (virtuals_instantiated
4155                                    ? SLOT_TEMP
4156                                    : SLOT_VIRTUAL);
4157       rtx temp = assign_386_stack_local (SFmode, slot);
4158       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4159       DONE;
4160     }
4161 })
4162
4163 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4164    cvtsd2ss:
4165       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4166       cvtpd2ps xmm2,xmm1
4167    We do the conversion post reload to avoid producing of 128bit spills
4168    that might lead to ICE on 32bit target.  The sequence unlikely combine
4169    anyway.  */
4170 (define_split
4171   [(set (match_operand:SF 0 "register_operand" "")
4172         (float_truncate:SF
4173           (match_operand:DF 1 "nonimmediate_operand" "")))]
4174   "TARGET_USE_VECTOR_FP_CONVERTS
4175    && optimize_insn_for_speed_p ()
4176    && reload_completed && SSE_REG_P (operands[0])"
4177    [(set (match_dup 2)
4178          (vec_concat:V4SF
4179            (float_truncate:V2SF
4180              (match_dup 4))
4181            (match_dup 3)))]
4182 {
4183   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4184   operands[3] = CONST0_RTX (V2SFmode);
4185   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4186   /* Use movsd for loading from memory, unpcklpd for registers.
4187      Try to avoid move when unpacking can be done in source, or SSE3
4188      movddup is available.  */
4189   if (REG_P (operands[1]))
4190     {
4191       if (!TARGET_SSE3
4192           && true_regnum (operands[0]) != true_regnum (operands[1])
4193           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4194               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4195         {
4196           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4197           emit_move_insn (tmp, operands[1]);
4198           operands[1] = tmp;
4199         }
4200       else if (!TARGET_SSE3)
4201         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4202       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4203     }
4204   else
4205     emit_insn (gen_sse2_loadlpd (operands[4],
4206                                  CONST0_RTX (V2DFmode), operands[1]));
4207 })
4208
4209 (define_expand "truncdfsf2_with_temp"
4210   [(parallel [(set (match_operand:SF 0 "" "")
4211                    (float_truncate:SF (match_operand:DF 1 "" "")))
4212               (clobber (match_operand:SF 2 "" ""))])]
4213   "")
4214
4215 (define_insn "*truncdfsf_fast_mixed"
4216   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4217         (float_truncate:SF
4218           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4219   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4220 {
4221   switch (which_alternative)
4222     {
4223     case 0:
4224       return output_387_reg_move (insn, operands);
4225     case 1:
4226       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4227     default:
4228       gcc_unreachable ();
4229     }
4230 }
4231   [(set_attr "type" "fmov,ssecvt")
4232    (set_attr "prefix" "orig,maybe_vex")
4233    (set_attr "mode" "SF")])
4234
4235 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4236 ;; because nothing we do here is unsafe.
4237 (define_insn "*truncdfsf_fast_sse"
4238   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4239         (float_truncate:SF
4240           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4241   "TARGET_SSE2 && TARGET_SSE_MATH"
4242   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4243   [(set_attr "type" "ssecvt")
4244    (set_attr "prefix" "maybe_vex")
4245    (set_attr "mode" "SF")])
4246
4247 (define_insn "*truncdfsf_fast_i387"
4248   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4249         (float_truncate:SF
4250           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4251   "TARGET_80387 && flag_unsafe_math_optimizations"
4252   "* return output_387_reg_move (insn, operands);"
4253   [(set_attr "type" "fmov")
4254    (set_attr "mode" "SF")])
4255
4256 (define_insn "*truncdfsf_mixed"
4257   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4258         (float_truncate:SF
4259           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4260    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4261   "TARGET_MIX_SSE_I387"
4262 {
4263   switch (which_alternative)
4264     {
4265     case 0:
4266       return output_387_reg_move (insn, operands);
4267     case 1:
4268       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4269
4270     default:
4271       return "#";
4272     }
4273 }
4274   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4275    (set_attr "unit" "*,*,i387,i387,i387")
4276    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4277    (set_attr "mode" "SF")])
4278
4279 (define_insn "*truncdfsf_i387"
4280   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4281         (float_truncate:SF
4282           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4283    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4284   "TARGET_80387"
4285 {
4286   switch (which_alternative)
4287     {
4288     case 0:
4289       return output_387_reg_move (insn, operands);
4290
4291     default:
4292       return "#";
4293     }
4294 }
4295   [(set_attr "type" "fmov,multi,multi,multi")
4296    (set_attr "unit" "*,i387,i387,i387")
4297    (set_attr "mode" "SF")])
4298
4299 (define_insn "*truncdfsf2_i387_1"
4300   [(set (match_operand:SF 0 "memory_operand" "=m")
4301         (float_truncate:SF
4302           (match_operand:DF 1 "register_operand" "f")))]
4303   "TARGET_80387
4304    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4305    && !TARGET_MIX_SSE_I387"
4306   "* return output_387_reg_move (insn, operands);"
4307   [(set_attr "type" "fmov")
4308    (set_attr "mode" "SF")])
4309
4310 (define_split
4311   [(set (match_operand:SF 0 "register_operand" "")
4312         (float_truncate:SF
4313          (match_operand:DF 1 "fp_register_operand" "")))
4314    (clobber (match_operand 2 "" ""))]
4315   "reload_completed"
4316   [(set (match_dup 2) (match_dup 1))
4317    (set (match_dup 0) (match_dup 2))]
4318   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4319
4320 ;; Conversion from XFmode to {SF,DF}mode
4321
4322 (define_expand "truncxf<mode>2"
4323   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4324                    (float_truncate:MODEF
4325                      (match_operand:XF 1 "register_operand" "")))
4326               (clobber (match_dup 2))])]
4327   "TARGET_80387"
4328 {
4329   if (flag_unsafe_math_optimizations)
4330     {
4331       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4332       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4333       if (reg != operands[0])
4334         emit_move_insn (operands[0], reg);
4335       DONE;
4336     }
4337   else
4338     {
4339       enum ix86_stack_slot slot = (virtuals_instantiated
4340                                    ? SLOT_TEMP
4341                                    : SLOT_VIRTUAL);
4342       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4343     }
4344 })
4345
4346 (define_insn "*truncxfsf2_mixed"
4347   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4348         (float_truncate:SF
4349           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4350    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4351   "TARGET_80387"
4352 {
4353   gcc_assert (!which_alternative);
4354   return output_387_reg_move (insn, operands);
4355 }
4356   [(set_attr "type" "fmov,multi,multi,multi")
4357    (set_attr "unit" "*,i387,i387,i387")
4358    (set_attr "mode" "SF")])
4359
4360 (define_insn "*truncxfdf2_mixed"
4361   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4362         (float_truncate:DF
4363           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4364    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4365   "TARGET_80387"
4366 {
4367   gcc_assert (!which_alternative);
4368   return output_387_reg_move (insn, operands);
4369 }
4370   [(set_attr "type" "fmov,multi,multi,multi")
4371    (set_attr "unit" "*,i387,i387,i387")
4372    (set_attr "mode" "DF")])
4373
4374 (define_insn "truncxf<mode>2_i387_noop"
4375   [(set (match_operand:MODEF 0 "register_operand" "=f")
4376         (float_truncate:MODEF
4377           (match_operand:XF 1 "register_operand" "f")))]
4378   "TARGET_80387 && flag_unsafe_math_optimizations"
4379   "* return output_387_reg_move (insn, operands);"
4380   [(set_attr "type" "fmov")
4381    (set_attr "mode" "<MODE>")])
4382
4383 (define_insn "*truncxf<mode>2_i387"
4384   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4385         (float_truncate:MODEF
4386           (match_operand:XF 1 "register_operand" "f")))]
4387   "TARGET_80387"
4388   "* return output_387_reg_move (insn, operands);"
4389   [(set_attr "type" "fmov")
4390    (set_attr "mode" "<MODE>")])
4391
4392 (define_split
4393   [(set (match_operand:MODEF 0 "register_operand" "")
4394         (float_truncate:MODEF
4395           (match_operand:XF 1 "register_operand" "")))
4396    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4397   "TARGET_80387 && reload_completed"
4398   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4399    (set (match_dup 0) (match_dup 2))])
4400
4401 (define_split
4402   [(set (match_operand:MODEF 0 "memory_operand" "")
4403         (float_truncate:MODEF
4404           (match_operand:XF 1 "register_operand" "")))
4405    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4406   "TARGET_80387"
4407   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4408 \f
4409 ;; Signed conversion to DImode.
4410
4411 (define_expand "fix_truncxfdi2"
4412   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4413                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4414               (clobber (reg:CC FLAGS_REG))])]
4415   "TARGET_80387"
4416 {
4417   if (TARGET_FISTTP)
4418    {
4419      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4420      DONE;
4421    }
4422 })
4423
4424 (define_expand "fix_trunc<mode>di2"
4425   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4426                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4427               (clobber (reg:CC FLAGS_REG))])]
4428   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4429 {
4430   if (TARGET_FISTTP
4431       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4432    {
4433      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4434      DONE;
4435    }
4436   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4437    {
4438      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4439      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4440      if (out != operands[0])
4441         emit_move_insn (operands[0], out);
4442      DONE;
4443    }
4444 })
4445
4446 ;; Signed conversion to SImode.
4447
4448 (define_expand "fix_truncxfsi2"
4449   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4450                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4451               (clobber (reg:CC FLAGS_REG))])]
4452   "TARGET_80387"
4453 {
4454   if (TARGET_FISTTP)
4455    {
4456      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4457      DONE;
4458    }
4459 })
4460
4461 (define_expand "fix_trunc<mode>si2"
4462   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4463                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4464               (clobber (reg:CC FLAGS_REG))])]
4465   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4466 {
4467   if (TARGET_FISTTP
4468       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4469    {
4470      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4471      DONE;
4472    }
4473   if (SSE_FLOAT_MODE_P (<MODE>mode))
4474    {
4475      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4476      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4477      if (out != operands[0])
4478         emit_move_insn (operands[0], out);
4479      DONE;
4480    }
4481 })
4482
4483 ;; Signed conversion to HImode.
4484
4485 (define_expand "fix_trunc<mode>hi2"
4486   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4487                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4488               (clobber (reg:CC FLAGS_REG))])]
4489   "TARGET_80387
4490    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4491 {
4492   if (TARGET_FISTTP)
4493    {
4494      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4495      DONE;
4496    }
4497 })
4498
4499 ;; Unsigned conversion to SImode.
4500
4501 (define_expand "fixuns_trunc<mode>si2"
4502   [(parallel
4503     [(set (match_operand:SI 0 "register_operand" "")
4504           (unsigned_fix:SI
4505             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4506      (use (match_dup 2))
4507      (clobber (match_scratch:<ssevecmode> 3 ""))
4508      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4509   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4510 {
4511   enum machine_mode mode = <MODE>mode;
4512   enum machine_mode vecmode = <ssevecmode>mode;
4513   REAL_VALUE_TYPE TWO31r;
4514   rtx two31;
4515
4516   if (optimize_insn_for_size_p ())
4517     FAIL;
4518
4519   real_ldexp (&TWO31r, &dconst1, 31);
4520   two31 = const_double_from_real_value (TWO31r, mode);
4521   two31 = ix86_build_const_vector (mode, true, two31);
4522   operands[2] = force_reg (vecmode, two31);
4523 })
4524
4525 (define_insn_and_split "*fixuns_trunc<mode>_1"
4526   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4527         (unsigned_fix:SI
4528           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4529    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4530    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4531    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4532   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4533    && optimize_function_for_speed_p (cfun)"
4534   "#"
4535   "&& reload_completed"
4536   [(const_int 0)]
4537 {
4538   ix86_split_convert_uns_si_sse (operands);
4539   DONE;
4540 })
4541
4542 ;; Unsigned conversion to HImode.
4543 ;; Without these patterns, we'll try the unsigned SI conversion which
4544 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4545
4546 (define_expand "fixuns_trunc<mode>hi2"
4547   [(set (match_dup 2)
4548         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4549    (set (match_operand:HI 0 "nonimmediate_operand" "")
4550         (subreg:HI (match_dup 2) 0))]
4551   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4552   "operands[2] = gen_reg_rtx (SImode);")
4553
4554 ;; When SSE is available, it is always faster to use it!
4555 (define_insn "fix_trunc<mode>di_sse"
4556   [(set (match_operand:DI 0 "register_operand" "=r,r")
4557         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4558   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4559    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4560   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4561   [(set_attr "type" "sseicvt")
4562    (set_attr "prefix" "maybe_vex")
4563    (set_attr "prefix_rex" "1")
4564    (set_attr "mode" "<MODE>")
4565    (set_attr "athlon_decode" "double,vector")
4566    (set_attr "amdfam10_decode" "double,double")])
4567
4568 (define_insn "fix_trunc<mode>si_sse"
4569   [(set (match_operand:SI 0 "register_operand" "=r,r")
4570         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4571   "SSE_FLOAT_MODE_P (<MODE>mode)
4572    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4573   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4574   [(set_attr "type" "sseicvt")
4575    (set_attr "prefix" "maybe_vex")
4576    (set_attr "mode" "<MODE>")
4577    (set_attr "athlon_decode" "double,vector")
4578    (set_attr "amdfam10_decode" "double,double")])
4579
4580 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4581 (define_peephole2
4582   [(set (match_operand:MODEF 0 "register_operand" "")
4583         (match_operand:MODEF 1 "memory_operand" ""))
4584    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4585         (fix:SSEMODEI24 (match_dup 0)))]
4586   "TARGET_SHORTEN_X87_SSE
4587    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4588    && peep2_reg_dead_p (2, operands[0])"
4589   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4590
4591 ;; Avoid vector decoded forms of the instruction.
4592 (define_peephole2
4593   [(match_scratch:DF 2 "Y2")
4594    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4595         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4596   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4597   [(set (match_dup 2) (match_dup 1))
4598    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4599
4600 (define_peephole2
4601   [(match_scratch:SF 2 "x")
4602    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4603         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4604   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4605   [(set (match_dup 2) (match_dup 1))
4606    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4607
4608 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4609   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4610         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4611   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4612    && TARGET_FISTTP
4613    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4614          && (TARGET_64BIT || <MODE>mode != DImode))
4615         && TARGET_SSE_MATH)
4616    && can_create_pseudo_p ()"
4617   "#"
4618   "&& 1"
4619   [(const_int 0)]
4620 {
4621   if (memory_operand (operands[0], VOIDmode))
4622     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4623   else
4624     {
4625       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4626       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4627                                                             operands[1],
4628                                                             operands[2]));
4629     }
4630   DONE;
4631 }
4632   [(set_attr "type" "fisttp")
4633    (set_attr "mode" "<MODE>")])
4634
4635 (define_insn "fix_trunc<mode>_i387_fisttp"
4636   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4637         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4638    (clobber (match_scratch:XF 2 "=&1f"))]
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   "* return output_fix_trunc (insn, operands, 1);"
4645   [(set_attr "type" "fisttp")
4646    (set_attr "mode" "<MODE>")])
4647
4648 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4649   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4650         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4651    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4652    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4653   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654    && TARGET_FISTTP
4655    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4656         && (TARGET_64BIT || <MODE>mode != DImode))
4657         && TARGET_SSE_MATH)"
4658   "#"
4659   [(set_attr "type" "fisttp")
4660    (set_attr "mode" "<MODE>")])
4661
4662 (define_split
4663   [(set (match_operand:X87MODEI 0 "register_operand" "")
4664         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4665    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4666    (clobber (match_scratch 3 ""))]
4667   "reload_completed"
4668   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4669               (clobber (match_dup 3))])
4670    (set (match_dup 0) (match_dup 2))])
4671
4672 (define_split
4673   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4674         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4675    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4676    (clobber (match_scratch 3 ""))]
4677   "reload_completed"
4678   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4679               (clobber (match_dup 3))])])
4680
4681 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4682 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4683 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4684 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4685 ;; function in i386.c.
4686 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4687   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4688         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4689    (clobber (reg:CC FLAGS_REG))]
4690   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4691    && !TARGET_FISTTP
4692    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4693          && (TARGET_64BIT || <MODE>mode != DImode))
4694    && can_create_pseudo_p ()"
4695   "#"
4696   "&& 1"
4697   [(const_int 0)]
4698 {
4699   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4700
4701   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4702   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4703   if (memory_operand (operands[0], VOIDmode))
4704     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4705                                          operands[2], operands[3]));
4706   else
4707     {
4708       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4709       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4710                                                      operands[2], operands[3],
4711                                                      operands[4]));
4712     }
4713   DONE;
4714 }
4715   [(set_attr "type" "fistp")
4716    (set_attr "i387_cw" "trunc")
4717    (set_attr "mode" "<MODE>")])
4718
4719 (define_insn "fix_truncdi_i387"
4720   [(set (match_operand:DI 0 "memory_operand" "=m")
4721         (fix:DI (match_operand 1 "register_operand" "f")))
4722    (use (match_operand:HI 2 "memory_operand" "m"))
4723    (use (match_operand:HI 3 "memory_operand" "m"))
4724    (clobber (match_scratch:XF 4 "=&1f"))]
4725   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4726    && !TARGET_FISTTP
4727    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4728   "* return output_fix_trunc (insn, operands, 0);"
4729   [(set_attr "type" "fistp")
4730    (set_attr "i387_cw" "trunc")
4731    (set_attr "mode" "DI")])
4732
4733 (define_insn "fix_truncdi_i387_with_temp"
4734   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4735         (fix:DI (match_operand 1 "register_operand" "f,f")))
4736    (use (match_operand:HI 2 "memory_operand" "m,m"))
4737    (use (match_operand:HI 3 "memory_operand" "m,m"))
4738    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4739    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4740   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4741    && !TARGET_FISTTP
4742    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4743   "#"
4744   [(set_attr "type" "fistp")
4745    (set_attr "i387_cw" "trunc")
4746    (set_attr "mode" "DI")])
4747
4748 (define_split
4749   [(set (match_operand:DI 0 "register_operand" "")
4750         (fix:DI (match_operand 1 "register_operand" "")))
4751    (use (match_operand:HI 2 "memory_operand" ""))
4752    (use (match_operand:HI 3 "memory_operand" ""))
4753    (clobber (match_operand:DI 4 "memory_operand" ""))
4754    (clobber (match_scratch 5 ""))]
4755   "reload_completed"
4756   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4757               (use (match_dup 2))
4758               (use (match_dup 3))
4759               (clobber (match_dup 5))])
4760    (set (match_dup 0) (match_dup 4))])
4761
4762 (define_split
4763   [(set (match_operand:DI 0 "memory_operand" "")
4764         (fix:DI (match_operand 1 "register_operand" "")))
4765    (use (match_operand:HI 2 "memory_operand" ""))
4766    (use (match_operand:HI 3 "memory_operand" ""))
4767    (clobber (match_operand:DI 4 "memory_operand" ""))
4768    (clobber (match_scratch 5 ""))]
4769   "reload_completed"
4770   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4771               (use (match_dup 2))
4772               (use (match_dup 3))
4773               (clobber (match_dup 5))])])
4774
4775 (define_insn "fix_trunc<mode>_i387"
4776   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4777         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4778    (use (match_operand:HI 2 "memory_operand" "m"))
4779    (use (match_operand:HI 3 "memory_operand" "m"))]
4780   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4781    && !TARGET_FISTTP
4782    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4783   "* return output_fix_trunc (insn, operands, 0);"
4784   [(set_attr "type" "fistp")
4785    (set_attr "i387_cw" "trunc")
4786    (set_attr "mode" "<MODE>")])
4787
4788 (define_insn "fix_trunc<mode>_i387_with_temp"
4789   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4790         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4791    (use (match_operand:HI 2 "memory_operand" "m,m"))
4792    (use (match_operand:HI 3 "memory_operand" "m,m"))
4793    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4794   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4795    && !TARGET_FISTTP
4796    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4797   "#"
4798   [(set_attr "type" "fistp")
4799    (set_attr "i387_cw" "trunc")
4800    (set_attr "mode" "<MODE>")])
4801
4802 (define_split
4803   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4804         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4805    (use (match_operand:HI 2 "memory_operand" ""))
4806    (use (match_operand:HI 3 "memory_operand" ""))
4807    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4808   "reload_completed"
4809   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4810               (use (match_dup 2))
4811               (use (match_dup 3))])
4812    (set (match_dup 0) (match_dup 4))])
4813
4814 (define_split
4815   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4816         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4817    (use (match_operand:HI 2 "memory_operand" ""))
4818    (use (match_operand:HI 3 "memory_operand" ""))
4819    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4820   "reload_completed"
4821   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4822               (use (match_dup 2))
4823               (use (match_dup 3))])])
4824
4825 (define_insn "x86_fnstcw_1"
4826   [(set (match_operand:HI 0 "memory_operand" "=m")
4827         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4828   "TARGET_80387"
4829   "fnstcw\t%0"
4830   [(set (attr "length")
4831         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4832    (set_attr "mode" "HI")
4833    (set_attr "unit" "i387")])
4834
4835 (define_insn "x86_fldcw_1"
4836   [(set (reg:HI FPCR_REG)
4837         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4838   "TARGET_80387"
4839   "fldcw\t%0"
4840   [(set (attr "length")
4841         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4842    (set_attr "mode" "HI")
4843    (set_attr "unit" "i387")
4844    (set_attr "athlon_decode" "vector")
4845    (set_attr "amdfam10_decode" "vector")])
4846 \f
4847 ;; Conversion between fixed point and floating point.
4848
4849 ;; Even though we only accept memory inputs, the backend _really_
4850 ;; wants to be able to do this between registers.
4851
4852 (define_expand "floathi<mode>2"
4853   [(set (match_operand:X87MODEF 0 "register_operand" "")
4854         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4855   "TARGET_80387
4856    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4857        || TARGET_MIX_SSE_I387)"
4858   "")
4859
4860 ;; Pre-reload splitter to add memory clobber to the pattern.
4861 (define_insn_and_split "*floathi<mode>2_1"
4862   [(set (match_operand:X87MODEF 0 "register_operand" "")
4863         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4864   "TARGET_80387
4865    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4866        || TARGET_MIX_SSE_I387)
4867    && can_create_pseudo_p ()"
4868   "#"
4869   "&& 1"
4870   [(parallel [(set (match_dup 0)
4871               (float:X87MODEF (match_dup 1)))
4872    (clobber (match_dup 2))])]
4873   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4874
4875 (define_insn "*floathi<mode>2_i387_with_temp"
4876   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4877         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4878   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4879   "TARGET_80387
4880    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4881        || TARGET_MIX_SSE_I387)"
4882   "#"
4883   [(set_attr "type" "fmov,multi")
4884    (set_attr "mode" "<MODE>")
4885    (set_attr "unit" "*,i387")
4886    (set_attr "fp_int_src" "true")])
4887
4888 (define_insn "*floathi<mode>2_i387"
4889   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4890         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4891   "TARGET_80387
4892    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4893        || TARGET_MIX_SSE_I387)"
4894   "fild%Z1\t%1"
4895   [(set_attr "type" "fmov")
4896    (set_attr "mode" "<MODE>")
4897    (set_attr "fp_int_src" "true")])
4898
4899 (define_split
4900   [(set (match_operand:X87MODEF 0 "register_operand" "")
4901         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4902    (clobber (match_operand:HI 2 "memory_operand" ""))]
4903   "TARGET_80387
4904    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4905        || TARGET_MIX_SSE_I387)
4906    && reload_completed"
4907   [(set (match_dup 2) (match_dup 1))
4908    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4909
4910 (define_split
4911   [(set (match_operand:X87MODEF 0 "register_operand" "")
4912         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4913    (clobber (match_operand:HI 2 "memory_operand" ""))]
4914    "TARGET_80387
4915     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4916         || TARGET_MIX_SSE_I387)
4917     && reload_completed"
4918   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4919
4920 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4921   [(set (match_operand:X87MODEF 0 "register_operand" "")
4922         (float:X87MODEF
4923           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4924   "TARGET_80387
4925    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4926        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4927 {
4928   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4929         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4930       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4931     {
4932       rtx reg = gen_reg_rtx (XFmode);
4933       rtx insn;
4934
4935       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4936
4937       if (<X87MODEF:MODE>mode == SFmode)
4938         insn = gen_truncxfsf2 (operands[0], reg);
4939       else if (<X87MODEF:MODE>mode == DFmode)
4940         insn = gen_truncxfdf2 (operands[0], reg);
4941       else
4942         gcc_unreachable ();
4943
4944       emit_insn (insn);
4945       DONE;
4946     }
4947 })
4948
4949 ;; Pre-reload splitter to add memory clobber to the pattern.
4950 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4951   [(set (match_operand:X87MODEF 0 "register_operand" "")
4952         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4953   "((TARGET_80387
4954      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4955      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4956            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4957          || TARGET_MIX_SSE_I387))
4958     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4959         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4960         && ((<SSEMODEI24:MODE>mode == SImode
4961              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4962              && optimize_function_for_speed_p (cfun)
4963              && flag_trapping_math)
4964             || !(TARGET_INTER_UNIT_CONVERSIONS
4965                  || optimize_function_for_size_p (cfun)))))
4966    && can_create_pseudo_p ()"
4967   "#"
4968   "&& 1"
4969   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4970               (clobber (match_dup 2))])]
4971 {
4972   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4973
4974   /* Avoid store forwarding (partial memory) stall penalty
4975      by passing DImode value through XMM registers.  */
4976   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4977       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4978       && optimize_function_for_speed_p (cfun))
4979     {
4980       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4981                                                             operands[1],
4982                                                             operands[2]));
4983       DONE;
4984     }
4985 })
4986
4987 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4988   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4989         (float:MODEF
4990           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4991    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4992   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4993    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4994   "#"
4995   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4996    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4997    (set_attr "unit" "*,i387,*,*,*")
4998    (set_attr "athlon_decode" "*,*,double,direct,double")
4999    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5000    (set_attr "fp_int_src" "true")])
5001
5002 (define_insn "*floatsi<mode>2_vector_mixed"
5003   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5004         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5005   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5006    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5007   "@
5008    fild%Z1\t%1
5009    #"
5010   [(set_attr "type" "fmov,sseicvt")
5011    (set_attr "mode" "<MODE>,<ssevecmode>")
5012    (set_attr "unit" "i387,*")
5013    (set_attr "athlon_decode" "*,direct")
5014    (set_attr "amdfam10_decode" "*,double")
5015    (set_attr "fp_int_src" "true")])
5016
5017 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5018   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5019         (float:MODEF
5020           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5021   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5022   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5023    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5024   "#"
5025   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5026    (set_attr "mode" "<MODEF:MODE>")
5027    (set_attr "unit" "*,i387,*,*")
5028    (set_attr "athlon_decode" "*,*,double,direct")
5029    (set_attr "amdfam10_decode" "*,*,vector,double")
5030    (set_attr "fp_int_src" "true")])
5031
5032 (define_split
5033   [(set (match_operand:MODEF 0 "register_operand" "")
5034         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5035    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5036   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5037    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5038    && TARGET_INTER_UNIT_CONVERSIONS
5039    && reload_completed
5040    && (SSE_REG_P (operands[0])
5041        || (GET_CODE (operands[0]) == SUBREG
5042            && SSE_REG_P (operands[0])))"
5043   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5044
5045 (define_split
5046   [(set (match_operand:MODEF 0 "register_operand" "")
5047         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5048    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5049   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5050    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5051    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5052    && reload_completed
5053    && (SSE_REG_P (operands[0])
5054        || (GET_CODE (operands[0]) == SUBREG
5055            && SSE_REG_P (operands[0])))"
5056   [(set (match_dup 2) (match_dup 1))
5057    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5058
5059 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5060   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5061         (float:MODEF
5062           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5063   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5064    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5065    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5066   "@
5067    fild%Z1\t%1
5068    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5069    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5070   [(set_attr "type" "fmov,sseicvt,sseicvt")
5071    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5072    (set_attr "mode" "<MODEF:MODE>")
5073    (set (attr "prefix_rex")
5074      (if_then_else
5075        (and (eq_attr "prefix" "maybe_vex")
5076             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5077        (const_string "1")
5078        (const_string "*")))
5079    (set_attr "unit" "i387,*,*")
5080    (set_attr "athlon_decode" "*,double,direct")
5081    (set_attr "amdfam10_decode" "*,vector,double")
5082    (set_attr "fp_int_src" "true")])
5083
5084 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5085   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5086         (float:MODEF
5087           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5088   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5089    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5090    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5091   "@
5092    fild%Z1\t%1
5093    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5094   [(set_attr "type" "fmov,sseicvt")
5095    (set_attr "prefix" "orig,maybe_vex")
5096    (set_attr "mode" "<MODEF:MODE>")
5097    (set (attr "prefix_rex")
5098      (if_then_else
5099        (and (eq_attr "prefix" "maybe_vex")
5100             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5101        (const_string "1")
5102        (const_string "*")))
5103    (set_attr "athlon_decode" "*,direct")
5104    (set_attr "amdfam10_decode" "*,double")
5105    (set_attr "fp_int_src" "true")])
5106
5107 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5108   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5109         (float:MODEF
5110           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5111    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5112   "TARGET_SSE2 && TARGET_SSE_MATH
5113    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5114   "#"
5115   [(set_attr "type" "sseicvt")
5116    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5117    (set_attr "athlon_decode" "double,direct,double")
5118    (set_attr "amdfam10_decode" "vector,double,double")
5119    (set_attr "fp_int_src" "true")])
5120
5121 (define_insn "*floatsi<mode>2_vector_sse"
5122   [(set (match_operand:MODEF 0 "register_operand" "=x")
5123         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5124   "TARGET_SSE2 && TARGET_SSE_MATH
5125    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5126   "#"
5127   [(set_attr "type" "sseicvt")
5128    (set_attr "mode" "<MODE>")
5129    (set_attr "athlon_decode" "direct")
5130    (set_attr "amdfam10_decode" "double")
5131    (set_attr "fp_int_src" "true")])
5132
5133 (define_split
5134   [(set (match_operand:MODEF 0 "register_operand" "")
5135         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5136    (clobber (match_operand:SI 2 "memory_operand" ""))]
5137   "TARGET_SSE2 && TARGET_SSE_MATH
5138    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5139    && reload_completed
5140    && (SSE_REG_P (operands[0])
5141        || (GET_CODE (operands[0]) == SUBREG
5142            && SSE_REG_P (operands[0])))"
5143   [(const_int 0)]
5144 {
5145   rtx op1 = operands[1];
5146
5147   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5148                                      <MODE>mode, 0);
5149   if (GET_CODE (op1) == SUBREG)
5150     op1 = SUBREG_REG (op1);
5151
5152   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5153     {
5154       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5155       emit_insn (gen_sse2_loadld (operands[4],
5156                                   CONST0_RTX (V4SImode), operands[1]));
5157     }
5158   /* We can ignore possible trapping value in the
5159      high part of SSE register for non-trapping math. */
5160   else if (SSE_REG_P (op1) && !flag_trapping_math)
5161     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5162   else
5163     {
5164       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5165       emit_move_insn (operands[2], operands[1]);
5166       emit_insn (gen_sse2_loadld (operands[4],
5167                                   CONST0_RTX (V4SImode), operands[2]));
5168     }
5169   emit_insn
5170     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5171   DONE;
5172 })
5173
5174 (define_split
5175   [(set (match_operand:MODEF 0 "register_operand" "")
5176         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5177    (clobber (match_operand:SI 2 "memory_operand" ""))]
5178   "TARGET_SSE2 && TARGET_SSE_MATH
5179    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5180    && reload_completed
5181    && (SSE_REG_P (operands[0])
5182        || (GET_CODE (operands[0]) == SUBREG
5183            && SSE_REG_P (operands[0])))"
5184   [(const_int 0)]
5185 {
5186   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5187                                      <MODE>mode, 0);
5188   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5189
5190   emit_insn (gen_sse2_loadld (operands[4],
5191                               CONST0_RTX (V4SImode), operands[1]));
5192   emit_insn
5193     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5194   DONE;
5195 })
5196
5197 (define_split
5198   [(set (match_operand:MODEF 0 "register_operand" "")
5199         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5200   "TARGET_SSE2 && TARGET_SSE_MATH
5201    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5202    && reload_completed
5203    && (SSE_REG_P (operands[0])
5204        || (GET_CODE (operands[0]) == SUBREG
5205            && SSE_REG_P (operands[0])))"
5206   [(const_int 0)]
5207 {
5208   rtx op1 = operands[1];
5209
5210   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5211                                      <MODE>mode, 0);
5212   if (GET_CODE (op1) == SUBREG)
5213     op1 = SUBREG_REG (op1);
5214
5215   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5216     {
5217       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5218       emit_insn (gen_sse2_loadld (operands[4],
5219                                   CONST0_RTX (V4SImode), operands[1]));
5220     }
5221   /* We can ignore possible trapping value in the
5222      high part of SSE register for non-trapping math. */
5223   else if (SSE_REG_P (op1) && !flag_trapping_math)
5224     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5225   else
5226     gcc_unreachable ();
5227   emit_insn
5228     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5229   DONE;
5230 })
5231
5232 (define_split
5233   [(set (match_operand:MODEF 0 "register_operand" "")
5234         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5235   "TARGET_SSE2 && TARGET_SSE_MATH
5236    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5237    && reload_completed
5238    && (SSE_REG_P (operands[0])
5239        || (GET_CODE (operands[0]) == SUBREG
5240            && SSE_REG_P (operands[0])))"
5241   [(const_int 0)]
5242 {
5243   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5244                                      <MODE>mode, 0);
5245   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5246
5247   emit_insn (gen_sse2_loadld (operands[4],
5248                               CONST0_RTX (V4SImode), operands[1]));
5249   emit_insn
5250     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5251   DONE;
5252 })
5253
5254 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5255   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5256         (float:MODEF
5257           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5258   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5259   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5261   "#"
5262   [(set_attr "type" "sseicvt")
5263    (set_attr "mode" "<MODEF:MODE>")
5264    (set_attr "athlon_decode" "double,direct")
5265    (set_attr "amdfam10_decode" "vector,double")
5266    (set_attr "fp_int_src" "true")])
5267
5268 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5269   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5270         (float:MODEF
5271           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5272   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5273    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5274    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5275   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5276   [(set_attr "type" "sseicvt")
5277    (set_attr "prefix" "maybe_vex")
5278    (set_attr "mode" "<MODEF:MODE>")
5279    (set (attr "prefix_rex")
5280      (if_then_else
5281        (and (eq_attr "prefix" "maybe_vex")
5282             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5283        (const_string "1")
5284        (const_string "*")))
5285    (set_attr "athlon_decode" "double,direct")
5286    (set_attr "amdfam10_decode" "vector,double")
5287    (set_attr "fp_int_src" "true")])
5288
5289 (define_split
5290   [(set (match_operand:MODEF 0 "register_operand" "")
5291         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5292    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5293   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5294    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5295    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5296    && reload_completed
5297    && (SSE_REG_P (operands[0])
5298        || (GET_CODE (operands[0]) == SUBREG
5299            && SSE_REG_P (operands[0])))"
5300   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5301
5302 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5303   [(set (match_operand:MODEF 0 "register_operand" "=x")
5304         (float:MODEF
5305           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5306   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5307    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5308    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5309   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5310   [(set_attr "type" "sseicvt")
5311    (set_attr "prefix" "maybe_vex")
5312    (set_attr "mode" "<MODEF:MODE>")
5313    (set (attr "prefix_rex")
5314      (if_then_else
5315        (and (eq_attr "prefix" "maybe_vex")
5316             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5317        (const_string "1")
5318        (const_string "*")))
5319    (set_attr "athlon_decode" "direct")
5320    (set_attr "amdfam10_decode" "double")
5321    (set_attr "fp_int_src" "true")])
5322
5323 (define_split
5324   [(set (match_operand:MODEF 0 "register_operand" "")
5325         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5326    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5327   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5328    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5329    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5330    && reload_completed
5331    && (SSE_REG_P (operands[0])
5332        || (GET_CODE (operands[0]) == SUBREG
5333            && SSE_REG_P (operands[0])))"
5334   [(set (match_dup 2) (match_dup 1))
5335    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5336
5337 (define_split
5338   [(set (match_operand:MODEF 0 "register_operand" "")
5339         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5340    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5341   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5342    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5343    && reload_completed
5344    && (SSE_REG_P (operands[0])
5345        || (GET_CODE (operands[0]) == SUBREG
5346            && SSE_REG_P (operands[0])))"
5347   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5348
5349 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5350   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5351         (float:X87MODEF
5352           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5353   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5354   "TARGET_80387
5355    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5356   "@
5357    fild%Z1\t%1
5358    #"
5359   [(set_attr "type" "fmov,multi")
5360    (set_attr "mode" "<X87MODEF:MODE>")
5361    (set_attr "unit" "*,i387")
5362    (set_attr "fp_int_src" "true")])
5363
5364 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5365   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5366         (float:X87MODEF
5367           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5368   "TARGET_80387
5369    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5370   "fild%Z1\t%1"
5371   [(set_attr "type" "fmov")
5372    (set_attr "mode" "<X87MODEF:MODE>")
5373    (set_attr "fp_int_src" "true")])
5374
5375 (define_split
5376   [(set (match_operand:X87MODEF 0 "register_operand" "")
5377         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5378    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5379   "TARGET_80387
5380    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5381    && reload_completed
5382    && FP_REG_P (operands[0])"
5383   [(set (match_dup 2) (match_dup 1))
5384    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5385
5386 (define_split
5387   [(set (match_operand:X87MODEF 0 "register_operand" "")
5388         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5389    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5390   "TARGET_80387
5391    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5392    && reload_completed
5393    && FP_REG_P (operands[0])"
5394   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5395
5396 ;; Avoid store forwarding (partial memory) stall penalty
5397 ;; by passing DImode value through XMM registers.  */
5398
5399 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5400   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5401         (float:X87MODEF
5402           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5403    (clobber (match_scratch:V4SI 3 "=X,x"))
5404    (clobber (match_scratch:V4SI 4 "=X,x"))
5405    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5406   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5407    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5408    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5409   "#"
5410   [(set_attr "type" "multi")
5411    (set_attr "mode" "<X87MODEF:MODE>")
5412    (set_attr "unit" "i387")
5413    (set_attr "fp_int_src" "true")])
5414
5415 (define_split
5416   [(set (match_operand:X87MODEF 0 "register_operand" "")
5417         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5418    (clobber (match_scratch:V4SI 3 ""))
5419    (clobber (match_scratch:V4SI 4 ""))
5420    (clobber (match_operand:DI 2 "memory_operand" ""))]
5421   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5422    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5423    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5424    && reload_completed
5425    && FP_REG_P (operands[0])"
5426   [(set (match_dup 2) (match_dup 3))
5427    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5428 {
5429   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5430      Assemble the 64-bit DImode value in an xmm register.  */
5431   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5432                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5433   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5434                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5435   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5436                                          operands[4]));
5437
5438   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5439 })
5440
5441 (define_split
5442   [(set (match_operand:X87MODEF 0 "register_operand" "")
5443         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5444    (clobber (match_scratch:V4SI 3 ""))
5445    (clobber (match_scratch:V4SI 4 ""))
5446    (clobber (match_operand:DI 2 "memory_operand" ""))]
5447   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5448    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5449    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5450    && reload_completed
5451    && FP_REG_P (operands[0])"
5452   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5453
5454 ;; Avoid store forwarding (partial memory) stall penalty by extending
5455 ;; SImode value to DImode through XMM register instead of pushing two
5456 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5457 ;; targets benefit from this optimization. Also note that fild
5458 ;; loads from memory only.
5459
5460 (define_insn "*floatunssi<mode>2_1"
5461   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5462         (unsigned_float:X87MODEF
5463           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5464    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5465    (clobber (match_scratch:SI 3 "=X,x"))]
5466   "!TARGET_64BIT
5467    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5468    && TARGET_SSE"
5469   "#"
5470   [(set_attr "type" "multi")
5471    (set_attr "mode" "<MODE>")])
5472
5473 (define_split
5474   [(set (match_operand:X87MODEF 0 "register_operand" "")
5475         (unsigned_float:X87MODEF
5476           (match_operand:SI 1 "register_operand" "")))
5477    (clobber (match_operand:DI 2 "memory_operand" ""))
5478    (clobber (match_scratch:SI 3 ""))]
5479   "!TARGET_64BIT
5480    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5481    && TARGET_SSE
5482    && reload_completed"
5483   [(set (match_dup 2) (match_dup 1))
5484    (set (match_dup 0)
5485         (float:X87MODEF (match_dup 2)))]
5486   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5487
5488 (define_split
5489   [(set (match_operand:X87MODEF 0 "register_operand" "")
5490         (unsigned_float:X87MODEF
5491           (match_operand:SI 1 "memory_operand" "")))
5492    (clobber (match_operand:DI 2 "memory_operand" ""))
5493    (clobber (match_scratch:SI 3 ""))]
5494   "!TARGET_64BIT
5495    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5496    && TARGET_SSE
5497    && reload_completed"
5498   [(set (match_dup 2) (match_dup 3))
5499    (set (match_dup 0)
5500         (float:X87MODEF (match_dup 2)))]
5501 {
5502   emit_move_insn (operands[3], operands[1]);
5503   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5504 })
5505
5506 (define_expand "floatunssi<mode>2"
5507   [(parallel
5508      [(set (match_operand:X87MODEF 0 "register_operand" "")
5509            (unsigned_float:X87MODEF
5510              (match_operand:SI 1 "nonimmediate_operand" "")))
5511       (clobber (match_dup 2))
5512       (clobber (match_scratch:SI 3 ""))])]
5513   "!TARGET_64BIT
5514    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5515         && TARGET_SSE)
5516        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5517 {
5518   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5519     {
5520       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5521       DONE;
5522     }
5523   else
5524     {
5525       enum ix86_stack_slot slot = (virtuals_instantiated
5526                                    ? SLOT_TEMP
5527                                    : SLOT_VIRTUAL);
5528       operands[2] = assign_386_stack_local (DImode, slot);
5529     }
5530 })
5531
5532 (define_expand "floatunsdisf2"
5533   [(use (match_operand:SF 0 "register_operand" ""))
5534    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5535   "TARGET_64BIT && TARGET_SSE_MATH"
5536   "x86_emit_floatuns (operands); DONE;")
5537
5538 (define_expand "floatunsdidf2"
5539   [(use (match_operand:DF 0 "register_operand" ""))
5540    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5541   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5542    && TARGET_SSE2 && TARGET_SSE_MATH"
5543 {
5544   if (TARGET_64BIT)
5545     x86_emit_floatuns (operands);
5546   else
5547     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5548   DONE;
5549 })
5550 \f
5551 ;; Add instructions
5552
5553 (define_expand "add<mode>3"
5554   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5555         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5556                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5557   ""
5558   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5559
5560 (define_insn_and_split "*add<dwi>3_doubleword"
5561   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5562         (plus:<DWI>
5563           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5564           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5565    (clobber (reg:CC FLAGS_REG))]
5566   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5567   "#"
5568   "reload_completed"
5569   [(parallel [(set (reg:CC FLAGS_REG)
5570                    (unspec:CC [(match_dup 1) (match_dup 2)]
5571                               UNSPEC_ADD_CARRY))
5572               (set (match_dup 0)
5573                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5574    (parallel [(set (match_dup 3)
5575                    (plus:DWIH
5576                      (match_dup 4)
5577                      (plus:DWIH
5578                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5579                        (match_dup 5))))
5580               (clobber (reg:CC FLAGS_REG))])]
5581   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5582
5583 (define_insn "*add<mode>3_cc"
5584   [(set (reg:CC FLAGS_REG)
5585         (unspec:CC
5586           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5587            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5588           UNSPEC_ADD_CARRY))
5589    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5590         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5591   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5592   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5593   [(set_attr "type" "alu")
5594    (set_attr "mode" "<MODE>")])
5595
5596 (define_insn "addqi3_cc"
5597   [(set (reg:CC FLAGS_REG)
5598         (unspec:CC
5599           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5600            (match_operand:QI 2 "general_operand" "qn,qm")]
5601           UNSPEC_ADD_CARRY))
5602    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5603         (plus:QI (match_dup 1) (match_dup 2)))]
5604   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5605   "add{b}\t{%2, %0|%0, %2}"
5606   [(set_attr "type" "alu")
5607    (set_attr "mode" "QI")])
5608
5609 (define_insn "*lea_1"
5610   [(set (match_operand:P 0 "register_operand" "=r")
5611         (match_operand:P 1 "no_seg_address_operand" "p"))]
5612   ""
5613   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5614   [(set_attr "type" "lea")
5615    (set_attr "mode" "<MODE>")])
5616
5617 (define_insn "*lea_2"
5618   [(set (match_operand:SI 0 "register_operand" "=r")
5619         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5620   "TARGET_64BIT"
5621   "lea{l}\t{%a1, %0|%0, %a1}"
5622   [(set_attr "type" "lea")
5623    (set_attr "mode" "SI")])
5624
5625 (define_insn "*lea_2_zext"
5626   [(set (match_operand:DI 0 "register_operand" "=r")
5627         (zero_extend:DI
5628           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5629   "TARGET_64BIT"
5630   "lea{l}\t{%a1, %k0|%k0, %a1}"
5631   [(set_attr "type" "lea")
5632    (set_attr "mode" "SI")])
5633
5634 (define_insn "*add<mode>_1"
5635   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5636         (plus:SWI48
5637           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5638           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5639    (clobber (reg:CC FLAGS_REG))]
5640   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5641 {
5642   switch (get_attr_type (insn))
5643     {
5644     case TYPE_LEA:
5645       return "#";
5646
5647     case TYPE_INCDEC:
5648       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5649       if (operands[2] == const1_rtx)
5650         return "inc{<imodesuffix>}\t%0";
5651       else
5652         {
5653           gcc_assert (operands[2] == constm1_rtx);
5654           return "dec{<imodesuffix>}\t%0";
5655         }
5656
5657     default:
5658       /* For most processors, ADD is faster than LEA.  This alternative
5659          was added to use ADD as much as possible.  */
5660       if (which_alternative == 2)
5661         {
5662           rtx tmp;
5663           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5664         }
5665         
5666       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5667       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5668         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5669
5670       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5671     }
5672 }
5673   [(set (attr "type")
5674      (cond [(eq_attr "alternative" "3")
5675               (const_string "lea")
5676             (match_operand:SWI48 2 "incdec_operand" "")
5677               (const_string "incdec")
5678            ]
5679            (const_string "alu")))
5680    (set (attr "length_immediate")
5681       (if_then_else
5682         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5683         (const_string "1")
5684         (const_string "*")))
5685    (set_attr "mode" "<MODE>")])
5686
5687 ;; It may seem that nonimmediate operand is proper one for operand 1.
5688 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5689 ;; we take care in ix86_binary_operator_ok to not allow two memory
5690 ;; operands so proper swapping will be done in reload.  This allow
5691 ;; patterns constructed from addsi_1 to match.
5692
5693 (define_insn "*addsi_1_zext"
5694   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5695         (zero_extend:DI
5696           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5697                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5698    (clobber (reg:CC FLAGS_REG))]
5699   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5700 {
5701   switch (get_attr_type (insn))
5702     {
5703     case TYPE_LEA:
5704       return "#";
5705
5706     case TYPE_INCDEC:
5707       if (operands[2] == const1_rtx)
5708         return "inc{l}\t%k0";
5709       else
5710         {
5711           gcc_assert (operands[2] == constm1_rtx);
5712           return "dec{l}\t%k0";
5713         }
5714
5715     default:
5716       /* For most processors, ADD is faster than LEA.  This alternative
5717          was added to use ADD as much as possible.  */
5718       if (which_alternative == 1)
5719         {
5720           rtx tmp;
5721           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5722         }
5723
5724       if (x86_maybe_negate_const_int (&operands[2], SImode))
5725         return "sub{l}\t{%2, %k0|%k0, %2}";
5726
5727       return "add{l}\t{%2, %k0|%k0, %2}";
5728     }
5729 }
5730   [(set (attr "type")
5731      (cond [(eq_attr "alternative" "2")
5732               (const_string "lea")
5733             (match_operand:SI 2 "incdec_operand" "")
5734               (const_string "incdec")
5735            ]
5736            (const_string "alu")))
5737    (set (attr "length_immediate")
5738       (if_then_else
5739         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5740         (const_string "1")
5741         (const_string "*")))
5742    (set_attr "mode" "SI")])
5743
5744 (define_insn "*addhi_1"
5745   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5746         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5747                  (match_operand:HI 2 "general_operand" "rn,rm")))
5748    (clobber (reg:CC FLAGS_REG))]
5749   "TARGET_PARTIAL_REG_STALL
5750    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5751 {
5752   switch (get_attr_type (insn))
5753     {
5754     case TYPE_INCDEC:
5755       if (operands[2] == const1_rtx)
5756         return "inc{w}\t%0";
5757       else
5758         {
5759           gcc_assert (operands[2] == constm1_rtx);
5760           return "dec{w}\t%0";
5761         }
5762
5763     default:
5764       if (x86_maybe_negate_const_int (&operands[2], HImode))
5765         return "sub{w}\t{%2, %0|%0, %2}";
5766
5767       return "add{w}\t{%2, %0|%0, %2}";
5768     }
5769 }
5770   [(set (attr "type")
5771      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5772         (const_string "incdec")
5773         (const_string "alu")))
5774    (set (attr "length_immediate")
5775       (if_then_else
5776         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5777         (const_string "1")
5778         (const_string "*")))
5779    (set_attr "mode" "HI")])
5780
5781 (define_insn "*addhi_1_lea"
5782   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5783         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5784                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5785    (clobber (reg:CC FLAGS_REG))]
5786   "!TARGET_PARTIAL_REG_STALL
5787    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5788 {
5789   switch (get_attr_type (insn))
5790     {
5791     case TYPE_LEA:
5792       return "#";
5793
5794     case TYPE_INCDEC:
5795       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5796       if (operands[2] == const1_rtx)
5797         return "inc{w}\t%0";
5798       else
5799         {
5800           gcc_assert (operands[2] == constm1_rtx);
5801           return "dec{w}\t%0";
5802         }
5803
5804     default:
5805       /* For most processors, ADD is faster than LEA.  This alternative
5806          was added to use ADD as much as possible.  */
5807       if (which_alternative == 2)
5808         {
5809           rtx tmp;
5810           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5811         }
5812
5813       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5814       if (x86_maybe_negate_const_int (&operands[2], HImode))
5815         return "sub{w}\t{%2, %0|%0, %2}";
5816
5817       return "add{w}\t{%2, %0|%0, %2}";
5818     }
5819 }
5820   [(set (attr "type")
5821      (cond [(eq_attr "alternative" "3")
5822               (const_string "lea")
5823             (match_operand:HI 2 "incdec_operand" "")
5824               (const_string "incdec")
5825            ]
5826            (const_string "alu")))
5827    (set (attr "length_immediate")
5828       (if_then_else
5829         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5830         (const_string "1")
5831         (const_string "*")))
5832    (set_attr "mode" "HI,HI,HI,SI")])
5833
5834 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5835 (define_insn "*addqi_1"
5836   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5837         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5838                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5839    (clobber (reg:CC FLAGS_REG))]
5840   "TARGET_PARTIAL_REG_STALL
5841    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5842 {
5843   int widen = (which_alternative == 2);
5844   switch (get_attr_type (insn))
5845     {
5846     case TYPE_INCDEC:
5847       if (operands[2] == const1_rtx)
5848         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5849       else
5850         {
5851           gcc_assert (operands[2] == constm1_rtx);
5852           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5853         }
5854
5855     default:
5856       if (x86_maybe_negate_const_int (&operands[2], QImode))
5857         {
5858           if (widen)
5859             return "sub{l}\t{%2, %k0|%k0, %2}";
5860           else
5861             return "sub{b}\t{%2, %0|%0, %2}";
5862         }
5863       if (widen)
5864         return "add{l}\t{%k2, %k0|%k0, %k2}";
5865       else
5866         return "add{b}\t{%2, %0|%0, %2}";
5867     }
5868 }
5869   [(set (attr "type")
5870      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5871         (const_string "incdec")
5872         (const_string "alu")))
5873    (set (attr "length_immediate")
5874       (if_then_else
5875         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5876         (const_string "1")
5877         (const_string "*")))
5878    (set_attr "mode" "QI,QI,SI")])
5879
5880 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5881 (define_insn "*addqi_1_lea"
5882   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5883         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5884                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5885    (clobber (reg:CC FLAGS_REG))]
5886   "!TARGET_PARTIAL_REG_STALL
5887    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5888 {
5889   int widen = (which_alternative == 3 || which_alternative == 4);
5890
5891   switch (get_attr_type (insn))
5892     {
5893     case TYPE_LEA:
5894       return "#";
5895
5896     case TYPE_INCDEC:
5897       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5898       if (operands[2] == const1_rtx)
5899         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5900       else
5901         {
5902           gcc_assert (operands[2] == constm1_rtx);
5903           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5904         }
5905
5906     default:
5907       /* For most processors, ADD is faster than LEA.  These alternatives
5908          were added to use ADD as much as possible.  */
5909       if (which_alternative == 2 || which_alternative == 4)
5910         {
5911           rtx tmp;
5912           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5913         }
5914
5915       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5916       if (x86_maybe_negate_const_int (&operands[2], QImode))
5917         {
5918           if (widen)
5919             return "sub{l}\t{%2, %k0|%k0, %2}";
5920           else
5921             return "sub{b}\t{%2, %0|%0, %2}";
5922         }
5923       if (widen)
5924         return "add{l}\t{%k2, %k0|%k0, %k2}";
5925       else
5926         return "add{b}\t{%2, %0|%0, %2}";
5927     }
5928 }
5929   [(set (attr "type")
5930      (cond [(eq_attr "alternative" "5")
5931               (const_string "lea")
5932             (match_operand:QI 2 "incdec_operand" "")
5933               (const_string "incdec")
5934            ]
5935            (const_string "alu")))
5936    (set (attr "length_immediate")
5937       (if_then_else
5938         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5939         (const_string "1")
5940         (const_string "*")))
5941    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5942
5943 (define_insn "*addqi_1_slp"
5944   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5945         (plus:QI (match_dup 0)
5946                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5947    (clobber (reg:CC FLAGS_REG))]
5948   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5949    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5950 {
5951   switch (get_attr_type (insn))
5952     {
5953     case TYPE_INCDEC:
5954       if (operands[1] == const1_rtx)
5955         return "inc{b}\t%0";
5956       else
5957         {
5958           gcc_assert (operands[1] == constm1_rtx);
5959           return "dec{b}\t%0";
5960         }
5961
5962     default:
5963       if (x86_maybe_negate_const_int (&operands[1], QImode))
5964         return "sub{b}\t{%1, %0|%0, %1}";
5965
5966       return "add{b}\t{%1, %0|%0, %1}";
5967     }
5968 }
5969   [(set (attr "type")
5970      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5971         (const_string "incdec")
5972         (const_string "alu1")))
5973    (set (attr "memory")
5974      (if_then_else (match_operand 1 "memory_operand" "")
5975         (const_string "load")
5976         (const_string "none")))
5977    (set_attr "mode" "QI")])
5978
5979 ;; Convert lea to the lea pattern to avoid flags dependency.
5980 (define_split
5981   [(set (match_operand 0 "register_operand" "")
5982         (plus (match_operand 1 "register_operand" "")
5983               (match_operand 2 "nonmemory_operand" "")))
5984    (clobber (reg:CC FLAGS_REG))]
5985   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5986   [(const_int 0)]
5987 {
5988   rtx pat;
5989   enum machine_mode mode = GET_MODE (operands[0]);
5990
5991   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5992      may confuse gen_lowpart.  */
5993   if (mode != Pmode)
5994     {
5995       operands[1] = gen_lowpart (Pmode, operands[1]);
5996       operands[2] = gen_lowpart (Pmode, operands[2]);
5997     }
5998
5999   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6000
6001   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6002     operands[0] = gen_lowpart (SImode, operands[0]);
6003
6004   if (TARGET_64BIT && mode != Pmode)
6005     pat = gen_rtx_SUBREG (SImode, pat, 0);
6006
6007   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6008   DONE;
6009 })
6010
6011 ;; Convert lea to the lea pattern to avoid flags dependency.
6012 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6013 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6014 (define_split
6015   [(set (match_operand:DI 0 "register_operand" "")
6016         (plus:DI (match_operand:DI 1 "register_operand" "")
6017                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6018    (clobber (reg:CC FLAGS_REG))]
6019   "TARGET_64BIT && reload_completed 
6020    && true_regnum (operands[0]) != true_regnum (operands[1])"
6021   [(set (match_dup 0)
6022         (plus:DI (match_dup 1) (match_dup 2)))])
6023
6024 ;; Convert lea to the lea pattern to avoid flags dependency.
6025 (define_split
6026   [(set (match_operand:DI 0 "register_operand" "")
6027         (zero_extend:DI
6028           (plus:SI (match_operand:SI 1 "register_operand" "")
6029                    (match_operand:SI 2 "nonmemory_operand" ""))))
6030    (clobber (reg:CC FLAGS_REG))]
6031   "TARGET_64BIT && reload_completed
6032    && ix86_lea_for_add_ok (insn, operands)"
6033   [(set (match_dup 0)
6034         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6035 {
6036   operands[1] = gen_lowpart (DImode, operands[1]);
6037   operands[2] = gen_lowpart (DImode, operands[2]);
6038 })
6039
6040 (define_insn "*add<mode>_2"
6041   [(set (reg FLAGS_REG)
6042         (compare
6043           (plus:SWI
6044             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6045             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6046           (const_int 0)))
6047    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6048         (plus:SWI (match_dup 1) (match_dup 2)))]
6049   "ix86_match_ccmode (insn, CCGOCmode)
6050    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6051 {
6052   switch (get_attr_type (insn))
6053     {
6054     case TYPE_INCDEC:
6055       if (operands[2] == const1_rtx)
6056         return "inc{<imodesuffix>}\t%0";
6057       else
6058         {
6059           gcc_assert (operands[2] == constm1_rtx);
6060           return "dec{<imodesuffix>}\t%0";
6061         }
6062
6063     default:
6064       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6065         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6066
6067       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6068     }
6069 }
6070   [(set (attr "type")
6071      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6072         (const_string "incdec")
6073         (const_string "alu")))
6074    (set (attr "length_immediate")
6075       (if_then_else
6076         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6077         (const_string "1")
6078         (const_string "*")))
6079    (set_attr "mode" "<MODE>")])
6080
6081 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6082 (define_insn "*addsi_2_zext"
6083   [(set (reg FLAGS_REG)
6084         (compare
6085           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6086                    (match_operand:SI 2 "general_operand" "g"))
6087           (const_int 0)))
6088    (set (match_operand:DI 0 "register_operand" "=r")
6089         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6090   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6091    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6092 {
6093   switch (get_attr_type (insn))
6094     {
6095     case TYPE_INCDEC:
6096       if (operands[2] == const1_rtx)
6097         return "inc{l}\t%k0";
6098       else
6099         {
6100           gcc_assert (operands[2] == constm1_rtx);
6101           return "dec{l}\t%k0";
6102         }
6103
6104     default:
6105       if (x86_maybe_negate_const_int (&operands[2], SImode))
6106         return "sub{l}\t{%2, %k0|%k0, %2}";
6107
6108       return "add{l}\t{%2, %k0|%k0, %2}";
6109     }
6110 }
6111   [(set (attr "type")
6112      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6113         (const_string "incdec")
6114         (const_string "alu")))
6115    (set (attr "length_immediate")
6116       (if_then_else
6117         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6118         (const_string "1")
6119         (const_string "*")))
6120    (set_attr "mode" "SI")])
6121
6122 (define_insn "*add<mode>_3"
6123   [(set (reg FLAGS_REG)
6124         (compare
6125           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6126           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6127    (clobber (match_scratch:SWI 0 "=<r>"))]
6128   "ix86_match_ccmode (insn, CCZmode)
6129    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_INCDEC:
6134       if (operands[2] == const1_rtx)
6135         return "inc{<imodesuffix>}\t%0";
6136       else
6137         {
6138           gcc_assert (operands[2] == constm1_rtx);
6139           return "dec{<imodesuffix>}\t%0";
6140         }
6141
6142     default:
6143       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6144         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6145
6146       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6147     }
6148 }
6149   [(set (attr "type")
6150      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6151         (const_string "incdec")
6152         (const_string "alu")))
6153    (set (attr "length_immediate")
6154       (if_then_else
6155         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6156         (const_string "1")
6157         (const_string "*")))
6158    (set_attr "mode" "<MODE>")])
6159
6160 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6161 (define_insn "*addsi_3_zext"
6162   [(set (reg FLAGS_REG)
6163         (compare
6164           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6165           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6166    (set (match_operand:DI 0 "register_operand" "=r")
6167         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6168   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6169    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6170 {
6171   switch (get_attr_type (insn))
6172     {
6173     case TYPE_INCDEC:
6174       if (operands[2] == const1_rtx)
6175         return "inc{l}\t%k0";
6176       else
6177         {
6178           gcc_assert (operands[2] == constm1_rtx);
6179           return "dec{l}\t%k0";
6180         }
6181
6182     default:
6183       if (x86_maybe_negate_const_int (&operands[2], SImode))
6184         return "sub{l}\t{%2, %k0|%k0, %2}";
6185
6186       return "add{l}\t{%2, %k0|%k0, %2}";
6187     }
6188 }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set (attr "length_immediate")
6194       (if_then_else
6195         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6196         (const_string "1")
6197         (const_string "*")))
6198    (set_attr "mode" "SI")])
6199
6200 ; For comparisons against 1, -1 and 128, we may generate better code
6201 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6202 ; is matched then.  We can't accept general immediate, because for
6203 ; case of overflows,  the result is messed up.
6204 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6205 ; only for comparisons not depending on it.
6206
6207 (define_insn "*adddi_4"
6208   [(set (reg FLAGS_REG)
6209         (compare
6210           (match_operand:DI 1 "nonimmediate_operand" "0")
6211           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6212    (clobber (match_scratch:DI 0 "=rm"))]
6213   "TARGET_64BIT
6214    && ix86_match_ccmode (insn, CCGCmode)"
6215 {
6216   switch (get_attr_type (insn))
6217     {
6218     case TYPE_INCDEC:
6219       if (operands[2] == constm1_rtx)
6220         return "inc{q}\t%0";
6221       else
6222         {
6223           gcc_assert (operands[2] == const1_rtx);
6224           return "dec{q}\t%0";
6225         }
6226
6227     default:
6228       if (x86_maybe_negate_const_int (&operands[2], DImode))
6229         return "add{q}\t{%2, %0|%0, %2}";
6230
6231       return "sub{q}\t{%2, %0|%0, %2}";
6232     }
6233 }
6234   [(set (attr "type")
6235      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6236         (const_string "incdec")
6237         (const_string "alu")))
6238    (set (attr "length_immediate")
6239       (if_then_else
6240         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6241         (const_string "1")
6242         (const_string "*")))
6243    (set_attr "mode" "DI")])
6244
6245 ; For comparisons against 1, -1 and 128, we may generate better code
6246 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6247 ; is matched then.  We can't accept general immediate, because for
6248 ; case of overflows,  the result is messed up.
6249 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6250 ; only for comparisons not depending on it.
6251
6252 (define_insn "*add<mode>_4"
6253   [(set (reg FLAGS_REG)
6254         (compare
6255           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6256           (match_operand:SWI124 2 "const_int_operand" "n")))
6257    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6258   "ix86_match_ccmode (insn, CCGCmode)"
6259 {
6260   switch (get_attr_type (insn))
6261     {
6262     case TYPE_INCDEC:
6263       if (operands[2] == constm1_rtx)
6264         return "inc{<imodesuffix>}\t%0";
6265       else
6266         {
6267           gcc_assert (operands[2] == const1_rtx);
6268           return "dec{<imodesuffix>}\t%0";
6269         }
6270
6271     default:
6272       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6273         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6274
6275       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6276     }
6277 }
6278   [(set (attr "type")
6279      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6280         (const_string "incdec")
6281         (const_string "alu")))
6282    (set (attr "length_immediate")
6283       (if_then_else
6284         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6285         (const_string "1")
6286         (const_string "*")))
6287    (set_attr "mode" "<MODE>")])
6288
6289 (define_insn "*add<mode>_5"
6290   [(set (reg FLAGS_REG)
6291         (compare
6292           (plus:SWI
6293             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6294             (match_operand:SWI 2 "<general_operand>" "<g>"))
6295           (const_int 0)))
6296    (clobber (match_scratch:SWI 0 "=<r>"))]
6297   "ix86_match_ccmode (insn, CCGOCmode)
6298    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6299 {
6300   switch (get_attr_type (insn))
6301     {
6302     case TYPE_INCDEC:
6303       if (operands[2] == const1_rtx)
6304         return "inc{<imodesuffix>}\t%0";
6305       else
6306         {
6307           gcc_assert (operands[2] == constm1_rtx);
6308           return "dec{<imodesuffix>}\t%0";
6309         }
6310
6311     default:
6312       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6313         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6314
6315       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6316     }
6317 }
6318   [(set (attr "type")
6319      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6320         (const_string "incdec")
6321         (const_string "alu")))
6322    (set (attr "length_immediate")
6323       (if_then_else
6324         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6325         (const_string "1")
6326         (const_string "*")))
6327    (set_attr "mode" "<MODE>")])
6328
6329 (define_insn "*addqi_ext_1_rex64"
6330   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6331                          (const_int 8)
6332                          (const_int 8))
6333         (plus:SI
6334           (zero_extract:SI
6335             (match_operand 1 "ext_register_operand" "0")
6336             (const_int 8)
6337             (const_int 8))
6338           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6339    (clobber (reg:CC FLAGS_REG))]
6340   "TARGET_64BIT"
6341 {
6342   switch (get_attr_type (insn))
6343     {
6344     case TYPE_INCDEC:
6345       if (operands[2] == const1_rtx)
6346         return "inc{b}\t%h0";
6347       else
6348         {
6349           gcc_assert (operands[2] == constm1_rtx);
6350           return "dec{b}\t%h0";
6351         }
6352
6353     default:
6354       return "add{b}\t{%2, %h0|%h0, %2}";
6355     }
6356 }
6357   [(set (attr "type")
6358      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6359         (const_string "incdec")
6360         (const_string "alu")))
6361    (set_attr "modrm" "1")
6362    (set_attr "mode" "QI")])
6363
6364 (define_insn "addqi_ext_1"
6365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6366                          (const_int 8)
6367                          (const_int 8))
6368         (plus:SI
6369           (zero_extract:SI
6370             (match_operand 1 "ext_register_operand" "0")
6371             (const_int 8)
6372             (const_int 8))
6373           (match_operand:QI 2 "general_operand" "Qmn")))
6374    (clobber (reg:CC FLAGS_REG))]
6375   "!TARGET_64BIT"
6376 {
6377   switch (get_attr_type (insn))
6378     {
6379     case TYPE_INCDEC:
6380       if (operands[2] == const1_rtx)
6381         return "inc{b}\t%h0";
6382       else
6383         {
6384           gcc_assert (operands[2] == constm1_rtx);
6385           return "dec{b}\t%h0";
6386         }
6387
6388     default:
6389       return "add{b}\t{%2, %h0|%h0, %2}";
6390     }
6391 }
6392   [(set (attr "type")
6393      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394         (const_string "incdec")
6395         (const_string "alu")))
6396    (set_attr "modrm" "1")
6397    (set_attr "mode" "QI")])
6398
6399 (define_insn "*addqi_ext_2"
6400   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6401                          (const_int 8)
6402                          (const_int 8))
6403         (plus:SI
6404           (zero_extract:SI
6405             (match_operand 1 "ext_register_operand" "%0")
6406             (const_int 8)
6407             (const_int 8))
6408           (zero_extract:SI
6409             (match_operand 2 "ext_register_operand" "Q")
6410             (const_int 8)
6411             (const_int 8))))
6412    (clobber (reg:CC FLAGS_REG))]
6413   ""
6414   "add{b}\t{%h2, %h0|%h0, %h2}"
6415   [(set_attr "type" "alu")
6416    (set_attr "mode" "QI")])
6417
6418 ;; The lea patterns for non-Pmodes needs to be matched by
6419 ;; several insns converted to real lea by splitters.
6420
6421 (define_insn_and_split "*lea_general_1"
6422   [(set (match_operand 0 "register_operand" "=r")
6423         (plus (plus (match_operand 1 "index_register_operand" "l")
6424                     (match_operand 2 "register_operand" "r"))
6425               (match_operand 3 "immediate_operand" "i")))]
6426   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6427     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6428    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6429    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6430    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6431    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6432        || GET_MODE (operands[3]) == VOIDmode)"
6433   "#"
6434   "&& reload_completed"
6435   [(const_int 0)]
6436 {
6437   rtx pat;
6438   operands[0] = gen_lowpart (SImode, operands[0]);
6439   operands[1] = gen_lowpart (Pmode, operands[1]);
6440   operands[2] = gen_lowpart (Pmode, operands[2]);
6441   operands[3] = gen_lowpart (Pmode, operands[3]);
6442   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6443                       operands[3]);
6444   if (Pmode != SImode)
6445     pat = gen_rtx_SUBREG (SImode, pat, 0);
6446   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6447   DONE;
6448 }
6449   [(set_attr "type" "lea")
6450    (set_attr "mode" "SI")])
6451
6452 (define_insn_and_split "*lea_general_1_zext"
6453   [(set (match_operand:DI 0 "register_operand" "=r")
6454         (zero_extend:DI
6455           (plus:SI (plus:SI
6456                      (match_operand:SI 1 "index_register_operand" "l")
6457                      (match_operand:SI 2 "register_operand" "r"))
6458                    (match_operand:SI 3 "immediate_operand" "i"))))]
6459   "TARGET_64BIT"
6460   "#"
6461   "&& reload_completed"
6462   [(set (match_dup 0)
6463         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6464                                                      (match_dup 2))
6465                                             (match_dup 3)) 0)))]
6466 {
6467   operands[1] = gen_lowpart (Pmode, operands[1]);
6468   operands[2] = gen_lowpart (Pmode, operands[2]);
6469   operands[3] = gen_lowpart (Pmode, operands[3]);
6470 }
6471   [(set_attr "type" "lea")
6472    (set_attr "mode" "SI")])
6473
6474 (define_insn_and_split "*lea_general_2"
6475   [(set (match_operand 0 "register_operand" "=r")
6476         (plus (mult (match_operand 1 "index_register_operand" "l")
6477                     (match_operand 2 "const248_operand" "i"))
6478               (match_operand 3 "nonmemory_operand" "ri")))]
6479   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6480     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6481    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6482    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6483    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6484        || GET_MODE (operands[3]) == VOIDmode)"
6485   "#"
6486   "&& reload_completed"
6487   [(const_int 0)]
6488 {
6489   rtx pat;
6490   operands[0] = gen_lowpart (SImode, operands[0]);
6491   operands[1] = gen_lowpart (Pmode, operands[1]);
6492   operands[3] = gen_lowpart (Pmode, operands[3]);
6493   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6494                       operands[3]);
6495   if (Pmode != SImode)
6496     pat = gen_rtx_SUBREG (SImode, pat, 0);
6497   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6498   DONE;
6499 }
6500   [(set_attr "type" "lea")
6501    (set_attr "mode" "SI")])
6502
6503 (define_insn_and_split "*lea_general_2_zext"
6504   [(set (match_operand:DI 0 "register_operand" "=r")
6505         (zero_extend:DI
6506           (plus:SI (mult:SI
6507                      (match_operand:SI 1 "index_register_operand" "l")
6508                      (match_operand:SI 2 "const248_operand" "n"))
6509                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6510   "TARGET_64BIT"
6511   "#"
6512   "&& reload_completed"
6513   [(set (match_dup 0)
6514         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6515                                                      (match_dup 2))
6516                                             (match_dup 3)) 0)))]
6517 {
6518   operands[1] = gen_lowpart (Pmode, operands[1]);
6519   operands[3] = gen_lowpart (Pmode, operands[3]);
6520 }
6521   [(set_attr "type" "lea")
6522    (set_attr "mode" "SI")])
6523
6524 (define_insn_and_split "*lea_general_3"
6525   [(set (match_operand 0 "register_operand" "=r")
6526         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6527                           (match_operand 2 "const248_operand" "i"))
6528                     (match_operand 3 "register_operand" "r"))
6529               (match_operand 4 "immediate_operand" "i")))]
6530   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6531     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6532    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6533    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6534    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6535   "#"
6536   "&& reload_completed"
6537   [(const_int 0)]
6538 {
6539   rtx pat;
6540   operands[0] = gen_lowpart (SImode, operands[0]);
6541   operands[1] = gen_lowpart (Pmode, operands[1]);
6542   operands[3] = gen_lowpart (Pmode, operands[3]);
6543   operands[4] = gen_lowpart (Pmode, operands[4]);
6544   pat = gen_rtx_PLUS (Pmode,
6545                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6546                                                          operands[2]),
6547                                     operands[3]),
6548                       operands[4]);
6549   if (Pmode != SImode)
6550     pat = gen_rtx_SUBREG (SImode, pat, 0);
6551   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6552   DONE;
6553 }
6554   [(set_attr "type" "lea")
6555    (set_attr "mode" "SI")])
6556
6557 (define_insn_and_split "*lea_general_3_zext"
6558   [(set (match_operand:DI 0 "register_operand" "=r")
6559         (zero_extend:DI
6560           (plus:SI (plus:SI
6561                      (mult:SI
6562                        (match_operand:SI 1 "index_register_operand" "l")
6563                        (match_operand:SI 2 "const248_operand" "n"))
6564                      (match_operand:SI 3 "register_operand" "r"))
6565                    (match_operand:SI 4 "immediate_operand" "i"))))]
6566   "TARGET_64BIT"
6567   "#"
6568   "&& reload_completed"
6569   [(set (match_dup 0)
6570         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6571                                                               (match_dup 2))
6572                                                      (match_dup 3))
6573                                             (match_dup 4)) 0)))]
6574 {
6575   operands[1] = gen_lowpart (Pmode, operands[1]);
6576   operands[3] = gen_lowpart (Pmode, operands[3]);
6577   operands[4] = gen_lowpart (Pmode, operands[4]);
6578 }
6579   [(set_attr "type" "lea")
6580    (set_attr "mode" "SI")])
6581 \f
6582 ;; Subtract instructions
6583
6584 (define_expand "sub<mode>3"
6585   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6586         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6587                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6588   ""
6589   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6590
6591 (define_insn_and_split "*sub<dwi>3_doubleword"
6592   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6593         (minus:<DWI>
6594           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6595           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6598   "#"
6599   "reload_completed"
6600   [(parallel [(set (reg:CC FLAGS_REG)
6601                    (compare:CC (match_dup 1) (match_dup 2)))
6602               (set (match_dup 0)
6603                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6604    (parallel [(set (match_dup 3)
6605                    (minus:DWIH
6606                      (match_dup 4)
6607                      (plus:DWIH
6608                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6609                        (match_dup 5))))
6610               (clobber (reg:CC FLAGS_REG))])]
6611   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6612
6613 (define_insn "*sub<mode>_1"
6614   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6615         (minus:SWI
6616           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6617           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6618    (clobber (reg:CC FLAGS_REG))]
6619   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6620   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6621   [(set_attr "type" "alu")
6622    (set_attr "mode" "<MODE>")])
6623
6624 (define_insn "*subsi_1_zext"
6625   [(set (match_operand:DI 0 "register_operand" "=r")
6626         (zero_extend:DI
6627           (minus:SI (match_operand:SI 1 "register_operand" "0")
6628                     (match_operand:SI 2 "general_operand" "g"))))
6629    (clobber (reg:CC FLAGS_REG))]
6630   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6631   "sub{l}\t{%2, %k0|%k0, %2}"
6632   [(set_attr "type" "alu")
6633    (set_attr "mode" "SI")])
6634
6635 (define_insn "*subqi_1_slp"
6636   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6637         (minus:QI (match_dup 0)
6638                   (match_operand:QI 1 "general_operand" "qn,qm")))
6639    (clobber (reg:CC FLAGS_REG))]
6640   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6641    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6642   "sub{b}\t{%1, %0|%0, %1}"
6643   [(set_attr "type" "alu1")
6644    (set_attr "mode" "QI")])
6645
6646 (define_insn "*sub<mode>_2"
6647   [(set (reg FLAGS_REG)
6648         (compare
6649           (minus:SWI
6650             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6651             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6652           (const_int 0)))
6653    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6654         (minus:SWI (match_dup 1) (match_dup 2)))]
6655   "ix86_match_ccmode (insn, CCGOCmode)
6656    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6657   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6658   [(set_attr "type" "alu")
6659    (set_attr "mode" "<MODE>")])
6660
6661 (define_insn "*subsi_2_zext"
6662   [(set (reg FLAGS_REG)
6663         (compare
6664           (minus:SI (match_operand:SI 1 "register_operand" "0")
6665                     (match_operand:SI 2 "general_operand" "g"))
6666           (const_int 0)))
6667    (set (match_operand:DI 0 "register_operand" "=r")
6668         (zero_extend:DI
6669           (minus:SI (match_dup 1)
6670                     (match_dup 2))))]
6671   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6672    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6673   "sub{l}\t{%2, %k0|%k0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "mode" "SI")])
6676
6677 (define_insn "*sub<mode>_3"
6678   [(set (reg FLAGS_REG)
6679         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6680                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6681    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6682         (minus:SWI (match_dup 1) (match_dup 2)))]
6683   "ix86_match_ccmode (insn, CCmode)
6684    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6685   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "mode" "<MODE>")])
6688
6689 (define_insn "*subsi_3_zext"
6690   [(set (reg FLAGS_REG)
6691         (compare (match_operand:SI 1 "register_operand" "0")
6692                  (match_operand:SI 2 "general_operand" "g")))
6693    (set (match_operand:DI 0 "register_operand" "=r")
6694         (zero_extend:DI
6695           (minus:SI (match_dup 1)
6696                     (match_dup 2))))]
6697   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6698    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6699   "sub{l}\t{%2, %1|%1, %2}"
6700   [(set_attr "type" "alu")
6701    (set_attr "mode" "SI")])
6702 \f
6703 ;; Add with carry and subtract with borrow
6704
6705 (define_expand "<plusminus_insn><mode>3_carry"
6706   [(parallel
6707     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6708           (plusminus:SWI
6709             (match_operand:SWI 1 "nonimmediate_operand" "")
6710             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6711                        [(match_operand 3 "flags_reg_operand" "")
6712                         (const_int 0)])
6713                       (match_operand:SWI 2 "<general_operand>" ""))))
6714      (clobber (reg:CC FLAGS_REG))])]
6715   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6716   "")
6717
6718 (define_insn "*<plusminus_insn><mode>3_carry"
6719   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6720         (plusminus:SWI
6721           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6722           (plus:SWI
6723             (match_operator 3 "ix86_carry_flag_operator"
6724              [(reg FLAGS_REG) (const_int 0)])
6725             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6726    (clobber (reg:CC FLAGS_REG))]
6727   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6728   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "use_carry" "1")
6731    (set_attr "pent_pair" "pu")
6732    (set_attr "mode" "<MODE>")])
6733
6734 (define_insn "*addsi3_carry_zext"
6735   [(set (match_operand:DI 0 "register_operand" "=r")
6736         (zero_extend:DI
6737           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6738                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6739                              [(reg FLAGS_REG) (const_int 0)])
6740                             (match_operand:SI 2 "general_operand" "g")))))
6741    (clobber (reg:CC FLAGS_REG))]
6742   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6743   "adc{l}\t{%2, %k0|%k0, %2}"
6744   [(set_attr "type" "alu")
6745    (set_attr "use_carry" "1")
6746    (set_attr "pent_pair" "pu")
6747    (set_attr "mode" "SI")])
6748
6749 (define_insn "*subsi3_carry_zext"
6750   [(set (match_operand:DI 0 "register_operand" "=r")
6751         (zero_extend:DI
6752           (minus:SI (match_operand:SI 1 "register_operand" "0")
6753                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6754                               [(reg FLAGS_REG) (const_int 0)])
6755                              (match_operand:SI 2 "general_operand" "g")))))
6756    (clobber (reg:CC FLAGS_REG))]
6757   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758   "sbb{l}\t{%2, %k0|%k0, %2}"
6759   [(set_attr "type" "alu")
6760    (set_attr "pent_pair" "pu")
6761    (set_attr "mode" "SI")])
6762 \f
6763 ;; Overflow setting add and subtract instructions
6764
6765 (define_insn "*add<mode>3_cconly_overflow"
6766   [(set (reg:CCC FLAGS_REG)
6767         (compare:CCC
6768           (plus:SWI
6769             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6770             (match_operand:SWI 2 "<general_operand>" "<g>"))
6771           (match_dup 1)))
6772    (clobber (match_scratch:SWI 0 "=<r>"))]
6773   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6774   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6775   [(set_attr "type" "alu")
6776    (set_attr "mode" "<MODE>")])
6777
6778 (define_insn "*sub<mode>3_cconly_overflow"
6779   [(set (reg:CCC FLAGS_REG)
6780         (compare:CCC
6781           (minus:SWI
6782             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6783             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6784           (match_dup 0)))]
6785   ""
6786   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6787   [(set_attr "type" "icmp")
6788    (set_attr "mode" "<MODE>")])
6789
6790 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6791   [(set (reg:CCC FLAGS_REG)
6792         (compare:CCC
6793             (plusminus:SWI
6794                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6795                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6796             (match_dup 1)))
6797    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6798         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6799   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6800   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6801   [(set_attr "type" "alu")
6802    (set_attr "mode" "<MODE>")])
6803
6804 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6805   [(set (reg:CCC FLAGS_REG)
6806         (compare:CCC
6807           (plusminus:SI
6808             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6809             (match_operand:SI 2 "general_operand" "g"))
6810           (match_dup 1)))
6811    (set (match_operand:DI 0 "register_operand" "=r")
6812         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6813   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6814   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6815   [(set_attr "type" "alu")
6816    (set_attr "mode" "SI")])
6817
6818 ;; The patterns that match these are at the end of this file.
6819
6820 (define_expand "<plusminus_insn>xf3"
6821   [(set (match_operand:XF 0 "register_operand" "")
6822         (plusminus:XF
6823           (match_operand:XF 1 "register_operand" "")
6824           (match_operand:XF 2 "register_operand" "")))]
6825   "TARGET_80387"
6826   "")
6827
6828 (define_expand "<plusminus_insn><mode>3"
6829   [(set (match_operand:MODEF 0 "register_operand" "")
6830         (plusminus:MODEF
6831           (match_operand:MODEF 1 "register_operand" "")
6832           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6833   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6834     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6835   "")
6836 \f
6837 ;; Multiply instructions
6838
6839 (define_expand "mul<mode>3"
6840   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6841                    (mult:SWIM248
6842                      (match_operand:SWIM248 1 "register_operand" "")
6843                      (match_operand:SWIM248 2 "<general_operand>" "")))
6844               (clobber (reg:CC FLAGS_REG))])]
6845   ""
6846   "")
6847
6848 (define_expand "mulqi3"
6849   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6850                    (mult:QI
6851                      (match_operand:QI 1 "register_operand" "")
6852                      (match_operand:QI 2 "nonimmediate_operand" "")))
6853               (clobber (reg:CC FLAGS_REG))])]
6854   "TARGET_QIMODE_MATH"
6855   "")
6856
6857 ;; On AMDFAM10
6858 ;; IMUL reg32/64, reg32/64, imm8        Direct
6859 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6860 ;; IMUL reg32/64, reg32/64, imm32       Direct
6861 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6862 ;; IMUL reg32/64, reg32/64              Direct
6863 ;; IMUL reg32/64, mem32/64              Direct
6864
6865 (define_insn "*mul<mode>3_1"
6866   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6867         (mult:SWI48
6868           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6869           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6870    (clobber (reg:CC FLAGS_REG))]
6871   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6872   "@
6873    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6874    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6875    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6876   [(set_attr "type" "imul")
6877    (set_attr "prefix_0f" "0,0,1")
6878    (set (attr "athlon_decode")
6879         (cond [(eq_attr "cpu" "athlon")
6880                   (const_string "vector")
6881                (eq_attr "alternative" "1")
6882                   (const_string "vector")
6883                (and (eq_attr "alternative" "2")
6884                     (match_operand 1 "memory_operand" ""))
6885                   (const_string "vector")]
6886               (const_string "direct")))
6887    (set (attr "amdfam10_decode")
6888         (cond [(and (eq_attr "alternative" "0,1")
6889                     (match_operand 1 "memory_operand" ""))
6890                   (const_string "vector")]
6891               (const_string "direct")))
6892    (set_attr "mode" "<MODE>")])
6893
6894 (define_insn "*mulsi3_1_zext"
6895   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6896         (zero_extend:DI
6897           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6898                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6899    (clobber (reg:CC FLAGS_REG))]
6900   "TARGET_64BIT
6901    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902   "@
6903    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6904    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6905    imul{l}\t{%2, %k0|%k0, %2}"
6906   [(set_attr "type" "imul")
6907    (set_attr "prefix_0f" "0,0,1")
6908    (set (attr "athlon_decode")
6909         (cond [(eq_attr "cpu" "athlon")
6910                   (const_string "vector")
6911                (eq_attr "alternative" "1")
6912                   (const_string "vector")
6913                (and (eq_attr "alternative" "2")
6914                     (match_operand 1 "memory_operand" ""))
6915                   (const_string "vector")]
6916               (const_string "direct")))
6917    (set (attr "amdfam10_decode")
6918         (cond [(and (eq_attr "alternative" "0,1")
6919                     (match_operand 1 "memory_operand" ""))
6920                   (const_string "vector")]
6921               (const_string "direct")))
6922    (set_attr "mode" "SI")])
6923
6924 ;; On AMDFAM10
6925 ;; IMUL reg16, reg16, imm8      VectorPath
6926 ;; IMUL reg16, mem16, imm8      VectorPath
6927 ;; IMUL reg16, reg16, imm16     VectorPath
6928 ;; IMUL reg16, mem16, imm16     VectorPath
6929 ;; IMUL reg16, reg16            Direct
6930 ;; IMUL reg16, mem16            Direct
6931
6932 (define_insn "*mulhi3_1"
6933   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6934         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6935                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6936    (clobber (reg:CC FLAGS_REG))]
6937   "TARGET_HIMODE_MATH
6938    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6939   "@
6940    imul{w}\t{%2, %1, %0|%0, %1, %2}
6941    imul{w}\t{%2, %1, %0|%0, %1, %2}
6942    imul{w}\t{%2, %0|%0, %2}"
6943   [(set_attr "type" "imul")
6944    (set_attr "prefix_0f" "0,0,1")
6945    (set (attr "athlon_decode")
6946         (cond [(eq_attr "cpu" "athlon")
6947                   (const_string "vector")
6948                (eq_attr "alternative" "1,2")
6949                   (const_string "vector")]
6950               (const_string "direct")))
6951    (set (attr "amdfam10_decode")
6952         (cond [(eq_attr "alternative" "0,1")
6953                   (const_string "vector")]
6954               (const_string "direct")))
6955    (set_attr "mode" "HI")])
6956
6957 ;;On AMDFAM10
6958 ;; MUL reg8     Direct
6959 ;; MUL mem8     Direct
6960
6961 (define_insn "*mulqi3_1"
6962   [(set (match_operand:QI 0 "register_operand" "=a")
6963         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6964                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "TARGET_QIMODE_MATH
6967    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6968   "mul{b}\t%2"
6969   [(set_attr "type" "imul")
6970    (set_attr "length_immediate" "0")
6971    (set (attr "athlon_decode")
6972      (if_then_else (eq_attr "cpu" "athlon")
6973         (const_string "vector")
6974         (const_string "direct")))
6975    (set_attr "amdfam10_decode" "direct")
6976    (set_attr "mode" "QI")])
6977
6978 (define_expand "<u>mul<mode><dwi>3"
6979   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6980                    (mult:<DWI>
6981                      (any_extend:<DWI>
6982                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6983                      (any_extend:<DWI>
6984                        (match_operand:DWIH 2 "register_operand" ""))))
6985               (clobber (reg:CC FLAGS_REG))])]
6986   ""
6987   "")
6988
6989 (define_expand "<u>mulqihi3"
6990   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991                    (mult:HI
6992                      (any_extend:HI
6993                        (match_operand:QI 1 "nonimmediate_operand" ""))
6994                      (any_extend:HI
6995                        (match_operand:QI 2 "register_operand" ""))))
6996               (clobber (reg:CC FLAGS_REG))])]
6997   "TARGET_QIMODE_MATH"
6998   "")
6999
7000 (define_insn "*<u>mul<mode><dwi>3_1"
7001   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7002         (mult:<DWI>
7003           (any_extend:<DWI>
7004             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7005           (any_extend:<DWI>
7006             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7007    (clobber (reg:CC FLAGS_REG))]
7008   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7009   "<sgnprefix>mul{<imodesuffix>}\t%2"
7010   [(set_attr "type" "imul")
7011    (set_attr "length_immediate" "0")
7012    (set (attr "athlon_decode")
7013      (if_then_else (eq_attr "cpu" "athlon")
7014         (const_string "vector")
7015         (const_string "double")))
7016    (set_attr "amdfam10_decode" "double")
7017    (set_attr "mode" "<MODE>")])
7018
7019 (define_insn "*<u>mulqihi3_1"
7020   [(set (match_operand:HI 0 "register_operand" "=a")
7021         (mult:HI
7022           (any_extend:HI
7023             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7024           (any_extend:HI
7025             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7026    (clobber (reg:CC FLAGS_REG))]
7027   "TARGET_QIMODE_MATH
7028    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7029   "<sgnprefix>mul{b}\t%2"
7030   [(set_attr "type" "imul")
7031    (set_attr "length_immediate" "0")
7032    (set (attr "athlon_decode")
7033      (if_then_else (eq_attr "cpu" "athlon")
7034         (const_string "vector")
7035         (const_string "direct")))
7036    (set_attr "amdfam10_decode" "direct")
7037    (set_attr "mode" "QI")])
7038
7039 (define_expand "<s>mul<mode>3_highpart"
7040   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7041                    (truncate:SWI48
7042                      (lshiftrt:<DWI>
7043                        (mult:<DWI>
7044                          (any_extend:<DWI>
7045                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7046                          (any_extend:<DWI>
7047                            (match_operand:SWI48 2 "register_operand" "")))
7048                        (match_dup 4))))
7049               (clobber (match_scratch:SWI48 3 ""))
7050               (clobber (reg:CC FLAGS_REG))])]
7051   ""
7052   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7053
7054 (define_insn "*<s>muldi3_highpart_1"
7055   [(set (match_operand:DI 0 "register_operand" "=d")
7056         (truncate:DI
7057           (lshiftrt:TI
7058             (mult:TI
7059               (any_extend:TI
7060                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7061               (any_extend:TI
7062                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7063             (const_int 64))))
7064    (clobber (match_scratch:DI 3 "=1"))
7065    (clobber (reg:CC FLAGS_REG))]
7066   "TARGET_64BIT
7067    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7068   "<sgnprefix>mul{q}\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 "double")))
7075    (set_attr "amdfam10_decode" "double")
7076    (set_attr "mode" "DI")])
7077
7078 (define_insn "*<s>mulsi3_highpart_1"
7079   [(set (match_operand:SI 0 "register_operand" "=d")
7080         (truncate:SI
7081           (lshiftrt:DI
7082             (mult:DI
7083               (any_extend:DI
7084                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7085               (any_extend:DI
7086                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7087             (const_int 32))))
7088    (clobber (match_scratch:SI 3 "=1"))
7089    (clobber (reg:CC FLAGS_REG))]
7090   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7091   "<sgnprefix>mul{l}\t%2"
7092   [(set_attr "type" "imul")
7093    (set_attr "length_immediate" "0")
7094    (set (attr "athlon_decode")
7095      (if_then_else (eq_attr "cpu" "athlon")
7096         (const_string "vector")
7097         (const_string "double")))
7098    (set_attr "amdfam10_decode" "double")
7099    (set_attr "mode" "SI")])
7100
7101 (define_insn "*<s>mulsi3_highpart_zext"
7102   [(set (match_operand:DI 0 "register_operand" "=d")
7103         (zero_extend:DI (truncate:SI
7104           (lshiftrt:DI
7105             (mult:DI (any_extend:DI
7106                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7107                      (any_extend:DI
7108                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7109             (const_int 32)))))
7110    (clobber (match_scratch:SI 3 "=1"))
7111    (clobber (reg:CC FLAGS_REG))]
7112   "TARGET_64BIT
7113    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7114   "<sgnprefix>mul{l}\t%2"
7115   [(set_attr "type" "imul")
7116    (set_attr "length_immediate" "0")
7117    (set (attr "athlon_decode")
7118      (if_then_else (eq_attr "cpu" "athlon")
7119         (const_string "vector")
7120         (const_string "double")))
7121    (set_attr "amdfam10_decode" "double")
7122    (set_attr "mode" "SI")])
7123
7124 ;; The patterns that match these are at the end of this file.
7125
7126 (define_expand "mulxf3"
7127   [(set (match_operand:XF 0 "register_operand" "")
7128         (mult:XF (match_operand:XF 1 "register_operand" "")
7129                  (match_operand:XF 2 "register_operand" "")))]
7130   "TARGET_80387"
7131   "")
7132
7133 (define_expand "mul<mode>3"
7134   [(set (match_operand:MODEF 0 "register_operand" "")
7135         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7136                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7137   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7138     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7139   "")
7140 \f
7141 ;; Divide instructions
7142
7143 ;; The patterns that match these are at the end of this file.
7144
7145 (define_expand "divxf3"
7146   [(set (match_operand:XF 0 "register_operand" "")
7147         (div:XF (match_operand:XF 1 "register_operand" "")
7148                 (match_operand:XF 2 "register_operand" "")))]
7149   "TARGET_80387"
7150   "")
7151
7152 (define_expand "divdf3"
7153   [(set (match_operand:DF 0 "register_operand" "")
7154         (div:DF (match_operand:DF 1 "register_operand" "")
7155                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7156    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7157     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7158    "")
7159
7160 (define_expand "divsf3"
7161   [(set (match_operand:SF 0 "register_operand" "")
7162         (div:SF (match_operand:SF 1 "register_operand" "")
7163                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7164   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7165     || TARGET_SSE_MATH"
7166 {
7167   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7168       && flag_finite_math_only && !flag_trapping_math
7169       && flag_unsafe_math_optimizations)
7170     {
7171       ix86_emit_swdivsf (operands[0], operands[1],
7172                          operands[2], SFmode);
7173       DONE;
7174     }
7175 })
7176 \f
7177 ;; Divmod instructions.
7178
7179 (define_expand "divmodqi4"
7180   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7181                    (div:QI
7182                      (match_operand:QI 1 "register_operand" "")
7183                      (match_operand:QI 2 "nonimmediate_operand" "")))
7184               (set (match_operand:QI 3 "register_operand" "")
7185                    (mod:QI (match_dup 1) (match_dup 2)))
7186               (clobber (reg:CC FLAGS_REG))])]
7187   "TARGET_QIMODE_MATH"
7188 {
7189   rtx div, mod, insn;
7190   rtx tmp0, tmp1;
7191   
7192   tmp0 = gen_reg_rtx (HImode);
7193   tmp1 = gen_reg_rtx (HImode);
7194
7195   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7196      in AX.  */
7197   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7198   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7199
7200   /* Extract remainder from AH.  */
7201   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7202   insn = emit_move_insn (operands[3], tmp1);
7203
7204   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7205   set_unique_reg_note (insn, REG_EQUAL, mod);
7206
7207   /* Extract quotient from AL.  */
7208   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7209
7210   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7211   set_unique_reg_note (insn, REG_EQUAL, div);
7212
7213   DONE;
7214 })
7215
7216 (define_expand "udivmodqi4"
7217   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7218                    (udiv:QI
7219                      (match_operand:QI 1 "register_operand" "")
7220                      (match_operand:QI 2 "nonimmediate_operand" "")))
7221               (set (match_operand:QI 3 "register_operand" "")
7222                    (umod:QI (match_dup 1) (match_dup 2)))
7223               (clobber (reg:CC FLAGS_REG))])]
7224   "TARGET_QIMODE_MATH"
7225 {
7226   rtx div, mod, insn;
7227   rtx tmp0, tmp1;
7228   
7229   tmp0 = gen_reg_rtx (HImode);
7230   tmp1 = gen_reg_rtx (HImode);
7231
7232   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7233      in AX.  */
7234   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7235   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7236
7237   /* Extract remainder from AH.  */
7238   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7239   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7240   insn = emit_move_insn (operands[3], tmp1);
7241
7242   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7243   set_unique_reg_note (insn, REG_EQUAL, mod);
7244
7245   /* Extract quotient from AL.  */
7246   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7247
7248   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7249   set_unique_reg_note (insn, REG_EQUAL, div);
7250
7251   DONE;
7252 })
7253
7254 ;; Divide AX by r/m8, with result stored in
7255 ;; AL <- Quotient
7256 ;; AH <- Remainder
7257 ;; Change div/mod to HImode and extend the second argument to HImode
7258 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7259 ;; combine may fail.
7260 (define_insn "divmodhiqi3"
7261   [(set (match_operand:HI 0 "register_operand" "=a")
7262         (ior:HI
7263           (ashift:HI
7264             (zero_extend:HI
7265               (truncate:QI
7266                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7267                         (sign_extend:HI
7268                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7269             (const_int 8))
7270           (zero_extend:HI
7271             (truncate:QI
7272               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7273    (clobber (reg:CC FLAGS_REG))]
7274   "TARGET_QIMODE_MATH"
7275   "idiv{b}\t%2"
7276   [(set_attr "type" "idiv")
7277    (set_attr "mode" "QI")])
7278
7279 (define_insn "udivmodhiqi3"
7280   [(set (match_operand:HI 0 "register_operand" "=a")
7281         (ior:HI
7282           (ashift:HI
7283             (zero_extend:HI
7284               (truncate:QI
7285                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7286                         (zero_extend:HI
7287                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7288             (const_int 8))
7289           (zero_extend:HI
7290             (truncate:QI
7291               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7292    (clobber (reg:CC FLAGS_REG))]
7293   "TARGET_QIMODE_MATH"
7294   "div{b}\t%2"
7295   [(set_attr "type" "idiv")
7296    (set_attr "mode" "QI")])
7297
7298 (define_expand "divmod<mode>4"
7299   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7300                    (div:SWIM248
7301                      (match_operand:SWIM248 1 "register_operand" "")
7302                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7303               (set (match_operand:SWIM248 3 "register_operand" "")
7304                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7305               (clobber (reg:CC FLAGS_REG))])]
7306   ""
7307   "")
7308
7309 (define_insn_and_split "*divmod<mode>4"
7310   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7311         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7312                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7313    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7314         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7315    (clobber (reg:CC FLAGS_REG))]
7316   ""
7317   "#"
7318   "reload_completed"
7319   [(parallel [(set (match_dup 1)
7320                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7321               (clobber (reg:CC FLAGS_REG))])
7322    (parallel [(set (match_dup 0)
7323                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7324               (set (match_dup 1)
7325                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7326               (use (match_dup 1))
7327               (clobber (reg:CC FLAGS_REG))])]
7328 {
7329   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7330
7331   if (<MODE>mode != HImode
7332       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7333     operands[4] = operands[2];
7334   else
7335     {
7336       /* Avoid use of cltd in favor of a mov+shift.  */
7337       emit_move_insn (operands[1], operands[2]);
7338       operands[4] = operands[1];
7339     }
7340 }
7341   [(set_attr "type" "multi")
7342    (set_attr "mode" "<MODE>")])
7343
7344 (define_insn "*divmod<mode>4_noext"
7345   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7346         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7347                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7348    (set (match_operand:SWIM248 1 "register_operand" "=d")
7349         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7350    (use (match_operand:SWIM248 4 "register_operand" "1"))
7351    (clobber (reg:CC FLAGS_REG))]
7352   ""
7353   "idiv{<imodesuffix>}\t%3"
7354   [(set_attr "type" "idiv")
7355    (set_attr "mode" "<MODE>")])
7356
7357 (define_expand "udivmod<mode>4"
7358   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7359                    (udiv:SWIM248
7360                      (match_operand:SWIM248 1 "register_operand" "")
7361                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7362               (set (match_operand:SWIM248 3 "register_operand" "")
7363                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7364               (clobber (reg:CC FLAGS_REG))])]
7365   ""
7366   "")
7367
7368 (define_insn_and_split "*udivmod<mode>4"
7369   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7370         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7371                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7372    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7373         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7374    (clobber (reg:CC FLAGS_REG))]
7375   ""
7376   "#"
7377   "reload_completed"
7378   [(set (match_dup 1) (const_int 0))
7379    (parallel [(set (match_dup 0)
7380                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7381               (set (match_dup 1)
7382                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7383               (use (match_dup 1))
7384               (clobber (reg:CC FLAGS_REG))])]
7385   ""
7386   [(set_attr "type" "multi")
7387    (set_attr "mode" "<MODE>")])
7388
7389 (define_insn "*udivmod<mode>4_noext"
7390   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7391         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7392                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7393    (set (match_operand:SWIM248 1 "register_operand" "=d")
7394         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7395    (use (match_operand:SWIM248 4 "register_operand" "1"))
7396    (clobber (reg:CC FLAGS_REG))]
7397   ""
7398   "div{<imodesuffix>}\t%3"
7399   [(set_attr "type" "idiv")
7400    (set_attr "mode" "<MODE>")])
7401
7402 ;; We cannot use div/idiv for double division, because it causes
7403 ;; "division by zero" on the overflow and that's not what we expect
7404 ;; from truncate.  Because true (non truncating) double division is
7405 ;; never generated, we can't create this insn anyway.
7406 ;
7407 ;(define_insn ""
7408 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7409 ;       (truncate:SI
7410 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7411 ;                  (zero_extend:DI
7412 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7413 ;   (set (match_operand:SI 3 "register_operand" "=d")
7414 ;       (truncate:SI
7415 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7416 ;   (clobber (reg:CC FLAGS_REG))]
7417 ;  ""
7418 ;  "div{l}\t{%2, %0|%0, %2}"
7419 ;  [(set_attr "type" "idiv")])
7420 \f
7421 ;;- Logical AND instructions
7422
7423 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7424 ;; Note that this excludes ah.
7425
7426 (define_expand "testsi_ccno_1"
7427   [(set (reg:CCNO FLAGS_REG)
7428         (compare:CCNO
7429           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7430                   (match_operand:SI 1 "nonmemory_operand" ""))
7431           (const_int 0)))]
7432   ""
7433   "")
7434
7435 (define_expand "testqi_ccz_1"
7436   [(set (reg:CCZ FLAGS_REG)
7437         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7438                              (match_operand:QI 1 "nonmemory_operand" ""))
7439                  (const_int 0)))]
7440   ""
7441   "")
7442
7443 (define_insn "*testdi_1"
7444   [(set (reg FLAGS_REG)
7445         (compare
7446          (and:DI
7447           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7448           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7449          (const_int 0)))]
7450   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7451    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7452   "@
7453    test{l}\t{%k1, %k0|%k0, %k1}
7454    test{l}\t{%k1, %k0|%k0, %k1}
7455    test{q}\t{%1, %0|%0, %1}
7456    test{q}\t{%1, %0|%0, %1}
7457    test{q}\t{%1, %0|%0, %1}"
7458   [(set_attr "type" "test")
7459    (set_attr "modrm" "0,1,0,1,1")
7460    (set_attr "mode" "SI,SI,DI,DI,DI")])
7461
7462 (define_insn "*testqi_1_maybe_si"
7463   [(set (reg FLAGS_REG)
7464         (compare
7465           (and:QI
7466             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7467             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7468           (const_int 0)))]
7469    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7470     && ix86_match_ccmode (insn,
7471                          CONST_INT_P (operands[1])
7472                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7473 {
7474   if (which_alternative == 3)
7475     {
7476       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7477         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7478       return "test{l}\t{%1, %k0|%k0, %1}";
7479     }
7480   return "test{b}\t{%1, %0|%0, %1}";
7481 }
7482   [(set_attr "type" "test")
7483    (set_attr "modrm" "0,1,1,1")
7484    (set_attr "mode" "QI,QI,QI,SI")
7485    (set_attr "pent_pair" "uv,np,uv,np")])
7486
7487 (define_insn "*test<mode>_1"
7488   [(set (reg FLAGS_REG)
7489         (compare
7490          (and:SWI124
7491           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7492           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7493          (const_int 0)))]
7494   "ix86_match_ccmode (insn, CCNOmode)
7495    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7496   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7497   [(set_attr "type" "test")
7498    (set_attr "modrm" "0,1,1")
7499    (set_attr "mode" "<MODE>")
7500    (set_attr "pent_pair" "uv,np,uv")])
7501
7502 (define_expand "testqi_ext_ccno_0"
7503   [(set (reg:CCNO FLAGS_REG)
7504         (compare:CCNO
7505           (and:SI
7506             (zero_extract:SI
7507               (match_operand 0 "ext_register_operand" "")
7508               (const_int 8)
7509               (const_int 8))
7510             (match_operand 1 "const_int_operand" ""))
7511           (const_int 0)))]
7512   ""
7513   "")
7514
7515 (define_insn "*testqi_ext_0"
7516   [(set (reg FLAGS_REG)
7517         (compare
7518           (and:SI
7519             (zero_extract:SI
7520               (match_operand 0 "ext_register_operand" "Q")
7521               (const_int 8)
7522               (const_int 8))
7523             (match_operand 1 "const_int_operand" "n"))
7524           (const_int 0)))]
7525   "ix86_match_ccmode (insn, CCNOmode)"
7526   "test{b}\t{%1, %h0|%h0, %1}"
7527   [(set_attr "type" "test")
7528    (set_attr "mode" "QI")
7529    (set_attr "length_immediate" "1")
7530    (set_attr "modrm" "1")
7531    (set_attr "pent_pair" "np")])
7532
7533 (define_insn "*testqi_ext_1_rex64"
7534   [(set (reg FLAGS_REG)
7535         (compare
7536           (and:SI
7537             (zero_extract:SI
7538               (match_operand 0 "ext_register_operand" "Q")
7539               (const_int 8)
7540               (const_int 8))
7541             (zero_extend:SI
7542               (match_operand:QI 1 "register_operand" "Q")))
7543           (const_int 0)))]
7544   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7545   "test{b}\t{%1, %h0|%h0, %1}"
7546   [(set_attr "type" "test")
7547    (set_attr "mode" "QI")])
7548
7549 (define_insn "*testqi_ext_1"
7550   [(set (reg FLAGS_REG)
7551         (compare
7552           (and:SI
7553             (zero_extract:SI
7554               (match_operand 0 "ext_register_operand" "Q")
7555               (const_int 8)
7556               (const_int 8))
7557             (zero_extend:SI
7558               (match_operand:QI 1 "general_operand" "Qm")))
7559           (const_int 0)))]
7560   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7561   "test{b}\t{%1, %h0|%h0, %1}"
7562   [(set_attr "type" "test")
7563    (set_attr "mode" "QI")])
7564
7565 (define_insn "*testqi_ext_2"
7566   [(set (reg FLAGS_REG)
7567         (compare
7568           (and:SI
7569             (zero_extract:SI
7570               (match_operand 0 "ext_register_operand" "Q")
7571               (const_int 8)
7572               (const_int 8))
7573             (zero_extract:SI
7574               (match_operand 1 "ext_register_operand" "Q")
7575               (const_int 8)
7576               (const_int 8)))
7577           (const_int 0)))]
7578   "ix86_match_ccmode (insn, CCNOmode)"
7579   "test{b}\t{%h1, %h0|%h0, %h1}"
7580   [(set_attr "type" "test")
7581    (set_attr "mode" "QI")])
7582
7583 (define_insn "*testqi_ext_3_rex64"
7584   [(set (reg FLAGS_REG)
7585         (compare (zero_extract:DI
7586                    (match_operand 0 "nonimmediate_operand" "rm")
7587                    (match_operand:DI 1 "const_int_operand" "")
7588                    (match_operand:DI 2 "const_int_operand" ""))
7589                  (const_int 0)))]
7590   "TARGET_64BIT
7591    && ix86_match_ccmode (insn, CCNOmode)
7592    && INTVAL (operands[1]) > 0
7593    && INTVAL (operands[2]) >= 0
7594    /* Ensure that resulting mask is zero or sign extended operand.  */
7595    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7596        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7597            && INTVAL (operands[1]) > 32))
7598    && (GET_MODE (operands[0]) == SImode
7599        || GET_MODE (operands[0]) == DImode
7600        || GET_MODE (operands[0]) == HImode
7601        || GET_MODE (operands[0]) == QImode)"
7602   "#")
7603
7604 ;; Combine likes to form bit extractions for some tests.  Humor it.
7605 (define_insn "*testqi_ext_3"
7606   [(set (reg FLAGS_REG)
7607         (compare (zero_extract:SI
7608                    (match_operand 0 "nonimmediate_operand" "rm")
7609                    (match_operand:SI 1 "const_int_operand" "")
7610                    (match_operand:SI 2 "const_int_operand" ""))
7611                  (const_int 0)))]
7612   "ix86_match_ccmode (insn, CCNOmode)
7613    && INTVAL (operands[1]) > 0
7614    && INTVAL (operands[2]) >= 0
7615    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7616    && (GET_MODE (operands[0]) == SImode
7617        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7618        || GET_MODE (operands[0]) == HImode
7619        || GET_MODE (operands[0]) == QImode)"
7620   "#")
7621
7622 (define_split
7623   [(set (match_operand 0 "flags_reg_operand" "")
7624         (match_operator 1 "compare_operator"
7625           [(zero_extract
7626              (match_operand 2 "nonimmediate_operand" "")
7627              (match_operand 3 "const_int_operand" "")
7628              (match_operand 4 "const_int_operand" ""))
7629            (const_int 0)]))]
7630   "ix86_match_ccmode (insn, CCNOmode)"
7631   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7632 {
7633   rtx val = operands[2];
7634   HOST_WIDE_INT len = INTVAL (operands[3]);
7635   HOST_WIDE_INT pos = INTVAL (operands[4]);
7636   HOST_WIDE_INT mask;
7637   enum machine_mode mode, submode;
7638
7639   mode = GET_MODE (val);
7640   if (MEM_P (val))
7641     {
7642       /* ??? Combine likes to put non-volatile mem extractions in QImode
7643          no matter the size of the test.  So find a mode that works.  */
7644       if (! MEM_VOLATILE_P (val))
7645         {
7646           mode = smallest_mode_for_size (pos + len, MODE_INT);
7647           val = adjust_address (val, mode, 0);
7648         }
7649     }
7650   else if (GET_CODE (val) == SUBREG
7651            && (submode = GET_MODE (SUBREG_REG (val)),
7652                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7653            && pos + len <= GET_MODE_BITSIZE (submode)
7654            && GET_MODE_CLASS (submode) == MODE_INT)
7655     {
7656       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7657       mode = submode;
7658       val = SUBREG_REG (val);
7659     }
7660   else if (mode == HImode && pos + len <= 8)
7661     {
7662       /* Small HImode tests can be converted to QImode.  */
7663       mode = QImode;
7664       val = gen_lowpart (QImode, val);
7665     }
7666
7667   if (len == HOST_BITS_PER_WIDE_INT)
7668     mask = -1;
7669   else
7670     mask = ((HOST_WIDE_INT)1 << len) - 1;
7671   mask <<= pos;
7672
7673   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7674 })
7675
7676 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7677 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7678 ;; this is relatively important trick.
7679 ;; Do the conversion only post-reload to avoid limiting of the register class
7680 ;; to QI regs.
7681 (define_split
7682   [(set (match_operand 0 "flags_reg_operand" "")
7683         (match_operator 1 "compare_operator"
7684           [(and (match_operand 2 "register_operand" "")
7685                 (match_operand 3 "const_int_operand" ""))
7686            (const_int 0)]))]
7687    "reload_completed
7688     && QI_REG_P (operands[2])
7689     && GET_MODE (operands[2]) != QImode
7690     && ((ix86_match_ccmode (insn, CCZmode)
7691          && !(INTVAL (operands[3]) & ~(255 << 8)))
7692         || (ix86_match_ccmode (insn, CCNOmode)
7693             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7694   [(set (match_dup 0)
7695         (match_op_dup 1
7696           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7697                    (match_dup 3))
7698            (const_int 0)]))]
7699   "operands[2] = gen_lowpart (SImode, operands[2]);
7700    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7701
7702 (define_split
7703   [(set (match_operand 0 "flags_reg_operand" "")
7704         (match_operator 1 "compare_operator"
7705           [(and (match_operand 2 "nonimmediate_operand" "")
7706                 (match_operand 3 "const_int_operand" ""))
7707            (const_int 0)]))]
7708    "reload_completed
7709     && GET_MODE (operands[2]) != QImode
7710     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7711     && ((ix86_match_ccmode (insn, CCZmode)
7712          && !(INTVAL (operands[3]) & ~255))
7713         || (ix86_match_ccmode (insn, CCNOmode)
7714             && !(INTVAL (operands[3]) & ~127)))"
7715   [(set (match_dup 0)
7716         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7717                          (const_int 0)]))]
7718   "operands[2] = gen_lowpart (QImode, operands[2]);
7719    operands[3] = gen_lowpart (QImode, operands[3]);")
7720
7721 ;; %%% This used to optimize known byte-wide and operations to memory,
7722 ;; and sometimes to QImode registers.  If this is considered useful,
7723 ;; it should be done with splitters.
7724
7725 (define_expand "and<mode>3"
7726   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7727         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7728                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7729   ""
7730   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7731
7732 (define_insn "*anddi_1"
7733   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7734         (and:DI
7735          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7736          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7737    (clobber (reg:CC FLAGS_REG))]
7738   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7739 {
7740   switch (get_attr_type (insn))
7741     {
7742     case TYPE_IMOVX:
7743       {
7744         enum machine_mode mode;
7745
7746         gcc_assert (CONST_INT_P (operands[2]));
7747         if (INTVAL (operands[2]) == 0xff)
7748           mode = QImode;
7749         else
7750           {
7751             gcc_assert (INTVAL (operands[2]) == 0xffff);
7752             mode = HImode;
7753           }
7754
7755         operands[1] = gen_lowpart (mode, operands[1]);
7756         if (mode == QImode)
7757           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7758         else
7759           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7760       }
7761
7762     default:
7763       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7764       if (get_attr_mode (insn) == MODE_SI)
7765         return "and{l}\t{%k2, %k0|%k0, %k2}";
7766       else
7767         return "and{q}\t{%2, %0|%0, %2}";
7768     }
7769 }
7770   [(set_attr "type" "alu,alu,alu,imovx")
7771    (set_attr "length_immediate" "*,*,*,0")
7772    (set (attr "prefix_rex")
7773      (if_then_else
7774        (and (eq_attr "type" "imovx")
7775             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7776                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7777        (const_string "1")
7778        (const_string "*")))
7779    (set_attr "mode" "SI,DI,DI,SI")])
7780
7781 (define_insn "*andsi_1"
7782   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7783         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7784                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7785    (clobber (reg:CC FLAGS_REG))]
7786   "ix86_binary_operator_ok (AND, SImode, operands)"
7787 {
7788   switch (get_attr_type (insn))
7789     {
7790     case TYPE_IMOVX:
7791       {
7792         enum machine_mode mode;
7793
7794         gcc_assert (CONST_INT_P (operands[2]));
7795         if (INTVAL (operands[2]) == 0xff)
7796           mode = QImode;
7797         else
7798           {
7799             gcc_assert (INTVAL (operands[2]) == 0xffff);
7800             mode = HImode;
7801           }
7802
7803         operands[1] = gen_lowpart (mode, operands[1]);
7804         if (mode == QImode)
7805           return "movz{bl|x}\t{%1, %0|%0, %1}";
7806         else
7807           return "movz{wl|x}\t{%1, %0|%0, %1}";
7808       }
7809
7810     default:
7811       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7812       return "and{l}\t{%2, %0|%0, %2}";
7813     }
7814 }
7815   [(set_attr "type" "alu,alu,imovx")
7816    (set (attr "prefix_rex")
7817      (if_then_else
7818        (and (eq_attr "type" "imovx")
7819             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7820                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7821        (const_string "1")
7822        (const_string "*")))
7823    (set_attr "length_immediate" "*,*,0")
7824    (set_attr "mode" "SI")])
7825
7826 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7827 (define_insn "*andsi_1_zext"
7828   [(set (match_operand:DI 0 "register_operand" "=r")
7829         (zero_extend:DI
7830           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7831                   (match_operand:SI 2 "general_operand" "g"))))
7832    (clobber (reg:CC FLAGS_REG))]
7833   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7834   "and{l}\t{%2, %k0|%k0, %2}"
7835   [(set_attr "type" "alu")
7836    (set_attr "mode" "SI")])
7837
7838 (define_insn "*andhi_1"
7839   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7840         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7841                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7842    (clobber (reg:CC FLAGS_REG))]
7843   "ix86_binary_operator_ok (AND, HImode, operands)"
7844 {
7845   switch (get_attr_type (insn))
7846     {
7847     case TYPE_IMOVX:
7848       gcc_assert (CONST_INT_P (operands[2]));
7849       gcc_assert (INTVAL (operands[2]) == 0xff);
7850       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7851
7852     default:
7853       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7854
7855       return "and{w}\t{%2, %0|%0, %2}";
7856     }
7857 }
7858   [(set_attr "type" "alu,alu,imovx")
7859    (set_attr "length_immediate" "*,*,0")
7860    (set (attr "prefix_rex")
7861      (if_then_else
7862        (and (eq_attr "type" "imovx")
7863             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7864        (const_string "1")
7865        (const_string "*")))
7866    (set_attr "mode" "HI,HI,SI")])
7867
7868 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7869 (define_insn "*andqi_1"
7870   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7871         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7872                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7873    (clobber (reg:CC FLAGS_REG))]
7874   "ix86_binary_operator_ok (AND, QImode, operands)"
7875   "@
7876    and{b}\t{%2, %0|%0, %2}
7877    and{b}\t{%2, %0|%0, %2}
7878    and{l}\t{%k2, %k0|%k0, %k2}"
7879   [(set_attr "type" "alu")
7880    (set_attr "mode" "QI,QI,SI")])
7881
7882 (define_insn "*andqi_1_slp"
7883   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7884         (and:QI (match_dup 0)
7885                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7886    (clobber (reg:CC FLAGS_REG))]
7887   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7888    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7889   "and{b}\t{%1, %0|%0, %1}"
7890   [(set_attr "type" "alu1")
7891    (set_attr "mode" "QI")])
7892
7893 (define_split
7894   [(set (match_operand 0 "register_operand" "")
7895         (and (match_dup 0)
7896              (const_int -65536)))
7897    (clobber (reg:CC FLAGS_REG))]
7898   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7899     || optimize_function_for_size_p (cfun)"
7900   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7901   "operands[1] = gen_lowpart (HImode, operands[0]);")
7902
7903 (define_split
7904   [(set (match_operand 0 "ext_register_operand" "")
7905         (and (match_dup 0)
7906              (const_int -256)))
7907    (clobber (reg:CC FLAGS_REG))]
7908   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7909    && reload_completed"
7910   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7911   "operands[1] = gen_lowpart (QImode, operands[0]);")
7912
7913 (define_split
7914   [(set (match_operand 0 "ext_register_operand" "")
7915         (and (match_dup 0)
7916              (const_int -65281)))
7917    (clobber (reg:CC FLAGS_REG))]
7918   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7919    && reload_completed"
7920   [(parallel [(set (zero_extract:SI (match_dup 0)
7921                                     (const_int 8)
7922                                     (const_int 8))
7923                    (xor:SI
7924                      (zero_extract:SI (match_dup 0)
7925                                       (const_int 8)
7926                                       (const_int 8))
7927                      (zero_extract:SI (match_dup 0)
7928                                       (const_int 8)
7929                                       (const_int 8))))
7930               (clobber (reg:CC FLAGS_REG))])]
7931   "operands[0] = gen_lowpart (SImode, operands[0]);")
7932
7933 (define_insn "*anddi_2"
7934   [(set (reg FLAGS_REG)
7935         (compare
7936          (and:DI
7937           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7938           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7939          (const_int 0)))
7940    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7941         (and:DI (match_dup 1) (match_dup 2)))]
7942   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7943    && ix86_binary_operator_ok (AND, DImode, operands)"
7944   "@
7945    and{l}\t{%k2, %k0|%k0, %k2}
7946    and{q}\t{%2, %0|%0, %2}
7947    and{q}\t{%2, %0|%0, %2}"
7948   [(set_attr "type" "alu")
7949    (set_attr "mode" "SI,DI,DI")])
7950
7951 (define_insn "*andqi_2_maybe_si"
7952   [(set (reg FLAGS_REG)
7953         (compare (and:QI
7954                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7955                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7956                  (const_int 0)))
7957    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7958         (and:QI (match_dup 1) (match_dup 2)))]
7959   "ix86_binary_operator_ok (AND, QImode, operands)
7960    && ix86_match_ccmode (insn,
7961                          CONST_INT_P (operands[2])
7962                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7963 {
7964   if (which_alternative == 2)
7965     {
7966       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7967         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7968       return "and{l}\t{%2, %k0|%k0, %2}";
7969     }
7970   return "and{b}\t{%2, %0|%0, %2}";
7971 }
7972   [(set_attr "type" "alu")
7973    (set_attr "mode" "QI,QI,SI")])
7974
7975 (define_insn "*and<mode>_2"
7976   [(set (reg FLAGS_REG)
7977         (compare (and:SWI124
7978                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7979                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7980                  (const_int 0)))
7981    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7982         (and:SWI124 (match_dup 1) (match_dup 2)))]
7983   "ix86_match_ccmode (insn, CCNOmode)
7984    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7985   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7986   [(set_attr "type" "alu")
7987    (set_attr "mode" "<MODE>")])
7988
7989 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7990 (define_insn "*andsi_2_zext"
7991   [(set (reg FLAGS_REG)
7992         (compare (and:SI
7993                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7994                   (match_operand:SI 2 "general_operand" "g"))
7995                  (const_int 0)))
7996    (set (match_operand:DI 0 "register_operand" "=r")
7997         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7998   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7999    && ix86_binary_operator_ok (AND, SImode, operands)"
8000   "and{l}\t{%2, %k0|%k0, %2}"
8001   [(set_attr "type" "alu")
8002    (set_attr "mode" "SI")])
8003
8004 (define_insn "*andqi_2_slp"
8005   [(set (reg FLAGS_REG)
8006         (compare (and:QI
8007                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8008                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8009                  (const_int 0)))
8010    (set (strict_low_part (match_dup 0))
8011         (and:QI (match_dup 0) (match_dup 1)))]
8012   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8013    && ix86_match_ccmode (insn, CCNOmode)
8014    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8015   "and{b}\t{%1, %0|%0, %1}"
8016   [(set_attr "type" "alu1")
8017    (set_attr "mode" "QI")])
8018
8019 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8020 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8021 ;; for a QImode operand, which of course failed.
8022 (define_insn "andqi_ext_0"
8023   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8024                          (const_int 8)
8025                          (const_int 8))
8026         (and:SI
8027           (zero_extract:SI
8028             (match_operand 1 "ext_register_operand" "0")
8029             (const_int 8)
8030             (const_int 8))
8031           (match_operand 2 "const_int_operand" "n")))
8032    (clobber (reg:CC FLAGS_REG))]
8033   ""
8034   "and{b}\t{%2, %h0|%h0, %2}"
8035   [(set_attr "type" "alu")
8036    (set_attr "length_immediate" "1")
8037    (set_attr "modrm" "1")
8038    (set_attr "mode" "QI")])
8039
8040 ;; Generated by peephole translating test to and.  This shows up
8041 ;; often in fp comparisons.
8042 (define_insn "*andqi_ext_0_cc"
8043   [(set (reg FLAGS_REG)
8044         (compare
8045           (and:SI
8046             (zero_extract:SI
8047               (match_operand 1 "ext_register_operand" "0")
8048               (const_int 8)
8049               (const_int 8))
8050             (match_operand 2 "const_int_operand" "n"))
8051           (const_int 0)))
8052    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8053                          (const_int 8)
8054                          (const_int 8))
8055         (and:SI
8056           (zero_extract:SI
8057             (match_dup 1)
8058             (const_int 8)
8059             (const_int 8))
8060           (match_dup 2)))]
8061   "ix86_match_ccmode (insn, CCNOmode)"
8062   "and{b}\t{%2, %h0|%h0, %2}"
8063   [(set_attr "type" "alu")
8064    (set_attr "length_immediate" "1")
8065    (set_attr "modrm" "1")
8066    (set_attr "mode" "QI")])
8067
8068 (define_insn "*andqi_ext_1_rex64"
8069   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8070                          (const_int 8)
8071                          (const_int 8))
8072         (and:SI
8073           (zero_extract:SI
8074             (match_operand 1 "ext_register_operand" "0")
8075             (const_int 8)
8076             (const_int 8))
8077           (zero_extend:SI
8078             (match_operand 2 "ext_register_operand" "Q"))))
8079    (clobber (reg:CC FLAGS_REG))]
8080   "TARGET_64BIT"
8081   "and{b}\t{%2, %h0|%h0, %2}"
8082   [(set_attr "type" "alu")
8083    (set_attr "length_immediate" "0")
8084    (set_attr "mode" "QI")])
8085
8086 (define_insn "*andqi_ext_1"
8087   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8088                          (const_int 8)
8089                          (const_int 8))
8090         (and:SI
8091           (zero_extract:SI
8092             (match_operand 1 "ext_register_operand" "0")
8093             (const_int 8)
8094             (const_int 8))
8095           (zero_extend:SI
8096             (match_operand:QI 2 "general_operand" "Qm"))))
8097    (clobber (reg:CC FLAGS_REG))]
8098   "!TARGET_64BIT"
8099   "and{b}\t{%2, %h0|%h0, %2}"
8100   [(set_attr "type" "alu")
8101    (set_attr "length_immediate" "0")
8102    (set_attr "mode" "QI")])
8103
8104 (define_insn "*andqi_ext_2"
8105   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8106                          (const_int 8)
8107                          (const_int 8))
8108         (and:SI
8109           (zero_extract:SI
8110             (match_operand 1 "ext_register_operand" "%0")
8111             (const_int 8)
8112             (const_int 8))
8113           (zero_extract:SI
8114             (match_operand 2 "ext_register_operand" "Q")
8115             (const_int 8)
8116             (const_int 8))))
8117    (clobber (reg:CC FLAGS_REG))]
8118   ""
8119   "and{b}\t{%h2, %h0|%h0, %h2}"
8120   [(set_attr "type" "alu")
8121    (set_attr "length_immediate" "0")
8122    (set_attr "mode" "QI")])
8123
8124 ;; Convert wide AND instructions with immediate operand to shorter QImode
8125 ;; equivalents when possible.
8126 ;; Don't do the splitting with memory operands, since it introduces risk
8127 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8128 ;; for size, but that can (should?) be handled by generic code instead.
8129 (define_split
8130   [(set (match_operand 0 "register_operand" "")
8131         (and (match_operand 1 "register_operand" "")
8132              (match_operand 2 "const_int_operand" "")))
8133    (clobber (reg:CC FLAGS_REG))]
8134    "reload_completed
8135     && QI_REG_P (operands[0])
8136     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8137     && !(~INTVAL (operands[2]) & ~(255 << 8))
8138     && GET_MODE (operands[0]) != QImode"
8139   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8140                    (and:SI (zero_extract:SI (match_dup 1)
8141                                             (const_int 8) (const_int 8))
8142                            (match_dup 2)))
8143               (clobber (reg:CC FLAGS_REG))])]
8144   "operands[0] = gen_lowpart (SImode, operands[0]);
8145    operands[1] = gen_lowpart (SImode, operands[1]);
8146    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8147
8148 ;; Since AND can be encoded with sign extended immediate, this is only
8149 ;; profitable when 7th bit is not set.
8150 (define_split
8151   [(set (match_operand 0 "register_operand" "")
8152         (and (match_operand 1 "general_operand" "")
8153              (match_operand 2 "const_int_operand" "")))
8154    (clobber (reg:CC FLAGS_REG))]
8155    "reload_completed
8156     && ANY_QI_REG_P (operands[0])
8157     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8158     && !(~INTVAL (operands[2]) & ~255)
8159     && !(INTVAL (operands[2]) & 128)
8160     && GET_MODE (operands[0]) != QImode"
8161   [(parallel [(set (strict_low_part (match_dup 0))
8162                    (and:QI (match_dup 1)
8163                            (match_dup 2)))
8164               (clobber (reg:CC FLAGS_REG))])]
8165   "operands[0] = gen_lowpart (QImode, operands[0]);
8166    operands[1] = gen_lowpart (QImode, operands[1]);
8167    operands[2] = gen_lowpart (QImode, operands[2]);")
8168 \f
8169 ;; Logical inclusive and exclusive OR instructions
8170
8171 ;; %%% This used to optimize known byte-wide and operations to memory.
8172 ;; If this is considered useful, it should be done with splitters.
8173
8174 (define_expand "<code><mode>3"
8175   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8176         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8177                      (match_operand:SWIM 2 "<general_operand>" "")))]
8178   ""
8179   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8180
8181 (define_insn "*<code><mode>_1"
8182   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8183         (any_or:SWI248
8184          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8185          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8186    (clobber (reg:CC FLAGS_REG))]
8187   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8188   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8189   [(set_attr "type" "alu")
8190    (set_attr "mode" "<MODE>")])
8191
8192 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8193 (define_insn "*<code>qi_1"
8194   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8195         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8196                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8199   "@
8200    <logic>{b}\t{%2, %0|%0, %2}
8201    <logic>{b}\t{%2, %0|%0, %2}
8202    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8203   [(set_attr "type" "alu")
8204    (set_attr "mode" "QI,QI,SI")])
8205
8206 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8207 (define_insn "*<code>si_1_zext"
8208   [(set (match_operand:DI 0 "register_operand" "=r")
8209         (zero_extend:DI
8210          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8211                     (match_operand:SI 2 "general_operand" "g"))))
8212    (clobber (reg:CC FLAGS_REG))]
8213   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8214   "<logic>{l}\t{%2, %k0|%k0, %2}"
8215   [(set_attr "type" "alu")
8216    (set_attr "mode" "SI")])
8217
8218 (define_insn "*<code>si_1_zext_imm"
8219   [(set (match_operand:DI 0 "register_operand" "=r")
8220         (any_or:DI
8221          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8222          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8223    (clobber (reg:CC FLAGS_REG))]
8224   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8225   "<logic>{l}\t{%2, %k0|%k0, %2}"
8226   [(set_attr "type" "alu")
8227    (set_attr "mode" "SI")])
8228
8229 (define_insn "*<code>qi_1_slp"
8230   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8231         (any_or:QI (match_dup 0)
8232                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8236   "<logic>{b}\t{%1, %0|%0, %1}"
8237   [(set_attr "type" "alu1")
8238    (set_attr "mode" "QI")])
8239
8240 (define_insn "*<code><mode>_2"
8241   [(set (reg FLAGS_REG)
8242         (compare (any_or:SWI
8243                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8244                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8245                  (const_int 0)))
8246    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8247         (any_or:SWI (match_dup 1) (match_dup 2)))]
8248   "ix86_match_ccmode (insn, CCNOmode)
8249    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8250   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8251   [(set_attr "type" "alu")
8252    (set_attr "mode" "<MODE>")])
8253
8254 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8255 ;; ??? Special case for immediate operand is missing - it is tricky.
8256 (define_insn "*<code>si_2_zext"
8257   [(set (reg FLAGS_REG)
8258         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8259                             (match_operand:SI 2 "general_operand" "g"))
8260                  (const_int 0)))
8261    (set (match_operand:DI 0 "register_operand" "=r")
8262         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8263   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8264    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8265   "<logic>{l}\t{%2, %k0|%k0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "mode" "SI")])
8268
8269 (define_insn "*<code>si_2_zext_imm"
8270   [(set (reg FLAGS_REG)
8271         (compare (any_or:SI
8272                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8273                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8274                  (const_int 0)))
8275    (set (match_operand:DI 0 "register_operand" "=r")
8276         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8277   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8278    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8279   "<logic>{l}\t{%2, %k0|%k0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "mode" "SI")])
8282
8283 (define_insn "*<code>qi_2_slp"
8284   [(set (reg FLAGS_REG)
8285         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8286                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8287                  (const_int 0)))
8288    (set (strict_low_part (match_dup 0))
8289         (any_or:QI (match_dup 0) (match_dup 1)))]
8290   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8291    && ix86_match_ccmode (insn, CCNOmode)
8292    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8293   "<logic>{b}\t{%1, %0|%0, %1}"
8294   [(set_attr "type" "alu1")
8295    (set_attr "mode" "QI")])
8296
8297 (define_insn "*<code><mode>_3"
8298   [(set (reg FLAGS_REG)
8299         (compare (any_or:SWI
8300                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8301                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8302                  (const_int 0)))
8303    (clobber (match_scratch:SWI 0 "=<r>"))]
8304   "ix86_match_ccmode (insn, CCNOmode)
8305    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8306   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8307   [(set_attr "type" "alu")
8308    (set_attr "mode" "<MODE>")])
8309
8310 (define_insn "*<code>qi_ext_0"
8311   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8312                          (const_int 8)
8313                          (const_int 8))
8314         (any_or:SI
8315           (zero_extract:SI
8316             (match_operand 1 "ext_register_operand" "0")
8317             (const_int 8)
8318             (const_int 8))
8319           (match_operand 2 "const_int_operand" "n")))
8320    (clobber (reg:CC FLAGS_REG))]
8321   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8322   "<logic>{b}\t{%2, %h0|%h0, %2}"
8323   [(set_attr "type" "alu")
8324    (set_attr "length_immediate" "1")
8325    (set_attr "modrm" "1")
8326    (set_attr "mode" "QI")])
8327
8328 (define_insn "*<code>qi_ext_1_rex64"
8329   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8330                          (const_int 8)
8331                          (const_int 8))
8332         (any_or:SI
8333           (zero_extract:SI
8334             (match_operand 1 "ext_register_operand" "0")
8335             (const_int 8)
8336             (const_int 8))
8337           (zero_extend:SI
8338             (match_operand 2 "ext_register_operand" "Q"))))
8339    (clobber (reg:CC FLAGS_REG))]
8340   "TARGET_64BIT
8341    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8342   "<logic>{b}\t{%2, %h0|%h0, %2}"
8343   [(set_attr "type" "alu")
8344    (set_attr "length_immediate" "0")
8345    (set_attr "mode" "QI")])
8346
8347 (define_insn "*<code>qi_ext_1"
8348   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8349                          (const_int 8)
8350                          (const_int 8))
8351         (any_or:SI
8352           (zero_extract:SI
8353             (match_operand 1 "ext_register_operand" "0")
8354             (const_int 8)
8355             (const_int 8))
8356           (zero_extend:SI
8357             (match_operand:QI 2 "general_operand" "Qm"))))
8358    (clobber (reg:CC FLAGS_REG))]
8359   "!TARGET_64BIT
8360    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8361   "<logic>{b}\t{%2, %h0|%h0, %2}"
8362   [(set_attr "type" "alu")
8363    (set_attr "length_immediate" "0")
8364    (set_attr "mode" "QI")])
8365
8366 (define_insn "*<code>qi_ext_2"
8367   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8368                          (const_int 8)
8369                          (const_int 8))
8370         (any_or:SI
8371           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8372                            (const_int 8)
8373                            (const_int 8))
8374           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8375                            (const_int 8)
8376                            (const_int 8))))
8377    (clobber (reg:CC FLAGS_REG))]
8378   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8379   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8380   [(set_attr "type" "alu")
8381    (set_attr "length_immediate" "0")
8382    (set_attr "mode" "QI")])
8383
8384 (define_split
8385   [(set (match_operand 0 "register_operand" "")
8386         (any_or (match_operand 1 "register_operand" "")
8387                 (match_operand 2 "const_int_operand" "")))
8388    (clobber (reg:CC FLAGS_REG))]
8389    "reload_completed
8390     && QI_REG_P (operands[0])
8391     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8392     && !(INTVAL (operands[2]) & ~(255 << 8))
8393     && GET_MODE (operands[0]) != QImode"
8394   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8395                    (any_or:SI (zero_extract:SI (match_dup 1)
8396                                                (const_int 8) (const_int 8))
8397                               (match_dup 2)))
8398               (clobber (reg:CC FLAGS_REG))])]
8399   "operands[0] = gen_lowpart (SImode, operands[0]);
8400    operands[1] = gen_lowpart (SImode, operands[1]);
8401    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8402
8403 ;; Since OR can be encoded with sign extended immediate, this is only
8404 ;; profitable when 7th bit is set.
8405 (define_split
8406   [(set (match_operand 0 "register_operand" "")
8407         (any_or (match_operand 1 "general_operand" "")
8408                 (match_operand 2 "const_int_operand" "")))
8409    (clobber (reg:CC FLAGS_REG))]
8410    "reload_completed
8411     && ANY_QI_REG_P (operands[0])
8412     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413     && !(INTVAL (operands[2]) & ~255)
8414     && (INTVAL (operands[2]) & 128)
8415     && GET_MODE (operands[0]) != QImode"
8416   [(parallel [(set (strict_low_part (match_dup 0))
8417                    (any_or:QI (match_dup 1)
8418                               (match_dup 2)))
8419               (clobber (reg:CC FLAGS_REG))])]
8420   "operands[0] = gen_lowpart (QImode, operands[0]);
8421    operands[1] = gen_lowpart (QImode, operands[1]);
8422    operands[2] = gen_lowpart (QImode, operands[2]);")
8423
8424 (define_expand "xorqi_cc_ext_1"
8425   [(parallel [
8426      (set (reg:CCNO FLAGS_REG)
8427           (compare:CCNO
8428             (xor:SI
8429               (zero_extract:SI
8430                 (match_operand 1 "ext_register_operand" "")
8431                 (const_int 8)
8432                 (const_int 8))
8433               (match_operand:QI 2 "general_operand" ""))
8434             (const_int 0)))
8435      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8436                            (const_int 8)
8437                            (const_int 8))
8438           (xor:SI
8439             (zero_extract:SI
8440              (match_dup 1)
8441              (const_int 8)
8442              (const_int 8))
8443             (match_dup 2)))])]
8444   ""
8445   "")
8446
8447 (define_insn "*xorqi_cc_ext_1_rex64"
8448   [(set (reg FLAGS_REG)
8449         (compare
8450           (xor:SI
8451             (zero_extract:SI
8452               (match_operand 1 "ext_register_operand" "0")
8453               (const_int 8)
8454               (const_int 8))
8455             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8456           (const_int 0)))
8457    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8458                          (const_int 8)
8459                          (const_int 8))
8460         (xor:SI
8461           (zero_extract:SI
8462            (match_dup 1)
8463            (const_int 8)
8464            (const_int 8))
8465           (match_dup 2)))]
8466   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8467   "xor{b}\t{%2, %h0|%h0, %2}"
8468   [(set_attr "type" "alu")
8469    (set_attr "modrm" "1")
8470    (set_attr "mode" "QI")])
8471
8472 (define_insn "*xorqi_cc_ext_1"
8473   [(set (reg FLAGS_REG)
8474         (compare
8475           (xor:SI
8476             (zero_extract:SI
8477               (match_operand 1 "ext_register_operand" "0")
8478               (const_int 8)
8479               (const_int 8))
8480             (match_operand:QI 2 "general_operand" "qmn"))
8481           (const_int 0)))
8482    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8483                          (const_int 8)
8484                          (const_int 8))
8485         (xor:SI
8486           (zero_extract:SI
8487            (match_dup 1)
8488            (const_int 8)
8489            (const_int 8))
8490           (match_dup 2)))]
8491   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8492   "xor{b}\t{%2, %h0|%h0, %2}"
8493   [(set_attr "type" "alu")
8494    (set_attr "modrm" "1")
8495    (set_attr "mode" "QI")])
8496 \f
8497 ;; Negation instructions
8498
8499 (define_expand "neg<mode>2"
8500   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8501         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8502   ""
8503   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8504
8505 (define_insn_and_split "*neg<dwi>2_doubleword"
8506   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8507         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8508    (clobber (reg:CC FLAGS_REG))]
8509   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8510   "#"
8511   "reload_completed"
8512   [(parallel
8513     [(set (reg:CCZ FLAGS_REG)
8514           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8515      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8516    (parallel
8517     [(set (match_dup 2)
8518           (plus:DWIH (match_dup 3)
8519                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8520                                 (const_int 0))))
8521      (clobber (reg:CC FLAGS_REG))])
8522    (parallel
8523     [(set (match_dup 2)
8524           (neg:DWIH (match_dup 2)))
8525      (clobber (reg:CC FLAGS_REG))])]
8526   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8527
8528 (define_insn "*neg<mode>2_1"
8529   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8530         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8533   "neg{<imodesuffix>}\t%0"
8534   [(set_attr "type" "negnot")
8535    (set_attr "mode" "<MODE>")])
8536
8537 ;; Combine is quite creative about this pattern.
8538 (define_insn "*negsi2_1_zext"
8539   [(set (match_operand:DI 0 "register_operand" "=r")
8540         (lshiftrt:DI
8541           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8542                              (const_int 32)))
8543         (const_int 32)))
8544    (clobber (reg:CC FLAGS_REG))]
8545   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8546   "neg{l}\t%k0"
8547   [(set_attr "type" "negnot")
8548    (set_attr "mode" "SI")])
8549
8550 ;; The problem with neg is that it does not perform (compare x 0),
8551 ;; it really performs (compare 0 x), which leaves us with the zero
8552 ;; flag being the only useful item.
8553
8554 (define_insn "*neg<mode>2_cmpz"
8555   [(set (reg:CCZ FLAGS_REG)
8556         (compare:CCZ
8557           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8558                    (const_int 0)))
8559    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8560         (neg:SWI (match_dup 1)))]
8561   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8562   "neg{<imodesuffix>}\t%0"
8563   [(set_attr "type" "negnot")
8564    (set_attr "mode" "<MODE>")])
8565
8566 (define_insn "*negsi2_cmpz_zext"
8567   [(set (reg:CCZ FLAGS_REG)
8568         (compare:CCZ
8569           (lshiftrt:DI
8570             (neg:DI (ashift:DI
8571                       (match_operand:DI 1 "register_operand" "0")
8572                       (const_int 32)))
8573             (const_int 32))
8574           (const_int 0)))
8575    (set (match_operand:DI 0 "register_operand" "=r")
8576         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8577                                         (const_int 32)))
8578                      (const_int 32)))]
8579   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8580   "neg{l}\t%k0"
8581   [(set_attr "type" "negnot")
8582    (set_attr "mode" "SI")])
8583
8584 ;; Changing of sign for FP values is doable using integer unit too.
8585
8586 (define_expand "<code><mode>2"
8587   [(set (match_operand:X87MODEF 0 "register_operand" "")
8588         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8589   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8590   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8591
8592 (define_insn "*absneg<mode>2_mixed"
8593   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8594         (match_operator:MODEF 3 "absneg_operator"
8595           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8596    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8597    (clobber (reg:CC FLAGS_REG))]
8598   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8599   "#")
8600
8601 (define_insn "*absneg<mode>2_sse"
8602   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8603         (match_operator:MODEF 3 "absneg_operator"
8604           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8605    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8606    (clobber (reg:CC FLAGS_REG))]
8607   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8608   "#")
8609
8610 (define_insn "*absneg<mode>2_i387"
8611   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8612         (match_operator:X87MODEF 3 "absneg_operator"
8613           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8614    (use (match_operand 2 "" ""))
8615    (clobber (reg:CC FLAGS_REG))]
8616   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8617   "#")
8618
8619 (define_expand "<code>tf2"
8620   [(set (match_operand:TF 0 "register_operand" "")
8621         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8622   "TARGET_SSE2"
8623   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8624
8625 (define_insn "*absnegtf2_sse"
8626   [(set (match_operand:TF 0 "register_operand" "=x,x")
8627         (match_operator:TF 3 "absneg_operator"
8628           [(match_operand:TF 1 "register_operand" "0,x")]))
8629    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "TARGET_SSE2"
8632   "#")
8633
8634 ;; Splitters for fp abs and neg.
8635
8636 (define_split
8637   [(set (match_operand 0 "fp_register_operand" "")
8638         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8639    (use (match_operand 2 "" ""))
8640    (clobber (reg:CC FLAGS_REG))]
8641   "reload_completed"
8642   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8643
8644 (define_split
8645   [(set (match_operand 0 "register_operand" "")
8646         (match_operator 3 "absneg_operator"
8647           [(match_operand 1 "register_operand" "")]))
8648    (use (match_operand 2 "nonimmediate_operand" ""))
8649    (clobber (reg:CC FLAGS_REG))]
8650   "reload_completed && SSE_REG_P (operands[0])"
8651   [(set (match_dup 0) (match_dup 3))]
8652 {
8653   enum machine_mode mode = GET_MODE (operands[0]);
8654   enum machine_mode vmode = GET_MODE (operands[2]);
8655   rtx tmp;
8656
8657   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8658   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8659   if (operands_match_p (operands[0], operands[2]))
8660     {
8661       tmp = operands[1];
8662       operands[1] = operands[2];
8663       operands[2] = tmp;
8664     }
8665   if (GET_CODE (operands[3]) == ABS)
8666     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8667   else
8668     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8669   operands[3] = tmp;
8670 })
8671
8672 (define_split
8673   [(set (match_operand:SF 0 "register_operand" "")
8674         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8675    (use (match_operand:V4SF 2 "" ""))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "reload_completed"
8678   [(parallel [(set (match_dup 0) (match_dup 1))
8679               (clobber (reg:CC FLAGS_REG))])]
8680 {
8681   rtx tmp;
8682   operands[0] = gen_lowpart (SImode, operands[0]);
8683   if (GET_CODE (operands[1]) == ABS)
8684     {
8685       tmp = gen_int_mode (0x7fffffff, SImode);
8686       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8687     }
8688   else
8689     {
8690       tmp = gen_int_mode (0x80000000, SImode);
8691       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8692     }
8693   operands[1] = tmp;
8694 })
8695
8696 (define_split
8697   [(set (match_operand:DF 0 "register_operand" "")
8698         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8699    (use (match_operand 2 "" ""))
8700    (clobber (reg:CC FLAGS_REG))]
8701   "reload_completed"
8702   [(parallel [(set (match_dup 0) (match_dup 1))
8703               (clobber (reg:CC FLAGS_REG))])]
8704 {
8705   rtx tmp;
8706   if (TARGET_64BIT)
8707     {
8708       tmp = gen_lowpart (DImode, operands[0]);
8709       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8710       operands[0] = tmp;
8711
8712       if (GET_CODE (operands[1]) == ABS)
8713         tmp = const0_rtx;
8714       else
8715         tmp = gen_rtx_NOT (DImode, tmp);
8716     }
8717   else
8718     {
8719       operands[0] = gen_highpart (SImode, operands[0]);
8720       if (GET_CODE (operands[1]) == ABS)
8721         {
8722           tmp = gen_int_mode (0x7fffffff, SImode);
8723           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8724         }
8725       else
8726         {
8727           tmp = gen_int_mode (0x80000000, SImode);
8728           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8729         }
8730     }
8731   operands[1] = tmp;
8732 })
8733
8734 (define_split
8735   [(set (match_operand:XF 0 "register_operand" "")
8736         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8737    (use (match_operand 2 "" ""))
8738    (clobber (reg:CC FLAGS_REG))]
8739   "reload_completed"
8740   [(parallel [(set (match_dup 0) (match_dup 1))
8741               (clobber (reg:CC FLAGS_REG))])]
8742 {
8743   rtx tmp;
8744   operands[0] = gen_rtx_REG (SImode,
8745                              true_regnum (operands[0])
8746                              + (TARGET_64BIT ? 1 : 2));
8747   if (GET_CODE (operands[1]) == ABS)
8748     {
8749       tmp = GEN_INT (0x7fff);
8750       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8751     }
8752   else
8753     {
8754       tmp = GEN_INT (0x8000);
8755       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8756     }
8757   operands[1] = tmp;
8758 })
8759
8760 ;; Conditionalize these after reload. If they match before reload, we
8761 ;; lose the clobber and ability to use integer instructions.
8762
8763 (define_insn "*<code><mode>2_1"
8764   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8765         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8766   "TARGET_80387
8767    && (reload_completed
8768        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8769   "f<absneg_mnemonic>"
8770   [(set_attr "type" "fsgn")
8771    (set_attr "mode" "<MODE>")])
8772
8773 (define_insn "*<code>extendsfdf2"
8774   [(set (match_operand:DF 0 "register_operand" "=f")
8775         (absneg:DF (float_extend:DF
8776                      (match_operand:SF 1 "register_operand" "0"))))]
8777   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8778   "f<absneg_mnemonic>"
8779   [(set_attr "type" "fsgn")
8780    (set_attr "mode" "DF")])
8781
8782 (define_insn "*<code>extendsfxf2"
8783   [(set (match_operand:XF 0 "register_operand" "=f")
8784         (absneg:XF (float_extend:XF
8785                      (match_operand:SF 1 "register_operand" "0"))))]
8786   "TARGET_80387"
8787   "f<absneg_mnemonic>"
8788   [(set_attr "type" "fsgn")
8789    (set_attr "mode" "XF")])
8790
8791 (define_insn "*<code>extenddfxf2"
8792   [(set (match_operand:XF 0 "register_operand" "=f")
8793         (absneg:XF (float_extend:XF
8794                      (match_operand:DF 1 "register_operand" "0"))))]
8795   "TARGET_80387"
8796   "f<absneg_mnemonic>"
8797   [(set_attr "type" "fsgn")
8798    (set_attr "mode" "XF")])
8799
8800 ;; Copysign instructions
8801
8802 (define_mode_iterator CSGNMODE [SF DF TF])
8803 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8804
8805 (define_expand "copysign<mode>3"
8806   [(match_operand:CSGNMODE 0 "register_operand" "")
8807    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8808    (match_operand:CSGNMODE 2 "register_operand" "")]
8809   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8811   "ix86_expand_copysign (operands); DONE;")
8812
8813 (define_insn_and_split "copysign<mode>3_const"
8814   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8815         (unspec:CSGNMODE
8816           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8817            (match_operand:CSGNMODE 2 "register_operand" "0")
8818            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8819           UNSPEC_COPYSIGN))]
8820   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8821    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8822   "#"
8823   "&& reload_completed"
8824   [(const_int 0)]
8825   "ix86_split_copysign_const (operands); DONE;")
8826
8827 (define_insn "copysign<mode>3_var"
8828   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8829         (unspec:CSGNMODE
8830           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8831            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8832            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8833            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8834           UNSPEC_COPYSIGN))
8835    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8836   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8838   "#")
8839
8840 (define_split
8841   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8842         (unspec:CSGNMODE
8843           [(match_operand:CSGNMODE 2 "register_operand" "")
8844            (match_operand:CSGNMODE 3 "register_operand" "")
8845            (match_operand:<CSGNVMODE> 4 "" "")
8846            (match_operand:<CSGNVMODE> 5 "" "")]
8847           UNSPEC_COPYSIGN))
8848    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8849   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8850     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8851    && reload_completed"
8852   [(const_int 0)]
8853   "ix86_split_copysign_var (operands); DONE;")
8854 \f
8855 ;; One complement instructions
8856
8857 (define_expand "one_cmpl<mode>2"
8858   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8859         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8860   ""
8861   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8862
8863 (define_insn "*one_cmpl<mode>2_1"
8864   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8865         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8866   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8867   "not{<imodesuffix>}\t%0"
8868   [(set_attr "type" "negnot")
8869    (set_attr "mode" "<MODE>")])
8870
8871 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8872 (define_insn "*one_cmplqi2_1"
8873   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8874         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8875   "ix86_unary_operator_ok (NOT, QImode, operands)"
8876   "@
8877    not{b}\t%0
8878    not{l}\t%k0"
8879   [(set_attr "type" "negnot")
8880    (set_attr "mode" "QI,SI")])
8881
8882 ;; ??? Currently never generated - xor is used instead.
8883 (define_insn "*one_cmplsi2_1_zext"
8884   [(set (match_operand:DI 0 "register_operand" "=r")
8885         (zero_extend:DI
8886           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8887   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8888   "not{l}\t%k0"
8889   [(set_attr "type" "negnot")
8890    (set_attr "mode" "SI")])
8891
8892 (define_insn "*one_cmpl<mode>2_2"
8893   [(set (reg FLAGS_REG)
8894         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8895                  (const_int 0)))
8896    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8897         (not:SWI (match_dup 1)))]
8898   "ix86_match_ccmode (insn, CCNOmode)
8899    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8900   "#"
8901   [(set_attr "type" "alu1")
8902    (set_attr "mode" "<MODE>")])
8903
8904 (define_split
8905   [(set (match_operand 0 "flags_reg_operand" "")
8906         (match_operator 2 "compare_operator"
8907           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8908            (const_int 0)]))
8909    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8910         (not:SWI (match_dup 3)))]
8911   "ix86_match_ccmode (insn, CCNOmode)"
8912   [(parallel [(set (match_dup 0)
8913                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8914                                     (const_int 0)]))
8915               (set (match_dup 1)
8916                    (xor:SWI (match_dup 3) (const_int -1)))])])
8917
8918 ;; ??? Currently never generated - xor is used instead.
8919 (define_insn "*one_cmplsi2_2_zext"
8920   [(set (reg FLAGS_REG)
8921         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8922                  (const_int 0)))
8923    (set (match_operand:DI 0 "register_operand" "=r")
8924         (zero_extend:DI (not:SI (match_dup 1))))]
8925   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8926    && ix86_unary_operator_ok (NOT, SImode, operands)"
8927   "#"
8928   [(set_attr "type" "alu1")
8929    (set_attr "mode" "SI")])
8930
8931 (define_split
8932   [(set (match_operand 0 "flags_reg_operand" "")
8933         (match_operator 2 "compare_operator"
8934           [(not:SI (match_operand:SI 3 "register_operand" ""))
8935            (const_int 0)]))
8936    (set (match_operand:DI 1 "register_operand" "")
8937         (zero_extend:DI (not:SI (match_dup 3))))]
8938   "ix86_match_ccmode (insn, CCNOmode)"
8939   [(parallel [(set (match_dup 0)
8940                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8941                                     (const_int 0)]))
8942               (set (match_dup 1)
8943                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8944 \f
8945 ;; Shift instructions
8946
8947 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8948 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8949 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8950 ;; from the assembler input.
8951 ;;
8952 ;; This instruction shifts the target reg/mem as usual, but instead of
8953 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8954 ;; is a left shift double, bits are taken from the high order bits of
8955 ;; reg, else if the insn is a shift right double, bits are taken from the
8956 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8957 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8958 ;;
8959 ;; Since sh[lr]d does not change the `reg' operand, that is done
8960 ;; separately, making all shifts emit pairs of shift double and normal
8961 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8962 ;; support a 63 bit shift, each shift where the count is in a reg expands
8963 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8964 ;;
8965 ;; If the shift count is a constant, we need never emit more than one
8966 ;; shift pair, instead using moves and sign extension for counts greater
8967 ;; than 31.
8968
8969 (define_expand "ashl<mode>3"
8970   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8971         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8972                       (match_operand:QI 2 "nonmemory_operand" "")))]
8973   ""
8974   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8975
8976 (define_insn "*ashl<mode>3_doubleword"
8977   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8978         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8979                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8980    (clobber (reg:CC FLAGS_REG))]
8981   ""
8982   "#"
8983   [(set_attr "type" "multi")])
8984
8985 (define_split
8986   [(set (match_operand:DWI 0 "register_operand" "")
8987         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8988                     (match_operand:QI 2 "nonmemory_operand" "")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8991   [(const_int 0)]
8992   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8993
8994 ;; By default we don't ask for a scratch register, because when DWImode
8995 ;; values are manipulated, registers are already at a premium.  But if
8996 ;; we have one handy, we won't turn it away.
8997
8998 (define_peephole2
8999   [(match_scratch:DWIH 3 "r")
9000    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9001                    (ashift:<DWI>
9002                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9003                      (match_operand:QI 2 "nonmemory_operand" "")))
9004               (clobber (reg:CC FLAGS_REG))])
9005    (match_dup 3)]
9006   "TARGET_CMOVE"
9007   [(const_int 0)]
9008   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9009
9010 (define_insn "x86_64_shld"
9011   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9012         (ior:DI (ashift:DI (match_dup 0)
9013                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9014                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9015                   (minus:QI (const_int 64) (match_dup 2)))))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "TARGET_64BIT"
9018   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9019   [(set_attr "type" "ishift")
9020    (set_attr "prefix_0f" "1")
9021    (set_attr "mode" "DI")
9022    (set_attr "athlon_decode" "vector")
9023    (set_attr "amdfam10_decode" "vector")])
9024
9025 (define_insn "x86_shld"
9026   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9027         (ior:SI (ashift:SI (match_dup 0)
9028                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9029                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9030                   (minus:QI (const_int 32) (match_dup 2)))))
9031    (clobber (reg:CC FLAGS_REG))]
9032   ""
9033   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9034   [(set_attr "type" "ishift")
9035    (set_attr "prefix_0f" "1")
9036    (set_attr "mode" "SI")
9037    (set_attr "pent_pair" "np")
9038    (set_attr "athlon_decode" "vector")
9039    (set_attr "amdfam10_decode" "vector")])
9040
9041 (define_expand "x86_shift<mode>_adj_1"
9042   [(set (reg:CCZ FLAGS_REG)
9043         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9044                              (match_dup 4))
9045                      (const_int 0)))
9046    (set (match_operand:SWI48 0 "register_operand" "")
9047         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9048                             (match_operand:SWI48 1 "register_operand" "")
9049                             (match_dup 0)))
9050    (set (match_dup 1)
9051         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9052                             (match_operand:SWI48 3 "register_operand" "r")
9053                             (match_dup 1)))]
9054   "TARGET_CMOVE"
9055   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9056
9057 (define_expand "x86_shift<mode>_adj_2"
9058   [(use (match_operand:SWI48 0 "register_operand" ""))
9059    (use (match_operand:SWI48 1 "register_operand" ""))
9060    (use (match_operand:QI 2 "register_operand" ""))]
9061   ""
9062 {
9063   rtx label = gen_label_rtx ();
9064   rtx tmp;
9065
9066   emit_insn (gen_testqi_ccz_1 (operands[2],
9067                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9068
9069   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9070   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9071   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9072                               gen_rtx_LABEL_REF (VOIDmode, label),
9073                               pc_rtx);
9074   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9075   JUMP_LABEL (tmp) = label;
9076
9077   emit_move_insn (operands[0], operands[1]);
9078   ix86_expand_clear (operands[1]);
9079
9080   emit_label (label);
9081   LABEL_NUSES (label) = 1;
9082
9083   DONE;
9084 })
9085
9086 (define_insn "*ashl<mode>3_1"
9087   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9088         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9089                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9090    (clobber (reg:CC FLAGS_REG))]
9091   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9092 {
9093   switch (get_attr_type (insn))
9094     {
9095     case TYPE_LEA:
9096       return "#";
9097
9098     case TYPE_ALU:
9099       gcc_assert (operands[2] == const1_rtx);
9100       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9101       return "add{<imodesuffix>}\t%0, %0";
9102
9103     default:
9104       if (operands[2] == const1_rtx
9105           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9106         return "sal{<imodesuffix>}\t%0";
9107       else
9108         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9109     }
9110 }
9111   [(set (attr "type")
9112      (cond [(eq_attr "alternative" "1")
9113               (const_string "lea")
9114             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9115                           (const_int 0))
9116                       (match_operand 0 "register_operand" ""))
9117                  (match_operand 2 "const1_operand" ""))
9118               (const_string "alu")
9119            ]
9120            (const_string "ishift")))
9121    (set (attr "length_immediate")
9122      (if_then_else
9123        (ior (eq_attr "type" "alu")
9124             (and (eq_attr "type" "ishift")
9125                  (and (match_operand 2 "const1_operand" "")
9126                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9127                           (const_int 0)))))
9128        (const_string "0")
9129        (const_string "*")))
9130    (set_attr "mode" "<MODE>")])
9131
9132 (define_insn "*ashlsi3_1_zext"
9133   [(set (match_operand:DI 0 "register_operand" "=r,r")
9134         (zero_extend:DI
9135           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9136                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9139 {
9140   switch (get_attr_type (insn))
9141     {
9142     case TYPE_LEA:
9143       return "#";
9144
9145     case TYPE_ALU:
9146       gcc_assert (operands[2] == const1_rtx);
9147       return "add{l}\t%k0, %k0";
9148
9149     default:
9150       if (operands[2] == const1_rtx
9151           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9152         return "sal{l}\t%k0";
9153       else
9154         return "sal{l}\t{%2, %k0|%k0, %2}";
9155     }
9156 }
9157   [(set (attr "type")
9158      (cond [(eq_attr "alternative" "1")
9159               (const_string "lea")
9160             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9161                      (const_int 0))
9162                  (match_operand 2 "const1_operand" ""))
9163               (const_string "alu")
9164            ]
9165            (const_string "ishift")))
9166    (set (attr "length_immediate")
9167      (if_then_else
9168        (ior (eq_attr "type" "alu")
9169             (and (eq_attr "type" "ishift")
9170                  (and (match_operand 2 "const1_operand" "")
9171                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9172                           (const_int 0)))))
9173        (const_string "0")
9174        (const_string "*")))
9175    (set_attr "mode" "SI")])
9176
9177 (define_insn "*ashlhi3_1"
9178   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9179         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9180                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9181    (clobber (reg:CC FLAGS_REG))]
9182   "TARGET_PARTIAL_REG_STALL
9183    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9184 {
9185   switch (get_attr_type (insn))
9186     {
9187     case TYPE_ALU:
9188       gcc_assert (operands[2] == const1_rtx);
9189       return "add{w}\t%0, %0";
9190
9191     default:
9192       if (operands[2] == const1_rtx
9193           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9194         return "sal{w}\t%0";
9195       else
9196         return "sal{w}\t{%2, %0|%0, %2}";
9197     }
9198 }
9199   [(set (attr "type")
9200      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9201                           (const_int 0))
9202                       (match_operand 0 "register_operand" ""))
9203                  (match_operand 2 "const1_operand" ""))
9204               (const_string "alu")
9205            ]
9206            (const_string "ishift")))
9207    (set (attr "length_immediate")
9208      (if_then_else
9209        (ior (eq_attr "type" "alu")
9210             (and (eq_attr "type" "ishift")
9211                  (and (match_operand 2 "const1_operand" "")
9212                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9213                           (const_int 0)))))
9214        (const_string "0")
9215        (const_string "*")))
9216    (set_attr "mode" "HI")])
9217
9218 (define_insn "*ashlhi3_1_lea"
9219   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9220         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9221                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9222    (clobber (reg:CC FLAGS_REG))]
9223   "!TARGET_PARTIAL_REG_STALL
9224    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9225 {
9226   switch (get_attr_type (insn))
9227     {
9228     case TYPE_LEA:
9229       return "#";
9230
9231     case TYPE_ALU:
9232       gcc_assert (operands[2] == const1_rtx);
9233       return "add{w}\t%0, %0";
9234
9235     default:
9236       if (operands[2] == const1_rtx
9237           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9238         return "sal{w}\t%0";
9239       else
9240         return "sal{w}\t{%2, %0|%0, %2}";
9241     }
9242 }
9243   [(set (attr "type")
9244      (cond [(eq_attr "alternative" "1")
9245               (const_string "lea")
9246             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9247                           (const_int 0))
9248                       (match_operand 0 "register_operand" ""))
9249                  (match_operand 2 "const1_operand" ""))
9250               (const_string "alu")
9251            ]
9252            (const_string "ishift")))
9253    (set (attr "length_immediate")
9254      (if_then_else
9255        (ior (eq_attr "type" "alu")
9256             (and (eq_attr "type" "ishift")
9257                  (and (match_operand 2 "const1_operand" "")
9258                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9259                           (const_int 0)))))
9260        (const_string "0")
9261        (const_string "*")))
9262    (set_attr "mode" "HI,SI")])
9263
9264 (define_insn "*ashlqi3_1"
9265   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9266         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9267                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9268    (clobber (reg:CC FLAGS_REG))]
9269   "TARGET_PARTIAL_REG_STALL
9270    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9271 {
9272   switch (get_attr_type (insn))
9273     {
9274     case TYPE_ALU:
9275       gcc_assert (operands[2] == const1_rtx);
9276       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9277         return "add{l}\t%k0, %k0";
9278       else
9279         return "add{b}\t%0, %0";
9280
9281     default:
9282       if (operands[2] == const1_rtx
9283           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9284         {
9285           if (get_attr_mode (insn) == MODE_SI)
9286             return "sal{l}\t%k0";
9287           else
9288             return "sal{b}\t%0";
9289         }
9290       else
9291         {
9292           if (get_attr_mode (insn) == MODE_SI)
9293             return "sal{l}\t{%2, %k0|%k0, %2}";
9294           else
9295             return "sal{b}\t{%2, %0|%0, %2}";
9296         }
9297     }
9298 }
9299   [(set (attr "type")
9300      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9301                           (const_int 0))
9302                       (match_operand 0 "register_operand" ""))
9303                  (match_operand 2 "const1_operand" ""))
9304               (const_string "alu")
9305            ]
9306            (const_string "ishift")))
9307    (set (attr "length_immediate")
9308      (if_then_else
9309        (ior (eq_attr "type" "alu")
9310             (and (eq_attr "type" "ishift")
9311                  (and (match_operand 2 "const1_operand" "")
9312                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9313                           (const_int 0)))))
9314        (const_string "0")
9315        (const_string "*")))
9316    (set_attr "mode" "QI,SI")])
9317
9318 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9319 (define_insn "*ashlqi3_1_lea"
9320   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9321         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9322                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9323    (clobber (reg:CC FLAGS_REG))]
9324   "!TARGET_PARTIAL_REG_STALL
9325    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9326 {
9327   switch (get_attr_type (insn))
9328     {
9329     case TYPE_LEA:
9330       return "#";
9331
9332     case TYPE_ALU:
9333       gcc_assert (operands[2] == const1_rtx);
9334       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9335         return "add{l}\t%k0, %k0";
9336       else
9337         return "add{b}\t%0, %0";
9338
9339     default:
9340       if (operands[2] == const1_rtx
9341           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9342         {
9343           if (get_attr_mode (insn) == MODE_SI)
9344             return "sal{l}\t%k0";
9345           else
9346             return "sal{b}\t%0";
9347         }
9348       else
9349         {
9350           if (get_attr_mode (insn) == MODE_SI)
9351             return "sal{l}\t{%2, %k0|%k0, %2}";
9352           else
9353             return "sal{b}\t{%2, %0|%0, %2}";
9354         }
9355     }
9356 }
9357   [(set (attr "type")
9358      (cond [(eq_attr "alternative" "2")
9359               (const_string "lea")
9360             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9361                           (const_int 0))
9362                       (match_operand 0 "register_operand" ""))
9363                  (match_operand 2 "const1_operand" ""))
9364               (const_string "alu")
9365            ]
9366            (const_string "ishift")))
9367    (set (attr "length_immediate")
9368      (if_then_else
9369        (ior (eq_attr "type" "alu")
9370             (and (eq_attr "type" "ishift")
9371                  (and (match_operand 2 "const1_operand" "")
9372                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9373                           (const_int 0)))))
9374        (const_string "0")
9375        (const_string "*")))
9376    (set_attr "mode" "QI,SI,SI")])
9377
9378 (define_insn "*ashlqi3_1_slp"
9379   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9380         (ashift:QI (match_dup 0)
9381                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "(optimize_function_for_size_p (cfun)
9384     || !TARGET_PARTIAL_FLAG_REG_STALL
9385     || (operands[1] == const1_rtx
9386         && (TARGET_SHIFT1
9387             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9388 {
9389   switch (get_attr_type (insn))
9390     {
9391     case TYPE_ALU:
9392       gcc_assert (operands[1] == const1_rtx);
9393       return "add{b}\t%0, %0";
9394
9395     default:
9396       if (operands[1] == const1_rtx
9397           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9398         return "sal{b}\t%0";
9399       else
9400         return "sal{b}\t{%1, %0|%0, %1}";
9401     }
9402 }
9403   [(set (attr "type")
9404      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9405                           (const_int 0))
9406                       (match_operand 0 "register_operand" ""))
9407                  (match_operand 1 "const1_operand" ""))
9408               (const_string "alu")
9409            ]
9410            (const_string "ishift1")))
9411    (set (attr "length_immediate")
9412      (if_then_else
9413        (ior (eq_attr "type" "alu")
9414             (and (eq_attr "type" "ishift1")
9415                  (and (match_operand 1 "const1_operand" "")
9416                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9417                           (const_int 0)))))
9418        (const_string "0")
9419        (const_string "*")))
9420    (set_attr "mode" "QI")])
9421
9422 ;; Convert lea to the lea pattern to avoid flags dependency.
9423 (define_split
9424   [(set (match_operand 0 "register_operand" "")
9425         (ashift (match_operand 1 "index_register_operand" "")
9426                 (match_operand:QI 2 "const_int_operand" "")))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "reload_completed
9429    && true_regnum (operands[0]) != true_regnum (operands[1])"
9430   [(const_int 0)]
9431 {
9432   rtx pat;
9433   enum machine_mode mode = GET_MODE (operands[0]);
9434
9435   if (mode != Pmode)
9436     operands[1] = gen_lowpart (Pmode, operands[1]);
9437   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9438
9439   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9440
9441   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9442     operands[0] = gen_lowpart (SImode, operands[0]);
9443
9444   if (TARGET_64BIT && mode != Pmode)
9445     pat = gen_rtx_SUBREG (SImode, pat, 0);
9446
9447   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9448   DONE;
9449 })
9450
9451 ;; Convert lea to the lea pattern to avoid flags dependency.
9452 (define_split
9453   [(set (match_operand:DI 0 "register_operand" "")
9454         (zero_extend:DI
9455           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9456                      (match_operand:QI 2 "const_int_operand" ""))))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "TARGET_64BIT && reload_completed
9459    && true_regnum (operands[0]) != true_regnum (operands[1])"
9460   [(set (match_dup 0)
9461         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9462 {
9463   operands[1] = gen_lowpart (DImode, operands[1]);
9464   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9465 })
9466
9467 ;; This pattern can't accept a variable shift count, since shifts by
9468 ;; zero don't affect the flags.  We assume that shifts by constant
9469 ;; zero are optimized away.
9470 (define_insn "*ashl<mode>3_cmp"
9471   [(set (reg FLAGS_REG)
9472         (compare
9473           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9474                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9475           (const_int 0)))
9476    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9477         (ashift:SWI (match_dup 1) (match_dup 2)))]
9478   "(optimize_function_for_size_p (cfun)
9479     || !TARGET_PARTIAL_FLAG_REG_STALL
9480     || (operands[2] == const1_rtx
9481         && (TARGET_SHIFT1
9482             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9483    && ix86_match_ccmode (insn, CCGOCmode)
9484    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9485 {
9486   switch (get_attr_type (insn))
9487     {
9488     case TYPE_ALU:
9489       gcc_assert (operands[2] == const1_rtx);
9490       return "add{<imodesuffix>}\t%0, %0";
9491
9492     default:
9493       if (operands[2] == const1_rtx
9494           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9495         return "sal{<imodesuffix>}\t%0";
9496       else
9497         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9498     }
9499 }
9500   [(set (attr "type")
9501      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9502                           (const_int 0))
9503                       (match_operand 0 "register_operand" ""))
9504                  (match_operand 2 "const1_operand" ""))
9505               (const_string "alu")
9506            ]
9507            (const_string "ishift")))
9508    (set (attr "length_immediate")
9509      (if_then_else
9510        (ior (eq_attr "type" "alu")
9511             (and (eq_attr "type" "ishift")
9512                  (and (match_operand 2 "const1_operand" "")
9513                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9514                           (const_int 0)))))
9515        (const_string "0")
9516        (const_string "*")))
9517    (set_attr "mode" "<MODE>")])
9518
9519 (define_insn "*ashlsi3_cmp_zext"
9520   [(set (reg FLAGS_REG)
9521         (compare
9522           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9523                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9524           (const_int 0)))
9525    (set (match_operand:DI 0 "register_operand" "=r")
9526         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9527   "TARGET_64BIT
9528    && (optimize_function_for_size_p (cfun)
9529        || !TARGET_PARTIAL_FLAG_REG_STALL
9530        || (operands[2] == const1_rtx
9531            && (TARGET_SHIFT1
9532                || TARGET_DOUBLE_WITH_ADD)))
9533    && ix86_match_ccmode (insn, CCGOCmode)
9534    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9535 {
9536   switch (get_attr_type (insn))
9537     {
9538     case TYPE_ALU:
9539       gcc_assert (operands[2] == const1_rtx);
9540       return "add{l}\t%k0, %k0";
9541
9542     default:
9543       if (operands[2] == const1_rtx
9544           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9545         return "sal{l}\t%k0";
9546       else
9547         return "sal{l}\t{%2, %k0|%k0, %2}";
9548     }
9549 }
9550   [(set (attr "type")
9551      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9552                      (const_int 0))
9553                  (match_operand 2 "const1_operand" ""))
9554               (const_string "alu")
9555            ]
9556            (const_string "ishift")))
9557    (set (attr "length_immediate")
9558      (if_then_else
9559        (ior (eq_attr "type" "alu")
9560             (and (eq_attr "type" "ishift")
9561                  (and (match_operand 2 "const1_operand" "")
9562                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9563                           (const_int 0)))))
9564        (const_string "0")
9565        (const_string "*")))
9566    (set_attr "mode" "SI")])
9567
9568 (define_insn "*ashl<mode>3_cconly"
9569   [(set (reg FLAGS_REG)
9570         (compare
9571           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9572                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9573           (const_int 0)))
9574    (clobber (match_scratch:SWI 0 "=<r>"))]
9575   "(optimize_function_for_size_p (cfun)
9576     || !TARGET_PARTIAL_FLAG_REG_STALL
9577     || (operands[2] == const1_rtx
9578         && (TARGET_SHIFT1
9579             || TARGET_DOUBLE_WITH_ADD)))
9580    && ix86_match_ccmode (insn, CCGOCmode)
9581    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9582 {
9583   switch (get_attr_type (insn))
9584     {
9585     case TYPE_ALU:
9586       gcc_assert (operands[2] == const1_rtx);
9587       return "add{<imodesuffix>}\t%0, %0";
9588
9589     default:
9590       if (operands[2] == const1_rtx
9591           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592         return "sal{<imodesuffix>}\t%0";
9593       else
9594         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9595     }
9596 }
9597   [(set (attr "type")
9598      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9599                           (const_int 0))
9600                       (match_operand 0 "register_operand" ""))
9601                  (match_operand 2 "const1_operand" ""))
9602               (const_string "alu")
9603            ]
9604            (const_string "ishift")))
9605    (set (attr "length_immediate")
9606      (if_then_else
9607        (ior (eq_attr "type" "alu")
9608             (and (eq_attr "type" "ishift")
9609                  (and (match_operand 2 "const1_operand" "")
9610                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9611                           (const_int 0)))))
9612        (const_string "0")
9613        (const_string "*")))
9614    (set_attr "mode" "<MODE>")])
9615
9616 ;; See comment above `ashl<mode>3' about how this works.
9617
9618 (define_expand "<shiftrt_insn><mode>3"
9619   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9620         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9621                            (match_operand:QI 2 "nonmemory_operand" "")))]
9622   ""
9623   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9624
9625 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9626   [(set (match_operand:DWI 0 "register_operand" "=r")
9627         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9628                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9629    (clobber (reg:CC FLAGS_REG))]
9630   ""
9631   "#"
9632   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9633   [(const_int 0)]
9634   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9635   [(set_attr "type" "multi")])
9636
9637 ;; By default we don't ask for a scratch register, because when DWImode
9638 ;; values are manipulated, registers are already at a premium.  But if
9639 ;; we have one handy, we won't turn it away.
9640
9641 (define_peephole2
9642   [(match_scratch:DWIH 3 "r")
9643    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9644                    (any_shiftrt:<DWI>
9645                      (match_operand:<DWI> 1 "register_operand" "")
9646                      (match_operand:QI 2 "nonmemory_operand" "")))
9647               (clobber (reg:CC FLAGS_REG))])
9648    (match_dup 3)]
9649   "TARGET_CMOVE"
9650   [(const_int 0)]
9651   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9652
9653 (define_insn "x86_64_shrd"
9654   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9655         (ior:DI (ashiftrt:DI (match_dup 0)
9656                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9657                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9658                   (minus:QI (const_int 64) (match_dup 2)))))
9659    (clobber (reg:CC FLAGS_REG))]
9660   "TARGET_64BIT"
9661   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9662   [(set_attr "type" "ishift")
9663    (set_attr "prefix_0f" "1")
9664    (set_attr "mode" "DI")
9665    (set_attr "athlon_decode" "vector")
9666    (set_attr "amdfam10_decode" "vector")])
9667
9668 (define_insn "x86_shrd"
9669   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9670         (ior:SI (ashiftrt:SI (match_dup 0)
9671                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9672                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9673                   (minus:QI (const_int 32) (match_dup 2)))))
9674    (clobber (reg:CC FLAGS_REG))]
9675   ""
9676   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9677   [(set_attr "type" "ishift")
9678    (set_attr "prefix_0f" "1")
9679    (set_attr "mode" "SI")
9680    (set_attr "pent_pair" "np")
9681    (set_attr "athlon_decode" "vector")
9682    (set_attr "amdfam10_decode" "vector")])
9683
9684 (define_insn "ashrdi3_cvt"
9685   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9686         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9687                      (match_operand:QI 2 "const_int_operand" "")))
9688    (clobber (reg:CC FLAGS_REG))]
9689   "TARGET_64BIT && INTVAL (operands[2]) == 63
9690    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9691    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9692   "@
9693    {cqto|cqo}
9694    sar{q}\t{%2, %0|%0, %2}"
9695   [(set_attr "type" "imovx,ishift")
9696    (set_attr "prefix_0f" "0,*")
9697    (set_attr "length_immediate" "0,*")
9698    (set_attr "modrm" "0,1")
9699    (set_attr "mode" "DI")])
9700
9701 (define_insn "ashrsi3_cvt"
9702   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9703         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9704                      (match_operand:QI 2 "const_int_operand" "")))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "INTVAL (operands[2]) == 31
9707    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9708    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9709   "@
9710    {cltd|cdq}
9711    sar{l}\t{%2, %0|%0, %2}"
9712   [(set_attr "type" "imovx,ishift")
9713    (set_attr "prefix_0f" "0,*")
9714    (set_attr "length_immediate" "0,*")
9715    (set_attr "modrm" "0,1")
9716    (set_attr "mode" "SI")])
9717
9718 (define_insn "*ashrsi3_cvt_zext"
9719   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9720         (zero_extend:DI
9721           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9722                        (match_operand:QI 2 "const_int_operand" ""))))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "TARGET_64BIT && INTVAL (operands[2]) == 31
9725    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9726    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9727   "@
9728    {cltd|cdq}
9729    sar{l}\t{%2, %k0|%k0, %2}"
9730   [(set_attr "type" "imovx,ishift")
9731    (set_attr "prefix_0f" "0,*")
9732    (set_attr "length_immediate" "0,*")
9733    (set_attr "modrm" "0,1")
9734    (set_attr "mode" "SI")])
9735
9736 (define_expand "x86_shift<mode>_adj_3"
9737   [(use (match_operand:SWI48 0 "register_operand" ""))
9738    (use (match_operand:SWI48 1 "register_operand" ""))
9739    (use (match_operand:QI 2 "register_operand" ""))]
9740   ""
9741 {
9742   rtx label = gen_label_rtx ();
9743   rtx tmp;
9744
9745   emit_insn (gen_testqi_ccz_1 (operands[2],
9746                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9747
9748   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9749   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9750   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9751                               gen_rtx_LABEL_REF (VOIDmode, label),
9752                               pc_rtx);
9753   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9754   JUMP_LABEL (tmp) = label;
9755
9756   emit_move_insn (operands[0], operands[1]);
9757   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9758                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9759   emit_label (label);
9760   LABEL_NUSES (label) = 1;
9761
9762   DONE;
9763 })
9764
9765 (define_insn "*<shiftrt_insn><mode>3_1"
9766   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9767         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9768                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9769    (clobber (reg:CC FLAGS_REG))]
9770   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9771 {
9772   if (operands[2] == const1_rtx
9773       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9774     return "<shiftrt>{<imodesuffix>}\t%0";
9775   else
9776     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9777 }
9778   [(set_attr "type" "ishift")
9779    (set (attr "length_immediate")
9780      (if_then_else
9781        (and (match_operand 2 "const1_operand" "")
9782             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9783                 (const_int 0)))
9784        (const_string "0")
9785        (const_string "*")))
9786    (set_attr "mode" "<MODE>")])
9787
9788 (define_insn "*<shiftrt_insn>si3_1_zext"
9789   [(set (match_operand:DI 0 "register_operand" "=r")
9790         (zero_extend:DI
9791           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9792                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9793    (clobber (reg:CC FLAGS_REG))]
9794   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9795 {
9796   if (operands[2] == const1_rtx
9797       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9798     return "<shiftrt>{l}\t%k0";
9799   else
9800     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9801 }
9802   [(set_attr "type" "ishift")
9803    (set (attr "length_immediate")
9804      (if_then_else
9805        (and (match_operand 2 "const1_operand" "")
9806             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9807                 (const_int 0)))
9808        (const_string "0")
9809        (const_string "*")))
9810    (set_attr "mode" "SI")])
9811
9812 (define_insn "*<shiftrt_insn>qi3_1_slp"
9813   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9814         (any_shiftrt:QI (match_dup 0)
9815                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9816    (clobber (reg:CC FLAGS_REG))]
9817   "(optimize_function_for_size_p (cfun)
9818     || !TARGET_PARTIAL_REG_STALL
9819     || (operands[1] == const1_rtx
9820         && TARGET_SHIFT1))"
9821 {
9822   if (operands[1] == const1_rtx
9823       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9824     return "<shiftrt>{b}\t%0";
9825   else
9826     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9827 }
9828   [(set_attr "type" "ishift1")
9829    (set (attr "length_immediate")
9830      (if_then_else
9831        (and (match_operand 1 "const1_operand" "")
9832             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9833                 (const_int 0)))
9834        (const_string "0")
9835        (const_string "*")))
9836    (set_attr "mode" "QI")])
9837
9838 ;; This pattern can't accept a variable shift count, since shifts by
9839 ;; zero don't affect the flags.  We assume that shifts by constant
9840 ;; zero are optimized away.
9841 (define_insn "*<shiftrt_insn><mode>3_cmp"
9842   [(set (reg FLAGS_REG)
9843         (compare
9844           (any_shiftrt:SWI
9845             (match_operand:SWI 1 "nonimmediate_operand" "0")
9846             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9847           (const_int 0)))
9848    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9849         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9850   "(optimize_function_for_size_p (cfun)
9851     || !TARGET_PARTIAL_FLAG_REG_STALL
9852     || (operands[2] == const1_rtx
9853         && TARGET_SHIFT1))
9854    && ix86_match_ccmode (insn, CCGOCmode)
9855    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9856 {
9857   if (operands[2] == const1_rtx
9858       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9859     return "<shiftrt>{<imodesuffix>}\t%0";
9860   else
9861     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9862 }
9863   [(set_attr "type" "ishift")
9864    (set (attr "length_immediate")
9865      (if_then_else
9866        (and (match_operand 2 "const1_operand" "")
9867             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9868                 (const_int 0)))
9869        (const_string "0")
9870        (const_string "*")))
9871    (set_attr "mode" "<MODE>")])
9872
9873 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9874   [(set (reg FLAGS_REG)
9875         (compare
9876           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9877                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9878           (const_int 0)))
9879    (set (match_operand:DI 0 "register_operand" "=r")
9880         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9881   "TARGET_64BIT
9882    && (optimize_function_for_size_p (cfun)
9883        || !TARGET_PARTIAL_FLAG_REG_STALL
9884        || (operands[2] == const1_rtx
9885            && TARGET_SHIFT1))
9886    && ix86_match_ccmode (insn, CCGOCmode)
9887    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9888 {
9889   if (operands[2] == const1_rtx
9890       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9891     return "<shiftrt>{l}\t%k0";
9892   else
9893     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9894 }
9895   [(set_attr "type" "ishift")
9896    (set (attr "length_immediate")
9897      (if_then_else
9898        (and (match_operand 2 "const1_operand" "")
9899             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9900                 (const_int 0)))
9901        (const_string "0")
9902        (const_string "*")))
9903    (set_attr "mode" "SI")])
9904
9905 (define_insn "*<shiftrt_insn><mode>3_cconly"
9906   [(set (reg FLAGS_REG)
9907         (compare
9908           (any_shiftrt:SWI
9909             (match_operand:SWI 1 "nonimmediate_operand" "0")
9910             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9911           (const_int 0)))
9912    (clobber (match_scratch:SWI 0 "=<r>"))]
9913   "(optimize_function_for_size_p (cfun)
9914     || !TARGET_PARTIAL_FLAG_REG_STALL
9915     || (operands[2] == const1_rtx
9916         && TARGET_SHIFT1))
9917    && ix86_match_ccmode (insn, CCGOCmode)
9918    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9919 {
9920   if (operands[2] == const1_rtx
9921       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9922     return "<shiftrt>{<imodesuffix>}\t%0";
9923   else
9924     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9925 }
9926   [(set_attr "type" "ishift")
9927    (set (attr "length_immediate")
9928      (if_then_else
9929        (and (match_operand 2 "const1_operand" "")
9930             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9931                 (const_int 0)))
9932        (const_string "0")
9933        (const_string "*")))
9934    (set_attr "mode" "<MODE>")])
9935 \f
9936 ;; Rotate instructions
9937
9938 (define_expand "<rotate_insn>ti3"
9939   [(set (match_operand:TI 0 "register_operand" "")
9940         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9941                        (match_operand:QI 2 "nonmemory_operand" "")))]
9942   "TARGET_64BIT"
9943 {
9944   if (const_1_to_63_operand (operands[2], VOIDmode))
9945     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9946                 (operands[0], operands[1], operands[2]));
9947   else
9948     FAIL;
9949
9950   DONE;
9951 })
9952
9953 (define_expand "<rotate_insn>di3"
9954   [(set (match_operand:DI 0 "shiftdi_operand" "")
9955         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9956                        (match_operand:QI 2 "nonmemory_operand" "")))]
9957  ""
9958 {
9959   if (TARGET_64BIT)
9960     ix86_expand_binary_operator (<CODE>, DImode, operands);
9961   else if (const_1_to_31_operand (operands[2], VOIDmode))
9962     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9963                 (operands[0], operands[1], operands[2]));
9964   else
9965     FAIL;
9966
9967   DONE;
9968 })
9969
9970 (define_expand "<rotate_insn><mode>3"
9971   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9972         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9973                             (match_operand:QI 2 "nonmemory_operand" "")))]
9974   ""
9975   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9976
9977 ;; Implement rotation using two double-precision
9978 ;; shift instructions and a scratch register.
9979
9980 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9981  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9982        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9983                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9984   (clobber (reg:CC FLAGS_REG))
9985   (clobber (match_scratch:DWIH 3 "=&r"))]
9986  ""
9987  "#"
9988  "reload_completed"
9989  [(set (match_dup 3) (match_dup 4))
9990   (parallel
9991    [(set (match_dup 4)
9992          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9993                    (lshiftrt:DWIH (match_dup 5)
9994                                   (minus:QI (match_dup 6) (match_dup 2)))))
9995     (clobber (reg:CC FLAGS_REG))])
9996   (parallel
9997    [(set (match_dup 5)
9998          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9999                    (lshiftrt:DWIH (match_dup 3)
10000                                   (minus:QI (match_dup 6) (match_dup 2)))))
10001     (clobber (reg:CC FLAGS_REG))])]
10002 {
10003   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10004
10005   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10006 })
10007
10008 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10009  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10010        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10011                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10012   (clobber (reg:CC FLAGS_REG))
10013   (clobber (match_scratch:DWIH 3 "=&r"))]
10014  ""
10015  "#"
10016  "reload_completed"
10017  [(set (match_dup 3) (match_dup 4))
10018   (parallel
10019    [(set (match_dup 4)
10020          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10021                    (ashift:DWIH (match_dup 5)
10022                                 (minus:QI (match_dup 6) (match_dup 2)))))
10023     (clobber (reg:CC FLAGS_REG))])
10024   (parallel
10025    [(set (match_dup 5)
10026          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10027                    (ashift:DWIH (match_dup 3)
10028                                 (minus:QI (match_dup 6) (match_dup 2)))))
10029     (clobber (reg:CC FLAGS_REG))])]
10030 {
10031   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10032
10033   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10034 })
10035
10036 (define_insn "*<rotate_insn><mode>3_1"
10037   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10038         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10039                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10040    (clobber (reg:CC FLAGS_REG))]
10041   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10042 {
10043   if (operands[2] == const1_rtx
10044       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10045     return "<rotate>{<imodesuffix>}\t%0";
10046   else
10047     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10048 }
10049   [(set_attr "type" "rotate")
10050    (set (attr "length_immediate")
10051      (if_then_else
10052        (and (match_operand 2 "const1_operand" "")
10053             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10054                 (const_int 0)))
10055        (const_string "0")
10056        (const_string "*")))
10057    (set_attr "mode" "<MODE>")])
10058
10059 (define_insn "*<rotate_insn>si3_1_zext"
10060   [(set (match_operand:DI 0 "register_operand" "=r")
10061         (zero_extend:DI
10062           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10063                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10064    (clobber (reg:CC FLAGS_REG))]
10065   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10066 {
10067     if (operands[2] == const1_rtx
10068         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10069     return "<rotate>{l}\t%k0";
10070   else
10071     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10072 }
10073   [(set_attr "type" "rotate")
10074    (set (attr "length_immediate")
10075      (if_then_else
10076        (and (match_operand 2 "const1_operand" "")
10077             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10078                 (const_int 0)))
10079        (const_string "0")
10080        (const_string "*")))
10081    (set_attr "mode" "SI")])
10082
10083 (define_insn "*<rotate_insn>qi3_1_slp"
10084   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10085         (any_rotate:QI (match_dup 0)
10086                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10087    (clobber (reg:CC FLAGS_REG))]
10088   "(optimize_function_for_size_p (cfun)
10089     || !TARGET_PARTIAL_REG_STALL
10090     || (operands[1] == const1_rtx
10091         && TARGET_SHIFT1))"
10092 {
10093   if (operands[1] == const1_rtx
10094       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10095     return "<rotate>{b}\t%0";
10096   else
10097     return "<rotate>{b}\t{%1, %0|%0, %1}";
10098 }
10099   [(set_attr "type" "rotate1")
10100    (set (attr "length_immediate")
10101      (if_then_else
10102        (and (match_operand 1 "const1_operand" "")
10103             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10104                 (const_int 0)))
10105        (const_string "0")
10106        (const_string "*")))
10107    (set_attr "mode" "QI")])
10108
10109 (define_split
10110  [(set (match_operand:HI 0 "register_operand" "")
10111        (any_rotate:HI (match_dup 0) (const_int 8)))
10112   (clobber (reg:CC FLAGS_REG))]
10113  "reload_completed
10114   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10115  [(parallel [(set (strict_low_part (match_dup 0))
10116                   (bswap:HI (match_dup 0)))
10117              (clobber (reg:CC FLAGS_REG))])])
10118 \f
10119 ;; Bit set / bit test instructions
10120
10121 (define_expand "extv"
10122   [(set (match_operand:SI 0 "register_operand" "")
10123         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10124                          (match_operand:SI 2 "const8_operand" "")
10125                          (match_operand:SI 3 "const8_operand" "")))]
10126   ""
10127 {
10128   /* Handle extractions from %ah et al.  */
10129   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10130     FAIL;
10131
10132   /* From mips.md: extract_bit_field doesn't verify that our source
10133      matches the predicate, so check it again here.  */
10134   if (! ext_register_operand (operands[1], VOIDmode))
10135     FAIL;
10136 })
10137
10138 (define_expand "extzv"
10139   [(set (match_operand:SI 0 "register_operand" "")
10140         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10141                          (match_operand:SI 2 "const8_operand" "")
10142                          (match_operand:SI 3 "const8_operand" "")))]
10143   ""
10144 {
10145   /* Handle extractions from %ah et al.  */
10146   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10147     FAIL;
10148
10149   /* From mips.md: extract_bit_field doesn't verify that our source
10150      matches the predicate, so check it again here.  */
10151   if (! ext_register_operand (operands[1], VOIDmode))
10152     FAIL;
10153 })
10154
10155 (define_expand "insv"
10156   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10157                       (match_operand 1 "const8_operand" "")
10158                       (match_operand 2 "const8_operand" ""))
10159         (match_operand 3 "register_operand" ""))]
10160   ""
10161 {
10162   rtx (*gen_mov_insv_1) (rtx, rtx);
10163
10164   /* Handle insertions to %ah et al.  */
10165   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10166     FAIL;
10167
10168   /* From mips.md: insert_bit_field doesn't verify that our source
10169      matches the predicate, so check it again here.  */
10170   if (! ext_register_operand (operands[0], VOIDmode))
10171     FAIL;
10172
10173   gen_mov_insv_1 = (TARGET_64BIT
10174                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10175
10176   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10177   DONE;
10178 })
10179
10180 ;; %%% bts, btr, btc, bt.
10181 ;; In general these instructions are *slow* when applied to memory,
10182 ;; since they enforce atomic operation.  When applied to registers,
10183 ;; it depends on the cpu implementation.  They're never faster than
10184 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10185 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10186 ;; within the instruction itself, so operating on bits in the high
10187 ;; 32-bits of a register becomes easier.
10188 ;;
10189 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10190 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10191 ;; negdf respectively, so they can never be disabled entirely.
10192
10193 (define_insn "*btsq"
10194   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10195                          (const_int 1)
10196                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10197         (const_int 1))
10198    (clobber (reg:CC FLAGS_REG))]
10199   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10200   "bts{q}\t{%1, %0|%0, %1}"
10201   [(set_attr "type" "alu1")
10202    (set_attr "prefix_0f" "1")
10203    (set_attr "mode" "DI")])
10204
10205 (define_insn "*btrq"
10206   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10207                          (const_int 1)
10208                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10209         (const_int 0))
10210    (clobber (reg:CC FLAGS_REG))]
10211   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10212   "btr{q}\t{%1, %0|%0, %1}"
10213   [(set_attr "type" "alu1")
10214    (set_attr "prefix_0f" "1")
10215    (set_attr "mode" "DI")])
10216
10217 (define_insn "*btcq"
10218   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10219                          (const_int 1)
10220                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10221         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10222    (clobber (reg:CC FLAGS_REG))]
10223   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10224   "btc{q}\t{%1, %0|%0, %1}"
10225   [(set_attr "type" "alu1")
10226    (set_attr "prefix_0f" "1")
10227    (set_attr "mode" "DI")])
10228
10229 ;; Allow Nocona to avoid these instructions if a register is available.
10230
10231 (define_peephole2
10232   [(match_scratch:DI 2 "r")
10233    (parallel [(set (zero_extract:DI
10234                      (match_operand:DI 0 "register_operand" "")
10235                      (const_int 1)
10236                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10237                    (const_int 1))
10238               (clobber (reg:CC FLAGS_REG))])]
10239   "TARGET_64BIT && !TARGET_USE_BT"
10240   [(const_int 0)]
10241 {
10242   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10243   rtx op1;
10244
10245   if (HOST_BITS_PER_WIDE_INT >= 64)
10246     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10247   else if (i < HOST_BITS_PER_WIDE_INT)
10248     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10249   else
10250     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10251
10252   op1 = immed_double_const (lo, hi, DImode);
10253   if (i >= 31)
10254     {
10255       emit_move_insn (operands[2], op1);
10256       op1 = operands[2];
10257     }
10258
10259   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10260   DONE;
10261 })
10262
10263 (define_peephole2
10264   [(match_scratch:DI 2 "r")
10265    (parallel [(set (zero_extract:DI
10266                      (match_operand:DI 0 "register_operand" "")
10267                      (const_int 1)
10268                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10269                    (const_int 0))
10270               (clobber (reg:CC FLAGS_REG))])]
10271   "TARGET_64BIT && !TARGET_USE_BT"
10272   [(const_int 0)]
10273 {
10274   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10275   rtx op1;
10276
10277   if (HOST_BITS_PER_WIDE_INT >= 64)
10278     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10279   else if (i < HOST_BITS_PER_WIDE_INT)
10280     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10281   else
10282     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10283
10284   op1 = immed_double_const (~lo, ~hi, DImode);
10285   if (i >= 32)
10286     {
10287       emit_move_insn (operands[2], op1);
10288       op1 = operands[2];
10289     }
10290
10291   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10292   DONE;
10293 })
10294
10295 (define_peephole2
10296   [(match_scratch:DI 2 "r")
10297    (parallel [(set (zero_extract:DI
10298                      (match_operand:DI 0 "register_operand" "")
10299                      (const_int 1)
10300                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10301               (not:DI (zero_extract:DI
10302                         (match_dup 0) (const_int 1) (match_dup 1))))
10303               (clobber (reg:CC FLAGS_REG))])]
10304   "TARGET_64BIT && !TARGET_USE_BT"
10305   [(const_int 0)]
10306 {
10307   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10308   rtx op1;
10309
10310   if (HOST_BITS_PER_WIDE_INT >= 64)
10311     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10312   else if (i < HOST_BITS_PER_WIDE_INT)
10313     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10314   else
10315     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10316
10317   op1 = immed_double_const (lo, hi, DImode);
10318   if (i >= 31)
10319     {
10320       emit_move_insn (operands[2], op1);
10321       op1 = operands[2];
10322     }
10323
10324   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10325   DONE;
10326 })
10327
10328 (define_insn "*bt<mode>"
10329   [(set (reg:CCC FLAGS_REG)
10330         (compare:CCC
10331           (zero_extract:SWI48
10332             (match_operand:SWI48 0 "register_operand" "r")
10333             (const_int 1)
10334             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10335           (const_int 0)))]
10336   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10337   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10338   [(set_attr "type" "alu1")
10339    (set_attr "prefix_0f" "1")
10340    (set_attr "mode" "<MODE>")])
10341 \f
10342 ;; Store-flag instructions.
10343
10344 ;; For all sCOND expanders, also expand the compare or test insn that
10345 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10346
10347 (define_insn_and_split "*setcc_di_1"
10348   [(set (match_operand:DI 0 "register_operand" "=q")
10349         (match_operator:DI 1 "ix86_comparison_operator"
10350           [(reg FLAGS_REG) (const_int 0)]))]
10351   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10352   "#"
10353   "&& reload_completed"
10354   [(set (match_dup 2) (match_dup 1))
10355    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10356 {
10357   PUT_MODE (operands[1], QImode);
10358   operands[2] = gen_lowpart (QImode, operands[0]);
10359 })
10360
10361 (define_insn_and_split "*setcc_si_1_and"
10362   [(set (match_operand:SI 0 "register_operand" "=q")
10363         (match_operator:SI 1 "ix86_comparison_operator"
10364           [(reg FLAGS_REG) (const_int 0)]))
10365    (clobber (reg:CC FLAGS_REG))]
10366   "!TARGET_PARTIAL_REG_STALL
10367    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10368   "#"
10369   "&& reload_completed"
10370   [(set (match_dup 2) (match_dup 1))
10371    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10372               (clobber (reg:CC FLAGS_REG))])]
10373 {
10374   PUT_MODE (operands[1], QImode);
10375   operands[2] = gen_lowpart (QImode, operands[0]);
10376 })
10377
10378 (define_insn_and_split "*setcc_si_1_movzbl"
10379   [(set (match_operand:SI 0 "register_operand" "=q")
10380         (match_operator:SI 1 "ix86_comparison_operator"
10381           [(reg FLAGS_REG) (const_int 0)]))]
10382   "!TARGET_PARTIAL_REG_STALL
10383    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10384   "#"
10385   "&& reload_completed"
10386   [(set (match_dup 2) (match_dup 1))
10387    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10388 {
10389   PUT_MODE (operands[1], QImode);
10390   operands[2] = gen_lowpart (QImode, operands[0]);
10391 })
10392
10393 (define_insn "*setcc_qi"
10394   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10395         (match_operator:QI 1 "ix86_comparison_operator"
10396           [(reg FLAGS_REG) (const_int 0)]))]
10397   ""
10398   "set%C1\t%0"
10399   [(set_attr "type" "setcc")
10400    (set_attr "mode" "QI")])
10401
10402 (define_insn "*setcc_qi_slp"
10403   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10404         (match_operator:QI 1 "ix86_comparison_operator"
10405           [(reg FLAGS_REG) (const_int 0)]))]
10406   ""
10407   "set%C1\t%0"
10408   [(set_attr "type" "setcc")
10409    (set_attr "mode" "QI")])
10410
10411 ;; In general it is not safe to assume too much about CCmode registers,
10412 ;; so simplify-rtx stops when it sees a second one.  Under certain
10413 ;; conditions this is safe on x86, so help combine not create
10414 ;;
10415 ;;      seta    %al
10416 ;;      testb   %al, %al
10417 ;;      sete    %al
10418
10419 (define_split
10420   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10421         (ne:QI (match_operator 1 "ix86_comparison_operator"
10422                  [(reg FLAGS_REG) (const_int 0)])
10423             (const_int 0)))]
10424   ""
10425   [(set (match_dup 0) (match_dup 1))]
10426   "PUT_MODE (operands[1], QImode);")
10427
10428 (define_split
10429   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10430         (ne:QI (match_operator 1 "ix86_comparison_operator"
10431                  [(reg FLAGS_REG) (const_int 0)])
10432             (const_int 0)))]
10433   ""
10434   [(set (match_dup 0) (match_dup 1))]
10435   "PUT_MODE (operands[1], QImode);")
10436
10437 (define_split
10438   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10439         (eq:QI (match_operator 1 "ix86_comparison_operator"
10440                  [(reg FLAGS_REG) (const_int 0)])
10441             (const_int 0)))]
10442   ""
10443   [(set (match_dup 0) (match_dup 1))]
10444 {
10445   rtx new_op1 = copy_rtx (operands[1]);
10446   operands[1] = new_op1;
10447   PUT_MODE (new_op1, QImode);
10448   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10449                                              GET_MODE (XEXP (new_op1, 0))));
10450
10451   /* Make sure that (a) the CCmode we have for the flags is strong
10452      enough for the reversed compare or (b) we have a valid FP compare.  */
10453   if (! ix86_comparison_operator (new_op1, VOIDmode))
10454     FAIL;
10455 })
10456
10457 (define_split
10458   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10459         (eq:QI (match_operator 1 "ix86_comparison_operator"
10460                  [(reg FLAGS_REG) (const_int 0)])
10461             (const_int 0)))]
10462   ""
10463   [(set (match_dup 0) (match_dup 1))]
10464 {
10465   rtx new_op1 = copy_rtx (operands[1]);
10466   operands[1] = new_op1;
10467   PUT_MODE (new_op1, QImode);
10468   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10469                                              GET_MODE (XEXP (new_op1, 0))));
10470
10471   /* Make sure that (a) the CCmode we have for the flags is strong
10472      enough for the reversed compare or (b) we have a valid FP compare.  */
10473   if (! ix86_comparison_operator (new_op1, VOIDmode))
10474     FAIL;
10475 })
10476
10477 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10478 ;; subsequent logical operations are used to imitate conditional moves.
10479 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10480 ;; it directly.
10481
10482 (define_insn "*avx_setcc<mode>"
10483   [(set (match_operand:MODEF 0 "register_operand" "=x")
10484         (match_operator:MODEF 1 "avx_comparison_float_operator"
10485           [(match_operand:MODEF 2 "register_operand" "x")
10486            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10487   "TARGET_AVX"
10488   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10489   [(set_attr "type" "ssecmp")
10490    (set_attr "prefix" "vex")
10491    (set_attr "length_immediate" "1")
10492    (set_attr "mode" "<MODE>")])
10493
10494 (define_insn "*sse_setcc<mode>"
10495   [(set (match_operand:MODEF 0 "register_operand" "=x")
10496         (match_operator:MODEF 1 "sse_comparison_operator"
10497           [(match_operand:MODEF 2 "register_operand" "0")
10498            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10499   "SSE_FLOAT_MODE_P (<MODE>mode)"
10500   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10501   [(set_attr "type" "ssecmp")
10502    (set_attr "length_immediate" "1")
10503    (set_attr "mode" "<MODE>")])
10504 \f
10505 ;; Basic conditional jump instructions.
10506 ;; We ignore the overflow flag for signed branch instructions.
10507
10508 (define_insn "*jcc_1"
10509   [(set (pc)
10510         (if_then_else (match_operator 1 "ix86_comparison_operator"
10511                                       [(reg FLAGS_REG) (const_int 0)])
10512                       (label_ref (match_operand 0 "" ""))
10513                       (pc)))]
10514   ""
10515   "%+j%C1\t%l0"
10516   [(set_attr "type" "ibr")
10517    (set_attr "modrm" "0")
10518    (set (attr "length")
10519            (if_then_else (and (ge (minus (match_dup 0) (pc))
10520                                   (const_int -126))
10521                               (lt (minus (match_dup 0) (pc))
10522                                   (const_int 128)))
10523              (const_int 2)
10524              (const_int 6)))])
10525
10526 (define_insn "*jcc_2"
10527   [(set (pc)
10528         (if_then_else (match_operator 1 "ix86_comparison_operator"
10529                                       [(reg FLAGS_REG) (const_int 0)])
10530                       (pc)
10531                       (label_ref (match_operand 0 "" ""))))]
10532   ""
10533   "%+j%c1\t%l0"
10534   [(set_attr "type" "ibr")
10535    (set_attr "modrm" "0")
10536    (set (attr "length")
10537            (if_then_else (and (ge (minus (match_dup 0) (pc))
10538                                   (const_int -126))
10539                               (lt (minus (match_dup 0) (pc))
10540                                   (const_int 128)))
10541              (const_int 2)
10542              (const_int 6)))])
10543
10544 ;; In general it is not safe to assume too much about CCmode registers,
10545 ;; so simplify-rtx stops when it sees a second one.  Under certain
10546 ;; conditions this is safe on x86, so help combine not create
10547 ;;
10548 ;;      seta    %al
10549 ;;      testb   %al, %al
10550 ;;      je      Lfoo
10551
10552 (define_split
10553   [(set (pc)
10554         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10555                                       [(reg FLAGS_REG) (const_int 0)])
10556                           (const_int 0))
10557                       (label_ref (match_operand 1 "" ""))
10558                       (pc)))]
10559   ""
10560   [(set (pc)
10561         (if_then_else (match_dup 0)
10562                       (label_ref (match_dup 1))
10563                       (pc)))]
10564   "PUT_MODE (operands[0], VOIDmode);")
10565
10566 (define_split
10567   [(set (pc)
10568         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10569                                       [(reg FLAGS_REG) (const_int 0)])
10570                           (const_int 0))
10571                       (label_ref (match_operand 1 "" ""))
10572                       (pc)))]
10573   ""
10574   [(set (pc)
10575         (if_then_else (match_dup 0)
10576                       (label_ref (match_dup 1))
10577                       (pc)))]
10578 {
10579   rtx new_op0 = copy_rtx (operands[0]);
10580   operands[0] = new_op0;
10581   PUT_MODE (new_op0, VOIDmode);
10582   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10583                                              GET_MODE (XEXP (new_op0, 0))));
10584
10585   /* Make sure that (a) the CCmode we have for the flags is strong
10586      enough for the reversed compare or (b) we have a valid FP compare.  */
10587   if (! ix86_comparison_operator (new_op0, VOIDmode))
10588     FAIL;
10589 })
10590
10591 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10592 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10593 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10594 ;; appropriate modulo of the bit offset value.
10595
10596 (define_insn_and_split "*jcc_bt<mode>"
10597   [(set (pc)
10598         (if_then_else (match_operator 0 "bt_comparison_operator"
10599                         [(zero_extract:SWI48
10600                            (match_operand:SWI48 1 "register_operand" "r")
10601                            (const_int 1)
10602                            (zero_extend:SI
10603                              (match_operand:QI 2 "register_operand" "r")))
10604                          (const_int 0)])
10605                       (label_ref (match_operand 3 "" ""))
10606                       (pc)))
10607    (clobber (reg:CC FLAGS_REG))]
10608   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10609   "#"
10610   "&& 1"
10611   [(set (reg:CCC FLAGS_REG)
10612         (compare:CCC
10613           (zero_extract:SWI48
10614             (match_dup 1)
10615             (const_int 1)
10616             (match_dup 2))
10617           (const_int 0)))
10618    (set (pc)
10619         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10620                       (label_ref (match_dup 3))
10621                       (pc)))]
10622 {
10623   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10624
10625   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10626 })
10627
10628 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10629 ;; also for DImode, this is what combine produces.
10630 (define_insn_and_split "*jcc_bt<mode>_mask"
10631   [(set (pc)
10632         (if_then_else (match_operator 0 "bt_comparison_operator"
10633                         [(zero_extract:SWI48
10634                            (match_operand:SWI48 1 "register_operand" "r")
10635                            (const_int 1)
10636                            (and:SI
10637                              (match_operand:SI 2 "register_operand" "r")
10638                              (match_operand:SI 3 "const_int_operand" "n")))])
10639                       (label_ref (match_operand 4 "" ""))
10640                       (pc)))
10641    (clobber (reg:CC FLAGS_REG))]
10642   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10643    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10644       == GET_MODE_BITSIZE (<MODE>mode)-1"
10645   "#"
10646   "&& 1"
10647   [(set (reg:CCC FLAGS_REG)
10648         (compare:CCC
10649           (zero_extract:SWI48
10650             (match_dup 1)
10651             (const_int 1)
10652             (match_dup 2))
10653           (const_int 0)))
10654    (set (pc)
10655         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10656                       (label_ref (match_dup 4))
10657                       (pc)))]
10658 {
10659   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10660
10661   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10662 })
10663
10664 (define_insn_and_split "*jcc_btsi_1"
10665   [(set (pc)
10666         (if_then_else (match_operator 0 "bt_comparison_operator"
10667                         [(and:SI
10668                            (lshiftrt:SI
10669                              (match_operand:SI 1 "register_operand" "r")
10670                              (match_operand:QI 2 "register_operand" "r"))
10671                            (const_int 1))
10672                          (const_int 0)])
10673                       (label_ref (match_operand 3 "" ""))
10674                       (pc)))
10675    (clobber (reg:CC FLAGS_REG))]
10676   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10677   "#"
10678   "&& 1"
10679   [(set (reg:CCC FLAGS_REG)
10680         (compare:CCC
10681           (zero_extract:SI
10682             (match_dup 1)
10683             (const_int 1)
10684             (match_dup 2))
10685           (const_int 0)))
10686    (set (pc)
10687         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10688                       (label_ref (match_dup 3))
10689                       (pc)))]
10690 {
10691   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10692
10693   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10694 })
10695
10696 ;; avoid useless masking of bit offset operand
10697 (define_insn_and_split "*jcc_btsi_mask_1"
10698   [(set (pc)
10699         (if_then_else
10700           (match_operator 0 "bt_comparison_operator"
10701             [(and:SI
10702                (lshiftrt:SI
10703                  (match_operand:SI 1 "register_operand" "r")
10704                  (subreg:QI
10705                    (and:SI
10706                      (match_operand:SI 2 "register_operand" "r")
10707                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10708                (const_int 1))
10709              (const_int 0)])
10710           (label_ref (match_operand 4 "" ""))
10711           (pc)))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10714    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10715   "#"
10716   "&& 1"
10717   [(set (reg:CCC FLAGS_REG)
10718         (compare:CCC
10719           (zero_extract:SI
10720             (match_dup 1)
10721             (const_int 1)
10722             (match_dup 2))
10723           (const_int 0)))
10724    (set (pc)
10725         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10726                       (label_ref (match_dup 4))
10727                       (pc)))]
10728   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10729
10730 ;; Define combination compare-and-branch fp compare instructions to help
10731 ;; combine.
10732
10733 (define_insn "*fp_jcc_1_387"
10734   [(set (pc)
10735         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10736                         [(match_operand 1 "register_operand" "f")
10737                          (match_operand 2 "nonimmediate_operand" "fm")])
10738           (label_ref (match_operand 3 "" ""))
10739           (pc)))
10740    (clobber (reg:CCFP FPSR_REG))
10741    (clobber (reg:CCFP FLAGS_REG))
10742    (clobber (match_scratch:HI 4 "=a"))]
10743   "TARGET_80387
10744    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10745    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10746    && SELECT_CC_MODE (GET_CODE (operands[0]),
10747                       operands[1], operands[2]) == CCFPmode
10748    && !TARGET_CMOVE"
10749   "#")
10750
10751 (define_insn "*fp_jcc_1r_387"
10752   [(set (pc)
10753         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10754                         [(match_operand 1 "register_operand" "f")
10755                          (match_operand 2 "nonimmediate_operand" "fm")])
10756           (pc)
10757           (label_ref (match_operand 3 "" ""))))
10758    (clobber (reg:CCFP FPSR_REG))
10759    (clobber (reg:CCFP FLAGS_REG))
10760    (clobber (match_scratch:HI 4 "=a"))]
10761   "TARGET_80387
10762    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10763    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10764    && SELECT_CC_MODE (GET_CODE (operands[0]),
10765                       operands[1], operands[2]) == CCFPmode
10766    && !TARGET_CMOVE"
10767   "#")
10768
10769 (define_insn "*fp_jcc_2_387"
10770   [(set (pc)
10771         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10772                         [(match_operand 1 "register_operand" "f")
10773                          (match_operand 2 "register_operand" "f")])
10774           (label_ref (match_operand 3 "" ""))
10775           (pc)))
10776    (clobber (reg:CCFP FPSR_REG))
10777    (clobber (reg:CCFP FLAGS_REG))
10778    (clobber (match_scratch:HI 4 "=a"))]
10779   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10780    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10781    && !TARGET_CMOVE"
10782   "#")
10783
10784 (define_insn "*fp_jcc_2r_387"
10785   [(set (pc)
10786         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10787                         [(match_operand 1 "register_operand" "f")
10788                          (match_operand 2 "register_operand" "f")])
10789           (pc)
10790           (label_ref (match_operand 3 "" ""))))
10791    (clobber (reg:CCFP FPSR_REG))
10792    (clobber (reg:CCFP FLAGS_REG))
10793    (clobber (match_scratch:HI 4 "=a"))]
10794   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10795    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10796    && !TARGET_CMOVE"
10797   "#")
10798
10799 (define_insn "*fp_jcc_3_387"
10800   [(set (pc)
10801         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10802                         [(match_operand 1 "register_operand" "f")
10803                          (match_operand 2 "const0_operand" "")])
10804           (label_ref (match_operand 3 "" ""))
10805           (pc)))
10806    (clobber (reg:CCFP FPSR_REG))
10807    (clobber (reg:CCFP FLAGS_REG))
10808    (clobber (match_scratch:HI 4 "=a"))]
10809   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10810    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10811    && SELECT_CC_MODE (GET_CODE (operands[0]),
10812                       operands[1], operands[2]) == CCFPmode
10813    && !TARGET_CMOVE"
10814   "#")
10815
10816 (define_split
10817   [(set (pc)
10818         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10819                         [(match_operand 1 "register_operand" "")
10820                          (match_operand 2 "nonimmediate_operand" "")])
10821           (match_operand 3 "" "")
10822           (match_operand 4 "" "")))
10823    (clobber (reg:CCFP FPSR_REG))
10824    (clobber (reg:CCFP FLAGS_REG))]
10825   "reload_completed"
10826   [(const_int 0)]
10827 {
10828   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10829                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10830   DONE;
10831 })
10832
10833 (define_split
10834   [(set (pc)
10835         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10836                         [(match_operand 1 "register_operand" "")
10837                          (match_operand 2 "general_operand" "")])
10838           (match_operand 3 "" "")
10839           (match_operand 4 "" "")))
10840    (clobber (reg:CCFP FPSR_REG))
10841    (clobber (reg:CCFP FLAGS_REG))
10842    (clobber (match_scratch:HI 5 "=a"))]
10843   "reload_completed"
10844   [(const_int 0)]
10845 {
10846   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10847                         operands[3], operands[4], operands[5], NULL_RTX);
10848   DONE;
10849 })
10850
10851 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10852 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10853 ;; with a precedence over other operators and is always put in the first
10854 ;; place. Swap condition and operands to match ficom instruction.
10855
10856 (define_insn "*fp_jcc_4_<mode>_387"
10857   [(set (pc)
10858         (if_then_else
10859           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10860             [(match_operator 1 "float_operator"
10861               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10862              (match_operand 3 "register_operand" "f,f")])
10863           (label_ref (match_operand 4 "" ""))
10864           (pc)))
10865    (clobber (reg:CCFP FPSR_REG))
10866    (clobber (reg:CCFP FLAGS_REG))
10867    (clobber (match_scratch:HI 5 "=a,a"))]
10868   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10869    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10870    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10871    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10872    && !TARGET_CMOVE"
10873   "#")
10874
10875 (define_split
10876   [(set (pc)
10877         (if_then_else
10878           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10879             [(match_operator 1 "float_operator"
10880               [(match_operand:X87MODEI12 2 "memory_operand" "")])
10881              (match_operand 3 "register_operand" "")])
10882           (match_operand 4 "" "")
10883           (match_operand 5 "" "")))
10884    (clobber (reg:CCFP FPSR_REG))
10885    (clobber (reg:CCFP FLAGS_REG))
10886    (clobber (match_scratch:HI 6 "=a"))]
10887   "reload_completed"
10888   [(const_int 0)]
10889 {
10890   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10891
10892   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10893                         operands[3], operands[7],
10894                         operands[4], operands[5], operands[6], NULL_RTX);
10895   DONE;
10896 })
10897
10898 ;; %%% Kill this when reload knows how to do it.
10899 (define_split
10900   [(set (pc)
10901         (if_then_else
10902           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10903             [(match_operator 1 "float_operator"
10904               [(match_operand:X87MODEI12 2 "register_operand" "")])
10905              (match_operand 3 "register_operand" "")])
10906           (match_operand 4 "" "")
10907           (match_operand 5 "" "")))
10908    (clobber (reg:CCFP FPSR_REG))
10909    (clobber (reg:CCFP FLAGS_REG))
10910    (clobber (match_scratch:HI 6 "=a"))]
10911   "reload_completed"
10912   [(const_int 0)]
10913 {
10914   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10915   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10916
10917   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10918                         operands[3], operands[7],
10919                         operands[4], operands[5], operands[6], operands[2]);
10920   DONE;
10921 })
10922 \f
10923 ;; Unconditional and other jump instructions
10924
10925 (define_insn "jump"
10926   [(set (pc)
10927         (label_ref (match_operand 0 "" "")))]
10928   ""
10929   "jmp\t%l0"
10930   [(set_attr "type" "ibr")
10931    (set (attr "length")
10932            (if_then_else (and (ge (minus (match_dup 0) (pc))
10933                                   (const_int -126))
10934                               (lt (minus (match_dup 0) (pc))
10935                                   (const_int 128)))
10936              (const_int 2)
10937              (const_int 5)))
10938    (set_attr "modrm" "0")])
10939
10940 (define_expand "indirect_jump"
10941   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10942   ""
10943   "")
10944
10945 (define_insn "*indirect_jump"
10946   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10947   ""
10948   "jmp\t%A0"
10949   [(set_attr "type" "ibr")
10950    (set_attr "length_immediate" "0")])
10951
10952 (define_expand "tablejump"
10953   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10954               (use (label_ref (match_operand 1 "" "")))])]
10955   ""
10956 {
10957   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10958      relative.  Convert the relative address to an absolute address.  */
10959   if (flag_pic)
10960     {
10961       rtx op0, op1;
10962       enum rtx_code code;
10963
10964       /* We can't use @GOTOFF for text labels on VxWorks;
10965          see gotoff_operand.  */
10966       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10967         {
10968           code = PLUS;
10969           op0 = operands[0];
10970           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10971         }
10972       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10973         {
10974           code = PLUS;
10975           op0 = operands[0];
10976           op1 = pic_offset_table_rtx;
10977         }
10978       else
10979         {
10980           code = MINUS;
10981           op0 = pic_offset_table_rtx;
10982           op1 = operands[0];
10983         }
10984
10985       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10986                                          OPTAB_DIRECT);
10987     }
10988 })
10989
10990 (define_insn "*tablejump_1"
10991   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
10992    (use (label_ref (match_operand 1 "" "")))]
10993   ""
10994   "jmp\t%A0"
10995   [(set_attr "type" "ibr")
10996    (set_attr "length_immediate" "0")])
10997 \f
10998 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10999
11000 (define_peephole2
11001   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11002    (set (match_operand:QI 1 "register_operand" "")
11003         (match_operator:QI 2 "ix86_comparison_operator"
11004           [(reg FLAGS_REG) (const_int 0)]))
11005    (set (match_operand 3 "q_regs_operand" "")
11006         (zero_extend (match_dup 1)))]
11007   "(peep2_reg_dead_p (3, operands[1])
11008     || operands_match_p (operands[1], operands[3]))
11009    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11010   [(set (match_dup 4) (match_dup 0))
11011    (set (strict_low_part (match_dup 5))
11012         (match_dup 2))]
11013 {
11014   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11015   operands[5] = gen_lowpart (QImode, operands[3]);
11016   ix86_expand_clear (operands[3]);
11017 })
11018
11019 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11020
11021 (define_peephole2
11022   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11023    (set (match_operand:QI 1 "register_operand" "")
11024         (match_operator:QI 2 "ix86_comparison_operator"
11025           [(reg FLAGS_REG) (const_int 0)]))
11026    (parallel [(set (match_operand 3 "q_regs_operand" "")
11027                    (zero_extend (match_dup 1)))
11028               (clobber (reg:CC FLAGS_REG))])]
11029   "(peep2_reg_dead_p (3, operands[1])
11030     || operands_match_p (operands[1], operands[3]))
11031    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11032   [(set (match_dup 4) (match_dup 0))
11033    (set (strict_low_part (match_dup 5))
11034         (match_dup 2))]
11035 {
11036   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11037   operands[5] = gen_lowpart (QImode, operands[3]);
11038   ix86_expand_clear (operands[3]);
11039 })
11040 \f
11041 ;; Call instructions.
11042
11043 ;; The predicates normally associated with named expanders are not properly
11044 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11045 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11046
11047 ;; P6 processors will jump to the address after the decrement when %esp
11048 ;; is used as a call operand, so they will execute return address as a code.
11049 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11050  
11051 ;; Call subroutine returning no value.
11052
11053 (define_expand "call_pop"
11054   [(parallel [(call (match_operand:QI 0 "" "")
11055                     (match_operand:SI 1 "" ""))
11056               (set (reg:SI SP_REG)
11057                    (plus:SI (reg:SI SP_REG)
11058                             (match_operand:SI 3 "" "")))])]
11059   "!TARGET_64BIT"
11060 {
11061   ix86_expand_call (NULL, operands[0], operands[1],
11062                     operands[2], operands[3], 0);
11063   DONE;
11064 })
11065
11066 (define_insn "*call_pop_0"
11067   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11068          (match_operand:SI 1 "" ""))
11069    (set (reg:SI SP_REG)
11070         (plus:SI (reg:SI SP_REG)
11071                  (match_operand:SI 2 "immediate_operand" "")))]
11072   "!TARGET_64BIT"
11073 {
11074   if (SIBLING_CALL_P (insn))
11075     return "jmp\t%P0";
11076   else
11077     return "call\t%P0";
11078 }
11079   [(set_attr "type" "call")])
11080
11081 (define_insn "*call_pop_1"
11082   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11083          (match_operand:SI 1 "" ""))
11084    (set (reg:SI SP_REG)
11085         (plus:SI (reg:SI SP_REG)
11086                  (match_operand:SI 2 "immediate_operand" "i")))]
11087   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11088 {
11089   if (constant_call_address_operand (operands[0], Pmode))
11090     return "call\t%P0";
11091   return "call\t%A0";
11092 }
11093   [(set_attr "type" "call")])
11094
11095 (define_insn "*sibcall_pop_1"
11096   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11097          (match_operand:SI 1 "" ""))
11098    (set (reg:SI SP_REG)
11099         (plus:SI (reg:SI SP_REG)
11100                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11101   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11102   "@
11103    jmp\t%P0
11104    jmp\t%A0"
11105   [(set_attr "type" "call")])
11106
11107 (define_expand "call"
11108   [(call (match_operand:QI 0 "" "")
11109          (match_operand 1 "" ""))
11110    (use (match_operand 2 "" ""))]
11111   ""
11112 {
11113   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11114   DONE;
11115 })
11116
11117 (define_expand "sibcall"
11118   [(call (match_operand:QI 0 "" "")
11119          (match_operand 1 "" ""))
11120    (use (match_operand 2 "" ""))]
11121   ""
11122 {
11123   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11124   DONE;
11125 })
11126
11127 (define_insn "*call_0"
11128   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11129          (match_operand 1 "" ""))]
11130   ""
11131 {
11132   if (SIBLING_CALL_P (insn))
11133     return "jmp\t%P0";
11134   else
11135     return "call\t%P0";
11136 }
11137   [(set_attr "type" "call")])
11138
11139 (define_insn "*call_1"
11140   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11141          (match_operand 1 "" ""))]
11142   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11143 {
11144   if (constant_call_address_operand (operands[0], Pmode))
11145     return "call\t%P0";
11146   return "call\t%A0";
11147 }
11148   [(set_attr "type" "call")])
11149
11150 (define_insn "*sibcall_1"
11151   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11152          (match_operand 1 "" ""))]
11153   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11154   "@
11155    jmp\t%P0
11156    jmp\t%A0"
11157   [(set_attr "type" "call")])
11158
11159 (define_insn "*call_1_rex64"
11160   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11161          (match_operand 1 "" ""))]
11162   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11163    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11164 {
11165   if (constant_call_address_operand (operands[0], Pmode))
11166     return "call\t%P0";
11167   return "call\t%A0";
11168 }
11169   [(set_attr "type" "call")])
11170
11171 (define_insn "*call_1_rex64_ms_sysv"
11172   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11173          (match_operand 1 "" ""))
11174    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11175    (clobber (reg:TI XMM6_REG))
11176    (clobber (reg:TI XMM7_REG))
11177    (clobber (reg:TI XMM8_REG))
11178    (clobber (reg:TI XMM9_REG))
11179    (clobber (reg:TI XMM10_REG))
11180    (clobber (reg:TI XMM11_REG))
11181    (clobber (reg:TI XMM12_REG))
11182    (clobber (reg:TI XMM13_REG))
11183    (clobber (reg:TI XMM14_REG))
11184    (clobber (reg:TI XMM15_REG))
11185    (clobber (reg:DI SI_REG))
11186    (clobber (reg:DI DI_REG))]
11187   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11188 {
11189   if (constant_call_address_operand (operands[0], Pmode))
11190     return "call\t%P0";
11191   return "call\t%A0";
11192 }
11193   [(set_attr "type" "call")])
11194
11195 (define_insn "*call_1_rex64_large"
11196   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11197          (match_operand 1 "" ""))]
11198   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11199   "call\t%A0"
11200   [(set_attr "type" "call")])
11201
11202 (define_insn "*sibcall_1_rex64"
11203   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11204          (match_operand 1 "" ""))]
11205   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11206   "@
11207    jmp\t%P0
11208    jmp\t%A0"
11209   [(set_attr "type" "call")])
11210
11211 ;; Call subroutine, returning value in operand 0
11212 (define_expand "call_value_pop"
11213   [(parallel [(set (match_operand 0 "" "")
11214                    (call (match_operand:QI 1 "" "")
11215                          (match_operand:SI 2 "" "")))
11216               (set (reg:SI SP_REG)
11217                    (plus:SI (reg:SI SP_REG)
11218                             (match_operand:SI 4 "" "")))])]
11219   "!TARGET_64BIT"
11220 {
11221   ix86_expand_call (operands[0], operands[1], operands[2],
11222                     operands[3], operands[4], 0);
11223   DONE;
11224 })
11225
11226 (define_expand "call_value"
11227   [(set (match_operand 0 "" "")
11228         (call (match_operand:QI 1 "" "")
11229               (match_operand:SI 2 "" "")))
11230    (use (match_operand:SI 3 "" ""))]
11231   ;; Operand 3 is not used on the i386.
11232   ""
11233 {
11234   ix86_expand_call (operands[0], operands[1], operands[2],
11235                     operands[3], NULL, 0);
11236   DONE;
11237 })
11238
11239 (define_expand "sibcall_value"
11240   [(set (match_operand 0 "" "")
11241         (call (match_operand:QI 1 "" "")
11242               (match_operand:SI 2 "" "")))
11243    (use (match_operand:SI 3 "" ""))]
11244   ;; Operand 3 is not used on the i386.
11245   ""
11246 {
11247   ix86_expand_call (operands[0], operands[1], operands[2],
11248                     operands[3], NULL, 1);
11249   DONE;
11250 })
11251
11252 ;; Call subroutine returning any type.
11253
11254 (define_expand "untyped_call"
11255   [(parallel [(call (match_operand 0 "" "")
11256                     (const_int 0))
11257               (match_operand 1 "" "")
11258               (match_operand 2 "" "")])]
11259   ""
11260 {
11261   int i;
11262
11263   /* In order to give reg-stack an easier job in validating two
11264      coprocessor registers as containing a possible return value,
11265      simply pretend the untyped call returns a complex long double
11266      value. 
11267
11268      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11269      and should have the default ABI.  */
11270
11271   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11272                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11273                     operands[0], const0_rtx,
11274                     GEN_INT ((TARGET_64BIT
11275                               ? (ix86_abi == SYSV_ABI
11276                                  ? X86_64_SSE_REGPARM_MAX
11277                                  : X86_64_MS_SSE_REGPARM_MAX)
11278                               : X86_32_SSE_REGPARM_MAX)
11279                              - 1),
11280                     NULL, 0);
11281
11282   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11283     {
11284       rtx set = XVECEXP (operands[2], 0, i);
11285       emit_move_insn (SET_DEST (set), SET_SRC (set));
11286     }
11287
11288   /* The optimizer does not know that the call sets the function value
11289      registers we stored in the result block.  We avoid problems by
11290      claiming that all hard registers are used and clobbered at this
11291      point.  */
11292   emit_insn (gen_blockage ());
11293
11294   DONE;
11295 })
11296 \f
11297 ;; Prologue and epilogue instructions
11298
11299 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11300 ;; all of memory.  This blocks insns from being moved across this point.
11301
11302 (define_insn "blockage"
11303   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11304   ""
11305   ""
11306   [(set_attr "length" "0")])
11307
11308 ;; Do not schedule instructions accessing memory across this point.
11309
11310 (define_expand "memory_blockage"
11311   [(set (match_dup 0)
11312         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11313   ""
11314 {
11315   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11316   MEM_VOLATILE_P (operands[0]) = 1;
11317 })
11318
11319 (define_insn "*memory_blockage"
11320   [(set (match_operand:BLK 0 "" "")
11321         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11322   ""
11323   ""
11324   [(set_attr "length" "0")])
11325
11326 ;; As USE insns aren't meaningful after reload, this is used instead
11327 ;; to prevent deleting instructions setting registers for PIC code
11328 (define_insn "prologue_use"
11329   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11330   ""
11331   ""
11332   [(set_attr "length" "0")])
11333
11334 ;; Insn emitted into the body of a function to return from a function.
11335 ;; This is only done if the function's epilogue is known to be simple.
11336 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11337
11338 (define_expand "return"
11339   [(return)]
11340   "ix86_can_use_return_insn_p ()"
11341 {
11342   if (crtl->args.pops_args)
11343     {
11344       rtx popc = GEN_INT (crtl->args.pops_args);
11345       emit_jump_insn (gen_return_pop_internal (popc));
11346       DONE;
11347     }
11348 })
11349
11350 (define_insn "return_internal"
11351   [(return)]
11352   "reload_completed"
11353   "ret"
11354   [(set_attr "length" "1")
11355    (set_attr "atom_unit" "jeu")
11356    (set_attr "length_immediate" "0")
11357    (set_attr "modrm" "0")])
11358
11359 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11360 ;; instruction Athlon and K8 have.
11361
11362 (define_insn "return_internal_long"
11363   [(return)
11364    (unspec [(const_int 0)] UNSPEC_REP)]
11365   "reload_completed"
11366   "rep\;ret"
11367   [(set_attr "length" "2")
11368    (set_attr "atom_unit" "jeu")
11369    (set_attr "length_immediate" "0")
11370    (set_attr "prefix_rep" "1")
11371    (set_attr "modrm" "0")])
11372
11373 (define_insn "return_pop_internal"
11374   [(return)
11375    (use (match_operand:SI 0 "const_int_operand" ""))]
11376   "reload_completed"
11377   "ret\t%0"
11378   [(set_attr "length" "3")
11379    (set_attr "atom_unit" "jeu")
11380    (set_attr "length_immediate" "2")
11381    (set_attr "modrm" "0")])
11382
11383 (define_insn "return_indirect_internal"
11384   [(return)
11385    (use (match_operand:SI 0 "register_operand" "r"))]
11386   "reload_completed"
11387   "jmp\t%A0"
11388   [(set_attr "type" "ibr")
11389    (set_attr "length_immediate" "0")])
11390
11391 (define_insn "nop"
11392   [(const_int 0)]
11393   ""
11394   "nop"
11395   [(set_attr "length" "1")
11396    (set_attr "length_immediate" "0")
11397    (set_attr "modrm" "0")])
11398
11399 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11400 ;; branch prediction penalty for the third jump in a 16-byte
11401 ;; block on K8.
11402
11403 (define_insn "pad"
11404   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11405   ""
11406 {
11407 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11408   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11409 #else
11410   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11411      The align insn is used to avoid 3 jump instructions in the row to improve
11412      branch prediction and the benefits hardly outweigh the cost of extra 8
11413      nops on the average inserted by full alignment pseudo operation.  */
11414 #endif
11415   return "";
11416 }
11417   [(set_attr "length" "16")])
11418
11419 (define_expand "prologue"
11420   [(const_int 0)]
11421   ""
11422   "ix86_expand_prologue (); DONE;")
11423
11424 (define_insn "set_got"
11425   [(set (match_operand:SI 0 "register_operand" "=r")
11426         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11427    (clobber (reg:CC FLAGS_REG))]
11428   "!TARGET_64BIT"
11429   { return output_set_got (operands[0], NULL_RTX); }
11430   [(set_attr "type" "multi")
11431    (set_attr "length" "12")])
11432
11433 (define_insn "set_got_labelled"
11434   [(set (match_operand:SI 0 "register_operand" "=r")
11435         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11436          UNSPEC_SET_GOT))
11437    (clobber (reg:CC FLAGS_REG))]
11438   "!TARGET_64BIT"
11439   { return output_set_got (operands[0], operands[1]); }
11440   [(set_attr "type" "multi")
11441    (set_attr "length" "12")])
11442
11443 (define_insn "set_got_rex64"
11444   [(set (match_operand:DI 0 "register_operand" "=r")
11445         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11446   "TARGET_64BIT"
11447   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11448   [(set_attr "type" "lea")
11449    (set_attr "length_address" "4")
11450    (set_attr "mode" "DI")])
11451
11452 (define_insn "set_rip_rex64"
11453   [(set (match_operand:DI 0 "register_operand" "=r")
11454         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11455   "TARGET_64BIT"
11456   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11457   [(set_attr "type" "lea")
11458    (set_attr "length_address" "4")
11459    (set_attr "mode" "DI")])
11460
11461 (define_insn "set_got_offset_rex64"
11462   [(set (match_operand:DI 0 "register_operand" "=r")
11463         (unspec:DI
11464           [(label_ref (match_operand 1 "" ""))]
11465           UNSPEC_SET_GOT_OFFSET))]
11466   "TARGET_64BIT"
11467   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11468   [(set_attr "type" "imov")
11469    (set_attr "length_immediate" "0")
11470    (set_attr "length_address" "8")
11471    (set_attr "mode" "DI")])
11472
11473 (define_expand "epilogue"
11474   [(const_int 0)]
11475   ""
11476   "ix86_expand_epilogue (1); DONE;")
11477
11478 (define_expand "sibcall_epilogue"
11479   [(const_int 0)]
11480   ""
11481   "ix86_expand_epilogue (0); DONE;")
11482
11483 (define_expand "eh_return"
11484   [(use (match_operand 0 "register_operand" ""))]
11485   ""
11486 {
11487   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11488
11489   /* Tricky bit: we write the address of the handler to which we will
11490      be returning into someone else's stack frame, one word below the
11491      stack address we wish to restore.  */
11492   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11493   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11494   tmp = gen_rtx_MEM (Pmode, tmp);
11495   emit_move_insn (tmp, ra);
11496
11497   emit_jump_insn (gen_eh_return_internal ());
11498   emit_barrier ();
11499   DONE;
11500 })
11501
11502 (define_insn_and_split "eh_return_internal"
11503   [(eh_return)]
11504   ""
11505   "#"
11506   "epilogue_completed"
11507   [(const_int 0)]
11508   "ix86_expand_epilogue (2); DONE;")
11509
11510 (define_insn "leave"
11511   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11512    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11513    (clobber (mem:BLK (scratch)))]
11514   "!TARGET_64BIT"
11515   "leave"
11516   [(set_attr "type" "leave")])
11517
11518 (define_insn "leave_rex64"
11519   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11520    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11521    (clobber (mem:BLK (scratch)))]
11522   "TARGET_64BIT"
11523   "leave"
11524   [(set_attr "type" "leave")])
11525 \f
11526 ;; Bit manipulation instructions.
11527
11528 (define_expand "ffs<mode>2"
11529   [(set (match_dup 2) (const_int -1))
11530    (parallel [(set (reg:CCZ FLAGS_REG)
11531                    (compare:CCZ
11532                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11533                      (const_int 0)))
11534               (set (match_operand:SWI48 0 "register_operand" "")
11535                    (ctz:SWI48 (match_dup 1)))])
11536    (set (match_dup 0) (if_then_else:SWI48
11537                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11538                         (match_dup 2)
11539                         (match_dup 0)))
11540    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11541               (clobber (reg:CC FLAGS_REG))])]
11542   ""
11543 {
11544   if (<MODE>mode == SImode && !TARGET_CMOVE)
11545     {
11546       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11547       DONE;
11548     }
11549   operands[2] = gen_reg_rtx (<MODE>mode);
11550 })
11551
11552 (define_insn_and_split "ffssi2_no_cmove"
11553   [(set (match_operand:SI 0 "register_operand" "=r")
11554         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11555    (clobber (match_scratch:SI 2 "=&q"))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "!TARGET_CMOVE"
11558   "#"
11559   "&& reload_completed"
11560   [(parallel [(set (reg:CCZ FLAGS_REG)
11561                    (compare:CCZ (match_dup 1) (const_int 0)))
11562               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11563    (set (strict_low_part (match_dup 3))
11564         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11565    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11566               (clobber (reg:CC FLAGS_REG))])
11567    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11568               (clobber (reg:CC FLAGS_REG))])
11569    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11570               (clobber (reg:CC FLAGS_REG))])]
11571 {
11572   operands[3] = gen_lowpart (QImode, operands[2]);
11573   ix86_expand_clear (operands[2]);
11574 })
11575
11576 (define_insn "*ffs<mode>_1"
11577   [(set (reg:CCZ FLAGS_REG)
11578         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11579                      (const_int 0)))
11580    (set (match_operand:SWI48 0 "register_operand" "=r")
11581         (ctz:SWI48 (match_dup 1)))]
11582   ""
11583   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11584   [(set_attr "type" "alu1")
11585    (set_attr "prefix_0f" "1")
11586    (set_attr "mode" "<MODE>")])
11587
11588 (define_insn "ctz<mode>2"
11589   [(set (match_operand:SWI48 0 "register_operand" "=r")
11590         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11591    (clobber (reg:CC FLAGS_REG))]
11592   ""
11593   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11594   [(set_attr "type" "alu1")
11595    (set_attr "prefix_0f" "1")
11596    (set_attr "mode" "<MODE>")])
11597
11598 (define_expand "clz<mode>2"
11599   [(parallel
11600      [(set (match_operand:SWI248 0 "register_operand" "")
11601            (minus:SWI248
11602              (match_dup 2)
11603              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11604       (clobber (reg:CC FLAGS_REG))])
11605    (parallel
11606      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11607       (clobber (reg:CC FLAGS_REG))])]
11608   ""
11609 {
11610   if (TARGET_ABM)
11611     {
11612       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11613       DONE;
11614     }
11615   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11616 })
11617
11618 (define_insn "clz<mode>2_abm"
11619   [(set (match_operand:SWI248 0 "register_operand" "=r")
11620         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11621    (clobber (reg:CC FLAGS_REG))]
11622   "TARGET_ABM"
11623   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11624   [(set_attr "prefix_rep" "1")
11625    (set_attr "type" "bitmanip")
11626    (set_attr "mode" "<MODE>")])
11627
11628 (define_insn "bsr_rex64"
11629   [(set (match_operand:DI 0 "register_operand" "=r")
11630         (minus:DI (const_int 63)
11631                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11632    (clobber (reg:CC FLAGS_REG))]
11633   "TARGET_64BIT"
11634   "bsr{q}\t{%1, %0|%0, %1}"
11635   [(set_attr "type" "alu1")
11636    (set_attr "prefix_0f" "1")
11637    (set_attr "mode" "DI")])
11638
11639 (define_insn "bsr"
11640   [(set (match_operand:SI 0 "register_operand" "=r")
11641         (minus:SI (const_int 31)
11642                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11643    (clobber (reg:CC FLAGS_REG))]
11644   ""
11645   "bsr{l}\t{%1, %0|%0, %1}"
11646   [(set_attr "type" "alu1")
11647    (set_attr "prefix_0f" "1")
11648    (set_attr "mode" "SI")])
11649
11650 (define_insn "*bsrhi"
11651   [(set (match_operand:HI 0 "register_operand" "=r")
11652         (minus:HI (const_int 15)
11653                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11654    (clobber (reg:CC FLAGS_REG))]
11655   ""
11656   "bsr{w}\t{%1, %0|%0, %1}"
11657   [(set_attr "type" "alu1")
11658    (set_attr "prefix_0f" "1")
11659    (set_attr "mode" "HI")])
11660
11661 (define_insn "popcount<mode>2"
11662   [(set (match_operand:SWI248 0 "register_operand" "=r")
11663         (popcount:SWI248
11664           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11665    (clobber (reg:CC FLAGS_REG))]
11666   "TARGET_POPCNT"
11667 {
11668 #if TARGET_MACHO
11669   return "popcnt\t{%1, %0|%0, %1}";
11670 #else
11671   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11672 #endif
11673 }
11674   [(set_attr "prefix_rep" "1")
11675    (set_attr "type" "bitmanip")
11676    (set_attr "mode" "<MODE>")])
11677
11678 (define_insn "*popcount<mode>2_cmp"
11679   [(set (reg FLAGS_REG)
11680         (compare
11681           (popcount:SWI248
11682             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11683           (const_int 0)))
11684    (set (match_operand:SWI248 0 "register_operand" "=r")
11685         (popcount:SWI248 (match_dup 1)))]
11686   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11687 {
11688 #if TARGET_MACHO
11689   return "popcnt\t{%1, %0|%0, %1}";
11690 #else
11691   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11692 #endif
11693 }
11694   [(set_attr "prefix_rep" "1")
11695    (set_attr "type" "bitmanip")
11696    (set_attr "mode" "<MODE>")])
11697
11698 (define_insn "*popcountsi2_cmp_zext"
11699   [(set (reg FLAGS_REG)
11700         (compare
11701           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11702           (const_int 0)))
11703    (set (match_operand:DI 0 "register_operand" "=r")
11704         (zero_extend:DI(popcount:SI (match_dup 1))))]
11705   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11706 {
11707 #if TARGET_MACHO
11708   return "popcnt\t{%1, %0|%0, %1}";
11709 #else
11710   return "popcnt{l}\t{%1, %0|%0, %1}";
11711 #endif
11712 }
11713   [(set_attr "prefix_rep" "1")
11714    (set_attr "type" "bitmanip")
11715    (set_attr "mode" "SI")])
11716
11717 (define_expand "bswap<mode>2"
11718   [(set (match_operand:SWI48 0 "register_operand" "")
11719         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11720   ""
11721 {
11722   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11723     {
11724       rtx x = operands[0];
11725
11726       emit_move_insn (x, operands[1]);
11727       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11728       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11729       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11730       DONE;
11731     }
11732 })
11733
11734 (define_insn "*bswap<mode>2_movbe"
11735   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11736         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11737   "TARGET_MOVBE
11738    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11739   "@
11740     bswap\t%0
11741     movbe\t{%1, %0|%0, %1}
11742     movbe\t{%1, %0|%0, %1}"
11743   [(set_attr "type" "bitmanip,imov,imov")
11744    (set_attr "modrm" "0,1,1")
11745    (set_attr "prefix_0f" "*,1,1")
11746    (set_attr "prefix_extra" "*,1,1")
11747    (set_attr "mode" "<MODE>")])
11748
11749 (define_insn "*bswap<mode>2_1"
11750   [(set (match_operand:SWI48 0 "register_operand" "=r")
11751         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11752   "TARGET_BSWAP"
11753   "bswap\t%0"
11754   [(set_attr "type" "bitmanip")
11755    (set_attr "modrm" "0")
11756    (set_attr "mode" "<MODE>")])
11757
11758 (define_insn "*bswaphi_lowpart_1"
11759   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11760         (bswap:HI (match_dup 0)))
11761    (clobber (reg:CC FLAGS_REG))]
11762   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11763   "@
11764     xchg{b}\t{%h0, %b0|%b0, %h0}
11765     rol{w}\t{$8, %0|%0, 8}"
11766   [(set_attr "length" "2,4")
11767    (set_attr "mode" "QI,HI")])
11768
11769 (define_insn "bswaphi_lowpart"
11770   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11771         (bswap:HI (match_dup 0)))
11772    (clobber (reg:CC FLAGS_REG))]
11773   ""
11774   "rol{w}\t{$8, %0|%0, 8}"
11775   [(set_attr "length" "4")
11776    (set_attr "mode" "HI")])
11777
11778 (define_expand "paritydi2"
11779   [(set (match_operand:DI 0 "register_operand" "")
11780         (parity:DI (match_operand:DI 1 "register_operand" "")))]
11781   "! TARGET_POPCNT"
11782 {
11783   rtx scratch = gen_reg_rtx (QImode);
11784   rtx cond;
11785
11786   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11787                                 NULL_RTX, operands[1]));
11788
11789   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11790                          gen_rtx_REG (CCmode, FLAGS_REG),
11791                          const0_rtx);
11792   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11793
11794   if (TARGET_64BIT)
11795     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11796   else
11797     {
11798       rtx tmp = gen_reg_rtx (SImode);
11799
11800       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11801       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11802     }
11803   DONE;
11804 })
11805
11806 (define_expand "paritysi2"
11807   [(set (match_operand:SI 0 "register_operand" "")
11808         (parity:SI (match_operand:SI 1 "register_operand" "")))]
11809   "! TARGET_POPCNT"
11810 {
11811   rtx scratch = gen_reg_rtx (QImode);
11812   rtx cond;
11813
11814   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11815
11816   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11817                          gen_rtx_REG (CCmode, FLAGS_REG),
11818                          const0_rtx);
11819   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11820
11821   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11822   DONE;
11823 })
11824
11825 (define_insn_and_split "paritydi2_cmp"
11826   [(set (reg:CC FLAGS_REG)
11827         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11828                    UNSPEC_PARITY))
11829    (clobber (match_scratch:DI 0 "=r"))
11830    (clobber (match_scratch:SI 1 "=&r"))
11831    (clobber (match_scratch:HI 2 "=Q"))]
11832   "! TARGET_POPCNT"
11833   "#"
11834   "&& reload_completed"
11835   [(parallel
11836      [(set (match_dup 1)
11837            (xor:SI (match_dup 1) (match_dup 4)))
11838       (clobber (reg:CC FLAGS_REG))])
11839    (parallel
11840      [(set (reg:CC FLAGS_REG)
11841            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11842       (clobber (match_dup 1))
11843       (clobber (match_dup 2))])]
11844 {
11845   operands[4] = gen_lowpart (SImode, operands[3]);
11846
11847   if (TARGET_64BIT)
11848     {
11849       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11850       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11851     }
11852   else
11853     operands[1] = gen_highpart (SImode, operands[3]);
11854 })
11855
11856 (define_insn_and_split "paritysi2_cmp"
11857   [(set (reg:CC FLAGS_REG)
11858         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
11859                    UNSPEC_PARITY))
11860    (clobber (match_scratch:SI 0 "=r"))
11861    (clobber (match_scratch:HI 1 "=&Q"))]
11862   "! TARGET_POPCNT"
11863   "#"
11864   "&& reload_completed"
11865   [(parallel
11866      [(set (match_dup 1)
11867            (xor:HI (match_dup 1) (match_dup 3)))
11868       (clobber (reg:CC FLAGS_REG))])
11869    (parallel
11870      [(set (reg:CC FLAGS_REG)
11871            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11872       (clobber (match_dup 1))])]
11873 {
11874   operands[3] = gen_lowpart (HImode, operands[2]);
11875
11876   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
11877   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
11878 })
11879
11880 (define_insn "*parityhi2_cmp"
11881   [(set (reg:CC FLAGS_REG)
11882         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
11883                    UNSPEC_PARITY))
11884    (clobber (match_scratch:HI 0 "=Q"))]
11885   "! TARGET_POPCNT"
11886   "xor{b}\t{%h0, %b0|%b0, %h0}"
11887   [(set_attr "length" "2")
11888    (set_attr "mode" "HI")])
11889 \f
11890 ;; Thread-local storage patterns for ELF.
11891 ;;
11892 ;; Note that these code sequences must appear exactly as shown
11893 ;; in order to allow linker relaxation.
11894
11895 (define_insn "*tls_global_dynamic_32_gnu"
11896   [(set (match_operand:SI 0 "register_operand" "=a")
11897         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11898                     (match_operand:SI 2 "tls_symbolic_operand" "")
11899                     (match_operand:SI 3 "call_insn_operand" "")]
11900                     UNSPEC_TLS_GD))
11901    (clobber (match_scratch:SI 4 "=d"))
11902    (clobber (match_scratch:SI 5 "=c"))
11903    (clobber (reg:CC FLAGS_REG))]
11904   "!TARGET_64BIT && TARGET_GNU_TLS"
11905   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
11906   [(set_attr "type" "multi")
11907    (set_attr "length" "12")])
11908
11909 (define_expand "tls_global_dynamic_32"
11910   [(parallel [(set (match_operand:SI 0 "register_operand" "")
11911                    (unspec:SI
11912                     [(match_dup 2)
11913                      (match_operand:SI 1 "tls_symbolic_operand" "")
11914                      (match_dup 3)]
11915                     UNSPEC_TLS_GD))
11916               (clobber (match_scratch:SI 4 ""))
11917               (clobber (match_scratch:SI 5 ""))
11918               (clobber (reg:CC FLAGS_REG))])]
11919   ""
11920 {
11921   if (flag_pic)
11922     operands[2] = pic_offset_table_rtx;
11923   else
11924     {
11925       operands[2] = gen_reg_rtx (Pmode);
11926       emit_insn (gen_set_got (operands[2]));
11927     }
11928   if (TARGET_GNU2_TLS)
11929     {
11930        emit_insn (gen_tls_dynamic_gnu2_32
11931                   (operands[0], operands[1], operands[2]));
11932        DONE;
11933     }
11934   operands[3] = ix86_tls_get_addr ();
11935 })
11936
11937 (define_insn "*tls_global_dynamic_64"
11938   [(set (match_operand:DI 0 "register_operand" "=a")
11939         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
11940                  (match_operand:DI 3 "" "")))
11941    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11942               UNSPEC_TLS_GD)]
11943   "TARGET_64BIT"
11944   { 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"; }
11945   [(set_attr "type" "multi")
11946    (set_attr "length" "16")])
11947
11948 (define_expand "tls_global_dynamic_64"
11949   [(parallel [(set (match_operand:DI 0 "register_operand" "")
11950                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
11951               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11952                          UNSPEC_TLS_GD)])]
11953   ""
11954 {
11955   if (TARGET_GNU2_TLS)
11956     {
11957        emit_insn (gen_tls_dynamic_gnu2_64
11958                   (operands[0], operands[1]));
11959        DONE;
11960     }
11961   operands[2] = ix86_tls_get_addr ();
11962 })
11963
11964 (define_insn "*tls_local_dynamic_base_32_gnu"
11965   [(set (match_operand:SI 0 "register_operand" "=a")
11966         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11967                     (match_operand:SI 2 "call_insn_operand" "")]
11968                    UNSPEC_TLS_LD_BASE))
11969    (clobber (match_scratch:SI 3 "=d"))
11970    (clobber (match_scratch:SI 4 "=c"))
11971    (clobber (reg:CC FLAGS_REG))]
11972   "!TARGET_64BIT && TARGET_GNU_TLS"
11973   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
11974   [(set_attr "type" "multi")
11975    (set_attr "length" "11")])
11976
11977 (define_expand "tls_local_dynamic_base_32"
11978   [(parallel [(set (match_operand:SI 0 "register_operand" "")
11979                    (unspec:SI [(match_dup 1) (match_dup 2)]
11980                               UNSPEC_TLS_LD_BASE))
11981               (clobber (match_scratch:SI 3 ""))
11982               (clobber (match_scratch:SI 4 ""))
11983               (clobber (reg:CC FLAGS_REG))])]
11984   ""
11985 {
11986   if (flag_pic)
11987     operands[1] = pic_offset_table_rtx;
11988   else
11989     {
11990       operands[1] = gen_reg_rtx (Pmode);
11991       emit_insn (gen_set_got (operands[1]));
11992     }
11993   if (TARGET_GNU2_TLS)
11994     {
11995        emit_insn (gen_tls_dynamic_gnu2_32
11996                   (operands[0], ix86_tls_module_base (), operands[1]));
11997        DONE;
11998     }
11999   operands[2] = ix86_tls_get_addr ();
12000 })
12001
12002 (define_insn "*tls_local_dynamic_base_64"
12003   [(set (match_operand:DI 0 "register_operand" "=a")
12004         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12005                  (match_operand:DI 2 "" "")))
12006    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12007   "TARGET_64BIT"
12008   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12009   [(set_attr "type" "multi")
12010    (set_attr "length" "12")])
12011
12012 (define_expand "tls_local_dynamic_base_64"
12013   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12014                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12015               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12016   ""
12017 {
12018   if (TARGET_GNU2_TLS)
12019     {
12020        emit_insn (gen_tls_dynamic_gnu2_64
12021                   (operands[0], ix86_tls_module_base ()));
12022        DONE;
12023     }
12024   operands[1] = ix86_tls_get_addr ();
12025 })
12026
12027 ;; Local dynamic of a single variable is a lose.  Show combine how
12028 ;; to convert that back to global dynamic.
12029
12030 (define_insn_and_split "*tls_local_dynamic_32_once"
12031   [(set (match_operand:SI 0 "register_operand" "=a")
12032         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12033                              (match_operand:SI 2 "call_insn_operand" "")]
12034                             UNSPEC_TLS_LD_BASE)
12035                  (const:SI (unspec:SI
12036                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12037                             UNSPEC_DTPOFF))))
12038    (clobber (match_scratch:SI 4 "=d"))
12039    (clobber (match_scratch:SI 5 "=c"))
12040    (clobber (reg:CC FLAGS_REG))]
12041   ""
12042   "#"
12043   ""
12044   [(parallel [(set (match_dup 0)
12045                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12046                               UNSPEC_TLS_GD))
12047               (clobber (match_dup 4))
12048               (clobber (match_dup 5))
12049               (clobber (reg:CC FLAGS_REG))])]
12050   "")
12051
12052 ;; Segment register for the thread base ptr load
12053 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12054
12055 ;; Load and add the thread base pointer from %gs:0.
12056 (define_insn "*load_tp_<mode>"
12057   [(set (match_operand:P 0 "register_operand" "=r")
12058         (unspec:P [(const_int 0)] UNSPEC_TP))]
12059   ""
12060   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12061   [(set_attr "type" "imov")
12062    (set_attr "modrm" "0")
12063    (set_attr "length" "7")
12064    (set_attr "memory" "load")
12065    (set_attr "imm_disp" "false")])
12066
12067 (define_insn "*add_tp_<mode>"
12068   [(set (match_operand:P 0 "register_operand" "=r")
12069         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12070                 (match_operand:P 1 "register_operand" "0")))
12071    (clobber (reg:CC FLAGS_REG))]
12072   ""
12073   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12074   [(set_attr "type" "alu")
12075    (set_attr "modrm" "0")
12076    (set_attr "length" "7")
12077    (set_attr "memory" "load")
12078    (set_attr "imm_disp" "false")])
12079
12080 ;; GNU2 TLS patterns can be split.
12081
12082 (define_expand "tls_dynamic_gnu2_32"
12083   [(set (match_dup 3)
12084         (plus:SI (match_operand:SI 2 "register_operand" "")
12085                  (const:SI
12086                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12087                              UNSPEC_TLSDESC))))
12088    (parallel
12089     [(set (match_operand:SI 0 "register_operand" "")
12090           (unspec:SI [(match_dup 1) (match_dup 3)
12091                       (match_dup 2) (reg:SI SP_REG)]
12092                       UNSPEC_TLSDESC))
12093      (clobber (reg:CC FLAGS_REG))])]
12094   "!TARGET_64BIT && TARGET_GNU2_TLS"
12095 {
12096   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12097   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12098 })
12099
12100 (define_insn "*tls_dynamic_lea_32"
12101   [(set (match_operand:SI 0 "register_operand" "=r")
12102         (plus:SI (match_operand:SI 1 "register_operand" "b")
12103                  (const:SI
12104                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12105                               UNSPEC_TLSDESC))))]
12106   "!TARGET_64BIT && TARGET_GNU2_TLS"
12107   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12108   [(set_attr "type" "lea")
12109    (set_attr "mode" "SI")
12110    (set_attr "length" "6")
12111    (set_attr "length_address" "4")])
12112
12113 (define_insn "*tls_dynamic_call_32"
12114   [(set (match_operand:SI 0 "register_operand" "=a")
12115         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12116                     (match_operand:SI 2 "register_operand" "0")
12117                     ;; we have to make sure %ebx still points to the GOT
12118                     (match_operand:SI 3 "register_operand" "b")
12119                     (reg:SI SP_REG)]
12120                    UNSPEC_TLSDESC))
12121    (clobber (reg:CC FLAGS_REG))]
12122   "!TARGET_64BIT && TARGET_GNU2_TLS"
12123   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12124   [(set_attr "type" "call")
12125    (set_attr "length" "2")
12126    (set_attr "length_address" "0")])
12127
12128 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12129   [(set (match_operand:SI 0 "register_operand" "=&a")
12130         (plus:SI
12131          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12132                      (match_operand:SI 4 "" "")
12133                      (match_operand:SI 2 "register_operand" "b")
12134                      (reg:SI SP_REG)]
12135                     UNSPEC_TLSDESC)
12136          (const:SI (unspec:SI
12137                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12138                     UNSPEC_DTPOFF))))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "!TARGET_64BIT && TARGET_GNU2_TLS"
12141   "#"
12142   ""
12143   [(set (match_dup 0) (match_dup 5))]
12144 {
12145   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12146   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12147 })
12148
12149 (define_expand "tls_dynamic_gnu2_64"
12150   [(set (match_dup 2)
12151         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12152                    UNSPEC_TLSDESC))
12153    (parallel
12154     [(set (match_operand:DI 0 "register_operand" "")
12155           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12156                      UNSPEC_TLSDESC))
12157      (clobber (reg:CC FLAGS_REG))])]
12158   "TARGET_64BIT && TARGET_GNU2_TLS"
12159 {
12160   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12161   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12162 })
12163
12164 (define_insn "*tls_dynamic_lea_64"
12165   [(set (match_operand:DI 0 "register_operand" "=r")
12166         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12167                    UNSPEC_TLSDESC))]
12168   "TARGET_64BIT && TARGET_GNU2_TLS"
12169   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12170   [(set_attr "type" "lea")
12171    (set_attr "mode" "DI")
12172    (set_attr "length" "7")
12173    (set_attr "length_address" "4")])
12174
12175 (define_insn "*tls_dynamic_call_64"
12176   [(set (match_operand:DI 0 "register_operand" "=a")
12177         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12178                     (match_operand:DI 2 "register_operand" "0")
12179                     (reg:DI SP_REG)]
12180                    UNSPEC_TLSDESC))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "TARGET_64BIT && TARGET_GNU2_TLS"
12183   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12184   [(set_attr "type" "call")
12185    (set_attr "length" "2")
12186    (set_attr "length_address" "0")])
12187
12188 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12189   [(set (match_operand:DI 0 "register_operand" "=&a")
12190         (plus:DI
12191          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12192                      (match_operand:DI 3 "" "")
12193                      (reg:DI SP_REG)]
12194                     UNSPEC_TLSDESC)
12195          (const:DI (unspec:DI
12196                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12197                     UNSPEC_DTPOFF))))
12198    (clobber (reg:CC FLAGS_REG))]
12199   "TARGET_64BIT && TARGET_GNU2_TLS"
12200   "#"
12201   ""
12202   [(set (match_dup 0) (match_dup 4))]
12203 {
12204   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12205   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12206 })
12207 \f
12208 ;; These patterns match the binary 387 instructions for addM3, subM3,
12209 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12210 ;; SFmode.  The first is the normal insn, the second the same insn but
12211 ;; with one operand a conversion, and the third the same insn but with
12212 ;; the other operand a conversion.  The conversion may be SFmode or
12213 ;; SImode if the target mode DFmode, but only SImode if the target mode
12214 ;; is SFmode.
12215
12216 ;; Gcc is slightly more smart about handling normal two address instructions
12217 ;; so use special patterns for add and mull.
12218
12219 (define_insn "*fop_<mode>_comm_mixed_avx"
12220   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12221         (match_operator:MODEF 3 "binary_fp_operator"
12222           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12223            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12224   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12225    && COMMUTATIVE_ARITH_P (operands[3])
12226    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12227   "* return output_387_binary_op (insn, operands);"
12228   [(set (attr "type")
12229         (if_then_else (eq_attr "alternative" "1")
12230            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12231               (const_string "ssemul")
12232               (const_string "sseadd"))
12233            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12234               (const_string "fmul")
12235               (const_string "fop"))))
12236    (set_attr "prefix" "orig,maybe_vex")
12237    (set_attr "mode" "<MODE>")])
12238
12239 (define_insn "*fop_<mode>_comm_mixed"
12240   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12241         (match_operator:MODEF 3 "binary_fp_operator"
12242           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12243            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12244   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12245    && COMMUTATIVE_ARITH_P (operands[3])
12246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12247   "* return output_387_binary_op (insn, operands);"
12248   [(set (attr "type")
12249         (if_then_else (eq_attr "alternative" "1")
12250            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12251               (const_string "ssemul")
12252               (const_string "sseadd"))
12253            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12254               (const_string "fmul")
12255               (const_string "fop"))))
12256    (set_attr "mode" "<MODE>")])
12257
12258 (define_insn "*fop_<mode>_comm_avx"
12259   [(set (match_operand:MODEF 0 "register_operand" "=x")
12260         (match_operator:MODEF 3 "binary_fp_operator"
12261           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12262            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12263   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12264    && COMMUTATIVE_ARITH_P (operands[3])
12265    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12266   "* return output_387_binary_op (insn, operands);"
12267   [(set (attr "type")
12268         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12269            (const_string "ssemul")
12270            (const_string "sseadd")))
12271    (set_attr "prefix" "vex")
12272    (set_attr "mode" "<MODE>")])
12273
12274 (define_insn "*fop_<mode>_comm_sse"
12275   [(set (match_operand:MODEF 0 "register_operand" "=x")
12276         (match_operator:MODEF 3 "binary_fp_operator"
12277           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12278            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12279   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12280    && COMMUTATIVE_ARITH_P (operands[3])
12281    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12282   "* return output_387_binary_op (insn, operands);"
12283   [(set (attr "type")
12284         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12285            (const_string "ssemul")
12286            (const_string "sseadd")))
12287    (set_attr "mode" "<MODE>")])
12288
12289 (define_insn "*fop_<mode>_comm_i387"
12290   [(set (match_operand:MODEF 0 "register_operand" "=f")
12291         (match_operator:MODEF 3 "binary_fp_operator"
12292           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12293            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12294   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12295    && COMMUTATIVE_ARITH_P (operands[3])
12296    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12297   "* return output_387_binary_op (insn, operands);"
12298   [(set (attr "type")
12299         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12300            (const_string "fmul")
12301            (const_string "fop")))
12302    (set_attr "mode" "<MODE>")])
12303
12304 (define_insn "*fop_<mode>_1_mixed_avx"
12305   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12306         (match_operator:MODEF 3 "binary_fp_operator"
12307           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12308            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12309   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12310    && !COMMUTATIVE_ARITH_P (operands[3])
12311    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12312   "* return output_387_binary_op (insn, operands);"
12313   [(set (attr "type")
12314         (cond [(and (eq_attr "alternative" "2")
12315                     (match_operand:MODEF 3 "mult_operator" ""))
12316                  (const_string "ssemul")
12317                (and (eq_attr "alternative" "2")
12318                     (match_operand:MODEF 3 "div_operator" ""))
12319                  (const_string "ssediv")
12320                (eq_attr "alternative" "2")
12321                  (const_string "sseadd")
12322                (match_operand:MODEF 3 "mult_operator" "")
12323                  (const_string "fmul")
12324                (match_operand:MODEF 3 "div_operator" "")
12325                  (const_string "fdiv")
12326               ]
12327               (const_string "fop")))
12328    (set_attr "prefix" "orig,orig,maybe_vex")
12329    (set_attr "mode" "<MODE>")])
12330
12331 (define_insn "*fop_<mode>_1_mixed"
12332   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12333         (match_operator:MODEF 3 "binary_fp_operator"
12334           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12335            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12336   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12337    && !COMMUTATIVE_ARITH_P (operands[3])
12338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12339   "* return output_387_binary_op (insn, operands);"
12340   [(set (attr "type")
12341         (cond [(and (eq_attr "alternative" "2")
12342                     (match_operand:MODEF 3 "mult_operator" ""))
12343                  (const_string "ssemul")
12344                (and (eq_attr "alternative" "2")
12345                     (match_operand:MODEF 3 "div_operator" ""))
12346                  (const_string "ssediv")
12347                (eq_attr "alternative" "2")
12348                  (const_string "sseadd")
12349                (match_operand:MODEF 3 "mult_operator" "")
12350                  (const_string "fmul")
12351                (match_operand:MODEF 3 "div_operator" "")
12352                  (const_string "fdiv")
12353               ]
12354               (const_string "fop")))
12355    (set_attr "mode" "<MODE>")])
12356
12357 (define_insn "*rcpsf2_sse"
12358   [(set (match_operand:SF 0 "register_operand" "=x")
12359         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12360                    UNSPEC_RCP))]
12361   "TARGET_SSE_MATH"
12362   "%vrcpss\t{%1, %d0|%d0, %1}"
12363   [(set_attr "type" "sse")
12364    (set_attr "atom_sse_attr" "rcp")
12365    (set_attr "prefix" "maybe_vex")
12366    (set_attr "mode" "SF")])
12367
12368 (define_insn "*fop_<mode>_1_avx"
12369   [(set (match_operand:MODEF 0 "register_operand" "=x")
12370         (match_operator:MODEF 3 "binary_fp_operator"
12371           [(match_operand:MODEF 1 "register_operand" "x")
12372            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12373   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12374    && !COMMUTATIVE_ARITH_P (operands[3])"
12375   "* return output_387_binary_op (insn, operands);"
12376   [(set (attr "type")
12377         (cond [(match_operand:MODEF 3 "mult_operator" "")
12378                  (const_string "ssemul")
12379                (match_operand:MODEF 3 "div_operator" "")
12380                  (const_string "ssediv")
12381               ]
12382               (const_string "sseadd")))
12383    (set_attr "prefix" "vex")
12384    (set_attr "mode" "<MODE>")])
12385
12386 (define_insn "*fop_<mode>_1_sse"
12387   [(set (match_operand:MODEF 0 "register_operand" "=x")
12388         (match_operator:MODEF 3 "binary_fp_operator"
12389           [(match_operand:MODEF 1 "register_operand" "0")
12390            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12391   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12392    && !COMMUTATIVE_ARITH_P (operands[3])"
12393   "* return output_387_binary_op (insn, operands);"
12394   [(set (attr "type")
12395         (cond [(match_operand:MODEF 3 "mult_operator" "")
12396                  (const_string "ssemul")
12397                (match_operand:MODEF 3 "div_operator" "")
12398                  (const_string "ssediv")
12399               ]
12400               (const_string "sseadd")))
12401    (set_attr "mode" "<MODE>")])
12402
12403 ;; This pattern is not fully shadowed by the pattern above.
12404 (define_insn "*fop_<mode>_1_i387"
12405   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12406         (match_operator:MODEF 3 "binary_fp_operator"
12407           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12408            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12409   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12410    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12411    && !COMMUTATIVE_ARITH_P (operands[3])
12412    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12413   "* return output_387_binary_op (insn, operands);"
12414   [(set (attr "type")
12415         (cond [(match_operand:MODEF 3 "mult_operator" "")
12416                  (const_string "fmul")
12417                (match_operand:MODEF 3 "div_operator" "")
12418                  (const_string "fdiv")
12419               ]
12420               (const_string "fop")))
12421    (set_attr "mode" "<MODE>")])
12422
12423 ;; ??? Add SSE splitters for these!
12424 (define_insn "*fop_<MODEF:mode>_2_i387"
12425   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12426         (match_operator:MODEF 3 "binary_fp_operator"
12427           [(float:MODEF
12428              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12429            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12430   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12431    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12432    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12433   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12434   [(set (attr "type")
12435         (cond [(match_operand:MODEF 3 "mult_operator" "")
12436                  (const_string "fmul")
12437                (match_operand:MODEF 3 "div_operator" "")
12438                  (const_string "fdiv")
12439               ]
12440               (const_string "fop")))
12441    (set_attr "fp_int_src" "true")
12442    (set_attr "mode" "<X87MODEI12:MODE>")])
12443
12444 (define_insn "*fop_<MODEF:mode>_3_i387"
12445   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12446         (match_operator:MODEF 3 "binary_fp_operator"
12447           [(match_operand:MODEF 1 "register_operand" "0,0")
12448            (float:MODEF
12449              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12450   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12451    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12452    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12453   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12454   [(set (attr "type")
12455         (cond [(match_operand:MODEF 3 "mult_operator" "")
12456                  (const_string "fmul")
12457                (match_operand:MODEF 3 "div_operator" "")
12458                  (const_string "fdiv")
12459               ]
12460               (const_string "fop")))
12461    (set_attr "fp_int_src" "true")
12462    (set_attr "mode" "<MODE>")])
12463
12464 (define_insn "*fop_df_4_i387"
12465   [(set (match_operand:DF 0 "register_operand" "=f,f")
12466         (match_operator:DF 3 "binary_fp_operator"
12467            [(float_extend:DF
12468              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12469             (match_operand:DF 2 "register_operand" "0,f")]))]
12470   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12471    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12472    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12473   "* return output_387_binary_op (insn, operands);"
12474   [(set (attr "type")
12475         (cond [(match_operand:DF 3 "mult_operator" "")
12476                  (const_string "fmul")
12477                (match_operand:DF 3 "div_operator" "")
12478                  (const_string "fdiv")
12479               ]
12480               (const_string "fop")))
12481    (set_attr "mode" "SF")])
12482
12483 (define_insn "*fop_df_5_i387"
12484   [(set (match_operand:DF 0 "register_operand" "=f,f")
12485         (match_operator:DF 3 "binary_fp_operator"
12486           [(match_operand:DF 1 "register_operand" "0,f")
12487            (float_extend:DF
12488             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12489   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12490    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12491   "* return output_387_binary_op (insn, operands);"
12492   [(set (attr "type")
12493         (cond [(match_operand:DF 3 "mult_operator" "")
12494                  (const_string "fmul")
12495                (match_operand:DF 3 "div_operator" "")
12496                  (const_string "fdiv")
12497               ]
12498               (const_string "fop")))
12499    (set_attr "mode" "SF")])
12500
12501 (define_insn "*fop_df_6_i387"
12502   [(set (match_operand:DF 0 "register_operand" "=f,f")
12503         (match_operator:DF 3 "binary_fp_operator"
12504           [(float_extend:DF
12505             (match_operand:SF 1 "register_operand" "0,f"))
12506            (float_extend:DF
12507             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12508   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12509    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12510   "* return output_387_binary_op (insn, operands);"
12511   [(set (attr "type")
12512         (cond [(match_operand:DF 3 "mult_operator" "")
12513                  (const_string "fmul")
12514                (match_operand:DF 3 "div_operator" "")
12515                  (const_string "fdiv")
12516               ]
12517               (const_string "fop")))
12518    (set_attr "mode" "SF")])
12519
12520 (define_insn "*fop_xf_comm_i387"
12521   [(set (match_operand:XF 0 "register_operand" "=f")
12522         (match_operator:XF 3 "binary_fp_operator"
12523                         [(match_operand:XF 1 "register_operand" "%0")
12524                          (match_operand:XF 2 "register_operand" "f")]))]
12525   "TARGET_80387
12526    && COMMUTATIVE_ARITH_P (operands[3])"
12527   "* return output_387_binary_op (insn, operands);"
12528   [(set (attr "type")
12529         (if_then_else (match_operand:XF 3 "mult_operator" "")
12530            (const_string "fmul")
12531            (const_string "fop")))
12532    (set_attr "mode" "XF")])
12533
12534 (define_insn "*fop_xf_1_i387"
12535   [(set (match_operand:XF 0 "register_operand" "=f,f")
12536         (match_operator:XF 3 "binary_fp_operator"
12537                         [(match_operand:XF 1 "register_operand" "0,f")
12538                          (match_operand:XF 2 "register_operand" "f,0")]))]
12539   "TARGET_80387
12540    && !COMMUTATIVE_ARITH_P (operands[3])"
12541   "* return output_387_binary_op (insn, operands);"
12542   [(set (attr "type")
12543         (cond [(match_operand:XF 3 "mult_operator" "")
12544                  (const_string "fmul")
12545                (match_operand:XF 3 "div_operator" "")
12546                  (const_string "fdiv")
12547               ]
12548               (const_string "fop")))
12549    (set_attr "mode" "XF")])
12550
12551 (define_insn "*fop_xf_2_i387"
12552   [(set (match_operand:XF 0 "register_operand" "=f,f")
12553         (match_operator:XF 3 "binary_fp_operator"
12554           [(float:XF
12555              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12556            (match_operand:XF 2 "register_operand" "0,0")]))]
12557   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12558   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12559   [(set (attr "type")
12560         (cond [(match_operand:XF 3 "mult_operator" "")
12561                  (const_string "fmul")
12562                (match_operand:XF 3 "div_operator" "")
12563                  (const_string "fdiv")
12564               ]
12565               (const_string "fop")))
12566    (set_attr "fp_int_src" "true")
12567    (set_attr "mode" "<MODE>")])
12568
12569 (define_insn "*fop_xf_3_i387"
12570   [(set (match_operand:XF 0 "register_operand" "=f,f")
12571         (match_operator:XF 3 "binary_fp_operator"
12572           [(match_operand:XF 1 "register_operand" "0,0")
12573            (float:XF
12574              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12575   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12576   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12577   [(set (attr "type")
12578         (cond [(match_operand:XF 3 "mult_operator" "")
12579                  (const_string "fmul")
12580                (match_operand:XF 3 "div_operator" "")
12581                  (const_string "fdiv")
12582               ]
12583               (const_string "fop")))
12584    (set_attr "fp_int_src" "true")
12585    (set_attr "mode" "<MODE>")])
12586
12587 (define_insn "*fop_xf_4_i387"
12588   [(set (match_operand:XF 0 "register_operand" "=f,f")
12589         (match_operator:XF 3 "binary_fp_operator"
12590            [(float_extend:XF
12591               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12592             (match_operand:XF 2 "register_operand" "0,f")]))]
12593   "TARGET_80387"
12594   "* return output_387_binary_op (insn, operands);"
12595   [(set (attr "type")
12596         (cond [(match_operand:XF 3 "mult_operator" "")
12597                  (const_string "fmul")
12598                (match_operand:XF 3 "div_operator" "")
12599                  (const_string "fdiv")
12600               ]
12601               (const_string "fop")))
12602    (set_attr "mode" "<MODE>")])
12603
12604 (define_insn "*fop_xf_5_i387"
12605   [(set (match_operand:XF 0 "register_operand" "=f,f")
12606         (match_operator:XF 3 "binary_fp_operator"
12607           [(match_operand:XF 1 "register_operand" "0,f")
12608            (float_extend:XF
12609              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12610   "TARGET_80387"
12611   "* return output_387_binary_op (insn, operands);"
12612   [(set (attr "type")
12613         (cond [(match_operand:XF 3 "mult_operator" "")
12614                  (const_string "fmul")
12615                (match_operand:XF 3 "div_operator" "")
12616                  (const_string "fdiv")
12617               ]
12618               (const_string "fop")))
12619    (set_attr "mode" "<MODE>")])
12620
12621 (define_insn "*fop_xf_6_i387"
12622   [(set (match_operand:XF 0 "register_operand" "=f,f")
12623         (match_operator:XF 3 "binary_fp_operator"
12624           [(float_extend:XF
12625              (match_operand:MODEF 1 "register_operand" "0,f"))
12626            (float_extend:XF
12627              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12628   "TARGET_80387"
12629   "* return output_387_binary_op (insn, operands);"
12630   [(set (attr "type")
12631         (cond [(match_operand:XF 3 "mult_operator" "")
12632                  (const_string "fmul")
12633                (match_operand:XF 3 "div_operator" "")
12634                  (const_string "fdiv")
12635               ]
12636               (const_string "fop")))
12637    (set_attr "mode" "<MODE>")])
12638
12639 (define_split
12640   [(set (match_operand 0 "register_operand" "")
12641         (match_operator 3 "binary_fp_operator"
12642            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12643             (match_operand 2 "register_operand" "")]))]
12644   "reload_completed
12645    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12646    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12647   [(const_int 0)]
12648 {
12649   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12650   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12651   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12652                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12653                                           GET_MODE (operands[3]),
12654                                           operands[4],
12655                                           operands[2])));
12656   ix86_free_from_memory (GET_MODE (operands[1]));
12657   DONE;
12658 })
12659
12660 (define_split
12661   [(set (match_operand 0 "register_operand" "")
12662         (match_operator 3 "binary_fp_operator"
12663            [(match_operand 1 "register_operand" "")
12664             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12665   "reload_completed
12666    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12667    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12668   [(const_int 0)]
12669 {
12670   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12671   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12672   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12673                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12674                                           GET_MODE (operands[3]),
12675                                           operands[1],
12676                                           operands[4])));
12677   ix86_free_from_memory (GET_MODE (operands[2]));
12678   DONE;
12679 })
12680 \f
12681 ;; FPU special functions.
12682
12683 ;; This pattern implements a no-op XFmode truncation for
12684 ;; all fancy i386 XFmode math functions.
12685
12686 (define_insn "truncxf<mode>2_i387_noop_unspec"
12687   [(set (match_operand:MODEF 0 "register_operand" "=f")
12688         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12689         UNSPEC_TRUNC_NOOP))]
12690   "TARGET_USE_FANCY_MATH_387"
12691   "* return output_387_reg_move (insn, operands);"
12692   [(set_attr "type" "fmov")
12693    (set_attr "mode" "<MODE>")])
12694
12695 (define_insn "sqrtxf2"
12696   [(set (match_operand:XF 0 "register_operand" "=f")
12697         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12698   "TARGET_USE_FANCY_MATH_387"
12699   "fsqrt"
12700   [(set_attr "type" "fpspc")
12701    (set_attr "mode" "XF")
12702    (set_attr "athlon_decode" "direct")
12703    (set_attr "amdfam10_decode" "direct")])
12704
12705 (define_insn "sqrt_extend<mode>xf2_i387"
12706   [(set (match_operand:XF 0 "register_operand" "=f")
12707         (sqrt:XF
12708           (float_extend:XF
12709             (match_operand:MODEF 1 "register_operand" "0"))))]
12710   "TARGET_USE_FANCY_MATH_387"
12711   "fsqrt"
12712   [(set_attr "type" "fpspc")
12713    (set_attr "mode" "XF")
12714    (set_attr "athlon_decode" "direct")
12715    (set_attr "amdfam10_decode" "direct")])
12716
12717 (define_insn "*rsqrtsf2_sse"
12718   [(set (match_operand:SF 0 "register_operand" "=x")
12719         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12720                    UNSPEC_RSQRT))]
12721   "TARGET_SSE_MATH"
12722   "%vrsqrtss\t{%1, %d0|%d0, %1}"
12723   [(set_attr "type" "sse")
12724    (set_attr "atom_sse_attr" "rcp")
12725    (set_attr "prefix" "maybe_vex")
12726    (set_attr "mode" "SF")])
12727
12728 (define_expand "rsqrtsf2"
12729   [(set (match_operand:SF 0 "register_operand" "")
12730         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12731                    UNSPEC_RSQRT))]
12732   "TARGET_SSE_MATH"
12733 {
12734   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12735   DONE;
12736 })
12737
12738 (define_insn "*sqrt<mode>2_sse"
12739   [(set (match_operand:MODEF 0 "register_operand" "=x")
12740         (sqrt:MODEF
12741           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12742   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12743   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12744   [(set_attr "type" "sse")
12745    (set_attr "atom_sse_attr" "sqrt")
12746    (set_attr "prefix" "maybe_vex")
12747    (set_attr "mode" "<MODE>")
12748    (set_attr "athlon_decode" "*")
12749    (set_attr "amdfam10_decode" "*")])
12750
12751 (define_expand "sqrt<mode>2"
12752   [(set (match_operand:MODEF 0 "register_operand" "")
12753         (sqrt:MODEF
12754           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12755   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12756    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12757 {
12758   if (<MODE>mode == SFmode
12759       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12760       && flag_finite_math_only && !flag_trapping_math
12761       && flag_unsafe_math_optimizations)
12762     {
12763       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12764       DONE;
12765     }
12766
12767   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12768     {
12769       rtx op0 = gen_reg_rtx (XFmode);
12770       rtx op1 = force_reg (<MODE>mode, operands[1]);
12771
12772       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12773       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12774       DONE;
12775    }
12776 })
12777
12778 (define_insn "fpremxf4_i387"
12779   [(set (match_operand:XF 0 "register_operand" "=f")
12780         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12781                     (match_operand:XF 3 "register_operand" "1")]
12782                    UNSPEC_FPREM_F))
12783    (set (match_operand:XF 1 "register_operand" "=u")
12784         (unspec:XF [(match_dup 2) (match_dup 3)]
12785                    UNSPEC_FPREM_U))
12786    (set (reg:CCFP FPSR_REG)
12787         (unspec:CCFP [(match_dup 2) (match_dup 3)]
12788                      UNSPEC_C2_FLAG))]
12789   "TARGET_USE_FANCY_MATH_387"
12790   "fprem"
12791   [(set_attr "type" "fpspc")
12792    (set_attr "mode" "XF")])
12793
12794 (define_expand "fmodxf3"
12795   [(use (match_operand:XF 0 "register_operand" ""))
12796    (use (match_operand:XF 1 "general_operand" ""))
12797    (use (match_operand:XF 2 "general_operand" ""))]
12798   "TARGET_USE_FANCY_MATH_387"
12799 {
12800   rtx label = gen_label_rtx ();
12801
12802   rtx op1 = gen_reg_rtx (XFmode);
12803   rtx op2 = gen_reg_rtx (XFmode);
12804
12805   emit_move_insn (op2, operands[2]);
12806   emit_move_insn (op1, operands[1]);
12807
12808   emit_label (label);
12809   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12810   ix86_emit_fp_unordered_jump (label);
12811   LABEL_NUSES (label) = 1;
12812
12813   emit_move_insn (operands[0], op1);
12814   DONE;
12815 })
12816
12817 (define_expand "fmod<mode>3"
12818   [(use (match_operand:MODEF 0 "register_operand" ""))
12819    (use (match_operand:MODEF 1 "general_operand" ""))
12820    (use (match_operand:MODEF 2 "general_operand" ""))]
12821   "TARGET_USE_FANCY_MATH_387"
12822 {
12823   rtx (*gen_truncxf) (rtx, rtx);
12824
12825   rtx label = gen_label_rtx ();
12826
12827   rtx op1 = gen_reg_rtx (XFmode);
12828   rtx op2 = gen_reg_rtx (XFmode);
12829
12830   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12831   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12832
12833   emit_label (label);
12834   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12835   ix86_emit_fp_unordered_jump (label);
12836   LABEL_NUSES (label) = 1;
12837
12838   /* Truncate the result properly for strict SSE math.  */
12839   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12840       && !TARGET_MIX_SSE_I387)
12841     gen_truncxf = gen_truncxf<mode>2;
12842   else
12843     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12844
12845   emit_insn (gen_truncxf (operands[0], op1));
12846   DONE;
12847 })
12848
12849 (define_insn "fprem1xf4_i387"
12850   [(set (match_operand:XF 0 "register_operand" "=f")
12851         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12852                     (match_operand:XF 3 "register_operand" "1")]
12853                    UNSPEC_FPREM1_F))
12854    (set (match_operand:XF 1 "register_operand" "=u")
12855         (unspec:XF [(match_dup 2) (match_dup 3)]
12856                    UNSPEC_FPREM1_U))
12857    (set (reg:CCFP FPSR_REG)
12858         (unspec:CCFP [(match_dup 2) (match_dup 3)]
12859                      UNSPEC_C2_FLAG))]
12860   "TARGET_USE_FANCY_MATH_387"
12861   "fprem1"
12862   [(set_attr "type" "fpspc")
12863    (set_attr "mode" "XF")])
12864
12865 (define_expand "remainderxf3"
12866   [(use (match_operand:XF 0 "register_operand" ""))
12867    (use (match_operand:XF 1 "general_operand" ""))
12868    (use (match_operand:XF 2 "general_operand" ""))]
12869   "TARGET_USE_FANCY_MATH_387"
12870 {
12871   rtx label = gen_label_rtx ();
12872
12873   rtx op1 = gen_reg_rtx (XFmode);
12874   rtx op2 = gen_reg_rtx (XFmode);
12875
12876   emit_move_insn (op2, operands[2]);
12877   emit_move_insn (op1, operands[1]);
12878
12879   emit_label (label);
12880   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12881   ix86_emit_fp_unordered_jump (label);
12882   LABEL_NUSES (label) = 1;
12883
12884   emit_move_insn (operands[0], op1);
12885   DONE;
12886 })
12887
12888 (define_expand "remainder<mode>3"
12889   [(use (match_operand:MODEF 0 "register_operand" ""))
12890    (use (match_operand:MODEF 1 "general_operand" ""))
12891    (use (match_operand:MODEF 2 "general_operand" ""))]
12892   "TARGET_USE_FANCY_MATH_387"
12893 {
12894   rtx (*gen_truncxf) (rtx, rtx);
12895
12896   rtx label = gen_label_rtx ();
12897
12898   rtx op1 = gen_reg_rtx (XFmode);
12899   rtx op2 = gen_reg_rtx (XFmode);
12900
12901   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12902   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12903
12904   emit_label (label);
12905
12906   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12907   ix86_emit_fp_unordered_jump (label);
12908   LABEL_NUSES (label) = 1;
12909
12910   /* Truncate the result properly for strict SSE math.  */
12911   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12912       && !TARGET_MIX_SSE_I387)
12913     gen_truncxf = gen_truncxf<mode>2;
12914   else
12915     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12916
12917   emit_insn (gen_truncxf (operands[0], op1));
12918   DONE;
12919 })
12920
12921 (define_insn "*sinxf2_i387"
12922   [(set (match_operand:XF 0 "register_operand" "=f")
12923         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
12924   "TARGET_USE_FANCY_MATH_387
12925    && flag_unsafe_math_optimizations"
12926   "fsin"
12927   [(set_attr "type" "fpspc")
12928    (set_attr "mode" "XF")])
12929
12930 (define_insn "*sin_extend<mode>xf2_i387"
12931   [(set (match_operand:XF 0 "register_operand" "=f")
12932         (unspec:XF [(float_extend:XF
12933                       (match_operand:MODEF 1 "register_operand" "0"))]
12934                    UNSPEC_SIN))]
12935   "TARGET_USE_FANCY_MATH_387
12936    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12937        || TARGET_MIX_SSE_I387)
12938    && flag_unsafe_math_optimizations"
12939   "fsin"
12940   [(set_attr "type" "fpspc")
12941    (set_attr "mode" "XF")])
12942
12943 (define_insn "*cosxf2_i387"
12944   [(set (match_operand:XF 0 "register_operand" "=f")
12945         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
12946   "TARGET_USE_FANCY_MATH_387
12947    && flag_unsafe_math_optimizations"
12948   "fcos"
12949   [(set_attr "type" "fpspc")
12950    (set_attr "mode" "XF")])
12951
12952 (define_insn "*cos_extend<mode>xf2_i387"
12953   [(set (match_operand:XF 0 "register_operand" "=f")
12954         (unspec:XF [(float_extend:XF
12955                       (match_operand:MODEF 1 "register_operand" "0"))]
12956                    UNSPEC_COS))]
12957   "TARGET_USE_FANCY_MATH_387
12958    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12959        || TARGET_MIX_SSE_I387)
12960    && flag_unsafe_math_optimizations"
12961   "fcos"
12962   [(set_attr "type" "fpspc")
12963    (set_attr "mode" "XF")])
12964
12965 ;; When sincos pattern is defined, sin and cos builtin functions will be
12966 ;; expanded to sincos pattern with one of its outputs left unused.
12967 ;; CSE pass will figure out if two sincos patterns can be combined,
12968 ;; otherwise sincos pattern will be split back to sin or cos pattern,
12969 ;; depending on the unused output.
12970
12971 (define_insn "sincosxf3"
12972   [(set (match_operand:XF 0 "register_operand" "=f")
12973         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
12974                    UNSPEC_SINCOS_COS))
12975    (set (match_operand:XF 1 "register_operand" "=u")
12976         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
12977   "TARGET_USE_FANCY_MATH_387
12978    && flag_unsafe_math_optimizations"
12979   "fsincos"
12980   [(set_attr "type" "fpspc")
12981    (set_attr "mode" "XF")])
12982
12983 (define_split
12984   [(set (match_operand:XF 0 "register_operand" "")
12985         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
12986                    UNSPEC_SINCOS_COS))
12987    (set (match_operand:XF 1 "register_operand" "")
12988         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
12989   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
12990    && !(reload_completed || reload_in_progress)"
12991   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
12992
12993 (define_split
12994   [(set (match_operand:XF 0 "register_operand" "")
12995         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
12996                    UNSPEC_SINCOS_COS))
12997    (set (match_operand:XF 1 "register_operand" "")
12998         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
12999   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13000    && !(reload_completed || reload_in_progress)"
13001   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13002
13003 (define_insn "sincos_extend<mode>xf3_i387"
13004   [(set (match_operand:XF 0 "register_operand" "=f")
13005         (unspec:XF [(float_extend:XF
13006                       (match_operand:MODEF 2 "register_operand" "0"))]
13007                    UNSPEC_SINCOS_COS))
13008    (set (match_operand:XF 1 "register_operand" "=u")
13009         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13010   "TARGET_USE_FANCY_MATH_387
13011    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13012        || TARGET_MIX_SSE_I387)
13013    && flag_unsafe_math_optimizations"
13014   "fsincos"
13015   [(set_attr "type" "fpspc")
13016    (set_attr "mode" "XF")])
13017
13018 (define_split
13019   [(set (match_operand:XF 0 "register_operand" "")
13020         (unspec:XF [(float_extend:XF
13021                       (match_operand:MODEF 2 "register_operand" ""))]
13022                    UNSPEC_SINCOS_COS))
13023    (set (match_operand:XF 1 "register_operand" "")
13024         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13025   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13026    && !(reload_completed || reload_in_progress)"
13027   [(set (match_dup 1)
13028         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13029
13030 (define_split
13031   [(set (match_operand:XF 0 "register_operand" "")
13032         (unspec:XF [(float_extend:XF
13033                       (match_operand:MODEF 2 "register_operand" ""))]
13034                    UNSPEC_SINCOS_COS))
13035    (set (match_operand:XF 1 "register_operand" "")
13036         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13037   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13038    && !(reload_completed || reload_in_progress)"
13039   [(set (match_dup 0)
13040         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13041
13042 (define_expand "sincos<mode>3"
13043   [(use (match_operand:MODEF 0 "register_operand" ""))
13044    (use (match_operand:MODEF 1 "register_operand" ""))
13045    (use (match_operand:MODEF 2 "register_operand" ""))]
13046   "TARGET_USE_FANCY_MATH_387
13047    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13048        || TARGET_MIX_SSE_I387)
13049    && flag_unsafe_math_optimizations"
13050 {
13051   rtx op0 = gen_reg_rtx (XFmode);
13052   rtx op1 = gen_reg_rtx (XFmode);
13053
13054   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13055   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13056   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13057   DONE;
13058 })
13059
13060 (define_insn "fptanxf4_i387"
13061   [(set (match_operand:XF 0 "register_operand" "=f")
13062         (match_operand:XF 3 "const_double_operand" "F"))
13063    (set (match_operand:XF 1 "register_operand" "=u")
13064         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13065                    UNSPEC_TAN))]
13066   "TARGET_USE_FANCY_MATH_387
13067    && flag_unsafe_math_optimizations
13068    && standard_80387_constant_p (operands[3]) == 2"
13069   "fptan"
13070   [(set_attr "type" "fpspc")
13071    (set_attr "mode" "XF")])
13072
13073 (define_insn "fptan_extend<mode>xf4_i387"
13074   [(set (match_operand:MODEF 0 "register_operand" "=f")
13075         (match_operand:MODEF 3 "const_double_operand" "F"))
13076    (set (match_operand:XF 1 "register_operand" "=u")
13077         (unspec:XF [(float_extend:XF
13078                       (match_operand:MODEF 2 "register_operand" "0"))]
13079                    UNSPEC_TAN))]
13080   "TARGET_USE_FANCY_MATH_387
13081    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13082        || TARGET_MIX_SSE_I387)
13083    && flag_unsafe_math_optimizations
13084    && standard_80387_constant_p (operands[3]) == 2"
13085   "fptan"
13086   [(set_attr "type" "fpspc")
13087    (set_attr "mode" "XF")])
13088
13089 (define_expand "tanxf2"
13090   [(use (match_operand:XF 0 "register_operand" ""))
13091    (use (match_operand:XF 1 "register_operand" ""))]
13092   "TARGET_USE_FANCY_MATH_387
13093    && flag_unsafe_math_optimizations"
13094 {
13095   rtx one = gen_reg_rtx (XFmode);
13096   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13097
13098   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13099   DONE;
13100 })
13101
13102 (define_expand "tan<mode>2"
13103   [(use (match_operand:MODEF 0 "register_operand" ""))
13104    (use (match_operand:MODEF 1 "register_operand" ""))]
13105   "TARGET_USE_FANCY_MATH_387
13106    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13107        || TARGET_MIX_SSE_I387)
13108    && flag_unsafe_math_optimizations"
13109 {
13110   rtx op0 = gen_reg_rtx (XFmode);
13111
13112   rtx one = gen_reg_rtx (<MODE>mode);
13113   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13114
13115   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13116                                              operands[1], op2));
13117   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13118   DONE;
13119 })
13120
13121 (define_insn "*fpatanxf3_i387"
13122   [(set (match_operand:XF 0 "register_operand" "=f")
13123         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13124                     (match_operand:XF 2 "register_operand" "u")]
13125                    UNSPEC_FPATAN))
13126    (clobber (match_scratch:XF 3 "=2"))]
13127   "TARGET_USE_FANCY_MATH_387
13128    && flag_unsafe_math_optimizations"
13129   "fpatan"
13130   [(set_attr "type" "fpspc")
13131    (set_attr "mode" "XF")])
13132
13133 (define_insn "fpatan_extend<mode>xf3_i387"
13134   [(set (match_operand:XF 0 "register_operand" "=f")
13135         (unspec:XF [(float_extend:XF
13136                       (match_operand:MODEF 1 "register_operand" "0"))
13137                     (float_extend:XF
13138                       (match_operand:MODEF 2 "register_operand" "u"))]
13139                    UNSPEC_FPATAN))
13140    (clobber (match_scratch:XF 3 "=2"))]
13141   "TARGET_USE_FANCY_MATH_387
13142    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13143        || TARGET_MIX_SSE_I387)
13144    && flag_unsafe_math_optimizations"
13145   "fpatan"
13146   [(set_attr "type" "fpspc")
13147    (set_attr "mode" "XF")])
13148
13149 (define_expand "atan2xf3"
13150   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13151                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13152                                (match_operand:XF 1 "register_operand" "")]
13153                               UNSPEC_FPATAN))
13154               (clobber (match_scratch:XF 3 ""))])]
13155   "TARGET_USE_FANCY_MATH_387
13156    && flag_unsafe_math_optimizations"
13157   "")
13158
13159 (define_expand "atan2<mode>3"
13160   [(use (match_operand:MODEF 0 "register_operand" ""))
13161    (use (match_operand:MODEF 1 "register_operand" ""))
13162    (use (match_operand:MODEF 2 "register_operand" ""))]
13163   "TARGET_USE_FANCY_MATH_387
13164    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13165        || TARGET_MIX_SSE_I387)
13166    && flag_unsafe_math_optimizations"
13167 {
13168   rtx op0 = gen_reg_rtx (XFmode);
13169
13170   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13171   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13172   DONE;
13173 })
13174
13175 (define_expand "atanxf2"
13176   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13177                    (unspec:XF [(match_dup 2)
13178                                (match_operand:XF 1 "register_operand" "")]
13179                               UNSPEC_FPATAN))
13180               (clobber (match_scratch:XF 3 ""))])]
13181   "TARGET_USE_FANCY_MATH_387
13182    && flag_unsafe_math_optimizations"
13183 {
13184   operands[2] = gen_reg_rtx (XFmode);
13185   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13186 })
13187
13188 (define_expand "atan<mode>2"
13189   [(use (match_operand:MODEF 0 "register_operand" ""))
13190    (use (match_operand:MODEF 1 "register_operand" ""))]
13191   "TARGET_USE_FANCY_MATH_387
13192    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13193        || TARGET_MIX_SSE_I387)
13194    && flag_unsafe_math_optimizations"
13195 {
13196   rtx op0 = gen_reg_rtx (XFmode);
13197
13198   rtx op2 = gen_reg_rtx (<MODE>mode);
13199   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13200
13201   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13202   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13203   DONE;
13204 })
13205
13206 (define_expand "asinxf2"
13207   [(set (match_dup 2)
13208         (mult:XF (match_operand:XF 1 "register_operand" "")
13209                  (match_dup 1)))
13210    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13211    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13212    (parallel [(set (match_operand:XF 0 "register_operand" "")
13213                    (unspec:XF [(match_dup 5) (match_dup 1)]
13214                               UNSPEC_FPATAN))
13215               (clobber (match_scratch:XF 6 ""))])]
13216   "TARGET_USE_FANCY_MATH_387
13217    && flag_unsafe_math_optimizations"
13218 {
13219   int i;
13220
13221   if (optimize_insn_for_size_p ())
13222     FAIL;
13223
13224   for (i = 2; i < 6; i++)
13225     operands[i] = gen_reg_rtx (XFmode);
13226
13227   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13228 })
13229
13230 (define_expand "asin<mode>2"
13231   [(use (match_operand:MODEF 0 "register_operand" ""))
13232    (use (match_operand:MODEF 1 "general_operand" ""))]
13233  "TARGET_USE_FANCY_MATH_387
13234    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13235        || TARGET_MIX_SSE_I387)
13236    && flag_unsafe_math_optimizations"
13237 {
13238   rtx op0 = gen_reg_rtx (XFmode);
13239   rtx op1 = gen_reg_rtx (XFmode);
13240
13241   if (optimize_insn_for_size_p ())
13242     FAIL;
13243
13244   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13245   emit_insn (gen_asinxf2 (op0, op1));
13246   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13247   DONE;
13248 })
13249
13250 (define_expand "acosxf2"
13251   [(set (match_dup 2)
13252         (mult:XF (match_operand:XF 1 "register_operand" "")
13253                  (match_dup 1)))
13254    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13255    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13256    (parallel [(set (match_operand:XF 0 "register_operand" "")
13257                    (unspec:XF [(match_dup 1) (match_dup 5)]
13258                               UNSPEC_FPATAN))
13259               (clobber (match_scratch:XF 6 ""))])]
13260   "TARGET_USE_FANCY_MATH_387
13261    && flag_unsafe_math_optimizations"
13262 {
13263   int i;
13264
13265   if (optimize_insn_for_size_p ())
13266     FAIL;
13267
13268   for (i = 2; i < 6; i++)
13269     operands[i] = gen_reg_rtx (XFmode);
13270
13271   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13272 })
13273
13274 (define_expand "acos<mode>2"
13275   [(use (match_operand:MODEF 0 "register_operand" ""))
13276    (use (match_operand:MODEF 1 "general_operand" ""))]
13277  "TARGET_USE_FANCY_MATH_387
13278    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13279        || TARGET_MIX_SSE_I387)
13280    && flag_unsafe_math_optimizations"
13281 {
13282   rtx op0 = gen_reg_rtx (XFmode);
13283   rtx op1 = gen_reg_rtx (XFmode);
13284
13285   if (optimize_insn_for_size_p ())
13286     FAIL;
13287
13288   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13289   emit_insn (gen_acosxf2 (op0, op1));
13290   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13291   DONE;
13292 })
13293
13294 (define_insn "fyl2xxf3_i387"
13295   [(set (match_operand:XF 0 "register_operand" "=f")
13296         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13297                     (match_operand:XF 2 "register_operand" "u")]
13298                    UNSPEC_FYL2X))
13299    (clobber (match_scratch:XF 3 "=2"))]
13300   "TARGET_USE_FANCY_MATH_387
13301    && flag_unsafe_math_optimizations"
13302   "fyl2x"
13303   [(set_attr "type" "fpspc")
13304    (set_attr "mode" "XF")])
13305
13306 (define_insn "fyl2x_extend<mode>xf3_i387"
13307   [(set (match_operand:XF 0 "register_operand" "=f")
13308         (unspec:XF [(float_extend:XF
13309                       (match_operand:MODEF 1 "register_operand" "0"))
13310                     (match_operand:XF 2 "register_operand" "u")]
13311                    UNSPEC_FYL2X))
13312    (clobber (match_scratch:XF 3 "=2"))]
13313   "TARGET_USE_FANCY_MATH_387
13314    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13315        || TARGET_MIX_SSE_I387)
13316    && flag_unsafe_math_optimizations"
13317   "fyl2x"
13318   [(set_attr "type" "fpspc")
13319    (set_attr "mode" "XF")])
13320
13321 (define_expand "logxf2"
13322   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13323                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13324                                (match_dup 2)] UNSPEC_FYL2X))
13325               (clobber (match_scratch:XF 3 ""))])]
13326   "TARGET_USE_FANCY_MATH_387
13327    && flag_unsafe_math_optimizations"
13328 {
13329   operands[2] = gen_reg_rtx (XFmode);
13330   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13331 })
13332
13333 (define_expand "log<mode>2"
13334   [(use (match_operand:MODEF 0 "register_operand" ""))
13335    (use (match_operand:MODEF 1 "register_operand" ""))]
13336   "TARGET_USE_FANCY_MATH_387
13337    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13338        || TARGET_MIX_SSE_I387)
13339    && flag_unsafe_math_optimizations"
13340 {
13341   rtx op0 = gen_reg_rtx (XFmode);
13342
13343   rtx op2 = gen_reg_rtx (XFmode);
13344   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13345
13346   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13347   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13348   DONE;
13349 })
13350
13351 (define_expand "log10xf2"
13352   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13353                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13354                                (match_dup 2)] UNSPEC_FYL2X))
13355               (clobber (match_scratch:XF 3 ""))])]
13356   "TARGET_USE_FANCY_MATH_387
13357    && flag_unsafe_math_optimizations"
13358 {
13359   operands[2] = gen_reg_rtx (XFmode);
13360   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13361 })
13362
13363 (define_expand "log10<mode>2"
13364   [(use (match_operand:MODEF 0 "register_operand" ""))
13365    (use (match_operand:MODEF 1 "register_operand" ""))]
13366   "TARGET_USE_FANCY_MATH_387
13367    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13368        || TARGET_MIX_SSE_I387)
13369    && flag_unsafe_math_optimizations"
13370 {
13371   rtx op0 = gen_reg_rtx (XFmode);
13372
13373   rtx op2 = gen_reg_rtx (XFmode);
13374   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13375
13376   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13377   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13378   DONE;
13379 })
13380
13381 (define_expand "log2xf2"
13382   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13383                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13384                                (match_dup 2)] UNSPEC_FYL2X))
13385               (clobber (match_scratch:XF 3 ""))])]
13386   "TARGET_USE_FANCY_MATH_387
13387    && flag_unsafe_math_optimizations"
13388 {
13389   operands[2] = gen_reg_rtx (XFmode);
13390   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13391 })
13392
13393 (define_expand "log2<mode>2"
13394   [(use (match_operand:MODEF 0 "register_operand" ""))
13395    (use (match_operand:MODEF 1 "register_operand" ""))]
13396   "TARGET_USE_FANCY_MATH_387
13397    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398        || TARGET_MIX_SSE_I387)
13399    && flag_unsafe_math_optimizations"
13400 {
13401   rtx op0 = gen_reg_rtx (XFmode);
13402
13403   rtx op2 = gen_reg_rtx (XFmode);
13404   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13405
13406   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13407   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13408   DONE;
13409 })
13410
13411 (define_insn "fyl2xp1xf3_i387"
13412   [(set (match_operand:XF 0 "register_operand" "=f")
13413         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13414                     (match_operand:XF 2 "register_operand" "u")]
13415                    UNSPEC_FYL2XP1))
13416    (clobber (match_scratch:XF 3 "=2"))]
13417   "TARGET_USE_FANCY_MATH_387
13418    && flag_unsafe_math_optimizations"
13419   "fyl2xp1"
13420   [(set_attr "type" "fpspc")
13421    (set_attr "mode" "XF")])
13422
13423 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13424   [(set (match_operand:XF 0 "register_operand" "=f")
13425         (unspec:XF [(float_extend:XF
13426                       (match_operand:MODEF 1 "register_operand" "0"))
13427                     (match_operand:XF 2 "register_operand" "u")]
13428                    UNSPEC_FYL2XP1))
13429    (clobber (match_scratch:XF 3 "=2"))]
13430   "TARGET_USE_FANCY_MATH_387
13431    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13432        || TARGET_MIX_SSE_I387)
13433    && flag_unsafe_math_optimizations"
13434   "fyl2xp1"
13435   [(set_attr "type" "fpspc")
13436    (set_attr "mode" "XF")])
13437
13438 (define_expand "log1pxf2"
13439   [(use (match_operand:XF 0 "register_operand" ""))
13440    (use (match_operand:XF 1 "register_operand" ""))]
13441   "TARGET_USE_FANCY_MATH_387
13442    && flag_unsafe_math_optimizations"
13443 {
13444   if (optimize_insn_for_size_p ())
13445     FAIL;
13446
13447   ix86_emit_i387_log1p (operands[0], operands[1]);
13448   DONE;
13449 })
13450
13451 (define_expand "log1p<mode>2"
13452   [(use (match_operand:MODEF 0 "register_operand" ""))
13453    (use (match_operand:MODEF 1 "register_operand" ""))]
13454   "TARGET_USE_FANCY_MATH_387
13455    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13456        || TARGET_MIX_SSE_I387)
13457    && flag_unsafe_math_optimizations"
13458 {
13459   rtx op0;
13460
13461   if (optimize_insn_for_size_p ())
13462     FAIL;
13463
13464   op0 = gen_reg_rtx (XFmode);
13465
13466   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13467
13468   ix86_emit_i387_log1p (op0, operands[1]);
13469   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13470   DONE;
13471 })
13472
13473 (define_insn "fxtractxf3_i387"
13474   [(set (match_operand:XF 0 "register_operand" "=f")
13475         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13476                    UNSPEC_XTRACT_FRACT))
13477    (set (match_operand:XF 1 "register_operand" "=u")
13478         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13479   "TARGET_USE_FANCY_MATH_387
13480    && flag_unsafe_math_optimizations"
13481   "fxtract"
13482   [(set_attr "type" "fpspc")
13483    (set_attr "mode" "XF")])
13484
13485 (define_insn "fxtract_extend<mode>xf3_i387"
13486   [(set (match_operand:XF 0 "register_operand" "=f")
13487         (unspec:XF [(float_extend:XF
13488                       (match_operand:MODEF 2 "register_operand" "0"))]
13489                    UNSPEC_XTRACT_FRACT))
13490    (set (match_operand:XF 1 "register_operand" "=u")
13491         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13492   "TARGET_USE_FANCY_MATH_387
13493    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13494        || TARGET_MIX_SSE_I387)
13495    && flag_unsafe_math_optimizations"
13496   "fxtract"
13497   [(set_attr "type" "fpspc")
13498    (set_attr "mode" "XF")])
13499
13500 (define_expand "logbxf2"
13501   [(parallel [(set (match_dup 2)
13502                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13503                               UNSPEC_XTRACT_FRACT))
13504               (set (match_operand:XF 0 "register_operand" "")
13505                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13506   "TARGET_USE_FANCY_MATH_387
13507    && flag_unsafe_math_optimizations"
13508 {
13509   operands[2] = gen_reg_rtx (XFmode);
13510 })
13511
13512 (define_expand "logb<mode>2"
13513   [(use (match_operand:MODEF 0 "register_operand" ""))
13514    (use (match_operand:MODEF 1 "register_operand" ""))]
13515   "TARGET_USE_FANCY_MATH_387
13516    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13517        || TARGET_MIX_SSE_I387)
13518    && flag_unsafe_math_optimizations"
13519 {
13520   rtx op0 = gen_reg_rtx (XFmode);
13521   rtx op1 = gen_reg_rtx (XFmode);
13522
13523   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13524   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13525   DONE;
13526 })
13527
13528 (define_expand "ilogbxf2"
13529   [(use (match_operand:SI 0 "register_operand" ""))
13530    (use (match_operand:XF 1 "register_operand" ""))]
13531   "TARGET_USE_FANCY_MATH_387
13532    && flag_unsafe_math_optimizations"
13533 {
13534   rtx op0, op1;
13535
13536   if (optimize_insn_for_size_p ())
13537     FAIL;
13538
13539   op0 = gen_reg_rtx (XFmode);
13540   op1 = gen_reg_rtx (XFmode);
13541
13542   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13543   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13544   DONE;
13545 })
13546
13547 (define_expand "ilogb<mode>2"
13548   [(use (match_operand:SI 0 "register_operand" ""))
13549    (use (match_operand:MODEF 1 "register_operand" ""))]
13550   "TARGET_USE_FANCY_MATH_387
13551    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13552        || TARGET_MIX_SSE_I387)
13553    && flag_unsafe_math_optimizations"
13554 {
13555   rtx op0, op1;
13556
13557   if (optimize_insn_for_size_p ())
13558     FAIL;
13559
13560   op0 = gen_reg_rtx (XFmode);
13561   op1 = gen_reg_rtx (XFmode);
13562
13563   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13564   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13565   DONE;
13566 })
13567
13568 (define_insn "*f2xm1xf2_i387"
13569   [(set (match_operand:XF 0 "register_operand" "=f")
13570         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13571                    UNSPEC_F2XM1))]
13572   "TARGET_USE_FANCY_MATH_387
13573    && flag_unsafe_math_optimizations"
13574   "f2xm1"
13575   [(set_attr "type" "fpspc")
13576    (set_attr "mode" "XF")])
13577
13578 (define_insn "*fscalexf4_i387"
13579   [(set (match_operand:XF 0 "register_operand" "=f")
13580         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13581                     (match_operand:XF 3 "register_operand" "1")]
13582                    UNSPEC_FSCALE_FRACT))
13583    (set (match_operand:XF 1 "register_operand" "=u")
13584         (unspec:XF [(match_dup 2) (match_dup 3)]
13585                    UNSPEC_FSCALE_EXP))]
13586   "TARGET_USE_FANCY_MATH_387
13587    && flag_unsafe_math_optimizations"
13588   "fscale"
13589   [(set_attr "type" "fpspc")
13590    (set_attr "mode" "XF")])
13591
13592 (define_expand "expNcorexf3"
13593   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13594                                (match_operand:XF 2 "register_operand" "")))
13595    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13596    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13597    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13598    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13599    (parallel [(set (match_operand:XF 0 "register_operand" "")
13600                    (unspec:XF [(match_dup 8) (match_dup 4)]
13601                               UNSPEC_FSCALE_FRACT))
13602               (set (match_dup 9)
13603                    (unspec:XF [(match_dup 8) (match_dup 4)]
13604                               UNSPEC_FSCALE_EXP))])]
13605   "TARGET_USE_FANCY_MATH_387
13606    && flag_unsafe_math_optimizations"
13607 {
13608   int i;
13609
13610   if (optimize_insn_for_size_p ())
13611     FAIL;
13612
13613   for (i = 3; i < 10; i++)
13614     operands[i] = gen_reg_rtx (XFmode);
13615
13616   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13617 })
13618
13619 (define_expand "expxf2"
13620   [(use (match_operand:XF 0 "register_operand" ""))
13621    (use (match_operand:XF 1 "register_operand" ""))]
13622   "TARGET_USE_FANCY_MATH_387
13623    && flag_unsafe_math_optimizations"
13624 {
13625   rtx op2;
13626
13627   if (optimize_insn_for_size_p ())
13628     FAIL;
13629
13630   op2 = gen_reg_rtx (XFmode);
13631   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13632
13633   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13634   DONE;
13635 })
13636
13637 (define_expand "exp<mode>2"
13638   [(use (match_operand:MODEF 0 "register_operand" ""))
13639    (use (match_operand:MODEF 1 "general_operand" ""))]
13640  "TARGET_USE_FANCY_MATH_387
13641    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642        || TARGET_MIX_SSE_I387)
13643    && flag_unsafe_math_optimizations"
13644 {
13645   rtx op0, op1;
13646
13647   if (optimize_insn_for_size_p ())
13648     FAIL;
13649
13650   op0 = gen_reg_rtx (XFmode);
13651   op1 = gen_reg_rtx (XFmode);
13652
13653   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13654   emit_insn (gen_expxf2 (op0, op1));
13655   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13656   DONE;
13657 })
13658
13659 (define_expand "exp10xf2"
13660   [(use (match_operand:XF 0 "register_operand" ""))
13661    (use (match_operand:XF 1 "register_operand" ""))]
13662   "TARGET_USE_FANCY_MATH_387
13663    && flag_unsafe_math_optimizations"
13664 {
13665   rtx op2;
13666
13667   if (optimize_insn_for_size_p ())
13668     FAIL;
13669
13670   op2 = gen_reg_rtx (XFmode);
13671   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13672
13673   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13674   DONE;
13675 })
13676
13677 (define_expand "exp10<mode>2"
13678   [(use (match_operand:MODEF 0 "register_operand" ""))
13679    (use (match_operand:MODEF 1 "general_operand" ""))]
13680  "TARGET_USE_FANCY_MATH_387
13681    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13682        || TARGET_MIX_SSE_I387)
13683    && flag_unsafe_math_optimizations"
13684 {
13685   rtx op0, op1;
13686
13687   if (optimize_insn_for_size_p ())
13688     FAIL;
13689
13690   op0 = gen_reg_rtx (XFmode);
13691   op1 = gen_reg_rtx (XFmode);
13692
13693   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13694   emit_insn (gen_exp10xf2 (op0, op1));
13695   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13696   DONE;
13697 })
13698
13699 (define_expand "exp2xf2"
13700   [(use (match_operand:XF 0 "register_operand" ""))
13701    (use (match_operand:XF 1 "register_operand" ""))]
13702   "TARGET_USE_FANCY_MATH_387
13703    && flag_unsafe_math_optimizations"
13704 {
13705   rtx op2;
13706
13707   if (optimize_insn_for_size_p ())
13708     FAIL;
13709
13710   op2 = gen_reg_rtx (XFmode);
13711   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
13712
13713   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13714   DONE;
13715 })
13716
13717 (define_expand "exp2<mode>2"
13718   [(use (match_operand:MODEF 0 "register_operand" ""))
13719    (use (match_operand:MODEF 1 "general_operand" ""))]
13720  "TARGET_USE_FANCY_MATH_387
13721    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13722        || TARGET_MIX_SSE_I387)
13723    && flag_unsafe_math_optimizations"
13724 {
13725   rtx op0, op1;
13726
13727   if (optimize_insn_for_size_p ())
13728     FAIL;
13729
13730   op0 = gen_reg_rtx (XFmode);
13731   op1 = gen_reg_rtx (XFmode);
13732
13733   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13734   emit_insn (gen_exp2xf2 (op0, op1));
13735   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13736   DONE;
13737 })
13738
13739 (define_expand "expm1xf2"
13740   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13741                                (match_dup 2)))
13742    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13743    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13744    (set (match_dup 9) (float_extend:XF (match_dup 13)))
13745    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13746    (parallel [(set (match_dup 7)
13747                    (unspec:XF [(match_dup 6) (match_dup 4)]
13748                               UNSPEC_FSCALE_FRACT))
13749               (set (match_dup 8)
13750                    (unspec:XF [(match_dup 6) (match_dup 4)]
13751                               UNSPEC_FSCALE_EXP))])
13752    (parallel [(set (match_dup 10)
13753                    (unspec:XF [(match_dup 9) (match_dup 8)]
13754                               UNSPEC_FSCALE_FRACT))
13755               (set (match_dup 11)
13756                    (unspec:XF [(match_dup 9) (match_dup 8)]
13757                               UNSPEC_FSCALE_EXP))])
13758    (set (match_dup 12) (minus:XF (match_dup 10)
13759                                  (float_extend:XF (match_dup 13))))
13760    (set (match_operand:XF 0 "register_operand" "")
13761         (plus:XF (match_dup 12) (match_dup 7)))]
13762   "TARGET_USE_FANCY_MATH_387
13763    && flag_unsafe_math_optimizations"
13764 {
13765   int i;
13766
13767   if (optimize_insn_for_size_p ())
13768     FAIL;
13769
13770   for (i = 2; i < 13; i++)
13771     operands[i] = gen_reg_rtx (XFmode);
13772
13773   operands[13]
13774     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13775
13776   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13777 })
13778
13779 (define_expand "expm1<mode>2"
13780   [(use (match_operand:MODEF 0 "register_operand" ""))
13781    (use (match_operand:MODEF 1 "general_operand" ""))]
13782  "TARGET_USE_FANCY_MATH_387
13783    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13784        || TARGET_MIX_SSE_I387)
13785    && flag_unsafe_math_optimizations"
13786 {
13787   rtx op0, op1;
13788
13789   if (optimize_insn_for_size_p ())
13790     FAIL;
13791
13792   op0 = gen_reg_rtx (XFmode);
13793   op1 = gen_reg_rtx (XFmode);
13794
13795   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13796   emit_insn (gen_expm1xf2 (op0, op1));
13797   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13798   DONE;
13799 })
13800
13801 (define_expand "ldexpxf3"
13802   [(set (match_dup 3)
13803         (float:XF (match_operand:SI 2 "register_operand" "")))
13804    (parallel [(set (match_operand:XF 0 " register_operand" "")
13805                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13806                                (match_dup 3)]
13807                               UNSPEC_FSCALE_FRACT))
13808               (set (match_dup 4)
13809                    (unspec:XF [(match_dup 1) (match_dup 3)]
13810                               UNSPEC_FSCALE_EXP))])]
13811   "TARGET_USE_FANCY_MATH_387
13812    && flag_unsafe_math_optimizations"
13813 {
13814   if (optimize_insn_for_size_p ())
13815     FAIL;
13816
13817   operands[3] = gen_reg_rtx (XFmode);
13818   operands[4] = gen_reg_rtx (XFmode);
13819 })
13820
13821 (define_expand "ldexp<mode>3"
13822   [(use (match_operand:MODEF 0 "register_operand" ""))
13823    (use (match_operand:MODEF 1 "general_operand" ""))
13824    (use (match_operand:SI 2 "register_operand" ""))]
13825  "TARGET_USE_FANCY_MATH_387
13826    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13827        || TARGET_MIX_SSE_I387)
13828    && flag_unsafe_math_optimizations"
13829 {
13830   rtx op0, op1;
13831
13832   if (optimize_insn_for_size_p ())
13833     FAIL;
13834
13835   op0 = gen_reg_rtx (XFmode);
13836   op1 = gen_reg_rtx (XFmode);
13837
13838   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13839   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13840   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13841   DONE;
13842 })
13843
13844 (define_expand "scalbxf3"
13845   [(parallel [(set (match_operand:XF 0 " register_operand" "")
13846                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13847                                (match_operand:XF 2 "register_operand" "")]
13848                               UNSPEC_FSCALE_FRACT))
13849               (set (match_dup 3)
13850                    (unspec:XF [(match_dup 1) (match_dup 2)]
13851                               UNSPEC_FSCALE_EXP))])]
13852   "TARGET_USE_FANCY_MATH_387
13853    && flag_unsafe_math_optimizations"
13854 {
13855   if (optimize_insn_for_size_p ())
13856     FAIL;
13857
13858   operands[3] = gen_reg_rtx (XFmode);
13859 })
13860
13861 (define_expand "scalb<mode>3"
13862   [(use (match_operand:MODEF 0 "register_operand" ""))
13863    (use (match_operand:MODEF 1 "general_operand" ""))
13864    (use (match_operand:MODEF 2 "general_operand" ""))]
13865  "TARGET_USE_FANCY_MATH_387
13866    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13867        || TARGET_MIX_SSE_I387)
13868    && flag_unsafe_math_optimizations"
13869 {
13870   rtx op0, op1, op2;
13871
13872   if (optimize_insn_for_size_p ())
13873     FAIL;
13874
13875   op0 = gen_reg_rtx (XFmode);
13876   op1 = gen_reg_rtx (XFmode);
13877   op2 = gen_reg_rtx (XFmode);
13878
13879   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13880   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13881   emit_insn (gen_scalbxf3 (op0, op1, op2));
13882   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13883   DONE;
13884 })
13885
13886 (define_expand "significandxf2"
13887   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13888                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13889                               UNSPEC_XTRACT_FRACT))
13890               (set (match_dup 2)
13891                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13892   "TARGET_USE_FANCY_MATH_387
13893    && flag_unsafe_math_optimizations"
13894 {
13895   operands[2] = gen_reg_rtx (XFmode);
13896 })
13897
13898 (define_expand "significand<mode>2"
13899   [(use (match_operand:MODEF 0 "register_operand" ""))
13900    (use (match_operand:MODEF 1 "register_operand" ""))]
13901   "TARGET_USE_FANCY_MATH_387
13902    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903        || TARGET_MIX_SSE_I387)
13904    && flag_unsafe_math_optimizations"
13905 {
13906   rtx op0 = gen_reg_rtx (XFmode);
13907   rtx op1 = gen_reg_rtx (XFmode);
13908
13909   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13910   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13911   DONE;
13912 })
13913 \f
13914
13915 (define_insn "sse4_1_round<mode>2"
13916   [(set (match_operand:MODEF 0 "register_operand" "=x")
13917         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
13918                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
13919                       UNSPEC_ROUND))]
13920   "TARGET_ROUND"
13921   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
13922   [(set_attr "type" "ssecvt")
13923    (set_attr "prefix_extra" "1")
13924    (set_attr "prefix" "maybe_vex")
13925    (set_attr "mode" "<MODE>")])
13926
13927 (define_insn "rintxf2"
13928   [(set (match_operand:XF 0 "register_operand" "=f")
13929         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13930                    UNSPEC_FRNDINT))]
13931   "TARGET_USE_FANCY_MATH_387
13932    && flag_unsafe_math_optimizations"
13933   "frndint"
13934   [(set_attr "type" "fpspc")
13935    (set_attr "mode" "XF")])
13936
13937 (define_expand "rint<mode>2"
13938   [(use (match_operand:MODEF 0 "register_operand" ""))
13939    (use (match_operand:MODEF 1 "register_operand" ""))]
13940   "(TARGET_USE_FANCY_MATH_387
13941     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13942         || TARGET_MIX_SSE_I387)
13943     && flag_unsafe_math_optimizations)
13944    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13945        && !flag_trapping_math)"
13946 {
13947   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13948       && !flag_trapping_math)
13949     {
13950       if (!TARGET_ROUND && optimize_insn_for_size_p ())
13951         FAIL;
13952       if (TARGET_ROUND)
13953         emit_insn (gen_sse4_1_round<mode>2
13954                    (operands[0], operands[1], GEN_INT (0x04)));
13955       else
13956         ix86_expand_rint (operand0, operand1);
13957     }
13958   else
13959     {
13960       rtx op0 = gen_reg_rtx (XFmode);
13961       rtx op1 = gen_reg_rtx (XFmode);
13962
13963       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13964       emit_insn (gen_rintxf2 (op0, op1));
13965
13966       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13967     }
13968   DONE;
13969 })
13970
13971 (define_expand "round<mode>2"
13972   [(match_operand:MODEF 0 "register_operand" "")
13973    (match_operand:MODEF 1 "nonimmediate_operand" "")]
13974   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13975    && !flag_trapping_math && !flag_rounding_math"
13976 {
13977   if (optimize_insn_for_size_p ())
13978     FAIL;
13979   if (TARGET_64BIT || (<MODE>mode != DFmode))
13980     ix86_expand_round (operand0, operand1);
13981   else
13982     ix86_expand_rounddf_32 (operand0, operand1);
13983   DONE;
13984 })
13985
13986 (define_insn_and_split "*fistdi2_1"
13987   [(set (match_operand:DI 0 "nonimmediate_operand" "")
13988         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
13989                    UNSPEC_FIST))]
13990   "TARGET_USE_FANCY_MATH_387
13991    && can_create_pseudo_p ()"
13992   "#"
13993   "&& 1"
13994   [(const_int 0)]
13995 {
13996   if (memory_operand (operands[0], VOIDmode))
13997     emit_insn (gen_fistdi2 (operands[0], operands[1]));
13998   else
13999     {
14000       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14001       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14002                                          operands[2]));
14003     }
14004   DONE;
14005 }
14006   [(set_attr "type" "fpspc")
14007    (set_attr "mode" "DI")])
14008
14009 (define_insn "fistdi2"
14010   [(set (match_operand:DI 0 "memory_operand" "=m")
14011         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14012                    UNSPEC_FIST))
14013    (clobber (match_scratch:XF 2 "=&1f"))]
14014   "TARGET_USE_FANCY_MATH_387"
14015   "* return output_fix_trunc (insn, operands, 0);"
14016   [(set_attr "type" "fpspc")
14017    (set_attr "mode" "DI")])
14018
14019 (define_insn "fistdi2_with_temp"
14020   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14021         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14022                    UNSPEC_FIST))
14023    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14024    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14025   "TARGET_USE_FANCY_MATH_387"
14026   "#"
14027   [(set_attr "type" "fpspc")
14028    (set_attr "mode" "DI")])
14029
14030 (define_split
14031   [(set (match_operand:DI 0 "register_operand" "")
14032         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14033                    UNSPEC_FIST))
14034    (clobber (match_operand:DI 2 "memory_operand" ""))
14035    (clobber (match_scratch 3 ""))]
14036   "reload_completed"
14037   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14038               (clobber (match_dup 3))])
14039    (set (match_dup 0) (match_dup 2))])
14040
14041 (define_split
14042   [(set (match_operand:DI 0 "memory_operand" "")
14043         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14044                    UNSPEC_FIST))
14045    (clobber (match_operand:DI 2 "memory_operand" ""))
14046    (clobber (match_scratch 3 ""))]
14047   "reload_completed"
14048   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14049               (clobber (match_dup 3))])])
14050
14051 (define_insn_and_split "*fist<mode>2_1"
14052   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14053         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14054                            UNSPEC_FIST))]
14055   "TARGET_USE_FANCY_MATH_387
14056    && can_create_pseudo_p ()"
14057   "#"
14058   "&& 1"
14059   [(const_int 0)]
14060 {
14061   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14062   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14063                                         operands[2]));
14064   DONE;
14065 }
14066   [(set_attr "type" "fpspc")
14067    (set_attr "mode" "<MODE>")])
14068
14069 (define_insn "fist<mode>2"
14070   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14071         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14072                            UNSPEC_FIST))]
14073   "TARGET_USE_FANCY_MATH_387"
14074   "* return output_fix_trunc (insn, operands, 0);"
14075   [(set_attr "type" "fpspc")
14076    (set_attr "mode" "<MODE>")])
14077
14078 (define_insn "fist<mode>2_with_temp"
14079   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14080         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14081                            UNSPEC_FIST))
14082    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14083   "TARGET_USE_FANCY_MATH_387"
14084   "#"
14085   [(set_attr "type" "fpspc")
14086    (set_attr "mode" "<MODE>")])
14087
14088 (define_split
14089   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14090         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14091                            UNSPEC_FIST))
14092    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14093   "reload_completed"
14094   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14095    (set (match_dup 0) (match_dup 2))])
14096
14097 (define_split
14098   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14099         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14100                            UNSPEC_FIST))
14101    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14102   "reload_completed"
14103   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14104
14105 (define_expand "lrintxf<mode>2"
14106   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14107      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14108                       UNSPEC_FIST))]
14109   "TARGET_USE_FANCY_MATH_387"
14110   "")
14111
14112 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14113   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14114      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14115                         UNSPEC_FIX_NOTRUNC))]
14116   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14117    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14118   "")
14119
14120 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14121   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14122    (match_operand:MODEF 1 "register_operand" "")]
14123   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14124    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14125    && !flag_trapping_math && !flag_rounding_math"
14126 {
14127   if (optimize_insn_for_size_p ())
14128     FAIL;
14129   ix86_expand_lround (operand0, operand1);
14130   DONE;
14131 })
14132
14133 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14134 (define_insn_and_split "frndintxf2_floor"
14135   [(set (match_operand:XF 0 "register_operand" "")
14136         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14137          UNSPEC_FRNDINT_FLOOR))
14138    (clobber (reg:CC FLAGS_REG))]
14139   "TARGET_USE_FANCY_MATH_387
14140    && flag_unsafe_math_optimizations
14141    && can_create_pseudo_p ()"
14142   "#"
14143   "&& 1"
14144   [(const_int 0)]
14145 {
14146   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14147
14148   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14149   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14150
14151   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14152                                         operands[2], operands[3]));
14153   DONE;
14154 }
14155   [(set_attr "type" "frndint")
14156    (set_attr "i387_cw" "floor")
14157    (set_attr "mode" "XF")])
14158
14159 (define_insn "frndintxf2_floor_i387"
14160   [(set (match_operand:XF 0 "register_operand" "=f")
14161         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14162          UNSPEC_FRNDINT_FLOOR))
14163    (use (match_operand:HI 2 "memory_operand" "m"))
14164    (use (match_operand:HI 3 "memory_operand" "m"))]
14165   "TARGET_USE_FANCY_MATH_387
14166    && flag_unsafe_math_optimizations"
14167   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14168   [(set_attr "type" "frndint")
14169    (set_attr "i387_cw" "floor")
14170    (set_attr "mode" "XF")])
14171
14172 (define_expand "floorxf2"
14173   [(use (match_operand:XF 0 "register_operand" ""))
14174    (use (match_operand:XF 1 "register_operand" ""))]
14175   "TARGET_USE_FANCY_MATH_387
14176    && flag_unsafe_math_optimizations"
14177 {
14178   if (optimize_insn_for_size_p ())
14179     FAIL;
14180   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14181   DONE;
14182 })
14183
14184 (define_expand "floor<mode>2"
14185   [(use (match_operand:MODEF 0 "register_operand" ""))
14186    (use (match_operand:MODEF 1 "register_operand" ""))]
14187   "(TARGET_USE_FANCY_MATH_387
14188     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14189         || TARGET_MIX_SSE_I387)
14190     && flag_unsafe_math_optimizations)
14191    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14192        && !flag_trapping_math)"
14193 {
14194   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14195       && !flag_trapping_math
14196       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14197     {
14198       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14199         FAIL;
14200       if (TARGET_ROUND)
14201         emit_insn (gen_sse4_1_round<mode>2
14202                    (operands[0], operands[1], GEN_INT (0x01)));
14203       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14204         ix86_expand_floorceil (operand0, operand1, true);
14205       else
14206         ix86_expand_floorceildf_32 (operand0, operand1, true);
14207     }
14208   else
14209     {
14210       rtx op0, op1;
14211
14212       if (optimize_insn_for_size_p ())
14213         FAIL;
14214
14215       op0 = gen_reg_rtx (XFmode);
14216       op1 = gen_reg_rtx (XFmode);
14217       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14218       emit_insn (gen_frndintxf2_floor (op0, op1));
14219
14220       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14221     }
14222   DONE;
14223 })
14224
14225 (define_insn_and_split "*fist<mode>2_floor_1"
14226   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14227         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14228          UNSPEC_FIST_FLOOR))
14229    (clobber (reg:CC FLAGS_REG))]
14230   "TARGET_USE_FANCY_MATH_387
14231    && flag_unsafe_math_optimizations
14232    && can_create_pseudo_p ()"
14233   "#"
14234   "&& 1"
14235   [(const_int 0)]
14236 {
14237   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14238
14239   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14240   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14241   if (memory_operand (operands[0], VOIDmode))
14242     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14243                                       operands[2], operands[3]));
14244   else
14245     {
14246       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14247       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14248                                                   operands[2], operands[3],
14249                                                   operands[4]));
14250     }
14251   DONE;
14252 }
14253   [(set_attr "type" "fistp")
14254    (set_attr "i387_cw" "floor")
14255    (set_attr "mode" "<MODE>")])
14256
14257 (define_insn "fistdi2_floor"
14258   [(set (match_operand:DI 0 "memory_operand" "=m")
14259         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14260          UNSPEC_FIST_FLOOR))
14261    (use (match_operand:HI 2 "memory_operand" "m"))
14262    (use (match_operand:HI 3 "memory_operand" "m"))
14263    (clobber (match_scratch:XF 4 "=&1f"))]
14264   "TARGET_USE_FANCY_MATH_387
14265    && flag_unsafe_math_optimizations"
14266   "* return output_fix_trunc (insn, operands, 0);"
14267   [(set_attr "type" "fistp")
14268    (set_attr "i387_cw" "floor")
14269    (set_attr "mode" "DI")])
14270
14271 (define_insn "fistdi2_floor_with_temp"
14272   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14273         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14274          UNSPEC_FIST_FLOOR))
14275    (use (match_operand:HI 2 "memory_operand" "m,m"))
14276    (use (match_operand:HI 3 "memory_operand" "m,m"))
14277    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14278    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14279   "TARGET_USE_FANCY_MATH_387
14280    && flag_unsafe_math_optimizations"
14281   "#"
14282   [(set_attr "type" "fistp")
14283    (set_attr "i387_cw" "floor")
14284    (set_attr "mode" "DI")])
14285
14286 (define_split
14287   [(set (match_operand:DI 0 "register_operand" "")
14288         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14289          UNSPEC_FIST_FLOOR))
14290    (use (match_operand:HI 2 "memory_operand" ""))
14291    (use (match_operand:HI 3 "memory_operand" ""))
14292    (clobber (match_operand:DI 4 "memory_operand" ""))
14293    (clobber (match_scratch 5 ""))]
14294   "reload_completed"
14295   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14296               (use (match_dup 2))
14297               (use (match_dup 3))
14298               (clobber (match_dup 5))])
14299    (set (match_dup 0) (match_dup 4))])
14300
14301 (define_split
14302   [(set (match_operand:DI 0 "memory_operand" "")
14303         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14304          UNSPEC_FIST_FLOOR))
14305    (use (match_operand:HI 2 "memory_operand" ""))
14306    (use (match_operand:HI 3 "memory_operand" ""))
14307    (clobber (match_operand:DI 4 "memory_operand" ""))
14308    (clobber (match_scratch 5 ""))]
14309   "reload_completed"
14310   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14311               (use (match_dup 2))
14312               (use (match_dup 3))
14313               (clobber (match_dup 5))])])
14314
14315 (define_insn "fist<mode>2_floor"
14316   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14317         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14318          UNSPEC_FIST_FLOOR))
14319    (use (match_operand:HI 2 "memory_operand" "m"))
14320    (use (match_operand:HI 3 "memory_operand" "m"))]
14321   "TARGET_USE_FANCY_MATH_387
14322    && flag_unsafe_math_optimizations"
14323   "* return output_fix_trunc (insn, operands, 0);"
14324   [(set_attr "type" "fistp")
14325    (set_attr "i387_cw" "floor")
14326    (set_attr "mode" "<MODE>")])
14327
14328 (define_insn "fist<mode>2_floor_with_temp"
14329   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14330         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14331          UNSPEC_FIST_FLOOR))
14332    (use (match_operand:HI 2 "memory_operand" "m,m"))
14333    (use (match_operand:HI 3 "memory_operand" "m,m"))
14334    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14335   "TARGET_USE_FANCY_MATH_387
14336    && flag_unsafe_math_optimizations"
14337   "#"
14338   [(set_attr "type" "fistp")
14339    (set_attr "i387_cw" "floor")
14340    (set_attr "mode" "<MODE>")])
14341
14342 (define_split
14343   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14344         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14345          UNSPEC_FIST_FLOOR))
14346    (use (match_operand:HI 2 "memory_operand" ""))
14347    (use (match_operand:HI 3 "memory_operand" ""))
14348    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14349   "reload_completed"
14350   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14351                                   UNSPEC_FIST_FLOOR))
14352               (use (match_dup 2))
14353               (use (match_dup 3))])
14354    (set (match_dup 0) (match_dup 4))])
14355
14356 (define_split
14357   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14358         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14359          UNSPEC_FIST_FLOOR))
14360    (use (match_operand:HI 2 "memory_operand" ""))
14361    (use (match_operand:HI 3 "memory_operand" ""))
14362    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14363   "reload_completed"
14364   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14365                                   UNSPEC_FIST_FLOOR))
14366               (use (match_dup 2))
14367               (use (match_dup 3))])])
14368
14369 (define_expand "lfloorxf<mode>2"
14370   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14371                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14372                     UNSPEC_FIST_FLOOR))
14373               (clobber (reg:CC FLAGS_REG))])]
14374   "TARGET_USE_FANCY_MATH_387
14375    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14376    && flag_unsafe_math_optimizations"
14377   "")
14378
14379 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14380   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14381    (match_operand:MODEF 1 "register_operand" "")]
14382   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14383    && !flag_trapping_math"
14384 {
14385   if (TARGET_64BIT && optimize_insn_for_size_p ())
14386     FAIL;
14387   ix86_expand_lfloorceil (operand0, operand1, true);
14388   DONE;
14389 })
14390
14391 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14392 (define_insn_and_split "frndintxf2_ceil"
14393   [(set (match_operand:XF 0 "register_operand" "")
14394         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14395          UNSPEC_FRNDINT_CEIL))
14396    (clobber (reg:CC FLAGS_REG))]
14397   "TARGET_USE_FANCY_MATH_387
14398    && flag_unsafe_math_optimizations
14399    && can_create_pseudo_p ()"
14400   "#"
14401   "&& 1"
14402   [(const_int 0)]
14403 {
14404   ix86_optimize_mode_switching[I387_CEIL] = 1;
14405
14406   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14407   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14408
14409   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14410                                        operands[2], operands[3]));
14411   DONE;
14412 }
14413   [(set_attr "type" "frndint")
14414    (set_attr "i387_cw" "ceil")
14415    (set_attr "mode" "XF")])
14416
14417 (define_insn "frndintxf2_ceil_i387"
14418   [(set (match_operand:XF 0 "register_operand" "=f")
14419         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14420          UNSPEC_FRNDINT_CEIL))
14421    (use (match_operand:HI 2 "memory_operand" "m"))
14422    (use (match_operand:HI 3 "memory_operand" "m"))]
14423   "TARGET_USE_FANCY_MATH_387
14424    && flag_unsafe_math_optimizations"
14425   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14426   [(set_attr "type" "frndint")
14427    (set_attr "i387_cw" "ceil")
14428    (set_attr "mode" "XF")])
14429
14430 (define_expand "ceilxf2"
14431   [(use (match_operand:XF 0 "register_operand" ""))
14432    (use (match_operand:XF 1 "register_operand" ""))]
14433   "TARGET_USE_FANCY_MATH_387
14434    && flag_unsafe_math_optimizations"
14435 {
14436   if (optimize_insn_for_size_p ())
14437     FAIL;
14438   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14439   DONE;
14440 })
14441
14442 (define_expand "ceil<mode>2"
14443   [(use (match_operand:MODEF 0 "register_operand" ""))
14444    (use (match_operand:MODEF 1 "register_operand" ""))]
14445   "(TARGET_USE_FANCY_MATH_387
14446     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447         || TARGET_MIX_SSE_I387)
14448     && flag_unsafe_math_optimizations)
14449    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14450        && !flag_trapping_math)"
14451 {
14452   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14453       && !flag_trapping_math
14454       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14455     {
14456       if (TARGET_ROUND)
14457         emit_insn (gen_sse4_1_round<mode>2
14458                    (operands[0], operands[1], GEN_INT (0x02)));
14459       else if (optimize_insn_for_size_p ())
14460         FAIL;
14461       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14462         ix86_expand_floorceil (operand0, operand1, false);
14463       else
14464         ix86_expand_floorceildf_32 (operand0, operand1, false);
14465     }
14466   else
14467     {
14468       rtx op0, op1;
14469
14470       if (optimize_insn_for_size_p ())
14471         FAIL;
14472
14473       op0 = gen_reg_rtx (XFmode);
14474       op1 = gen_reg_rtx (XFmode);
14475       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14476       emit_insn (gen_frndintxf2_ceil (op0, op1));
14477
14478       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14479     }
14480   DONE;
14481 })
14482
14483 (define_insn_and_split "*fist<mode>2_ceil_1"
14484   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14485         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14486          UNSPEC_FIST_CEIL))
14487    (clobber (reg:CC FLAGS_REG))]
14488   "TARGET_USE_FANCY_MATH_387
14489    && flag_unsafe_math_optimizations
14490    && can_create_pseudo_p ()"
14491   "#"
14492   "&& 1"
14493   [(const_int 0)]
14494 {
14495   ix86_optimize_mode_switching[I387_CEIL] = 1;
14496
14497   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14498   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14499   if (memory_operand (operands[0], VOIDmode))
14500     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14501                                      operands[2], operands[3]));
14502   else
14503     {
14504       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14505       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14506                                                  operands[2], operands[3],
14507                                                  operands[4]));
14508     }
14509   DONE;
14510 }
14511   [(set_attr "type" "fistp")
14512    (set_attr "i387_cw" "ceil")
14513    (set_attr "mode" "<MODE>")])
14514
14515 (define_insn "fistdi2_ceil"
14516   [(set (match_operand:DI 0 "memory_operand" "=m")
14517         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14518          UNSPEC_FIST_CEIL))
14519    (use (match_operand:HI 2 "memory_operand" "m"))
14520    (use (match_operand:HI 3 "memory_operand" "m"))
14521    (clobber (match_scratch:XF 4 "=&1f"))]
14522   "TARGET_USE_FANCY_MATH_387
14523    && flag_unsafe_math_optimizations"
14524   "* return output_fix_trunc (insn, operands, 0);"
14525   [(set_attr "type" "fistp")
14526    (set_attr "i387_cw" "ceil")
14527    (set_attr "mode" "DI")])
14528
14529 (define_insn "fistdi2_ceil_with_temp"
14530   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14531         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14532          UNSPEC_FIST_CEIL))
14533    (use (match_operand:HI 2 "memory_operand" "m,m"))
14534    (use (match_operand:HI 3 "memory_operand" "m,m"))
14535    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14536    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14537   "TARGET_USE_FANCY_MATH_387
14538    && flag_unsafe_math_optimizations"
14539   "#"
14540   [(set_attr "type" "fistp")
14541    (set_attr "i387_cw" "ceil")
14542    (set_attr "mode" "DI")])
14543
14544 (define_split
14545   [(set (match_operand:DI 0 "register_operand" "")
14546         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14547          UNSPEC_FIST_CEIL))
14548    (use (match_operand:HI 2 "memory_operand" ""))
14549    (use (match_operand:HI 3 "memory_operand" ""))
14550    (clobber (match_operand:DI 4 "memory_operand" ""))
14551    (clobber (match_scratch 5 ""))]
14552   "reload_completed"
14553   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14554               (use (match_dup 2))
14555               (use (match_dup 3))
14556               (clobber (match_dup 5))])
14557    (set (match_dup 0) (match_dup 4))])
14558
14559 (define_split
14560   [(set (match_operand:DI 0 "memory_operand" "")
14561         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14562          UNSPEC_FIST_CEIL))
14563    (use (match_operand:HI 2 "memory_operand" ""))
14564    (use (match_operand:HI 3 "memory_operand" ""))
14565    (clobber (match_operand:DI 4 "memory_operand" ""))
14566    (clobber (match_scratch 5 ""))]
14567   "reload_completed"
14568   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14569               (use (match_dup 2))
14570               (use (match_dup 3))
14571               (clobber (match_dup 5))])])
14572
14573 (define_insn "fist<mode>2_ceil"
14574   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14575         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14576          UNSPEC_FIST_CEIL))
14577    (use (match_operand:HI 2 "memory_operand" "m"))
14578    (use (match_operand:HI 3 "memory_operand" "m"))]
14579   "TARGET_USE_FANCY_MATH_387
14580    && flag_unsafe_math_optimizations"
14581   "* return output_fix_trunc (insn, operands, 0);"
14582   [(set_attr "type" "fistp")
14583    (set_attr "i387_cw" "ceil")
14584    (set_attr "mode" "<MODE>")])
14585
14586 (define_insn "fist<mode>2_ceil_with_temp"
14587   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14588         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14589          UNSPEC_FIST_CEIL))
14590    (use (match_operand:HI 2 "memory_operand" "m,m"))
14591    (use (match_operand:HI 3 "memory_operand" "m,m"))
14592    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14593   "TARGET_USE_FANCY_MATH_387
14594    && flag_unsafe_math_optimizations"
14595   "#"
14596   [(set_attr "type" "fistp")
14597    (set_attr "i387_cw" "ceil")
14598    (set_attr "mode" "<MODE>")])
14599
14600 (define_split
14601   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14602         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14603          UNSPEC_FIST_CEIL))
14604    (use (match_operand:HI 2 "memory_operand" ""))
14605    (use (match_operand:HI 3 "memory_operand" ""))
14606    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14607   "reload_completed"
14608   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14609                                   UNSPEC_FIST_CEIL))
14610               (use (match_dup 2))
14611               (use (match_dup 3))])
14612    (set (match_dup 0) (match_dup 4))])
14613
14614 (define_split
14615   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14616         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14617          UNSPEC_FIST_CEIL))
14618    (use (match_operand:HI 2 "memory_operand" ""))
14619    (use (match_operand:HI 3 "memory_operand" ""))
14620    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14621   "reload_completed"
14622   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14623                                   UNSPEC_FIST_CEIL))
14624               (use (match_dup 2))
14625               (use (match_dup 3))])])
14626
14627 (define_expand "lceilxf<mode>2"
14628   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14629                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14630                     UNSPEC_FIST_CEIL))
14631               (clobber (reg:CC FLAGS_REG))])]
14632   "TARGET_USE_FANCY_MATH_387
14633    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14634    && flag_unsafe_math_optimizations"
14635   "")
14636
14637 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14638   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14639    (match_operand:MODEF 1 "register_operand" "")]
14640   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14641    && !flag_trapping_math"
14642 {
14643   ix86_expand_lfloorceil (operand0, operand1, false);
14644   DONE;
14645 })
14646
14647 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14648 (define_insn_and_split "frndintxf2_trunc"
14649   [(set (match_operand:XF 0 "register_operand" "")
14650         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14651          UNSPEC_FRNDINT_TRUNC))
14652    (clobber (reg:CC FLAGS_REG))]
14653   "TARGET_USE_FANCY_MATH_387
14654    && flag_unsafe_math_optimizations
14655    && can_create_pseudo_p ()"
14656   "#"
14657   "&& 1"
14658   [(const_int 0)]
14659 {
14660   ix86_optimize_mode_switching[I387_TRUNC] = 1;
14661
14662   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14663   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14664
14665   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14666                                         operands[2], operands[3]));
14667   DONE;
14668 }
14669   [(set_attr "type" "frndint")
14670    (set_attr "i387_cw" "trunc")
14671    (set_attr "mode" "XF")])
14672
14673 (define_insn "frndintxf2_trunc_i387"
14674   [(set (match_operand:XF 0 "register_operand" "=f")
14675         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14676          UNSPEC_FRNDINT_TRUNC))
14677    (use (match_operand:HI 2 "memory_operand" "m"))
14678    (use (match_operand:HI 3 "memory_operand" "m"))]
14679   "TARGET_USE_FANCY_MATH_387
14680    && flag_unsafe_math_optimizations"
14681   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14682   [(set_attr "type" "frndint")
14683    (set_attr "i387_cw" "trunc")
14684    (set_attr "mode" "XF")])
14685
14686 (define_expand "btruncxf2"
14687   [(use (match_operand:XF 0 "register_operand" ""))
14688    (use (match_operand:XF 1 "register_operand" ""))]
14689   "TARGET_USE_FANCY_MATH_387
14690    && flag_unsafe_math_optimizations"
14691 {
14692   if (optimize_insn_for_size_p ())
14693     FAIL;
14694   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14695   DONE;
14696 })
14697
14698 (define_expand "btrunc<mode>2"
14699   [(use (match_operand:MODEF 0 "register_operand" ""))
14700    (use (match_operand:MODEF 1 "register_operand" ""))]
14701   "(TARGET_USE_FANCY_MATH_387
14702     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14703         || TARGET_MIX_SSE_I387)
14704     && flag_unsafe_math_optimizations)
14705    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14706        && !flag_trapping_math)"
14707 {
14708   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14709       && !flag_trapping_math
14710       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14711     {
14712       if (TARGET_ROUND)
14713         emit_insn (gen_sse4_1_round<mode>2
14714                    (operands[0], operands[1], GEN_INT (0x03)));
14715       else if (optimize_insn_for_size_p ())
14716         FAIL;
14717       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14718         ix86_expand_trunc (operand0, operand1);
14719       else
14720         ix86_expand_truncdf_32 (operand0, operand1);
14721     }
14722   else
14723     {
14724       rtx op0, op1;
14725
14726       if (optimize_insn_for_size_p ())
14727         FAIL;
14728
14729       op0 = gen_reg_rtx (XFmode);
14730       op1 = gen_reg_rtx (XFmode);
14731       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14732       emit_insn (gen_frndintxf2_trunc (op0, op1));
14733
14734       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14735     }
14736   DONE;
14737 })
14738
14739 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14740 (define_insn_and_split "frndintxf2_mask_pm"
14741   [(set (match_operand:XF 0 "register_operand" "")
14742         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14743          UNSPEC_FRNDINT_MASK_PM))
14744    (clobber (reg:CC FLAGS_REG))]
14745   "TARGET_USE_FANCY_MATH_387
14746    && flag_unsafe_math_optimizations
14747    && can_create_pseudo_p ()"
14748   "#"
14749   "&& 1"
14750   [(const_int 0)]
14751 {
14752   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14753
14754   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14755   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14756
14757   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14758                                           operands[2], operands[3]));
14759   DONE;
14760 }
14761   [(set_attr "type" "frndint")
14762    (set_attr "i387_cw" "mask_pm")
14763    (set_attr "mode" "XF")])
14764
14765 (define_insn "frndintxf2_mask_pm_i387"
14766   [(set (match_operand:XF 0 "register_operand" "=f")
14767         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14768          UNSPEC_FRNDINT_MASK_PM))
14769    (use (match_operand:HI 2 "memory_operand" "m"))
14770    (use (match_operand:HI 3 "memory_operand" "m"))]
14771   "TARGET_USE_FANCY_MATH_387
14772    && flag_unsafe_math_optimizations"
14773   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14774   [(set_attr "type" "frndint")
14775    (set_attr "i387_cw" "mask_pm")
14776    (set_attr "mode" "XF")])
14777
14778 (define_expand "nearbyintxf2"
14779   [(use (match_operand:XF 0 "register_operand" ""))
14780    (use (match_operand:XF 1 "register_operand" ""))]
14781   "TARGET_USE_FANCY_MATH_387
14782    && flag_unsafe_math_optimizations"
14783 {
14784   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14785
14786   DONE;
14787 })
14788
14789 (define_expand "nearbyint<mode>2"
14790   [(use (match_operand:MODEF 0 "register_operand" ""))
14791    (use (match_operand:MODEF 1 "register_operand" ""))]
14792   "TARGET_USE_FANCY_MATH_387
14793    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14794        || TARGET_MIX_SSE_I387)
14795    && flag_unsafe_math_optimizations"
14796 {
14797   rtx op0 = gen_reg_rtx (XFmode);
14798   rtx op1 = gen_reg_rtx (XFmode);
14799
14800   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14801   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14802
14803   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14804   DONE;
14805 })
14806
14807 (define_insn "fxam<mode>2_i387"
14808   [(set (match_operand:HI 0 "register_operand" "=a")
14809         (unspec:HI
14810           [(match_operand:X87MODEF 1 "register_operand" "f")]
14811           UNSPEC_FXAM))]
14812   "TARGET_USE_FANCY_MATH_387"
14813   "fxam\n\tfnstsw\t%0"
14814   [(set_attr "type" "multi")
14815    (set_attr "length" "4")
14816    (set_attr "unit" "i387")
14817    (set_attr "mode" "<MODE>")])
14818
14819 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14820   [(set (match_operand:HI 0 "register_operand" "")
14821         (unspec:HI
14822           [(match_operand:MODEF 1 "memory_operand" "")]
14823           UNSPEC_FXAM_MEM))]
14824   "TARGET_USE_FANCY_MATH_387
14825    && can_create_pseudo_p ()"
14826   "#"
14827   "&& 1"
14828   [(set (match_dup 2)(match_dup 1))
14829    (set (match_dup 0)
14830         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14831 {
14832   operands[2] = gen_reg_rtx (<MODE>mode);
14833
14834   MEM_VOLATILE_P (operands[1]) = 1;
14835 }
14836   [(set_attr "type" "multi")
14837    (set_attr "unit" "i387")
14838    (set_attr "mode" "<MODE>")])
14839
14840 (define_expand "isinfxf2"
14841   [(use (match_operand:SI 0 "register_operand" ""))
14842    (use (match_operand:XF 1 "register_operand" ""))]
14843   "TARGET_USE_FANCY_MATH_387
14844    && TARGET_C99_FUNCTIONS"
14845 {
14846   rtx mask = GEN_INT (0x45);
14847   rtx val = GEN_INT (0x05);
14848
14849   rtx cond;
14850
14851   rtx scratch = gen_reg_rtx (HImode);
14852   rtx res = gen_reg_rtx (QImode);
14853
14854   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14855
14856   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14857   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14858   cond = gen_rtx_fmt_ee (EQ, QImode,
14859                          gen_rtx_REG (CCmode, FLAGS_REG),
14860                          const0_rtx);
14861   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14862   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14863   DONE;
14864 })
14865
14866 (define_expand "isinf<mode>2"
14867   [(use (match_operand:SI 0 "register_operand" ""))
14868    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
14869   "TARGET_USE_FANCY_MATH_387
14870    && TARGET_C99_FUNCTIONS
14871    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14872 {
14873   rtx mask = GEN_INT (0x45);
14874   rtx val = GEN_INT (0x05);
14875
14876   rtx cond;
14877
14878   rtx scratch = gen_reg_rtx (HImode);
14879   rtx res = gen_reg_rtx (QImode);
14880
14881   /* Remove excess precision by forcing value through memory. */
14882   if (memory_operand (operands[1], VOIDmode))
14883     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14884   else
14885     {
14886       enum ix86_stack_slot slot = (virtuals_instantiated
14887                                    ? SLOT_TEMP
14888                                    : SLOT_VIRTUAL);
14889       rtx temp = assign_386_stack_local (<MODE>mode, slot);
14890
14891       emit_move_insn (temp, operands[1]);
14892       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14893     }
14894
14895   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14896   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14897   cond = gen_rtx_fmt_ee (EQ, QImode,
14898                          gen_rtx_REG (CCmode, FLAGS_REG),
14899                          const0_rtx);
14900   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14901   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14902   DONE;
14903 })
14904
14905 (define_expand "signbit<mode>2"
14906   [(use (match_operand:SI 0 "register_operand" ""))
14907    (use (match_operand:X87MODEF 1 "register_operand" ""))]
14908   "TARGET_USE_FANCY_MATH_387
14909    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14910 {
14911   rtx mask = GEN_INT (0x0200);
14912
14913   rtx scratch = gen_reg_rtx (HImode);
14914
14915   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
14916   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
14917   DONE;
14918 })
14919 \f
14920 ;; Block operation instructions
14921
14922 (define_insn "cld"
14923   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14924   ""
14925   "cld"
14926   [(set_attr "length" "1")
14927    (set_attr "length_immediate" "0")
14928    (set_attr "modrm" "0")])
14929
14930 (define_expand "movmemsi"
14931   [(use (match_operand:BLK 0 "memory_operand" ""))
14932    (use (match_operand:BLK 1 "memory_operand" ""))
14933    (use (match_operand:SI 2 "nonmemory_operand" ""))
14934    (use (match_operand:SI 3 "const_int_operand" ""))
14935    (use (match_operand:SI 4 "const_int_operand" ""))
14936    (use (match_operand:SI 5 "const_int_operand" ""))]
14937   ""
14938 {
14939  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14940                          operands[4], operands[5]))
14941    DONE;
14942  else
14943    FAIL;
14944 })
14945
14946 (define_expand "movmemdi"
14947   [(use (match_operand:BLK 0 "memory_operand" ""))
14948    (use (match_operand:BLK 1 "memory_operand" ""))
14949    (use (match_operand:DI 2 "nonmemory_operand" ""))
14950    (use (match_operand:DI 3 "const_int_operand" ""))
14951    (use (match_operand:SI 4 "const_int_operand" ""))
14952    (use (match_operand:SI 5 "const_int_operand" ""))]
14953   "TARGET_64BIT"
14954 {
14955  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14956                          operands[4], operands[5]))
14957    DONE;
14958  else
14959    FAIL;
14960 })
14961
14962 ;; Most CPUs don't like single string operations
14963 ;; Handle this case here to simplify previous expander.
14964
14965 (define_expand "strmov"
14966   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
14967    (set (match_operand 1 "memory_operand" "") (match_dup 4))
14968    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
14969               (clobber (reg:CC FLAGS_REG))])
14970    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
14971               (clobber (reg:CC FLAGS_REG))])]
14972   ""
14973 {
14974   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
14975
14976   /* If .md ever supports :P for Pmode, these can be directly
14977      in the pattern above.  */
14978   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
14979   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
14980
14981   /* Can't use this if the user has appropriated esi or edi.  */
14982   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
14983       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
14984     {
14985       emit_insn (gen_strmov_singleop (operands[0], operands[1],
14986                                       operands[2], operands[3],
14987                                       operands[5], operands[6]));
14988       DONE;
14989     }
14990
14991   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
14992 })
14993
14994 (define_expand "strmov_singleop"
14995   [(parallel [(set (match_operand 1 "memory_operand" "")
14996                    (match_operand 3 "memory_operand" ""))
14997               (set (match_operand 0 "register_operand" "")
14998                    (match_operand 4 "" ""))
14999               (set (match_operand 2 "register_operand" "")
15000                    (match_operand 5 "" ""))])]
15001   ""
15002   "ix86_current_function_needs_cld = 1;")
15003
15004 (define_insn "*strmovdi_rex_1"
15005   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15006         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15007    (set (match_operand:DI 0 "register_operand" "=D")
15008         (plus:DI (match_dup 2)
15009                  (const_int 8)))
15010    (set (match_operand:DI 1 "register_operand" "=S")
15011         (plus:DI (match_dup 3)
15012                  (const_int 8)))]
15013   "TARGET_64BIT"
15014   "movsq"
15015   [(set_attr "type" "str")
15016    (set_attr "mode" "DI")
15017    (set_attr "memory" "both")])
15018
15019 (define_insn "*strmovsi_1"
15020   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15021         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15022    (set (match_operand:SI 0 "register_operand" "=D")
15023         (plus:SI (match_dup 2)
15024                  (const_int 4)))
15025    (set (match_operand:SI 1 "register_operand" "=S")
15026         (plus:SI (match_dup 3)
15027                  (const_int 4)))]
15028   "!TARGET_64BIT"
15029   "movs{l|d}"
15030   [(set_attr "type" "str")
15031    (set_attr "mode" "SI")
15032    (set_attr "memory" "both")])
15033
15034 (define_insn "*strmovsi_rex_1"
15035   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15036         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15037    (set (match_operand:DI 0 "register_operand" "=D")
15038         (plus:DI (match_dup 2)
15039                  (const_int 4)))
15040    (set (match_operand:DI 1 "register_operand" "=S")
15041         (plus:DI (match_dup 3)
15042                  (const_int 4)))]
15043   "TARGET_64BIT"
15044   "movs{l|d}"
15045   [(set_attr "type" "str")
15046    (set_attr "mode" "SI")
15047    (set_attr "memory" "both")])
15048
15049 (define_insn "*strmovhi_1"
15050   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15051         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15052    (set (match_operand:SI 0 "register_operand" "=D")
15053         (plus:SI (match_dup 2)
15054                  (const_int 2)))
15055    (set (match_operand:SI 1 "register_operand" "=S")
15056         (plus:SI (match_dup 3)
15057                  (const_int 2)))]
15058   "!TARGET_64BIT"
15059   "movsw"
15060   [(set_attr "type" "str")
15061    (set_attr "memory" "both")
15062    (set_attr "mode" "HI")])
15063
15064 (define_insn "*strmovhi_rex_1"
15065   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15066         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15067    (set (match_operand:DI 0 "register_operand" "=D")
15068         (plus:DI (match_dup 2)
15069                  (const_int 2)))
15070    (set (match_operand:DI 1 "register_operand" "=S")
15071         (plus:DI (match_dup 3)
15072                  (const_int 2)))]
15073   "TARGET_64BIT"
15074   "movsw"
15075   [(set_attr "type" "str")
15076    (set_attr "memory" "both")
15077    (set_attr "mode" "HI")])
15078
15079 (define_insn "*strmovqi_1"
15080   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15081         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15082    (set (match_operand:SI 0 "register_operand" "=D")
15083         (plus:SI (match_dup 2)
15084                  (const_int 1)))
15085    (set (match_operand:SI 1 "register_operand" "=S")
15086         (plus:SI (match_dup 3)
15087                  (const_int 1)))]
15088   "!TARGET_64BIT"
15089   "movsb"
15090   [(set_attr "type" "str")
15091    (set_attr "memory" "both")
15092    (set_attr "mode" "QI")])
15093
15094 (define_insn "*strmovqi_rex_1"
15095   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15096         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15097    (set (match_operand:DI 0 "register_operand" "=D")
15098         (plus:DI (match_dup 2)
15099                  (const_int 1)))
15100    (set (match_operand:DI 1 "register_operand" "=S")
15101         (plus:DI (match_dup 3)
15102                  (const_int 1)))]
15103   "TARGET_64BIT"
15104   "movsb"
15105   [(set_attr "type" "str")
15106    (set_attr "memory" "both")
15107    (set_attr "prefix_rex" "0")
15108    (set_attr "mode" "QI")])
15109
15110 (define_expand "rep_mov"
15111   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15112               (set (match_operand 0 "register_operand" "")
15113                    (match_operand 5 "" ""))
15114               (set (match_operand 2 "register_operand" "")
15115                    (match_operand 6 "" ""))
15116               (set (match_operand 1 "memory_operand" "")
15117                    (match_operand 3 "memory_operand" ""))
15118               (use (match_dup 4))])]
15119   ""
15120   "ix86_current_function_needs_cld = 1;")
15121
15122 (define_insn "*rep_movdi_rex64"
15123   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15124    (set (match_operand:DI 0 "register_operand" "=D")
15125         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15126                             (const_int 3))
15127                  (match_operand:DI 3 "register_operand" "0")))
15128    (set (match_operand:DI 1 "register_operand" "=S")
15129         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15130                  (match_operand:DI 4 "register_operand" "1")))
15131    (set (mem:BLK (match_dup 3))
15132         (mem:BLK (match_dup 4)))
15133    (use (match_dup 5))]
15134   "TARGET_64BIT"
15135   "rep{%;} movsq"
15136   [(set_attr "type" "str")
15137    (set_attr "prefix_rep" "1")
15138    (set_attr "memory" "both")
15139    (set_attr "mode" "DI")])
15140
15141 (define_insn "*rep_movsi"
15142   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15143    (set (match_operand:SI 0 "register_operand" "=D")
15144         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15145                             (const_int 2))
15146                  (match_operand:SI 3 "register_operand" "0")))
15147    (set (match_operand:SI 1 "register_operand" "=S")
15148         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15149                  (match_operand:SI 4 "register_operand" "1")))
15150    (set (mem:BLK (match_dup 3))
15151         (mem:BLK (match_dup 4)))
15152    (use (match_dup 5))]
15153   "!TARGET_64BIT"
15154   "rep{%;} movs{l|d}"
15155   [(set_attr "type" "str")
15156    (set_attr "prefix_rep" "1")
15157    (set_attr "memory" "both")
15158    (set_attr "mode" "SI")])
15159
15160 (define_insn "*rep_movsi_rex64"
15161   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15162    (set (match_operand:DI 0 "register_operand" "=D")
15163         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15164                             (const_int 2))
15165                  (match_operand:DI 3 "register_operand" "0")))
15166    (set (match_operand:DI 1 "register_operand" "=S")
15167         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15168                  (match_operand:DI 4 "register_operand" "1")))
15169    (set (mem:BLK (match_dup 3))
15170         (mem:BLK (match_dup 4)))
15171    (use (match_dup 5))]
15172   "TARGET_64BIT"
15173   "rep{%;} movs{l|d}"
15174   [(set_attr "type" "str")
15175    (set_attr "prefix_rep" "1")
15176    (set_attr "memory" "both")
15177    (set_attr "mode" "SI")])
15178
15179 (define_insn "*rep_movqi"
15180   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15181    (set (match_operand:SI 0 "register_operand" "=D")
15182         (plus:SI (match_operand:SI 3 "register_operand" "0")
15183                  (match_operand:SI 5 "register_operand" "2")))
15184    (set (match_operand:SI 1 "register_operand" "=S")
15185         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15186    (set (mem:BLK (match_dup 3))
15187         (mem:BLK (match_dup 4)))
15188    (use (match_dup 5))]
15189   "!TARGET_64BIT"
15190   "rep{%;} movsb"
15191   [(set_attr "type" "str")
15192    (set_attr "prefix_rep" "1")
15193    (set_attr "memory" "both")
15194    (set_attr "mode" "SI")])
15195
15196 (define_insn "*rep_movqi_rex64"
15197   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15198    (set (match_operand:DI 0 "register_operand" "=D")
15199         (plus:DI (match_operand:DI 3 "register_operand" "0")
15200                  (match_operand:DI 5 "register_operand" "2")))
15201    (set (match_operand:DI 1 "register_operand" "=S")
15202         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15203    (set (mem:BLK (match_dup 3))
15204         (mem:BLK (match_dup 4)))
15205    (use (match_dup 5))]
15206   "TARGET_64BIT"
15207   "rep{%;} movsb"
15208   [(set_attr "type" "str")
15209    (set_attr "prefix_rep" "1")
15210    (set_attr "memory" "both")
15211    (set_attr "mode" "SI")])
15212
15213 (define_expand "setmemsi"
15214    [(use (match_operand:BLK 0 "memory_operand" ""))
15215     (use (match_operand:SI 1 "nonmemory_operand" ""))
15216     (use (match_operand 2 "const_int_operand" ""))
15217     (use (match_operand 3 "const_int_operand" ""))
15218     (use (match_operand:SI 4 "const_int_operand" ""))
15219     (use (match_operand:SI 5 "const_int_operand" ""))]
15220   ""
15221 {
15222  if (ix86_expand_setmem (operands[0], operands[1],
15223                          operands[2], operands[3],
15224                          operands[4], operands[5]))
15225    DONE;
15226  else
15227    FAIL;
15228 })
15229
15230 (define_expand "setmemdi"
15231    [(use (match_operand:BLK 0 "memory_operand" ""))
15232     (use (match_operand:DI 1 "nonmemory_operand" ""))
15233     (use (match_operand 2 "const_int_operand" ""))
15234     (use (match_operand 3 "const_int_operand" ""))
15235     (use (match_operand 4 "const_int_operand" ""))
15236     (use (match_operand 5 "const_int_operand" ""))]
15237   "TARGET_64BIT"
15238 {
15239  if (ix86_expand_setmem (operands[0], operands[1],
15240                          operands[2], operands[3],
15241                          operands[4], operands[5]))
15242    DONE;
15243  else
15244    FAIL;
15245 })
15246
15247 ;; Most CPUs don't like single string operations
15248 ;; Handle this case here to simplify previous expander.
15249
15250 (define_expand "strset"
15251   [(set (match_operand 1 "memory_operand" "")
15252         (match_operand 2 "register_operand" ""))
15253    (parallel [(set (match_operand 0 "register_operand" "")
15254                    (match_dup 3))
15255               (clobber (reg:CC FLAGS_REG))])]
15256   ""
15257 {
15258   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15259     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15260
15261   /* If .md ever supports :P for Pmode, this can be directly
15262      in the pattern above.  */
15263   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15264                               GEN_INT (GET_MODE_SIZE (GET_MODE
15265                                                       (operands[2]))));
15266   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15267     {
15268       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15269                                       operands[3]));
15270       DONE;
15271     }
15272 })
15273
15274 (define_expand "strset_singleop"
15275   [(parallel [(set (match_operand 1 "memory_operand" "")
15276                    (match_operand 2 "register_operand" ""))
15277               (set (match_operand 0 "register_operand" "")
15278                    (match_operand 3 "" ""))])]
15279   ""
15280   "ix86_current_function_needs_cld = 1;")
15281
15282 (define_insn "*strsetdi_rex_1"
15283   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15284         (match_operand:DI 2 "register_operand" "a"))
15285    (set (match_operand:DI 0 "register_operand" "=D")
15286         (plus:DI (match_dup 1)
15287                  (const_int 8)))]
15288   "TARGET_64BIT"
15289   "stosq"
15290   [(set_attr "type" "str")
15291    (set_attr "memory" "store")
15292    (set_attr "mode" "DI")])
15293
15294 (define_insn "*strsetsi_1"
15295   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15296         (match_operand:SI 2 "register_operand" "a"))
15297    (set (match_operand:SI 0 "register_operand" "=D")
15298         (plus:SI (match_dup 1)
15299                  (const_int 4)))]
15300   "!TARGET_64BIT"
15301   "stos{l|d}"
15302   [(set_attr "type" "str")
15303    (set_attr "memory" "store")
15304    (set_attr "mode" "SI")])
15305
15306 (define_insn "*strsetsi_rex_1"
15307   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15308         (match_operand:SI 2 "register_operand" "a"))
15309    (set (match_operand:DI 0 "register_operand" "=D")
15310         (plus:DI (match_dup 1)
15311                  (const_int 4)))]
15312   "TARGET_64BIT"
15313   "stos{l|d}"
15314   [(set_attr "type" "str")
15315    (set_attr "memory" "store")
15316    (set_attr "mode" "SI")])
15317
15318 (define_insn "*strsethi_1"
15319   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15320         (match_operand:HI 2 "register_operand" "a"))
15321    (set (match_operand:SI 0 "register_operand" "=D")
15322         (plus:SI (match_dup 1)
15323                  (const_int 2)))]
15324   "!TARGET_64BIT"
15325   "stosw"
15326   [(set_attr "type" "str")
15327    (set_attr "memory" "store")
15328    (set_attr "mode" "HI")])
15329
15330 (define_insn "*strsethi_rex_1"
15331   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15332         (match_operand:HI 2 "register_operand" "a"))
15333    (set (match_operand:DI 0 "register_operand" "=D")
15334         (plus:DI (match_dup 1)
15335                  (const_int 2)))]
15336   "TARGET_64BIT"
15337   "stosw"
15338   [(set_attr "type" "str")
15339    (set_attr "memory" "store")
15340    (set_attr "mode" "HI")])
15341
15342 (define_insn "*strsetqi_1"
15343   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15344         (match_operand:QI 2 "register_operand" "a"))
15345    (set (match_operand:SI 0 "register_operand" "=D")
15346         (plus:SI (match_dup 1)
15347                  (const_int 1)))]
15348   "!TARGET_64BIT"
15349   "stosb"
15350   [(set_attr "type" "str")
15351    (set_attr "memory" "store")
15352    (set_attr "mode" "QI")])
15353
15354 (define_insn "*strsetqi_rex_1"
15355   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15356         (match_operand:QI 2 "register_operand" "a"))
15357    (set (match_operand:DI 0 "register_operand" "=D")
15358         (plus:DI (match_dup 1)
15359                  (const_int 1)))]
15360   "TARGET_64BIT"
15361   "stosb"
15362   [(set_attr "type" "str")
15363    (set_attr "memory" "store")
15364    (set_attr "prefix_rex" "0")
15365    (set_attr "mode" "QI")])
15366
15367 (define_expand "rep_stos"
15368   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15369               (set (match_operand 0 "register_operand" "")
15370                    (match_operand 4 "" ""))
15371               (set (match_operand 2 "memory_operand" "") (const_int 0))
15372               (use (match_operand 3 "register_operand" ""))
15373               (use (match_dup 1))])]
15374   ""
15375   "ix86_current_function_needs_cld = 1;")
15376
15377 (define_insn "*rep_stosdi_rex64"
15378   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15379    (set (match_operand:DI 0 "register_operand" "=D")
15380         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15381                             (const_int 3))
15382                  (match_operand:DI 3 "register_operand" "0")))
15383    (set (mem:BLK (match_dup 3))
15384         (const_int 0))
15385    (use (match_operand:DI 2 "register_operand" "a"))
15386    (use (match_dup 4))]
15387   "TARGET_64BIT"
15388   "rep{%;} stosq"
15389   [(set_attr "type" "str")
15390    (set_attr "prefix_rep" "1")
15391    (set_attr "memory" "store")
15392    (set_attr "mode" "DI")])
15393
15394 (define_insn "*rep_stossi"
15395   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15396    (set (match_operand:SI 0 "register_operand" "=D")
15397         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15398                             (const_int 2))
15399                  (match_operand:SI 3 "register_operand" "0")))
15400    (set (mem:BLK (match_dup 3))
15401         (const_int 0))
15402    (use (match_operand:SI 2 "register_operand" "a"))
15403    (use (match_dup 4))]
15404   "!TARGET_64BIT"
15405   "rep{%;} stos{l|d}"
15406   [(set_attr "type" "str")
15407    (set_attr "prefix_rep" "1")
15408    (set_attr "memory" "store")
15409    (set_attr "mode" "SI")])
15410
15411 (define_insn "*rep_stossi_rex64"
15412   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15413    (set (match_operand:DI 0 "register_operand" "=D")
15414         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15415                             (const_int 2))
15416                  (match_operand:DI 3 "register_operand" "0")))
15417    (set (mem:BLK (match_dup 3))
15418         (const_int 0))
15419    (use (match_operand:SI 2 "register_operand" "a"))
15420    (use (match_dup 4))]
15421   "TARGET_64BIT"
15422   "rep{%;} stos{l|d}"
15423   [(set_attr "type" "str")
15424    (set_attr "prefix_rep" "1")
15425    (set_attr "memory" "store")
15426    (set_attr "mode" "SI")])
15427
15428 (define_insn "*rep_stosqi"
15429   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15430    (set (match_operand:SI 0 "register_operand" "=D")
15431         (plus:SI (match_operand:SI 3 "register_operand" "0")
15432                  (match_operand:SI 4 "register_operand" "1")))
15433    (set (mem:BLK (match_dup 3))
15434         (const_int 0))
15435    (use (match_operand:QI 2 "register_operand" "a"))
15436    (use (match_dup 4))]
15437   "!TARGET_64BIT"
15438   "rep{%;} stosb"
15439   [(set_attr "type" "str")
15440    (set_attr "prefix_rep" "1")
15441    (set_attr "memory" "store")
15442    (set_attr "mode" "QI")])
15443
15444 (define_insn "*rep_stosqi_rex64"
15445   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15446    (set (match_operand:DI 0 "register_operand" "=D")
15447         (plus:DI (match_operand:DI 3 "register_operand" "0")
15448                  (match_operand:DI 4 "register_operand" "1")))
15449    (set (mem:BLK (match_dup 3))
15450         (const_int 0))
15451    (use (match_operand:QI 2 "register_operand" "a"))
15452    (use (match_dup 4))]
15453   "TARGET_64BIT"
15454   "rep{%;} stosb"
15455   [(set_attr "type" "str")
15456    (set_attr "prefix_rep" "1")
15457    (set_attr "memory" "store")
15458    (set_attr "prefix_rex" "0")
15459    (set_attr "mode" "QI")])
15460
15461 (define_expand "cmpstrnsi"
15462   [(set (match_operand:SI 0 "register_operand" "")
15463         (compare:SI (match_operand:BLK 1 "general_operand" "")
15464                     (match_operand:BLK 2 "general_operand" "")))
15465    (use (match_operand 3 "general_operand" ""))
15466    (use (match_operand 4 "immediate_operand" ""))]
15467   ""
15468 {
15469   rtx addr1, addr2, out, outlow, count, countreg, align;
15470
15471   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15472     FAIL;
15473
15474   /* Can't use this if the user has appropriated esi or edi.  */
15475   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15476     FAIL;
15477
15478   out = operands[0];
15479   if (!REG_P (out))
15480     out = gen_reg_rtx (SImode);
15481
15482   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15483   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15484   if (addr1 != XEXP (operands[1], 0))
15485     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15486   if (addr2 != XEXP (operands[2], 0))
15487     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15488
15489   count = operands[3];
15490   countreg = ix86_zero_extend_to_Pmode (count);
15491
15492   /* %%% Iff we are testing strict equality, we can use known alignment
15493      to good advantage.  This may be possible with combine, particularly
15494      once cc0 is dead.  */
15495   align = operands[4];
15496
15497   if (CONST_INT_P (count))
15498     {
15499       if (INTVAL (count) == 0)
15500         {
15501           emit_move_insn (operands[0], const0_rtx);
15502           DONE;
15503         }
15504       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15505                                      operands[1], operands[2]));
15506     }
15507   else
15508     {
15509       rtx (*gen_cmp) (rtx, rtx);
15510
15511       gen_cmp = (TARGET_64BIT
15512                  ? gen_cmpdi_1 : gen_cmpsi_1);
15513
15514       emit_insn (gen_cmp (countreg, countreg));
15515       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15516                                   operands[1], operands[2]));
15517     }
15518
15519   outlow = gen_lowpart (QImode, out);
15520   emit_insn (gen_cmpintqi (outlow));
15521   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15522
15523   if (operands[0] != out)
15524     emit_move_insn (operands[0], out);
15525
15526   DONE;
15527 })
15528
15529 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15530
15531 (define_expand "cmpintqi"
15532   [(set (match_dup 1)
15533         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15534    (set (match_dup 2)
15535         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15536    (parallel [(set (match_operand:QI 0 "register_operand" "")
15537                    (minus:QI (match_dup 1)
15538                              (match_dup 2)))
15539               (clobber (reg:CC FLAGS_REG))])]
15540   ""
15541   "operands[1] = gen_reg_rtx (QImode);
15542    operands[2] = gen_reg_rtx (QImode);")
15543
15544 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15545 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15546
15547 (define_expand "cmpstrnqi_nz_1"
15548   [(parallel [(set (reg:CC FLAGS_REG)
15549                    (compare:CC (match_operand 4 "memory_operand" "")
15550                                (match_operand 5 "memory_operand" "")))
15551               (use (match_operand 2 "register_operand" ""))
15552               (use (match_operand:SI 3 "immediate_operand" ""))
15553               (clobber (match_operand 0 "register_operand" ""))
15554               (clobber (match_operand 1 "register_operand" ""))
15555               (clobber (match_dup 2))])]
15556   ""
15557   "ix86_current_function_needs_cld = 1;")
15558
15559 (define_insn "*cmpstrnqi_nz_1"
15560   [(set (reg:CC FLAGS_REG)
15561         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15562                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15563    (use (match_operand:SI 6 "register_operand" "2"))
15564    (use (match_operand:SI 3 "immediate_operand" "i"))
15565    (clobber (match_operand:SI 0 "register_operand" "=S"))
15566    (clobber (match_operand:SI 1 "register_operand" "=D"))
15567    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15568   "!TARGET_64BIT"
15569   "repz{%;} cmpsb"
15570   [(set_attr "type" "str")
15571    (set_attr "mode" "QI")
15572    (set_attr "prefix_rep" "1")])
15573
15574 (define_insn "*cmpstrnqi_nz_rex_1"
15575   [(set (reg:CC FLAGS_REG)
15576         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15577                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15578    (use (match_operand:DI 6 "register_operand" "2"))
15579    (use (match_operand:SI 3 "immediate_operand" "i"))
15580    (clobber (match_operand:DI 0 "register_operand" "=S"))
15581    (clobber (match_operand:DI 1 "register_operand" "=D"))
15582    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15583   "TARGET_64BIT"
15584   "repz{%;} cmpsb"
15585   [(set_attr "type" "str")
15586    (set_attr "mode" "QI")
15587    (set_attr "prefix_rex" "0")
15588    (set_attr "prefix_rep" "1")])
15589
15590 ;; The same, but the count is not known to not be zero.
15591
15592 (define_expand "cmpstrnqi_1"
15593   [(parallel [(set (reg:CC FLAGS_REG)
15594                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15595                                      (const_int 0))
15596                   (compare:CC (match_operand 4 "memory_operand" "")
15597                               (match_operand 5 "memory_operand" ""))
15598                   (const_int 0)))
15599               (use (match_operand:SI 3 "immediate_operand" ""))
15600               (use (reg:CC FLAGS_REG))
15601               (clobber (match_operand 0 "register_operand" ""))
15602               (clobber (match_operand 1 "register_operand" ""))
15603               (clobber (match_dup 2))])]
15604   ""
15605   "ix86_current_function_needs_cld = 1;")
15606
15607 (define_insn "*cmpstrnqi_1"
15608   [(set (reg:CC FLAGS_REG)
15609         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15610                              (const_int 0))
15611           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15612                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15613           (const_int 0)))
15614    (use (match_operand:SI 3 "immediate_operand" "i"))
15615    (use (reg:CC FLAGS_REG))
15616    (clobber (match_operand:SI 0 "register_operand" "=S"))
15617    (clobber (match_operand:SI 1 "register_operand" "=D"))
15618    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15619   "!TARGET_64BIT"
15620   "repz{%;} cmpsb"
15621   [(set_attr "type" "str")
15622    (set_attr "mode" "QI")
15623    (set_attr "prefix_rep" "1")])
15624
15625 (define_insn "*cmpstrnqi_rex_1"
15626   [(set (reg:CC FLAGS_REG)
15627         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15628                              (const_int 0))
15629           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15630                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15631           (const_int 0)))
15632    (use (match_operand:SI 3 "immediate_operand" "i"))
15633    (use (reg:CC FLAGS_REG))
15634    (clobber (match_operand:DI 0 "register_operand" "=S"))
15635    (clobber (match_operand:DI 1 "register_operand" "=D"))
15636    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15637   "TARGET_64BIT"
15638   "repz{%;} cmpsb"
15639   [(set_attr "type" "str")
15640    (set_attr "mode" "QI")
15641    (set_attr "prefix_rex" "0")
15642    (set_attr "prefix_rep" "1")])
15643
15644 (define_expand "strlensi"
15645   [(set (match_operand:SI 0 "register_operand" "")
15646         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15647                     (match_operand:QI 2 "immediate_operand" "")
15648                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15649   ""
15650 {
15651  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15652    DONE;
15653  else
15654    FAIL;
15655 })
15656
15657 (define_expand "strlendi"
15658   [(set (match_operand:DI 0 "register_operand" "")
15659         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15660                     (match_operand:QI 2 "immediate_operand" "")
15661                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15662   ""
15663 {
15664  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15665    DONE;
15666  else
15667    FAIL;
15668 })
15669
15670 (define_expand "strlenqi_1"
15671   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15672               (clobber (match_operand 1 "register_operand" ""))
15673               (clobber (reg:CC FLAGS_REG))])]
15674   ""
15675   "ix86_current_function_needs_cld = 1;")
15676
15677 (define_insn "*strlenqi_1"
15678   [(set (match_operand:SI 0 "register_operand" "=&c")
15679         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15680                     (match_operand:QI 2 "register_operand" "a")
15681                     (match_operand:SI 3 "immediate_operand" "i")
15682                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15683    (clobber (match_operand:SI 1 "register_operand" "=D"))
15684    (clobber (reg:CC FLAGS_REG))]
15685   "!TARGET_64BIT"
15686   "repnz{%;} scasb"
15687   [(set_attr "type" "str")
15688    (set_attr "mode" "QI")
15689    (set_attr "prefix_rep" "1")])
15690
15691 (define_insn "*strlenqi_rex_1"
15692   [(set (match_operand:DI 0 "register_operand" "=&c")
15693         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15694                     (match_operand:QI 2 "register_operand" "a")
15695                     (match_operand:DI 3 "immediate_operand" "i")
15696                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15697    (clobber (match_operand:DI 1 "register_operand" "=D"))
15698    (clobber (reg:CC FLAGS_REG))]
15699   "TARGET_64BIT"
15700   "repnz{%;} scasb"
15701   [(set_attr "type" "str")
15702    (set_attr "mode" "QI")
15703    (set_attr "prefix_rex" "0")
15704    (set_attr "prefix_rep" "1")])
15705
15706 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15707 ;; handled in combine, but it is not currently up to the task.
15708 ;; When used for their truth value, the cmpstrn* expanders generate
15709 ;; code like this:
15710 ;;
15711 ;;   repz cmpsb
15712 ;;   seta       %al
15713 ;;   setb       %dl
15714 ;;   cmpb       %al, %dl
15715 ;;   jcc        label
15716 ;;
15717 ;; The intermediate three instructions are unnecessary.
15718
15719 ;; This one handles cmpstrn*_nz_1...
15720 (define_peephole2
15721   [(parallel[
15722      (set (reg:CC FLAGS_REG)
15723           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15724                       (mem:BLK (match_operand 5 "register_operand" ""))))
15725      (use (match_operand 6 "register_operand" ""))
15726      (use (match_operand:SI 3 "immediate_operand" ""))
15727      (clobber (match_operand 0 "register_operand" ""))
15728      (clobber (match_operand 1 "register_operand" ""))
15729      (clobber (match_operand 2 "register_operand" ""))])
15730    (set (match_operand:QI 7 "register_operand" "")
15731         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15732    (set (match_operand:QI 8 "register_operand" "")
15733         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15734    (set (reg FLAGS_REG)
15735         (compare (match_dup 7) (match_dup 8)))
15736   ]
15737   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15738   [(parallel[
15739      (set (reg:CC FLAGS_REG)
15740           (compare:CC (mem:BLK (match_dup 4))
15741                       (mem:BLK (match_dup 5))))
15742      (use (match_dup 6))
15743      (use (match_dup 3))
15744      (clobber (match_dup 0))
15745      (clobber (match_dup 1))
15746      (clobber (match_dup 2))])])
15747
15748 ;; ...and this one handles cmpstrn*_1.
15749 (define_peephole2
15750   [(parallel[
15751      (set (reg:CC FLAGS_REG)
15752           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15753                                (const_int 0))
15754             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15755                         (mem:BLK (match_operand 5 "register_operand" "")))
15756             (const_int 0)))
15757      (use (match_operand:SI 3 "immediate_operand" ""))
15758      (use (reg:CC FLAGS_REG))
15759      (clobber (match_operand 0 "register_operand" ""))
15760      (clobber (match_operand 1 "register_operand" ""))
15761      (clobber (match_operand 2 "register_operand" ""))])
15762    (set (match_operand:QI 7 "register_operand" "")
15763         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15764    (set (match_operand:QI 8 "register_operand" "")
15765         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15766    (set (reg FLAGS_REG)
15767         (compare (match_dup 7) (match_dup 8)))
15768   ]
15769   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15770   [(parallel[
15771      (set (reg:CC FLAGS_REG)
15772           (if_then_else:CC (ne (match_dup 6)
15773                                (const_int 0))
15774             (compare:CC (mem:BLK (match_dup 4))
15775                         (mem:BLK (match_dup 5)))
15776             (const_int 0)))
15777      (use (match_dup 3))
15778      (use (reg:CC FLAGS_REG))
15779      (clobber (match_dup 0))
15780      (clobber (match_dup 1))
15781      (clobber (match_dup 2))])])
15782 \f
15783 ;; Conditional move instructions.
15784
15785 (define_expand "mov<mode>cc"
15786   [(set (match_operand:SWIM 0 "register_operand" "")
15787         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15788                            (match_operand:SWIM 2 "general_operand" "")
15789                            (match_operand:SWIM 3 "general_operand" "")))]
15790   ""
15791   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15792
15793 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15794 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15795 ;; So just document what we're doing explicitly.
15796
15797 (define_expand "x86_mov<mode>cc_0_m1"
15798   [(parallel
15799     [(set (match_operand:SWI48 0 "register_operand" "")
15800           (if_then_else:SWI48
15801             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15802              [(match_operand 1 "flags_reg_operand" "")
15803               (const_int 0)])
15804             (const_int -1)
15805             (const_int 0)))
15806      (clobber (reg:CC FLAGS_REG))])]
15807   ""
15808   "")
15809
15810 (define_insn "*x86_mov<mode>cc_0_m1"
15811   [(set (match_operand:SWI48 0 "register_operand" "=r")
15812         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15813                              [(reg FLAGS_REG) (const_int 0)])
15814           (const_int -1)
15815           (const_int 0)))
15816    (clobber (reg:CC FLAGS_REG))]
15817   ""
15818   "sbb{<imodesuffix>}\t%0, %0"
15819   ; Since we don't have the proper number of operands for an alu insn,
15820   ; fill in all the blanks.
15821   [(set_attr "type" "alu")
15822    (set_attr "use_carry" "1")
15823    (set_attr "pent_pair" "pu")
15824    (set_attr "memory" "none")
15825    (set_attr "imm_disp" "false")
15826    (set_attr "mode" "<MODE>")
15827    (set_attr "length_immediate" "0")])
15828
15829 (define_insn "*x86_mov<mode>cc_0_m1_se"
15830   [(set (match_operand:SWI48 0 "register_operand" "=r")
15831         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15832                              [(reg FLAGS_REG) (const_int 0)])
15833                             (const_int 1)
15834                             (const_int 0)))
15835    (clobber (reg:CC FLAGS_REG))]
15836   ""
15837   "sbb{<imodesuffix>}\t%0, %0"
15838   [(set_attr "type" "alu")
15839    (set_attr "use_carry" "1")
15840    (set_attr "pent_pair" "pu")
15841    (set_attr "memory" "none")
15842    (set_attr "imm_disp" "false")
15843    (set_attr "mode" "<MODE>")
15844    (set_attr "length_immediate" "0")])
15845
15846 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15847   [(set (match_operand:SWI48 0 "register_operand" "=r")
15848         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15849                     [(reg FLAGS_REG) (const_int 0)])))]
15850   ""
15851   "sbb{<imodesuffix>}\t%0, %0"
15852   [(set_attr "type" "alu")
15853    (set_attr "use_carry" "1")
15854    (set_attr "pent_pair" "pu")
15855    (set_attr "memory" "none")
15856    (set_attr "imm_disp" "false")
15857    (set_attr "mode" "<MODE>")
15858    (set_attr "length_immediate" "0")])
15859
15860 (define_insn "*mov<mode>cc_noc"
15861   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15862         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15863                                [(reg FLAGS_REG) (const_int 0)])
15864           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15865           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15866   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15867   "@
15868    cmov%O2%C1\t{%2, %0|%0, %2}
15869    cmov%O2%c1\t{%3, %0|%0, %3}"
15870   [(set_attr "type" "icmov")
15871    (set_attr "mode" "<MODE>")])
15872
15873 (define_insn_and_split "*movqicc_noc"
15874   [(set (match_operand:QI 0 "register_operand" "=r,r")
15875         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15876                            [(match_operand 4 "flags_reg_operand" "")
15877                             (const_int 0)])
15878                       (match_operand:QI 2 "register_operand" "r,0")
15879                       (match_operand:QI 3 "register_operand" "0,r")))]
15880   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15881   "#"
15882   "&& reload_completed"
15883   [(set (match_dup 0)
15884         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15885                       (match_dup 2)
15886                       (match_dup 3)))]
15887   "operands[0] = gen_lowpart (SImode, operands[0]);
15888    operands[2] = gen_lowpart (SImode, operands[2]);
15889    operands[3] = gen_lowpart (SImode, operands[3]);"
15890   [(set_attr "type" "icmov")
15891    (set_attr "mode" "SI")])
15892
15893 (define_expand "mov<mode>cc"
15894   [(set (match_operand:X87MODEF 0 "register_operand" "")
15895         (if_then_else:X87MODEF
15896           (match_operand 1 "ix86_fp_comparison_operator" "")
15897           (match_operand:X87MODEF 2 "register_operand" "")
15898           (match_operand:X87MODEF 3 "register_operand" "")))]
15899   "(TARGET_80387 && TARGET_CMOVE)
15900    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15901   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15902
15903 (define_insn "*movsfcc_1_387"
15904   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15905         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15906                                 [(reg FLAGS_REG) (const_int 0)])
15907                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15908                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15909   "TARGET_80387 && TARGET_CMOVE
15910    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15911   "@
15912    fcmov%F1\t{%2, %0|%0, %2}
15913    fcmov%f1\t{%3, %0|%0, %3}
15914    cmov%O2%C1\t{%2, %0|%0, %2}
15915    cmov%O2%c1\t{%3, %0|%0, %3}"
15916   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15917    (set_attr "mode" "SF,SF,SI,SI")])
15918
15919 (define_insn "*movdfcc_1"
15920   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15921         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15922                                 [(reg FLAGS_REG) (const_int 0)])
15923                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15924                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15925   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15926    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15927   "@
15928    fcmov%F1\t{%2, %0|%0, %2}
15929    fcmov%f1\t{%3, %0|%0, %3}
15930    #
15931    #"
15932   [(set_attr "type" "fcmov,fcmov,multi,multi")
15933    (set_attr "mode" "DF")])
15934
15935 (define_insn "*movdfcc_1_rex64"
15936   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15937         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15938                                 [(reg FLAGS_REG) (const_int 0)])
15939                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15940                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15941   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15942    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15943   "@
15944    fcmov%F1\t{%2, %0|%0, %2}
15945    fcmov%f1\t{%3, %0|%0, %3}
15946    cmov%O2%C1\t{%2, %0|%0, %2}
15947    cmov%O2%c1\t{%3, %0|%0, %3}"
15948   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15949    (set_attr "mode" "DF")])
15950
15951 (define_split
15952   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
15953         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15954                                 [(match_operand 4 "flags_reg_operand" "")
15955                                  (const_int 0)])
15956                       (match_operand:DF 2 "nonimmediate_operand" "")
15957                       (match_operand:DF 3 "nonimmediate_operand" "")))]
15958   "!TARGET_64BIT && reload_completed"
15959   [(set (match_dup 2)
15960         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15961                       (match_dup 5)
15962                       (match_dup 6)))
15963    (set (match_dup 3)
15964         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15965                       (match_dup 7)
15966                       (match_dup 8)))]
15967 {
15968   split_di (&operands[2], 2, &operands[5], &operands[7]);
15969   split_di (&operands[0], 1, &operands[2], &operands[3]);
15970 })
15971
15972 (define_insn "*movxfcc_1"
15973   [(set (match_operand:XF 0 "register_operand" "=f,f")
15974         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15975                                 [(reg FLAGS_REG) (const_int 0)])
15976                       (match_operand:XF 2 "register_operand" "f,0")
15977                       (match_operand:XF 3 "register_operand" "0,f")))]
15978   "TARGET_80387 && TARGET_CMOVE"
15979   "@
15980    fcmov%F1\t{%2, %0|%0, %2}
15981    fcmov%f1\t{%3, %0|%0, %3}"
15982   [(set_attr "type" "fcmov")
15983    (set_attr "mode" "XF")])
15984
15985 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
15986 ;; the scalar versions to have only XMM registers as operands.
15987
15988 ;; XOP conditional move
15989 (define_insn "*xop_pcmov_<mode>"
15990   [(set (match_operand:MODEF 0 "register_operand" "=x")
15991         (if_then_else:MODEF
15992           (match_operand:MODEF 1 "register_operand" "x")
15993           (match_operand:MODEF 2 "register_operand" "x")
15994           (match_operand:MODEF 3 "register_operand" "x")))]
15995   "TARGET_XOP"
15996   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
15997   [(set_attr "type" "sse4arg")])
15998
15999 ;; These versions of the min/max patterns are intentionally ignorant of
16000 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16001 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16002 ;; are undefined in this condition, we're certain this is correct.
16003
16004 (define_insn "*avx_<code><mode>3"
16005   [(set (match_operand:MODEF 0 "register_operand" "=x")
16006         (smaxmin:MODEF
16007           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16008           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16009   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16010   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16011   [(set_attr "type" "sseadd")
16012    (set_attr "prefix" "vex")
16013    (set_attr "mode" "<MODE>")])
16014
16015 (define_insn "<code><mode>3"
16016   [(set (match_operand:MODEF 0 "register_operand" "=x")
16017         (smaxmin:MODEF
16018           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16019           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16020   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16021   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16022   [(set_attr "type" "sseadd")
16023    (set_attr "mode" "<MODE>")])
16024
16025 ;; These versions of the min/max patterns implement exactly the operations
16026 ;;   min = (op1 < op2 ? op1 : op2)
16027 ;;   max = (!(op1 < op2) ? op1 : op2)
16028 ;; Their operands are not commutative, and thus they may be used in the
16029 ;; presence of -0.0 and NaN.
16030
16031 (define_insn "*avx_ieee_smin<mode>3"
16032   [(set (match_operand:MODEF 0 "register_operand" "=x")
16033         (unspec:MODEF
16034           [(match_operand:MODEF 1 "register_operand" "x")
16035            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16036          UNSPEC_IEEE_MIN))]
16037   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16038   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16039   [(set_attr "type" "sseadd")
16040    (set_attr "prefix" "vex")
16041    (set_attr "mode" "<MODE>")])
16042
16043 (define_insn "*ieee_smin<mode>3"
16044   [(set (match_operand:MODEF 0 "register_operand" "=x")
16045         (unspec:MODEF
16046           [(match_operand:MODEF 1 "register_operand" "0")
16047            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16048          UNSPEC_IEEE_MIN))]
16049   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16050   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16051   [(set_attr "type" "sseadd")
16052    (set_attr "mode" "<MODE>")])
16053
16054 (define_insn "*avx_ieee_smax<mode>3"
16055   [(set (match_operand:MODEF 0 "register_operand" "=x")
16056         (unspec:MODEF
16057           [(match_operand:MODEF 1 "register_operand" "0")
16058            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16059          UNSPEC_IEEE_MAX))]
16060   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16061   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16062   [(set_attr "type" "sseadd")
16063    (set_attr "prefix" "vex")
16064    (set_attr "mode" "<MODE>")])
16065
16066 (define_insn "*ieee_smax<mode>3"
16067   [(set (match_operand:MODEF 0 "register_operand" "=x")
16068         (unspec:MODEF
16069           [(match_operand:MODEF 1 "register_operand" "0")
16070            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16071          UNSPEC_IEEE_MAX))]
16072   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16073   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16074   [(set_attr "type" "sseadd")
16075    (set_attr "mode" "<MODE>")])
16076
16077 ;; Make two stack loads independent:
16078 ;;   fld aa              fld aa
16079 ;;   fld %st(0)     ->   fld bb
16080 ;;   fmul bb             fmul %st(1), %st
16081 ;;
16082 ;; Actually we only match the last two instructions for simplicity.
16083 (define_peephole2
16084   [(set (match_operand 0 "fp_register_operand" "")
16085         (match_operand 1 "fp_register_operand" ""))
16086    (set (match_dup 0)
16087         (match_operator 2 "binary_fp_operator"
16088            [(match_dup 0)
16089             (match_operand 3 "memory_operand" "")]))]
16090   "REGNO (operands[0]) != REGNO (operands[1])"
16091   [(set (match_dup 0) (match_dup 3))
16092    (set (match_dup 0) (match_dup 4))]
16093
16094   ;; The % modifier is not operational anymore in peephole2's, so we have to
16095   ;; swap the operands manually in the case of addition and multiplication.
16096   "if (COMMUTATIVE_ARITH_P (operands[2]))
16097      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16098                                    GET_MODE (operands[2]),
16099                                    operands[0], operands[1]);
16100    else
16101      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16102                                    GET_MODE (operands[2]),
16103                                    operands[1], operands[0]);")
16104
16105 ;; Conditional addition patterns
16106 (define_expand "add<mode>cc"
16107   [(match_operand:SWI 0 "register_operand" "")
16108    (match_operand 1 "ordered_comparison_operator" "")
16109    (match_operand:SWI 2 "register_operand" "")
16110    (match_operand:SWI 3 "const_int_operand" "")]
16111   ""
16112   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16113 \f
16114 ;; Misc patterns (?)
16115
16116 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16117 ;; Otherwise there will be nothing to keep
16118 ;;
16119 ;; [(set (reg ebp) (reg esp))]
16120 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16121 ;;  (clobber (eflags)]
16122 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16123 ;;
16124 ;; in proper program order.
16125
16126 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16127   [(set (match_operand:P 0 "register_operand" "=r,r")
16128         (plus:P (match_operand:P 1 "register_operand" "0,r")
16129                 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16130    (clobber (reg:CC FLAGS_REG))
16131    (clobber (mem:BLK (scratch)))]
16132   ""
16133 {
16134   switch (get_attr_type (insn))
16135     {
16136     case TYPE_IMOV:
16137       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16138
16139     case TYPE_ALU:
16140       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16141       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16142         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16143
16144       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16145
16146     default:
16147       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16148       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16149     }
16150 }
16151   [(set (attr "type")
16152         (cond [(and (eq_attr "alternative" "0")
16153                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16154                  (const_string "alu")
16155                (match_operand:<MODE> 2 "const0_operand" "")
16156                  (const_string "imov")
16157               ]
16158               (const_string "lea")))
16159    (set (attr "length_immediate")
16160         (cond [(eq_attr "type" "imov")
16161                  (const_string "0")
16162                (and (eq_attr "type" "alu")
16163                     (match_operand 2 "const128_operand" ""))
16164                  (const_string "1")
16165               ]
16166               (const_string "*")))
16167    (set_attr "mode" "<MODE>")])
16168
16169 (define_insn "pro_epilogue_adjust_stack_di_2"
16170   [(set (match_operand:DI 0 "register_operand" "=r,r")
16171         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16172                  (match_operand:DI 3 "immediate_operand" "i,i")))
16173    (use (match_operand:DI 2 "register_operand" "r,l"))
16174    (clobber (reg:CC FLAGS_REG))
16175    (clobber (mem:BLK (scratch)))]
16176   "TARGET_64BIT"
16177 {
16178   switch (get_attr_type (insn))
16179     {
16180     case TYPE_ALU:
16181       return "add{q}\t{%2, %0|%0, %2}";
16182
16183     case TYPE_LEA:
16184       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16185       return "lea{q}\t{%a2, %0|%0, %a2}";
16186
16187     default:
16188       gcc_unreachable ();
16189     }
16190 }
16191   [(set_attr "type" "alu,lea")
16192    (set_attr "mode" "DI")])
16193
16194 (define_insn "allocate_stack_worker_32"
16195   [(set (match_operand:SI 0 "register_operand" "=a")
16196         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16197                             UNSPECV_STACK_PROBE))
16198    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16199    (clobber (reg:CC FLAGS_REG))]
16200   "!TARGET_64BIT && ix86_target_stack_probe ()"
16201   "call\t___chkstk"
16202   [(set_attr "type" "multi")
16203    (set_attr "length" "5")])
16204
16205 (define_insn "allocate_stack_worker_64"
16206   [(set (match_operand:DI 0 "register_operand" "=a")
16207         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16208                             UNSPECV_STACK_PROBE))
16209    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16210    (clobber (reg:DI R10_REG))
16211    (clobber (reg:DI R11_REG))
16212    (clobber (reg:CC FLAGS_REG))]
16213   "TARGET_64BIT && ix86_target_stack_probe ()"
16214   "call\t___chkstk"
16215   [(set_attr "type" "multi")
16216    (set_attr "length" "5")])
16217
16218 (define_expand "allocate_stack"
16219   [(match_operand 0 "register_operand" "")
16220    (match_operand 1 "general_operand" "")]
16221   "ix86_target_stack_probe ()"
16222 {
16223   rtx x;
16224
16225 #ifndef CHECK_STACK_LIMIT
16226 #define CHECK_STACK_LIMIT 0
16227 #endif
16228
16229   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16230       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16231     {
16232       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16233                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16234       if (x != stack_pointer_rtx)
16235         emit_move_insn (stack_pointer_rtx, x);
16236     }
16237   else
16238     {
16239       rtx (*gen_allocate_stack_worker) (rtx, rtx);
16240
16241       if (TARGET_64BIT)
16242         gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16243       else
16244         gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16245
16246       x = copy_to_mode_reg (Pmode, operands[1]);
16247       emit_insn (gen_allocate_stack_worker (x, x));
16248     }
16249
16250   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16251   DONE;
16252 })
16253
16254 ;; Use IOR for stack probes, this is shorter.
16255 (define_expand "probe_stack"
16256   [(match_operand 0 "memory_operand" "")]
16257   ""
16258 {
16259   rtx (*gen_ior3) (rtx, rtx, rtx);
16260
16261   gen_ior3 = (GET_MODE (operands[0]) == DImode
16262               ? gen_iordi3 : gen_iorsi3);
16263
16264   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16265   DONE;
16266 })
16267
16268 (define_insn "adjust_stack_and_probe<mode>"
16269   [(set (match_operand:P 0 "register_operand" "=r")
16270         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16271                             UNSPECV_PROBE_STACK_RANGE))
16272    (set (reg:P SP_REG)
16273         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16274    (clobber (reg:CC FLAGS_REG))
16275    (clobber (mem:BLK (scratch)))]
16276   ""
16277   "* return output_adjust_stack_and_probe (operands[0]);"
16278   [(set_attr "type" "multi")])
16279
16280 (define_insn "probe_stack_range<mode>"
16281   [(set (match_operand:P 0 "register_operand" "=r")
16282         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16283                             (match_operand:P 2 "const_int_operand" "n")]
16284                             UNSPECV_PROBE_STACK_RANGE))
16285    (clobber (reg:CC FLAGS_REG))]
16286   ""
16287   "* return output_probe_stack_range (operands[0], operands[2]);"
16288   [(set_attr "type" "multi")])
16289
16290 (define_expand "builtin_setjmp_receiver"
16291   [(label_ref (match_operand 0 "" ""))]
16292   "!TARGET_64BIT && flag_pic"
16293 {
16294 #if TARGET_MACHO
16295   if (TARGET_MACHO)
16296     {
16297       rtx xops[3];
16298       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16299       rtx label_rtx = gen_label_rtx ();
16300       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16301       xops[0] = xops[1] = picreg;
16302       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16303       ix86_expand_binary_operator (MINUS, SImode, xops);
16304     }
16305   else
16306 #endif
16307     emit_insn (gen_set_got (pic_offset_table_rtx));
16308   DONE;
16309 })
16310 \f
16311 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16312
16313 (define_split
16314   [(set (match_operand 0 "register_operand" "")
16315         (match_operator 3 "promotable_binary_operator"
16316            [(match_operand 1 "register_operand" "")
16317             (match_operand 2 "aligned_operand" "")]))
16318    (clobber (reg:CC FLAGS_REG))]
16319   "! TARGET_PARTIAL_REG_STALL && reload_completed
16320    && ((GET_MODE (operands[0]) == HImode
16321         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16322             /* ??? next two lines just !satisfies_constraint_K (...) */
16323             || !CONST_INT_P (operands[2])
16324             || satisfies_constraint_K (operands[2])))
16325        || (GET_MODE (operands[0]) == QImode
16326            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16327   [(parallel [(set (match_dup 0)
16328                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16329               (clobber (reg:CC FLAGS_REG))])]
16330   "operands[0] = gen_lowpart (SImode, operands[0]);
16331    operands[1] = gen_lowpart (SImode, operands[1]);
16332    if (GET_CODE (operands[3]) != ASHIFT)
16333      operands[2] = gen_lowpart (SImode, operands[2]);
16334    PUT_MODE (operands[3], SImode);")
16335
16336 ; Promote the QImode tests, as i386 has encoding of the AND
16337 ; instruction with 32-bit sign-extended immediate and thus the
16338 ; instruction size is unchanged, except in the %eax case for
16339 ; which it is increased by one byte, hence the ! optimize_size.
16340 (define_split
16341   [(set (match_operand 0 "flags_reg_operand" "")
16342         (match_operator 2 "compare_operator"
16343           [(and (match_operand 3 "aligned_operand" "")
16344                 (match_operand 4 "const_int_operand" ""))
16345            (const_int 0)]))
16346    (set (match_operand 1 "register_operand" "")
16347         (and (match_dup 3) (match_dup 4)))]
16348   "! TARGET_PARTIAL_REG_STALL && reload_completed
16349    && optimize_insn_for_speed_p ()
16350    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16351        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16352    /* Ensure that the operand will remain sign-extended immediate.  */
16353    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16354   [(parallel [(set (match_dup 0)
16355                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16356                                     (const_int 0)]))
16357               (set (match_dup 1)
16358                    (and:SI (match_dup 3) (match_dup 4)))])]
16359 {
16360   operands[4]
16361     = gen_int_mode (INTVAL (operands[4])
16362                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16363   operands[1] = gen_lowpart (SImode, operands[1]);
16364   operands[3] = gen_lowpart (SImode, operands[3]);
16365 })
16366
16367 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16368 ; the TEST instruction with 32-bit sign-extended immediate and thus
16369 ; the instruction size would at least double, which is not what we
16370 ; want even with ! optimize_size.
16371 (define_split
16372   [(set (match_operand 0 "flags_reg_operand" "")
16373         (match_operator 1 "compare_operator"
16374           [(and (match_operand:HI 2 "aligned_operand" "")
16375                 (match_operand:HI 3 "const_int_operand" ""))
16376            (const_int 0)]))]
16377   "! TARGET_PARTIAL_REG_STALL && reload_completed
16378    && ! TARGET_FAST_PREFIX
16379    && optimize_insn_for_speed_p ()
16380    /* Ensure that the operand will remain sign-extended immediate.  */
16381    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16382   [(set (match_dup 0)
16383         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16384                          (const_int 0)]))]
16385 {
16386   operands[3]
16387     = gen_int_mode (INTVAL (operands[3])
16388                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16389   operands[2] = gen_lowpart (SImode, operands[2]);
16390 })
16391
16392 (define_split
16393   [(set (match_operand 0 "register_operand" "")
16394         (neg (match_operand 1 "register_operand" "")))
16395    (clobber (reg:CC FLAGS_REG))]
16396   "! TARGET_PARTIAL_REG_STALL && reload_completed
16397    && (GET_MODE (operands[0]) == HImode
16398        || (GET_MODE (operands[0]) == QImode
16399            && (TARGET_PROMOTE_QImode
16400                || optimize_insn_for_size_p ())))"
16401   [(parallel [(set (match_dup 0)
16402                    (neg:SI (match_dup 1)))
16403               (clobber (reg:CC FLAGS_REG))])]
16404   "operands[0] = gen_lowpart (SImode, operands[0]);
16405    operands[1] = gen_lowpart (SImode, operands[1]);")
16406
16407 (define_split
16408   [(set (match_operand 0 "register_operand" "")
16409         (not (match_operand 1 "register_operand" "")))]
16410   "! TARGET_PARTIAL_REG_STALL && reload_completed
16411    && (GET_MODE (operands[0]) == HImode
16412        || (GET_MODE (operands[0]) == QImode
16413            && (TARGET_PROMOTE_QImode
16414                || optimize_insn_for_size_p ())))"
16415   [(set (match_dup 0)
16416         (not:SI (match_dup 1)))]
16417   "operands[0] = gen_lowpart (SImode, operands[0]);
16418    operands[1] = gen_lowpart (SImode, operands[1]);")
16419
16420 (define_split
16421   [(set (match_operand 0 "register_operand" "")
16422         (if_then_else (match_operator 1 "ordered_comparison_operator"
16423                                 [(reg FLAGS_REG) (const_int 0)])
16424                       (match_operand 2 "register_operand" "")
16425                       (match_operand 3 "register_operand" "")))]
16426   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16427    && (GET_MODE (operands[0]) == HImode
16428        || (GET_MODE (operands[0]) == QImode
16429            && (TARGET_PROMOTE_QImode
16430                || optimize_insn_for_size_p ())))"
16431   [(set (match_dup 0)
16432         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16433   "operands[0] = gen_lowpart (SImode, operands[0]);
16434    operands[2] = gen_lowpart (SImode, operands[2]);
16435    operands[3] = gen_lowpart (SImode, operands[3]);")
16436 \f
16437 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16438 ;; transform a complex memory operation into two memory to register operations.
16439
16440 ;; Don't push memory operands
16441 (define_peephole2
16442   [(set (match_operand:SWI 0 "push_operand" "")
16443         (match_operand:SWI 1 "memory_operand" ""))
16444    (match_scratch:SWI 2 "<r>")]
16445   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16446    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16447   [(set (match_dup 2) (match_dup 1))
16448    (set (match_dup 0) (match_dup 2))])
16449
16450 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16451 ;; SImode pushes.
16452 (define_peephole2
16453   [(set (match_operand:SF 0 "push_operand" "")
16454         (match_operand:SF 1 "memory_operand" ""))
16455    (match_scratch:SF 2 "r")]
16456   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16457    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16458   [(set (match_dup 2) (match_dup 1))
16459    (set (match_dup 0) (match_dup 2))])
16460
16461 ;; Don't move an immediate directly to memory when the instruction
16462 ;; gets too big.
16463 (define_peephole2
16464   [(match_scratch:SWI124 1 "<r>")
16465    (set (match_operand:SWI124 0 "memory_operand" "")
16466         (const_int 0))]
16467   "optimize_insn_for_speed_p ()
16468    && !TARGET_USE_MOV0
16469    && TARGET_SPLIT_LONG_MOVES
16470    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16471    && peep2_regno_dead_p (0, FLAGS_REG)"
16472   [(parallel [(set (match_dup 2) (const_int 0))
16473               (clobber (reg:CC FLAGS_REG))])
16474    (set (match_dup 0) (match_dup 1))]
16475   "operands[2] = gen_lowpart (SImode, operands[1]);")
16476
16477 (define_peephole2
16478   [(match_scratch:SWI124 2 "<r>")
16479    (set (match_operand:SWI124 0 "memory_operand" "")
16480         (match_operand:SWI124 1 "immediate_operand" ""))]
16481   "optimize_insn_for_speed_p ()
16482    && TARGET_SPLIT_LONG_MOVES
16483    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16484   [(set (match_dup 2) (match_dup 1))
16485    (set (match_dup 0) (match_dup 2))])
16486
16487 ;; Don't compare memory with zero, load and use a test instead.
16488 (define_peephole2
16489   [(set (match_operand 0 "flags_reg_operand" "")
16490         (match_operator 1 "compare_operator"
16491           [(match_operand:SI 2 "memory_operand" "")
16492            (const_int 0)]))
16493    (match_scratch:SI 3 "r")]
16494   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16495   [(set (match_dup 3) (match_dup 2))
16496    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16497
16498 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16499 ;; Don't split NOTs with a displacement operand, because resulting XOR
16500 ;; will not be pairable anyway.
16501 ;;
16502 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16503 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16504 ;; so this split helps here as well.
16505 ;;
16506 ;; Note: Can't do this as a regular split because we can't get proper
16507 ;; lifetime information then.
16508
16509 (define_peephole2
16510   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16511         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16512   "optimize_insn_for_speed_p ()
16513    && ((TARGET_NOT_UNPAIRABLE
16514         && (!MEM_P (operands[0])
16515             || !memory_displacement_operand (operands[0], <MODE>mode)))
16516        || (TARGET_NOT_VECTORMODE
16517            && long_memory_operand (operands[0], <MODE>mode)))
16518    && peep2_regno_dead_p (0, FLAGS_REG)"
16519   [(parallel [(set (match_dup 0)
16520                    (xor:SWI124 (match_dup 1) (const_int -1)))
16521               (clobber (reg:CC FLAGS_REG))])])
16522
16523 ;; Non pairable "test imm, reg" instructions can be translated to
16524 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16525 ;; byte opcode instead of two, have a short form for byte operands),
16526 ;; so do it for other CPUs as well.  Given that the value was dead,
16527 ;; this should not create any new dependencies.  Pass on the sub-word
16528 ;; versions if we're concerned about partial register stalls.
16529
16530 (define_peephole2
16531   [(set (match_operand 0 "flags_reg_operand" "")
16532         (match_operator 1 "compare_operator"
16533           [(and:SI (match_operand:SI 2 "register_operand" "")
16534                    (match_operand:SI 3 "immediate_operand" ""))
16535            (const_int 0)]))]
16536   "ix86_match_ccmode (insn, CCNOmode)
16537    && (true_regnum (operands[2]) != AX_REG
16538        || satisfies_constraint_K (operands[3]))
16539    && peep2_reg_dead_p (1, operands[2])"
16540   [(parallel
16541      [(set (match_dup 0)
16542            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16543                             (const_int 0)]))
16544       (set (match_dup 2)
16545            (and:SI (match_dup 2) (match_dup 3)))])])
16546
16547 ;; We don't need to handle HImode case, because it will be promoted to SImode
16548 ;; on ! TARGET_PARTIAL_REG_STALL
16549
16550 (define_peephole2
16551   [(set (match_operand 0 "flags_reg_operand" "")
16552         (match_operator 1 "compare_operator"
16553           [(and:QI (match_operand:QI 2 "register_operand" "")
16554                    (match_operand:QI 3 "immediate_operand" ""))
16555            (const_int 0)]))]
16556   "! TARGET_PARTIAL_REG_STALL
16557    && ix86_match_ccmode (insn, CCNOmode)
16558    && true_regnum (operands[2]) != AX_REG
16559    && peep2_reg_dead_p (1, operands[2])"
16560   [(parallel
16561      [(set (match_dup 0)
16562            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16563                             (const_int 0)]))
16564       (set (match_dup 2)
16565            (and:QI (match_dup 2) (match_dup 3)))])])
16566
16567 (define_peephole2
16568   [(set (match_operand 0 "flags_reg_operand" "")
16569         (match_operator 1 "compare_operator"
16570           [(and:SI
16571              (zero_extract:SI
16572                (match_operand 2 "ext_register_operand" "")
16573                (const_int 8)
16574                (const_int 8))
16575              (match_operand 3 "const_int_operand" ""))
16576            (const_int 0)]))]
16577   "! TARGET_PARTIAL_REG_STALL
16578    && ix86_match_ccmode (insn, CCNOmode)
16579    && true_regnum (operands[2]) != AX_REG
16580    && peep2_reg_dead_p (1, operands[2])"
16581   [(parallel [(set (match_dup 0)
16582                    (match_op_dup 1
16583                      [(and:SI
16584                         (zero_extract:SI
16585                           (match_dup 2)
16586                           (const_int 8)
16587                           (const_int 8))
16588                         (match_dup 3))
16589                       (const_int 0)]))
16590               (set (zero_extract:SI (match_dup 2)
16591                                     (const_int 8)
16592                                     (const_int 8))
16593                    (and:SI
16594                      (zero_extract:SI
16595                        (match_dup 2)
16596                        (const_int 8)
16597                        (const_int 8))
16598                      (match_dup 3)))])])
16599
16600 ;; Don't do logical operations with memory inputs.
16601 (define_peephole2
16602   [(match_scratch:SI 2 "r")
16603    (parallel [(set (match_operand:SI 0 "register_operand" "")
16604                    (match_operator:SI 3 "arith_or_logical_operator"
16605                      [(match_dup 0)
16606                       (match_operand:SI 1 "memory_operand" "")]))
16607               (clobber (reg:CC FLAGS_REG))])]
16608   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16609   [(set (match_dup 2) (match_dup 1))
16610    (parallel [(set (match_dup 0)
16611                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16612               (clobber (reg:CC FLAGS_REG))])])
16613
16614 (define_peephole2
16615   [(match_scratch:SI 2 "r")
16616    (parallel [(set (match_operand:SI 0 "register_operand" "")
16617                    (match_operator:SI 3 "arith_or_logical_operator"
16618                      [(match_operand:SI 1 "memory_operand" "")
16619                       (match_dup 0)]))
16620               (clobber (reg:CC FLAGS_REG))])]
16621   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16622   [(set (match_dup 2) (match_dup 1))
16623    (parallel [(set (match_dup 0)
16624                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16625               (clobber (reg:CC FLAGS_REG))])])
16626
16627 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16628 ;; refers to the destination of the load!
16629
16630 (define_peephole2
16631   [(set (match_operand:SI 0 "register_operand" "")
16632         (match_operand:SI 1 "register_operand" ""))
16633    (parallel [(set (match_dup 0)
16634                    (match_operator:SI 3 "commutative_operator"
16635                      [(match_dup 0)
16636                       (match_operand:SI 2 "memory_operand" "")]))
16637               (clobber (reg:CC FLAGS_REG))])]
16638   "REGNO (operands[0]) != REGNO (operands[1])
16639    && GENERAL_REGNO_P (REGNO (operands[0]))
16640    && GENERAL_REGNO_P (REGNO (operands[1]))"
16641   [(set (match_dup 0) (match_dup 4))
16642    (parallel [(set (match_dup 0)
16643                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16644               (clobber (reg:CC FLAGS_REG))])]
16645   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16646
16647 (define_peephole2
16648   [(set (match_operand 0 "register_operand" "")
16649         (match_operand 1 "register_operand" ""))
16650    (set (match_dup 0)
16651                    (match_operator 3 "commutative_operator"
16652                      [(match_dup 0)
16653                       (match_operand 2 "memory_operand" "")]))]
16654   "REGNO (operands[0]) != REGNO (operands[1])
16655    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16656        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16657   [(set (match_dup 0) (match_dup 2))
16658    (set (match_dup 0)
16659         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16660
16661 ; Don't do logical operations with memory outputs
16662 ;
16663 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16664 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16665 ; the same decoder scheduling characteristics as the original.
16666
16667 (define_peephole2
16668   [(match_scratch:SI 2 "r")
16669    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16670                    (match_operator:SI 3 "arith_or_logical_operator"
16671                      [(match_dup 0)
16672                       (match_operand:SI 1 "nonmemory_operand" "")]))
16673               (clobber (reg:CC FLAGS_REG))])]
16674   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16675    /* Do not split stack checking probes.  */
16676    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16677   [(set (match_dup 2) (match_dup 0))
16678    (parallel [(set (match_dup 2)
16679                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16680               (clobber (reg:CC FLAGS_REG))])
16681    (set (match_dup 0) (match_dup 2))])
16682
16683 (define_peephole2
16684   [(match_scratch:SI 2 "r")
16685    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16686                    (match_operator:SI 3 "arith_or_logical_operator"
16687                      [(match_operand:SI 1 "nonmemory_operand" "")
16688                       (match_dup 0)]))
16689               (clobber (reg:CC FLAGS_REG))])]
16690   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16691    /* Do not split stack checking probes.  */
16692    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16693   [(set (match_dup 2) (match_dup 0))
16694    (parallel [(set (match_dup 2)
16695                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16696               (clobber (reg:CC FLAGS_REG))])
16697    (set (match_dup 0) (match_dup 2))])
16698
16699 ;; Attempt to always use XOR for zeroing registers.
16700 (define_peephole2
16701   [(set (match_operand 0 "register_operand" "")
16702         (match_operand 1 "const0_operand" ""))]
16703   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16704    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16705    && GENERAL_REG_P (operands[0])
16706    && peep2_regno_dead_p (0, FLAGS_REG)"
16707   [(parallel [(set (match_dup 0) (const_int 0))
16708               (clobber (reg:CC FLAGS_REG))])]
16709   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16710
16711 (define_peephole2
16712   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16713         (const_int 0))]
16714   "(GET_MODE (operands[0]) == QImode
16715     || GET_MODE (operands[0]) == HImode)
16716    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16717    && peep2_regno_dead_p (0, FLAGS_REG)"
16718   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16719               (clobber (reg:CC FLAGS_REG))])])
16720
16721 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16722 (define_peephole2
16723   [(set (match_operand:SWI248 0 "register_operand" "")
16724         (const_int -1))]
16725   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16726    && peep2_regno_dead_p (0, FLAGS_REG)"
16727   [(parallel [(set (match_dup 0) (const_int -1))
16728               (clobber (reg:CC FLAGS_REG))])]
16729 {
16730   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16731     operands[0] = gen_lowpart (SImode, operands[0]);
16732 })
16733
16734 ;; Attempt to convert simple lea to add/shift.
16735 ;; These can be created by move expanders.
16736
16737 (define_peephole2
16738   [(set (match_operand:SWI48 0 "register_operand" "")
16739         (plus:SWI48 (match_dup 0)
16740                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16741   "peep2_regno_dead_p (0, FLAGS_REG)"
16742   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16743               (clobber (reg:CC FLAGS_REG))])])
16744
16745 (define_peephole2
16746   [(set (match_operand:SI 0 "register_operand" "")
16747         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16748                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16749   "TARGET_64BIT
16750    && peep2_regno_dead_p (0, FLAGS_REG)
16751    && REGNO (operands[0]) == REGNO (operands[1])"
16752   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16753               (clobber (reg:CC FLAGS_REG))])]
16754   "operands[2] = gen_lowpart (SImode, operands[2]);")
16755
16756 (define_peephole2
16757   [(set (match_operand:SWI48 0 "register_operand" "")
16758         (mult:SWI48 (match_dup 0)
16759                     (match_operand:SWI48 1 "const_int_operand" "")))]
16760   "exact_log2 (INTVAL (operands[1])) >= 0
16761    && peep2_regno_dead_p (0, FLAGS_REG)"
16762   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16763               (clobber (reg:CC FLAGS_REG))])]
16764   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16765
16766 (define_peephole2
16767   [(set (match_operand:SI 0 "register_operand" "")
16768         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16769                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16770   "TARGET_64BIT
16771    && exact_log2 (INTVAL (operands[2])) >= 0
16772    && REGNO (operands[0]) == REGNO (operands[1])
16773    && peep2_regno_dead_p (0, FLAGS_REG)"
16774   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16775               (clobber (reg:CC FLAGS_REG))])]
16776   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16777
16778 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16779 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16780 ;; On many CPUs it is also faster, since special hardware to avoid esp
16781 ;; dependencies is present.
16782
16783 ;; While some of these conversions may be done using splitters, we use
16784 ;; peepholes in order to allow combine_stack_adjustments pass to see
16785 ;; nonobfuscated RTL.
16786
16787 ;; Convert prologue esp subtractions to push.
16788 ;; We need register to push.  In order to keep verify_flow_info happy we have
16789 ;; two choices
16790 ;; - use scratch and clobber it in order to avoid dependencies
16791 ;; - use already live register
16792 ;; We can't use the second way right now, since there is no reliable way how to
16793 ;; verify that given register is live.  First choice will also most likely in
16794 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16795 ;; call clobbered registers are dead.  We may want to use base pointer as an
16796 ;; alternative when no register is available later.
16797
16798 (define_peephole2
16799   [(match_scratch:P 1 "r")
16800    (parallel [(set (reg:P SP_REG)
16801                    (plus:P (reg:P SP_REG)
16802                            (match_operand:P 0 "const_int_operand" "")))
16803               (clobber (reg:CC FLAGS_REG))
16804               (clobber (mem:BLK (scratch)))])]
16805   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16806    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16807   [(clobber (match_dup 1))
16808    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16809               (clobber (mem:BLK (scratch)))])])
16810
16811 (define_peephole2
16812   [(match_scratch:P 1 "r")
16813    (parallel [(set (reg:P SP_REG)
16814                    (plus:P (reg:P SP_REG)
16815                            (match_operand:P 0 "const_int_operand" "")))
16816               (clobber (reg:CC FLAGS_REG))
16817               (clobber (mem:BLK (scratch)))])]
16818   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16819    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16820   [(clobber (match_dup 1))
16821    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16822    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16823               (clobber (mem:BLK (scratch)))])])
16824
16825 ;; Convert esp subtractions to push.
16826 (define_peephole2
16827   [(match_scratch:P 1 "r")
16828    (parallel [(set (reg:P SP_REG)
16829                    (plus:P (reg:P SP_REG)
16830                            (match_operand:P 0 "const_int_operand" "")))
16831               (clobber (reg:CC FLAGS_REG))])]
16832   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16833    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16834   [(clobber (match_dup 1))
16835    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16836
16837 (define_peephole2
16838   [(match_scratch:P 1 "r")
16839    (parallel [(set (reg:P SP_REG)
16840                    (plus:P (reg:P SP_REG)
16841                            (match_operand:P 0 "const_int_operand" "")))
16842               (clobber (reg:CC FLAGS_REG))])]
16843   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16844    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16845   [(clobber (match_dup 1))
16846    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16847    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16848
16849 ;; Convert epilogue deallocator to pop.
16850 (define_peephole2
16851   [(match_scratch:P 1 "r")
16852    (parallel [(set (reg:P SP_REG)
16853                    (plus:P (reg:P SP_REG)
16854                            (match_operand:P 0 "const_int_operand" "")))
16855               (clobber (reg:CC FLAGS_REG))
16856               (clobber (mem:BLK (scratch)))])]
16857   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16858    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16859   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16860               (clobber (mem:BLK (scratch)))])])
16861
16862 ;; Two pops case is tricky, since pop causes dependency
16863 ;; on destination register.  We use two registers if available.
16864 (define_peephole2
16865   [(match_scratch:P 1 "r")
16866    (match_scratch:P 2 "r")
16867    (parallel [(set (reg:P SP_REG)
16868                    (plus:P (reg:P SP_REG)
16869                            (match_operand:P 0 "const_int_operand" "")))
16870               (clobber (reg:CC FLAGS_REG))
16871               (clobber (mem:BLK (scratch)))])]
16872   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16873    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16874   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16875               (clobber (mem:BLK (scratch)))])
16876    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16877
16878 (define_peephole2
16879   [(match_scratch:P 1 "r")
16880    (parallel [(set (reg:P SP_REG)
16881                    (plus:P (reg:P SP_REG)
16882                            (match_operand:P 0 "const_int_operand" "")))
16883               (clobber (reg:CC FLAGS_REG))
16884               (clobber (mem:BLK (scratch)))])]
16885   "optimize_insn_for_size_p ()
16886    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16887   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16888               (clobber (mem:BLK (scratch)))])
16889    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16890
16891 ;; Convert esp additions to pop.
16892 (define_peephole2
16893   [(match_scratch:P 1 "r")
16894    (parallel [(set (reg:P SP_REG)
16895                    (plus:P (reg:P SP_REG)
16896                            (match_operand:P 0 "const_int_operand" "")))
16897               (clobber (reg:CC FLAGS_REG))])]
16898   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16899   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16900
16901 ;; Two pops case is tricky, since pop causes dependency
16902 ;; on destination register.  We use two registers if available.
16903 (define_peephole2
16904   [(match_scratch:P 1 "r")
16905    (match_scratch:P 2 "r")
16906    (parallel [(set (reg:P SP_REG)
16907                    (plus:P (reg:P SP_REG)
16908                            (match_operand:P 0 "const_int_operand" "")))
16909               (clobber (reg:CC FLAGS_REG))])]
16910   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16911   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16912    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16913
16914 (define_peephole2
16915   [(match_scratch:P 1 "r")
16916    (parallel [(set (reg:P SP_REG)
16917                    (plus:P (reg:P SP_REG)
16918                            (match_operand:P 0 "const_int_operand" "")))
16919               (clobber (reg:CC FLAGS_REG))])]
16920   "optimize_insn_for_size_p ()
16921    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16922   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16923    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16924 \f
16925 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16926 ;; required and register dies.  Similarly for 128 to -128.
16927 (define_peephole2
16928   [(set (match_operand 0 "flags_reg_operand" "")
16929         (match_operator 1 "compare_operator"
16930           [(match_operand 2 "register_operand" "")
16931            (match_operand 3 "const_int_operand" "")]))]
16932   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16933      && incdec_operand (operands[3], GET_MODE (operands[3])))
16934     || (!TARGET_FUSE_CMP_AND_BRANCH
16935         && INTVAL (operands[3]) == 128))
16936    && ix86_match_ccmode (insn, CCGCmode)
16937    && peep2_reg_dead_p (1, operands[2])"
16938   [(parallel [(set (match_dup 0)
16939                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16940               (clobber (match_dup 2))])])
16941 \f
16942 ;; Convert imul by three, five and nine into lea
16943 (define_peephole2
16944   [(parallel
16945     [(set (match_operand:SWI48 0 "register_operand" "")
16946           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
16947                       (match_operand:SWI48 2 "const_int_operand" "")))
16948      (clobber (reg:CC FLAGS_REG))])]
16949   "INTVAL (operands[2]) == 3
16950    || INTVAL (operands[2]) == 5
16951    || INTVAL (operands[2]) == 9"
16952   [(set (match_dup 0)
16953         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16954                     (match_dup 1)))]
16955   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16956
16957 (define_peephole2
16958   [(parallel
16959     [(set (match_operand:SWI48 0 "register_operand" "")
16960           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
16961                       (match_operand:SWI48 2 "const_int_operand" "")))
16962      (clobber (reg:CC FLAGS_REG))])]
16963   "optimize_insn_for_speed_p ()
16964    && (INTVAL (operands[2]) == 3
16965        || INTVAL (operands[2]) == 5
16966        || INTVAL (operands[2]) == 9)"
16967   [(set (match_dup 0) (match_dup 1))
16968    (set (match_dup 0)
16969         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
16970                     (match_dup 0)))]
16971   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16972
16973 ;; imul $32bit_imm, mem, reg is vector decoded, while
16974 ;; imul $32bit_imm, reg, reg is direct decoded.
16975 (define_peephole2
16976   [(match_scratch:SWI48 3 "r")
16977    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
16978                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
16979                                (match_operand:SWI48 2 "immediate_operand" "")))
16980               (clobber (reg:CC FLAGS_REG))])]
16981   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16982    && !satisfies_constraint_K (operands[2])"
16983   [(set (match_dup 3) (match_dup 1))
16984    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
16985               (clobber (reg:CC FLAGS_REG))])])
16986
16987 (define_peephole2
16988   [(match_scratch:SI 3 "r")
16989    (parallel [(set (match_operand:DI 0 "register_operand" "")
16990                    (zero_extend:DI
16991                      (mult:SI (match_operand:SI 1 "memory_operand" "")
16992                               (match_operand:SI 2 "immediate_operand" ""))))
16993               (clobber (reg:CC FLAGS_REG))])]
16994   "TARGET_64BIT
16995    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16996    && !satisfies_constraint_K (operands[2])"
16997   [(set (match_dup 3) (match_dup 1))
16998    (parallel [(set (match_dup 0)
16999                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17000               (clobber (reg:CC FLAGS_REG))])])
17001
17002 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17003 ;; Convert it into imul reg, reg
17004 ;; It would be better to force assembler to encode instruction using long
17005 ;; immediate, but there is apparently no way to do so.
17006 (define_peephole2
17007   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17008                    (mult:SWI248
17009                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17010                     (match_operand:SWI248 2 "const_int_operand" "")))
17011               (clobber (reg:CC FLAGS_REG))])
17012    (match_scratch:SWI248 3 "r")]
17013   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17014    && satisfies_constraint_K (operands[2])"
17015   [(set (match_dup 3) (match_dup 2))
17016    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17017               (clobber (reg:CC FLAGS_REG))])]
17018 {
17019   if (!rtx_equal_p (operands[0], operands[1]))
17020     emit_move_insn (operands[0], operands[1]);
17021 })
17022
17023 ;; After splitting up read-modify operations, array accesses with memory
17024 ;; operands might end up in form:
17025 ;;  sall    $2, %eax
17026 ;;  movl    4(%esp), %edx
17027 ;;  addl    %edx, %eax
17028 ;; instead of pre-splitting:
17029 ;;  sall    $2, %eax
17030 ;;  addl    4(%esp), %eax
17031 ;; Turn it into:
17032 ;;  movl    4(%esp), %edx
17033 ;;  leal    (%edx,%eax,4), %eax
17034
17035 (define_peephole2
17036   [(match_scratch:P 5 "r")
17037    (parallel [(set (match_operand 0 "register_operand" "")
17038                    (ashift (match_operand 1 "register_operand" "")
17039                            (match_operand 2 "const_int_operand" "")))
17040                (clobber (reg:CC FLAGS_REG))])
17041    (parallel [(set (match_operand 3 "register_operand" "")
17042                    (plus (match_dup 0)
17043                          (match_operand 4 "x86_64_general_operand" "")))
17044                    (clobber (reg:CC FLAGS_REG))])]
17045   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17046    /* Validate MODE for lea.  */
17047    && ((!TARGET_PARTIAL_REG_STALL
17048         && (GET_MODE (operands[0]) == QImode
17049             || GET_MODE (operands[0]) == HImode))
17050        || GET_MODE (operands[0]) == SImode
17051        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17052    && (rtx_equal_p (operands[0], operands[3])
17053        || peep2_reg_dead_p (2, operands[0]))
17054    /* We reorder load and the shift.  */
17055    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17056   [(set (match_dup 5) (match_dup 4))
17057    (set (match_dup 0) (match_dup 1))]
17058 {
17059   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17060   int scale = 1 << INTVAL (operands[2]);
17061   rtx index = gen_lowpart (Pmode, operands[1]);
17062   rtx base = gen_lowpart (Pmode, operands[5]);
17063   rtx dest = gen_lowpart (mode, operands[3]);
17064
17065   operands[1] = gen_rtx_PLUS (Pmode, base,
17066                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17067   operands[5] = base;
17068   if (mode != Pmode)
17069     {
17070       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17071       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17072     }
17073   operands[0] = dest;
17074 })
17075 \f
17076 ;; Call-value patterns last so that the wildcard operand does not
17077 ;; disrupt insn-recog's switch tables.
17078
17079 (define_insn "*call_value_pop_0"
17080   [(set (match_operand 0 "" "")
17081         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17082               (match_operand:SI 2 "" "")))
17083    (set (reg:SI SP_REG)
17084         (plus:SI (reg:SI SP_REG)
17085                  (match_operand:SI 3 "immediate_operand" "")))]
17086   "!TARGET_64BIT"
17087 {
17088   if (SIBLING_CALL_P (insn))
17089     return "jmp\t%P1";
17090   else
17091     return "call\t%P1";
17092 }
17093   [(set_attr "type" "callv")])
17094
17095 (define_insn "*call_value_pop_1"
17096   [(set (match_operand 0 "" "")
17097         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17098               (match_operand:SI 2 "" "")))
17099    (set (reg:SI SP_REG)
17100         (plus:SI (reg:SI SP_REG)
17101                  (match_operand:SI 3 "immediate_operand" "i")))]
17102   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17103 {
17104   if (constant_call_address_operand (operands[1], Pmode))
17105     return "call\t%P1";
17106   return "call\t%A1";
17107 }
17108   [(set_attr "type" "callv")])
17109
17110 (define_insn "*sibcall_value_pop_1"
17111   [(set (match_operand 0 "" "")
17112         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17113               (match_operand:SI 2 "" "")))
17114    (set (reg:SI SP_REG)
17115         (plus:SI (reg:SI SP_REG)
17116                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17117   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17118   "@
17119    jmp\t%P1
17120    jmp\t%A1"
17121   [(set_attr "type" "callv")])
17122
17123 (define_insn "*call_value_0"
17124   [(set (match_operand 0 "" "")
17125         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17126               (match_operand:SI 2 "" "")))]
17127   "!TARGET_64BIT"
17128 {
17129   if (SIBLING_CALL_P (insn))
17130     return "jmp\t%P1";
17131   else
17132     return "call\t%P1";
17133 }
17134   [(set_attr "type" "callv")])
17135
17136 (define_insn "*call_value_0_rex64"
17137   [(set (match_operand 0 "" "")
17138         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17139               (match_operand:DI 2 "const_int_operand" "")))]
17140   "TARGET_64BIT"
17141 {
17142   if (SIBLING_CALL_P (insn))
17143     return "jmp\t%P1";
17144   else
17145     return "call\t%P1";
17146 }
17147   [(set_attr "type" "callv")])
17148
17149 (define_insn "*call_value_0_rex64_ms_sysv"
17150   [(set (match_operand 0 "" "")
17151         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17152               (match_operand:DI 2 "const_int_operand" "")))
17153    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17154    (clobber (reg:TI XMM6_REG))
17155    (clobber (reg:TI XMM7_REG))
17156    (clobber (reg:TI XMM8_REG))
17157    (clobber (reg:TI XMM9_REG))
17158    (clobber (reg:TI XMM10_REG))
17159    (clobber (reg:TI XMM11_REG))
17160    (clobber (reg:TI XMM12_REG))
17161    (clobber (reg:TI XMM13_REG))
17162    (clobber (reg:TI XMM14_REG))
17163    (clobber (reg:TI XMM15_REG))
17164    (clobber (reg:DI SI_REG))
17165    (clobber (reg:DI DI_REG))]
17166   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17167 {
17168   if (SIBLING_CALL_P (insn))
17169     return "jmp\t%P1";
17170   else
17171     return "call\t%P1";
17172 }
17173   [(set_attr "type" "callv")])
17174
17175 (define_insn "*call_value_1"
17176   [(set (match_operand 0 "" "")
17177         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17178               (match_operand:SI 2 "" "")))]
17179   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17180 {
17181   if (constant_call_address_operand (operands[1], Pmode))
17182     return "call\t%P1";
17183   return "call\t%A1";
17184 }
17185   [(set_attr "type" "callv")])
17186
17187 (define_insn "*sibcall_value_1"
17188   [(set (match_operand 0 "" "")
17189         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17190               (match_operand:SI 2 "" "")))]
17191   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17192   "@
17193    jmp\t%P1
17194    jmp\t%A1"
17195   [(set_attr "type" "callv")])
17196
17197 (define_insn "*call_value_1_rex64"
17198   [(set (match_operand 0 "" "")
17199         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17200               (match_operand:DI 2 "" "")))]
17201   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17202    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17203 {
17204   if (constant_call_address_operand (operands[1], Pmode))
17205     return "call\t%P1";
17206   return "call\t%A1";
17207 }
17208   [(set_attr "type" "callv")])
17209
17210 (define_insn "*call_value_1_rex64_ms_sysv"
17211   [(set (match_operand 0 "" "")
17212         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17213               (match_operand:DI 2 "" "")))
17214    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17215    (clobber (reg:TI XMM6_REG))
17216    (clobber (reg:TI XMM7_REG))
17217    (clobber (reg:TI XMM8_REG))
17218    (clobber (reg:TI XMM9_REG))
17219    (clobber (reg:TI XMM10_REG))
17220    (clobber (reg:TI XMM11_REG))
17221    (clobber (reg:TI XMM12_REG))
17222    (clobber (reg:TI XMM13_REG))
17223    (clobber (reg:TI XMM14_REG))
17224    (clobber (reg:TI XMM15_REG))
17225    (clobber (reg:DI SI_REG))
17226    (clobber (reg:DI DI_REG))]
17227   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17228 {
17229   if (constant_call_address_operand (operands[1], Pmode))
17230     return "call\t%P1";
17231   return "call\t%A1";
17232 }
17233   [(set_attr "type" "callv")])
17234
17235 (define_insn "*call_value_1_rex64_large"
17236   [(set (match_operand 0 "" "")
17237         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17238               (match_operand:DI 2 "" "")))]
17239   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17240   "call\t%A1"
17241   [(set_attr "type" "callv")])
17242
17243 (define_insn "*sibcall_value_1_rex64"
17244   [(set (match_operand 0 "" "")
17245         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17246               (match_operand:DI 2 "" "")))]
17247   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17248   "@
17249    jmp\t%P1
17250    jmp\t%A1"
17251   [(set_attr "type" "callv")])
17252 \f
17253 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17254 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17255 ;; caught for use by garbage collectors and the like.  Using an insn that
17256 ;; maps to SIGILL makes it more likely the program will rightfully die.
17257 ;; Keeping with tradition, "6" is in honor of #UD.
17258 (define_insn "trap"
17259   [(trap_if (const_int 1) (const_int 6))]
17260   ""
17261   { return ASM_SHORT "0x0b0f"; }
17262   [(set_attr "length" "2")])
17263
17264 (define_expand "prefetch"
17265   [(prefetch (match_operand 0 "address_operand" "")
17266              (match_operand:SI 1 "const_int_operand" "")
17267              (match_operand:SI 2 "const_int_operand" ""))]
17268   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17269 {
17270   int rw = INTVAL (operands[1]);
17271   int locality = INTVAL (operands[2]);
17272
17273   gcc_assert (rw == 0 || rw == 1);
17274   gcc_assert (locality >= 0 && locality <= 3);
17275   gcc_assert (GET_MODE (operands[0]) == Pmode
17276               || GET_MODE (operands[0]) == VOIDmode);
17277
17278   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17279      supported by SSE counterpart or the SSE prefetch is not available
17280      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17281      of locality.  */
17282   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17283     operands[2] = GEN_INT (3);
17284   else
17285     operands[1] = const0_rtx;
17286 })
17287
17288 (define_insn "*prefetch_sse_<mode>"
17289   [(prefetch (match_operand:P 0 "address_operand" "p")
17290              (const_int 0)
17291              (match_operand:SI 1 "const_int_operand" ""))]
17292   "TARGET_PREFETCH_SSE"
17293 {
17294   static const char * const patterns[4] = {
17295    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17296   };
17297
17298   int locality = INTVAL (operands[1]);
17299   gcc_assert (locality >= 0 && locality <= 3);
17300
17301   return patterns[locality];
17302 }
17303   [(set_attr "type" "sse")
17304    (set_attr "atom_sse_attr" "prefetch")
17305    (set (attr "length_address")
17306         (symbol_ref "memory_address_length (operands[0])"))
17307    (set_attr "memory" "none")])
17308
17309 (define_insn "*prefetch_3dnow_<mode>"
17310   [(prefetch (match_operand:P 0 "address_operand" "p")
17311              (match_operand:SI 1 "const_int_operand" "n")
17312              (const_int 3))]
17313   "TARGET_3DNOW"
17314 {
17315   if (INTVAL (operands[1]) == 0)
17316     return "prefetch\t%a0";
17317   else
17318     return "prefetchw\t%a0";
17319 }
17320   [(set_attr "type" "mmx")
17321    (set (attr "length_address")
17322         (symbol_ref "memory_address_length (operands[0])"))
17323    (set_attr "memory" "none")])
17324
17325 (define_expand "stack_protect_set"
17326   [(match_operand 0 "memory_operand" "")
17327    (match_operand 1 "memory_operand" "")]
17328   ""
17329 {
17330   rtx (*insn)(rtx, rtx);
17331
17332 #ifdef TARGET_THREAD_SSP_OFFSET
17333   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17334   insn = (TARGET_64BIT
17335           ? gen_stack_tls_protect_set_di
17336           : gen_stack_tls_protect_set_si);
17337 #else
17338   insn = (TARGET_64BIT
17339           ? gen_stack_protect_set_di
17340           : gen_stack_protect_set_si);
17341 #endif
17342
17343   emit_insn (insn (operands[0], operands[1]));
17344   DONE;
17345 })
17346
17347 (define_insn "stack_protect_set_<mode>"
17348   [(set (match_operand:P 0 "memory_operand" "=m")
17349         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17350    (set (match_scratch:P 2 "=&r") (const_int 0))
17351    (clobber (reg:CC FLAGS_REG))]
17352   ""
17353   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17354   [(set_attr "type" "multi")])
17355
17356 (define_insn "stack_tls_protect_set_<mode>"
17357   [(set (match_operand:P 0 "memory_operand" "=m")
17358         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17359                   UNSPEC_SP_TLS_SET))
17360    (set (match_scratch:P 2 "=&r") (const_int 0))
17361    (clobber (reg:CC FLAGS_REG))]
17362   ""
17363   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17364   [(set_attr "type" "multi")])
17365
17366 (define_expand "stack_protect_test"
17367   [(match_operand 0 "memory_operand" "")
17368    (match_operand 1 "memory_operand" "")
17369    (match_operand 2 "" "")]
17370   ""
17371 {
17372   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17373
17374   rtx (*insn)(rtx, rtx, rtx);
17375
17376 #ifdef TARGET_THREAD_SSP_OFFSET
17377   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17378   insn = (TARGET_64BIT
17379           ? gen_stack_tls_protect_test_di
17380           : gen_stack_tls_protect_test_si);
17381 #else
17382   insn = (TARGET_64BIT
17383           ? gen_stack_protect_test_di
17384           : gen_stack_protect_test_si);
17385 #endif
17386
17387   emit_insn (insn (flags, operands[0], operands[1]));
17388
17389   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17390                                   flags, const0_rtx, operands[2]));
17391   DONE;
17392 })
17393
17394 (define_insn "stack_protect_test_<mode>"
17395   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17396         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17397                      (match_operand:P 2 "memory_operand" "m")]
17398                     UNSPEC_SP_TEST))
17399    (clobber (match_scratch:P 3 "=&r"))]
17400   ""
17401   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17402   [(set_attr "type" "multi")])
17403
17404 (define_insn "stack_tls_protect_test_<mode>"
17405   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17406         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17407                      (match_operand:P 2 "const_int_operand" "i")]
17408                     UNSPEC_SP_TLS_TEST))
17409    (clobber (match_scratch:P 3 "=r"))]
17410   ""
17411   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17412   [(set_attr "type" "multi")])
17413
17414 (define_insn "sse4_2_crc32<mode>"
17415   [(set (match_operand:SI 0 "register_operand" "=r")
17416         (unspec:SI
17417           [(match_operand:SI 1 "register_operand" "0")
17418            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17419           UNSPEC_CRC32))]
17420   "TARGET_SSE4_2 || TARGET_CRC32"
17421   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17422   [(set_attr "type" "sselog1")
17423    (set_attr "prefix_rep" "1")
17424    (set_attr "prefix_extra" "1")
17425    (set (attr "prefix_data16")
17426      (if_then_else (match_operand:HI 2 "" "")
17427        (const_string "1")
17428        (const_string "*")))
17429    (set (attr "prefix_rex")
17430      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17431        (const_string "1")
17432        (const_string "*")))
17433    (set_attr "mode" "SI")])
17434
17435 (define_insn "sse4_2_crc32di"
17436   [(set (match_operand:DI 0 "register_operand" "=r")
17437         (unspec:DI
17438           [(match_operand:DI 1 "register_operand" "0")
17439            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17440           UNSPEC_CRC32))]
17441   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17442   "crc32{q}\t{%2, %0|%0, %2}"
17443   [(set_attr "type" "sselog1")
17444    (set_attr "prefix_rep" "1")
17445    (set_attr "prefix_extra" "1")
17446    (set_attr "mode" "DI")])
17447
17448 (define_expand "rdpmc"
17449   [(match_operand:DI 0 "register_operand" "")
17450    (match_operand:SI 1 "register_operand" "")]
17451   ""
17452 {
17453   rtx reg = gen_reg_rtx (DImode);
17454   rtx si;
17455
17456   /* Force operand 1 into ECX.  */
17457   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17458   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17459   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17460                                 UNSPECV_RDPMC);
17461
17462   if (TARGET_64BIT)
17463     {
17464       rtvec vec = rtvec_alloc (2);
17465       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17466       rtx upper = gen_reg_rtx (DImode);
17467       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17468                                         gen_rtvec (1, const0_rtx),
17469                                         UNSPECV_RDPMC);
17470       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17471       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17472       emit_insn (load);
17473       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17474                                    NULL, 1, OPTAB_DIRECT);
17475       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17476                                  OPTAB_DIRECT);
17477     }
17478   else
17479     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17480   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17481   DONE;
17482 })
17483
17484 (define_insn "*rdpmc"
17485   [(set (match_operand:DI 0 "register_operand" "=A")
17486         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17487                             UNSPECV_RDPMC))]
17488   "!TARGET_64BIT"
17489   "rdpmc"
17490   [(set_attr "type" "other")
17491    (set_attr "length" "2")])
17492
17493 (define_insn "*rdpmc_rex64"
17494   [(set (match_operand:DI 0 "register_operand" "=a")
17495         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17496                             UNSPECV_RDPMC))
17497   (set (match_operand:DI 1 "register_operand" "=d")
17498        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17499   "TARGET_64BIT"
17500   "rdpmc"
17501   [(set_attr "type" "other")
17502    (set_attr "length" "2")])
17503
17504 (define_expand "rdtsc"
17505   [(set (match_operand:DI 0 "register_operand" "")
17506         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17507   ""
17508 {
17509   if (TARGET_64BIT)
17510     {
17511       rtvec vec = rtvec_alloc (2);
17512       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17513       rtx upper = gen_reg_rtx (DImode);
17514       rtx lower = gen_reg_rtx (DImode);
17515       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17516                                          gen_rtvec (1, const0_rtx),
17517                                          UNSPECV_RDTSC);
17518       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17519       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17520       emit_insn (load);
17521       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17522                                    NULL, 1, OPTAB_DIRECT);
17523       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17524                                    OPTAB_DIRECT);
17525       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17526       DONE;
17527     }
17528 })
17529
17530 (define_insn "*rdtsc"
17531   [(set (match_operand:DI 0 "register_operand" "=A")
17532         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17533   "!TARGET_64BIT"
17534   "rdtsc"
17535   [(set_attr "type" "other")
17536    (set_attr "length" "2")])
17537
17538 (define_insn "*rdtsc_rex64"
17539   [(set (match_operand:DI 0 "register_operand" "=a")
17540         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17541    (set (match_operand:DI 1 "register_operand" "=d")
17542         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17543   "TARGET_64BIT"
17544   "rdtsc"
17545   [(set_attr "type" "other")
17546    (set_attr "length" "2")])
17547
17548 (define_expand "rdtscp"
17549   [(match_operand:DI 0 "register_operand" "")
17550    (match_operand:SI 1 "memory_operand" "")]
17551   ""
17552 {
17553   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17554                                     gen_rtvec (1, const0_rtx),
17555                                     UNSPECV_RDTSCP);
17556   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17557                                     gen_rtvec (1, const0_rtx),
17558                                     UNSPECV_RDTSCP);
17559   rtx reg = gen_reg_rtx (DImode);
17560   rtx tmp = gen_reg_rtx (SImode);
17561
17562   if (TARGET_64BIT)
17563     {
17564       rtvec vec = rtvec_alloc (3);
17565       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17566       rtx upper = gen_reg_rtx (DImode);
17567       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17568       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17569       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17570       emit_insn (load);
17571       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17572                                    NULL, 1, OPTAB_DIRECT);
17573       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17574                                  OPTAB_DIRECT);
17575     }
17576   else
17577     {
17578       rtvec vec = rtvec_alloc (2);
17579       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17580       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17581       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17582       emit_insn (load);
17583     }
17584   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17585   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17586   DONE;
17587 })
17588
17589 (define_insn "*rdtscp"
17590   [(set (match_operand:DI 0 "register_operand" "=A")
17591         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17592    (set (match_operand:SI 1 "register_operand" "=c")
17593         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17594   "!TARGET_64BIT"
17595   "rdtscp"
17596   [(set_attr "type" "other")
17597    (set_attr "length" "3")])
17598
17599 (define_insn "*rdtscp_rex64"
17600   [(set (match_operand:DI 0 "register_operand" "=a")
17601         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17602    (set (match_operand:DI 1 "register_operand" "=d")
17603         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17604    (set (match_operand:SI 2 "register_operand" "=c")
17605         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17606   "TARGET_64BIT"
17607   "rdtscp"
17608   [(set_attr "type" "other")
17609    (set_attr "length" "3")])
17610
17611 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17612 ;;
17613 ;; LWP instructions
17614 ;;
17615 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17616
17617 (define_expand "lwp_llwpcb"
17618   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17619                     UNSPECV_LLWP_INTRINSIC)]
17620   "TARGET_LWP"
17621   "")
17622
17623 (define_insn "*lwp_llwpcb<mode>1"
17624   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17625                     UNSPECV_LLWP_INTRINSIC)]
17626   "TARGET_LWP"
17627   "llwpcb\t%0"
17628   [(set_attr "type" "lwp")
17629    (set_attr "mode" "<MODE>")
17630    (set_attr "length" "5")])
17631
17632 (define_expand "lwp_slwpcb"
17633   [(set (match_operand 0 "register_operand" "=r")
17634         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17635   "TARGET_LWP"
17636   {
17637     if (TARGET_64BIT)
17638       emit_insn (gen_lwp_slwpcbdi (operands[0]));
17639     else
17640       emit_insn (gen_lwp_slwpcbsi (operands[0]));
17641     DONE;
17642   })
17643
17644 (define_insn "lwp_slwpcb<mode>"
17645   [(set (match_operand:P 0 "register_operand" "=r")
17646         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17647   "TARGET_LWP"
17648   "slwpcb\t%0"
17649   [(set_attr "type" "lwp")
17650    (set_attr "mode" "<MODE>")
17651    (set_attr "length" "5")])
17652
17653 (define_expand "lwp_lwpval<mode>3"
17654   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17655                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17656                      (match_operand:SI 3 "const_int_operand" "i")]
17657                     UNSPECV_LWPVAL_INTRINSIC)]
17658   "TARGET_LWP"
17659   "/* Avoid unused variable warning.  */
17660    (void) operand0;")
17661
17662 (define_insn "*lwp_lwpval<mode>3_1"
17663   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17664                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17665                      (match_operand:SI 2 "const_int_operand" "i")]
17666                     UNSPECV_LWPVAL_INTRINSIC)]
17667   "TARGET_LWP"
17668   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17669   [(set_attr "type" "lwp")
17670    (set_attr "mode" "<MODE>")
17671    (set (attr "length")
17672         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17673
17674 (define_expand "lwp_lwpins<mode>3"
17675   [(set (reg:CCC FLAGS_REG)
17676         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17677                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17678                               (match_operand:SI 3 "const_int_operand" "i")]
17679                              UNSPECV_LWPINS_INTRINSIC))
17680    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17681         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17682   "TARGET_LWP"
17683   "")
17684
17685 (define_insn "*lwp_lwpins<mode>3_1"
17686   [(set (reg:CCC FLAGS_REG)
17687         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17688                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17689                               (match_operand:SI 2 "const_int_operand" "i")]
17690                              UNSPECV_LWPINS_INTRINSIC))]
17691   "TARGET_LWP"
17692   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17693   [(set_attr "type" "lwp")
17694    (set_attr "mode" "<MODE>")
17695    (set (attr "length")
17696         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17697
17698 (define_insn "rdfsbase<mode>"
17699   [(set (match_operand:SWI48 0 "register_operand" "=r")
17700         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17701   "TARGET_64BIT && TARGET_FSGSBASE"
17702   "rdfsbase %0"
17703   [(set_attr "type" "other")
17704    (set_attr "prefix_extra" "2")])
17705
17706 (define_insn "rdgsbase<mode>"
17707   [(set (match_operand:SWI48 0 "register_operand" "=r")
17708         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17709   "TARGET_64BIT && TARGET_FSGSBASE"
17710   "rdgsbase %0"
17711   [(set_attr "type" "other")
17712    (set_attr "prefix_extra" "2")])
17713
17714 (define_insn "wrfsbase<mode>"
17715   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17716                     UNSPECV_WRFSBASE)]
17717   "TARGET_64BIT && TARGET_FSGSBASE"
17718   "wrfsbase %0"
17719   [(set_attr "type" "other")
17720    (set_attr "prefix_extra" "2")])
17721
17722 (define_insn "wrgsbase<mode>"
17723   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17724                     UNSPECV_WRGSBASE)]
17725   "TARGET_64BIT && TARGET_FSGSBASE"
17726   "wrgsbase %0"
17727   [(set_attr "type" "other")
17728    (set_attr "prefix_extra" "2")])
17729
17730 (define_expand "rdrand<mode>"
17731   [(set (match_operand:SWI248 0 "register_operand" "=r")
17732         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17733   "TARGET_RDRND"
17734 {
17735   rtx retry_label, insn, ccc;
17736
17737   retry_label = gen_label_rtx ();
17738
17739   emit_label (retry_label);
17740
17741   /* Generate rdrand.  */
17742   emit_insn (gen_rdrand<mode>_1 (operands[0]));
17743
17744   /* Retry if the carry flag isn't valid.  */
17745   ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17746   ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17747   ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17748                               gen_rtx_LABEL_REF (VOIDmode, retry_label));
17749   insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17750   JUMP_LABEL (insn) = retry_label;
17751
17752   DONE;
17753 })
17754
17755 (define_insn "rdrand<mode>_1"
17756   [(set (match_operand:SWI248 0 "register_operand" "=r")
17757         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17758   "TARGET_RDRND"
17759   "rdrand %0"
17760   [(set_attr "type" "other")
17761    (set_attr "prefix_extra" "1")])
17762
17763 (include "mmx.md")
17764 (include "sse.md")
17765 (include "sync.md")