OSDN Git Service

* config/i386/i386.md (*tls_global_dynamic_32_gnu): Split asm template.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
63
64 ;; UNSPEC usage:
65
66 (define_c_enum "unspec" [
67   ;; Relocation specifiers
68   UNSPEC_GOT
69   UNSPEC_GOTOFF
70   UNSPEC_GOTPCREL
71   UNSPEC_GOTTPOFF
72   UNSPEC_TPOFF
73   UNSPEC_NTPOFF
74   UNSPEC_DTPOFF
75   UNSPEC_GOTNTPOFF
76   UNSPEC_INDNTPOFF
77   UNSPEC_PLTOFF
78   UNSPEC_MACHOPIC_OFFSET
79   UNSPEC_PCREL
80
81   ;; Prologue support
82   UNSPEC_STACK_ALLOC
83   UNSPEC_SET_GOT
84   UNSPEC_REG_SAVE
85   UNSPEC_DEF_CFA
86   UNSPEC_SET_RIP
87   UNSPEC_SET_GOT_OFFSET
88   UNSPEC_MEMORY_BLOCKAGE
89   UNSPEC_STACK_CHECK
90
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
97
98   ;; Other random patterns
99   UNSPEC_SCAS
100   UNSPEC_FNSTSW
101   UNSPEC_SAHF
102   UNSPEC_PARITY
103   UNSPEC_FSTCW
104   UNSPEC_ADD_CARRY
105   UNSPEC_FLDCW
106   UNSPEC_REP
107   UNSPEC_LD_MPIC        ; load_macho_picbase
108   UNSPEC_TRUNC_NOOP
109   UNSPEC_DIV_ALREADY_SPLIT
110   UNSPEC_CALL_NEEDS_VZEROUPPER
111
112   ;; For SSE/MMX support:
113   UNSPEC_FIX_NOTRUNC
114   UNSPEC_MASKMOV
115   UNSPEC_MOVMSK
116   UNSPEC_MOVNT
117   UNSPEC_MOVU
118   UNSPEC_RCP
119   UNSPEC_RSQRT
120   UNSPEC_SFENCE
121   UNSPEC_PFRCP
122   UNSPEC_PFRCPIT1
123   UNSPEC_PFRCPIT2
124   UNSPEC_PFRSQRT
125   UNSPEC_PFRSQIT1
126   UNSPEC_MFENCE
127   UNSPEC_LFENCE
128   UNSPEC_PSADBW
129   UNSPEC_LDDQU
130   UNSPEC_MS_TO_SYSV_CALL
131
132   ;; Generic math support
133   UNSPEC_COPYSIGN
134   UNSPEC_IEEE_MIN       ; not commutative
135   UNSPEC_IEEE_MAX       ; not commutative
136
137   ;; x87 Floating point
138   UNSPEC_SIN
139   UNSPEC_COS
140   UNSPEC_FPATAN
141   UNSPEC_FYL2X
142   UNSPEC_FYL2XP1
143   UNSPEC_FRNDINT
144   UNSPEC_FIST
145   UNSPEC_F2XM1
146   UNSPEC_TAN
147   UNSPEC_FXAM
148
149   ;; x87 Rounding
150   UNSPEC_FRNDINT_FLOOR
151   UNSPEC_FRNDINT_CEIL
152   UNSPEC_FRNDINT_TRUNC
153   UNSPEC_FRNDINT_MASK_PM
154   UNSPEC_FIST_FLOOR
155   UNSPEC_FIST_CEIL
156
157   ;; x87 Double output FP
158   UNSPEC_SINCOS_COS
159   UNSPEC_SINCOS_SIN
160   UNSPEC_XTRACT_FRACT
161   UNSPEC_XTRACT_EXP
162   UNSPEC_FSCALE_FRACT
163   UNSPEC_FSCALE_EXP
164   UNSPEC_FPREM_F
165   UNSPEC_FPREM_U
166   UNSPEC_FPREM1_F
167   UNSPEC_FPREM1_U
168
169   UNSPEC_C2_FLAG
170   UNSPEC_FXAM_MEM
171
172   ;; SSP patterns
173   UNSPEC_SP_SET
174   UNSPEC_SP_TEST
175   UNSPEC_SP_TLS_SET
176   UNSPEC_SP_TLS_TEST
177
178   ;; SSSE3
179   UNSPEC_PSHUFB
180   UNSPEC_PSIGN
181   UNSPEC_PALIGNR
182
183   ;; For SSE4A support
184   UNSPEC_EXTRQI
185   UNSPEC_EXTRQ
186   UNSPEC_INSERTQI
187   UNSPEC_INSERTQ
188
189   ;; For SSE4.1 support
190   UNSPEC_BLENDV
191   UNSPEC_INSERTPS
192   UNSPEC_DP
193   UNSPEC_MOVNTDQA
194   UNSPEC_MPSADBW
195   UNSPEC_PHMINPOSUW
196   UNSPEC_PTEST
197   UNSPEC_ROUND
198
199   ;; For SSE4.2 support
200   UNSPEC_CRC32
201   UNSPEC_PCMPESTR
202   UNSPEC_PCMPISTR
203
204   ;; For FMA4 support
205   UNSPEC_FMADDSUB
206   UNSPEC_XOP_UNSIGNED_CMP
207   UNSPEC_XOP_TRUEFALSE
208   UNSPEC_XOP_PERMUTE
209   UNSPEC_FRCZ
210
211   ;; For AES support
212   UNSPEC_AESENC
213   UNSPEC_AESENCLAST
214   UNSPEC_AESDEC
215   UNSPEC_AESDECLAST
216   UNSPEC_AESIMC
217   UNSPEC_AESKEYGENASSIST
218
219   ;; For PCLMUL support
220   UNSPEC_PCLMUL
221
222   ;; For AVX support
223   UNSPEC_PCMP
224   UNSPEC_VPERMIL
225   UNSPEC_VPERMIL2
226   UNSPEC_VPERMIL2F128
227   UNSPEC_CAST
228   UNSPEC_VTESTP
229   UNSPEC_VCVTPH2PS
230   UNSPEC_VCVTPS2PH
231
232   ;; For BMI support
233   UNSPEC_BEXTR
234
235   ;; For RDRAND support
236   UNSPEC_RDRAND
237 ])
238
239 (define_c_enum "unspecv" [
240   UNSPECV_BLOCKAGE
241   UNSPECV_STACK_PROBE
242   UNSPECV_PROBE_STACK_RANGE
243   UNSPECV_EMMS
244   UNSPECV_LDMXCSR
245   UNSPECV_STMXCSR
246   UNSPECV_FEMMS
247   UNSPECV_CLFLUSH
248   UNSPECV_ALIGN
249   UNSPECV_MONITOR
250   UNSPECV_MWAIT
251   UNSPECV_CMPXCHG
252   UNSPECV_XCHG
253   UNSPECV_LOCK
254   UNSPECV_PROLOGUE_USE
255   UNSPECV_CLD
256   UNSPECV_NOPS
257   UNSPECV_VZEROALL
258   UNSPECV_VZEROUPPER
259   UNSPECV_RDTSC
260   UNSPECV_RDTSCP
261   UNSPECV_RDPMC
262   UNSPECV_LLWP_INTRINSIC
263   UNSPECV_SLWP_INTRINSIC
264   UNSPECV_LWPVAL_INTRINSIC
265   UNSPECV_LWPINS_INTRINSIC
266   UNSPECV_RDFSBASE
267   UNSPECV_RDGSBASE
268   UNSPECV_WRFSBASE
269   UNSPECV_WRGSBASE
270   UNSPECV_SPLIT_STACK_RETURN
271 ])
272
273 ;; Constants to represent rounding modes in the ROUND instruction
274 (define_constants
275   [(ROUND_FLOOR                 0x1)
276    (ROUND_CEIL                  0x2)
277    (ROUND_TRUNC                 0x3)
278    (ROUND_MXCSR                 0x4)
279    (ROUND_NO_EXC                0x8)
280   ])
281
282 ;; Constants to represent pcomtrue/pcomfalse variants
283 (define_constants
284   [(PCOM_FALSE                  0)
285    (PCOM_TRUE                   1)
286    (COM_FALSE_S                 2)
287    (COM_FALSE_P                 3)
288    (COM_TRUE_S                  4)
289    (COM_TRUE_P                  5)
290   ])
291
292 ;; Constants used in the XOP pperm instruction
293 (define_constants
294   [(PPERM_SRC                   0x00)   /* copy source */
295    (PPERM_INVERT                0x20)   /* invert source */
296    (PPERM_REVERSE               0x40)   /* bit reverse source */
297    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
298    (PPERM_ZERO                  0x80)   /* all 0's */
299    (PPERM_ONES                  0xa0)   /* all 1's */
300    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
301    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
302    (PPERM_SRC1                  0x00)   /* use first source byte */
303    (PPERM_SRC2                  0x10)   /* use second source byte */
304    ])
305
306 ;; Registers by name.
307 (define_constants
308   [(AX_REG                       0)
309    (DX_REG                       1)
310    (CX_REG                       2)
311    (BX_REG                       3)
312    (SI_REG                       4)
313    (DI_REG                       5)
314    (BP_REG                       6)
315    (SP_REG                       7)
316    (ST0_REG                      8)
317    (ST1_REG                      9)
318    (ST2_REG                     10)
319    (ST3_REG                     11)
320    (ST4_REG                     12)
321    (ST5_REG                     13)
322    (ST6_REG                     14)
323    (ST7_REG                     15)
324    (FLAGS_REG                   17)
325    (FPSR_REG                    18)
326    (FPCR_REG                    19)
327    (XMM0_REG                    21)
328    (XMM1_REG                    22)
329    (XMM2_REG                    23)
330    (XMM3_REG                    24)
331    (XMM4_REG                    25)
332    (XMM5_REG                    26)
333    (XMM6_REG                    27)
334    (XMM7_REG                    28)
335    (MM0_REG                     29)
336    (MM1_REG                     30)
337    (MM2_REG                     31)
338    (MM3_REG                     32)
339    (MM4_REG                     33)
340    (MM5_REG                     34)
341    (MM6_REG                     35)
342    (MM7_REG                     36)
343    (R8_REG                      37)
344    (R9_REG                      38)
345    (R10_REG                     39)
346    (R11_REG                     40)
347    (R12_REG                     41)
348    (R13_REG                     42)
349    (XMM8_REG                    45)
350    (XMM9_REG                    46)
351    (XMM10_REG                   47)
352    (XMM11_REG                   48)
353    (XMM12_REG                   49)
354    (XMM13_REG                   50)
355    (XMM14_REG                   51)
356    (XMM15_REG                   52)
357   ])
358
359 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
360 ;; from i386.c.
361
362 ;; In C guard expressions, put expressions which may be compile-time
363 ;; constants first.  This allows for better optimization.  For
364 ;; example, write "TARGET_64BIT && reload_completed", not
365 ;; "reload_completed && TARGET_64BIT".
366
367 \f
368 ;; Processor type.
369 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
370                     atom,generic64,amdfam10,bdver1,btver1"
371   (const (symbol_ref "ix86_schedule")))
372
373 ;; A basic instruction type.  Refinements due to arguments to be
374 ;; provided in other attributes.
375 (define_attr "type"
376   "other,multi,
377    alu,alu1,negnot,imov,imovx,lea,
378    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
379    icmp,test,ibr,setcc,icmov,
380    push,pop,call,callv,leave,
381    str,bitmanip,
382    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
383    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
384    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
385    ssemuladd,sse4arg,lwp,
386    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
387   (const_string "other"))
388
389 ;; Main data type used by the insn
390 (define_attr "mode"
391   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
392   (const_string "unknown"))
393
394 ;; The CPU unit operations uses.
395 (define_attr "unit" "integer,i387,sse,mmx,unknown"
396   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
397            (const_string "i387")
398          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
399                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
400                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
401            (const_string "sse")
402          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
403            (const_string "mmx")
404          (eq_attr "type" "other")
405            (const_string "unknown")]
406          (const_string "integer")))
407
408 ;; The (bounding maximum) length of an instruction immediate.
409 (define_attr "length_immediate" ""
410   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
411                           bitmanip")
412            (const_int 0)
413          (eq_attr "unit" "i387,sse,mmx")
414            (const_int 0)
415          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
416                           imul,icmp,push,pop")
417            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
418          (eq_attr "type" "imov,test")
419            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
420          (eq_attr "type" "call")
421            (if_then_else (match_operand 0 "constant_call_address_operand" "")
422              (const_int 4)
423              (const_int 0))
424          (eq_attr "type" "callv")
425            (if_then_else (match_operand 1 "constant_call_address_operand" "")
426              (const_int 4)
427              (const_int 0))
428          ;; We don't know the size before shorten_branches.  Expect
429          ;; the instruction to fit for better scheduling.
430          (eq_attr "type" "ibr")
431            (const_int 1)
432          ]
433          (symbol_ref "/* Update immediate_length and other attributes! */
434                       gcc_unreachable (),1")))
435
436 ;; The (bounding maximum) length of an instruction address.
437 (define_attr "length_address" ""
438   (cond [(eq_attr "type" "str,other,multi,fxch")
439            (const_int 0)
440          (and (eq_attr "type" "call")
441               (match_operand 0 "constant_call_address_operand" ""))
442              (const_int 0)
443          (and (eq_attr "type" "callv")
444               (match_operand 1 "constant_call_address_operand" ""))
445              (const_int 0)
446          ]
447          (symbol_ref "ix86_attr_length_address_default (insn)")))
448
449 ;; Set when length prefix is used.
450 (define_attr "prefix_data16" ""
451   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
452            (const_int 0)
453          (eq_attr "mode" "HI")
454            (const_int 1)
455          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
456            (const_int 1)
457         ]
458         (const_int 0)))
459
460 ;; Set when string REP prefix is used.
461 (define_attr "prefix_rep" ""
462   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
463            (const_int 0)
464          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
465            (const_int 1)
466         ]
467         (const_int 0)))
468
469 ;; Set when 0f opcode prefix is used.
470 (define_attr "prefix_0f" ""
471   (if_then_else
472     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
473          (eq_attr "unit" "sse,mmx"))
474     (const_int 1)
475     (const_int 0)))
476
477 ;; Set when REX opcode prefix is used.
478 (define_attr "prefix_rex" ""
479   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
480            (const_int 0)
481          (and (eq_attr "mode" "DI")
482               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
483                    (eq_attr "unit" "!mmx")))
484            (const_int 1)
485          (and (eq_attr "mode" "QI")
486               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
487                   (const_int 0)))
488            (const_int 1)
489          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
490              (const_int 0))
491            (const_int 1)
492          (and (eq_attr "type" "imovx")
493               (match_operand:QI 1 "ext_QIreg_operand" ""))
494            (const_int 1)
495         ]
496         (const_int 0)))
497
498 ;; There are also additional prefixes in 3DNOW, SSSE3.
499 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
500 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
501 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
502 (define_attr "prefix_extra" ""
503   (cond [(eq_attr "type" "ssemuladd,sse4arg")
504            (const_int 2)
505          (eq_attr "type" "sseiadd1,ssecvt1")
506            (const_int 1)
507         ]
508         (const_int 0)))
509
510 ;; Prefix used: original, VEX or maybe VEX.
511 (define_attr "prefix" "orig,vex,maybe_vex"
512   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
513     (const_string "vex")
514     (const_string "orig")))
515
516 ;; VEX W bit is used.
517 (define_attr "prefix_vex_w" "" (const_int 0))
518
519 ;; The length of VEX prefix
520 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
521 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
522 ;; still prefix_0f 1, with prefix_extra 1.
523 (define_attr "length_vex" ""
524   (if_then_else (and (eq_attr "prefix_0f" "1")
525                      (eq_attr "prefix_extra" "0"))
526     (if_then_else (eq_attr "prefix_vex_w" "1")
527       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
528       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
529     (if_then_else (eq_attr "prefix_vex_w" "1")
530       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
531       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
532
533 ;; Set when modrm byte is used.
534 (define_attr "modrm" ""
535   (cond [(eq_attr "type" "str,leave")
536            (const_int 0)
537          (eq_attr "unit" "i387")
538            (const_int 0)
539          (and (eq_attr "type" "incdec")
540               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
541                    (ior (match_operand:SI 1 "register_operand" "")
542                         (match_operand:HI 1 "register_operand" ""))))
543            (const_int 0)
544          (and (eq_attr "type" "push")
545               (not (match_operand 1 "memory_operand" "")))
546            (const_int 0)
547          (and (eq_attr "type" "pop")
548               (not (match_operand 0 "memory_operand" "")))
549            (const_int 0)
550          (and (eq_attr "type" "imov")
551               (and (not (eq_attr "mode" "DI"))
552                    (ior (and (match_operand 0 "register_operand" "")
553                              (match_operand 1 "immediate_operand" ""))
554                         (ior (and (match_operand 0 "ax_reg_operand" "")
555                                   (match_operand 1 "memory_displacement_only_operand" ""))
556                              (and (match_operand 0 "memory_displacement_only_operand" "")
557                                   (match_operand 1 "ax_reg_operand" ""))))))
558            (const_int 0)
559          (and (eq_attr "type" "call")
560               (match_operand 0 "constant_call_address_operand" ""))
561              (const_int 0)
562          (and (eq_attr "type" "callv")
563               (match_operand 1 "constant_call_address_operand" ""))
564              (const_int 0)
565          (and (eq_attr "type" "alu,alu1,icmp,test")
566               (match_operand 0 "ax_reg_operand" ""))
567              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
568          ]
569          (const_int 1)))
570
571 ;; The (bounding maximum) length of an instruction in bytes.
572 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
573 ;; Later we may want to split them and compute proper length as for
574 ;; other insns.
575 (define_attr "length" ""
576   (cond [(eq_attr "type" "other,multi,fistp,frndint")
577            (const_int 16)
578          (eq_attr "type" "fcmp")
579            (const_int 4)
580          (eq_attr "unit" "i387")
581            (plus (const_int 2)
582                  (plus (attr "prefix_data16")
583                        (attr "length_address")))
584          (ior (eq_attr "prefix" "vex")
585               (and (eq_attr "prefix" "maybe_vex")
586                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
587            (plus (attr "length_vex")
588                  (plus (attr "length_immediate")
589                        (plus (attr "modrm")
590                              (attr "length_address"))))]
591          (plus (plus (attr "modrm")
592                      (plus (attr "prefix_0f")
593                            (plus (attr "prefix_rex")
594                                  (plus (attr "prefix_extra")
595                                        (const_int 1)))))
596                (plus (attr "prefix_rep")
597                      (plus (attr "prefix_data16")
598                            (plus (attr "length_immediate")
599                                  (attr "length_address")))))))
600
601 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
602 ;; `store' if there is a simple memory reference therein, or `unknown'
603 ;; if the instruction is complex.
604
605 (define_attr "memory" "none,load,store,both,unknown"
606   (cond [(eq_attr "type" "other,multi,str,lwp")
607            (const_string "unknown")
608          (eq_attr "type" "lea,fcmov,fpspc")
609            (const_string "none")
610          (eq_attr "type" "fistp,leave")
611            (const_string "both")
612          (eq_attr "type" "frndint")
613            (const_string "load")
614          (eq_attr "type" "push")
615            (if_then_else (match_operand 1 "memory_operand" "")
616              (const_string "both")
617              (const_string "store"))
618          (eq_attr "type" "pop")
619            (if_then_else (match_operand 0 "memory_operand" "")
620              (const_string "both")
621              (const_string "load"))
622          (eq_attr "type" "setcc")
623            (if_then_else (match_operand 0 "memory_operand" "")
624              (const_string "store")
625              (const_string "none"))
626          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
627            (if_then_else (ior (match_operand 0 "memory_operand" "")
628                               (match_operand 1 "memory_operand" ""))
629              (const_string "load")
630              (const_string "none"))
631          (eq_attr "type" "ibr")
632            (if_then_else (match_operand 0 "memory_operand" "")
633              (const_string "load")
634              (const_string "none"))
635          (eq_attr "type" "call")
636            (if_then_else (match_operand 0 "constant_call_address_operand" "")
637              (const_string "none")
638              (const_string "load"))
639          (eq_attr "type" "callv")
640            (if_then_else (match_operand 1 "constant_call_address_operand" "")
641              (const_string "none")
642              (const_string "load"))
643          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
644               (match_operand 1 "memory_operand" ""))
645            (const_string "both")
646          (and (match_operand 0 "memory_operand" "")
647               (match_operand 1 "memory_operand" ""))
648            (const_string "both")
649          (match_operand 0 "memory_operand" "")
650            (const_string "store")
651          (match_operand 1 "memory_operand" "")
652            (const_string "load")
653          (and (eq_attr "type"
654                  "!alu1,negnot,ishift1,
655                    imov,imovx,icmp,test,bitmanip,
656                    fmov,fcmp,fsgn,
657                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
658                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
659               (match_operand 2 "memory_operand" ""))
660            (const_string "load")
661          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
662               (match_operand 3 "memory_operand" ""))
663            (const_string "load")
664         ]
665         (const_string "none")))
666
667 ;; Indicates if an instruction has both an immediate and a displacement.
668
669 (define_attr "imm_disp" "false,true,unknown"
670   (cond [(eq_attr "type" "other,multi")
671            (const_string "unknown")
672          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
673               (and (match_operand 0 "memory_displacement_operand" "")
674                    (match_operand 1 "immediate_operand" "")))
675            (const_string "true")
676          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
677               (and (match_operand 0 "memory_displacement_operand" "")
678                    (match_operand 2 "immediate_operand" "")))
679            (const_string "true")
680         ]
681         (const_string "false")))
682
683 ;; Indicates if an FP operation has an integer source.
684
685 (define_attr "fp_int_src" "false,true"
686   (const_string "false"))
687
688 ;; Defines rounding mode of an FP operation.
689
690 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
691   (const_string "any"))
692
693 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
694 (define_attr "use_carry" "0,1" (const_string "0"))
695
696 ;; Define attribute to indicate unaligned ssemov insns
697 (define_attr "movu" "0,1" (const_string "0"))
698
699 ;; Used to control the "enabled" attribute on a per-instruction basis.
700 (define_attr "isa" "base,noavx,avx"
701   (const_string "base"))
702
703 (define_attr "enabled" ""
704   (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
705          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
706         ]
707         (const_int 1)))
708
709 ;; Describe a user's asm statement.
710 (define_asm_attributes
711   [(set_attr "length" "128")
712    (set_attr "type" "multi")])
713
714 (define_code_iterator plusminus [plus minus])
715
716 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
717
718 ;; Base name for define_insn
719 (define_code_attr plusminus_insn
720   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
721    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
722
723 ;; Base name for insn mnemonic.
724 (define_code_attr plusminus_mnemonic
725   [(plus "add") (ss_plus "adds") (us_plus "addus")
726    (minus "sub") (ss_minus "subs") (us_minus "subus")])
727 (define_code_attr plusminus_carry_mnemonic
728   [(plus "adc") (minus "sbb")])
729
730 ;; Mark commutative operators as such in constraints.
731 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
732                         (minus "") (ss_minus "") (us_minus "")])
733
734 ;; Mapping of signed max and min
735 (define_code_iterator smaxmin [smax smin])
736
737 ;; Mapping of unsigned max and min
738 (define_code_iterator umaxmin [umax umin])
739
740 ;; Base name for integer and FP insn mnemonic
741 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
742                               (umax "maxu") (umin "minu")])
743 (define_code_attr maxmin_float [(smax "max") (smin "min")])
744
745 ;; Mapping of logic operators
746 (define_code_iterator any_logic [and ior xor])
747 (define_code_iterator any_or [ior xor])
748
749 ;; Base name for insn mnemonic.
750 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
751
752 ;; Mapping of shift-right operators
753 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
754
755 ;; Base name for define_insn
756 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
757
758 ;; Base name for insn mnemonic.
759 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
760
761 ;; Mapping of rotate operators
762 (define_code_iterator any_rotate [rotate rotatert])
763
764 ;; Base name for define_insn
765 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
766
767 ;; Base name for insn mnemonic.
768 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
769
770 ;; Mapping of abs neg operators
771 (define_code_iterator absneg [abs neg])
772
773 ;; Base name for x87 insn mnemonic.
774 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
775
776 ;; Used in signed and unsigned widening multiplications.
777 (define_code_iterator any_extend [sign_extend zero_extend])
778
779 ;; Various insn prefixes for signed and unsigned operations.
780 (define_code_attr u [(sign_extend "") (zero_extend "u")
781                      (div "") (udiv "u")])
782 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
783
784 ;; Used in signed and unsigned divisions.
785 (define_code_iterator any_div [div udiv])
786
787 ;; Instruction prefix for signed and unsigned operations.
788 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
789                              (div "i") (udiv "")])
790
791 ;; 64bit single word integer modes.
792 (define_mode_iterator SWI1248x [QI HI SI DI])
793
794 ;; 64bit single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48x [SI DI])
796
797 ;; Single word integer modes.
798 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
799
800 ;; Single word integer modes without SImode and DImode.
801 (define_mode_iterator SWI12 [QI HI])
802
803 ;; Single word integer modes without DImode.
804 (define_mode_iterator SWI124 [QI HI SI])
805
806 ;; Single word integer modes without QImode and DImode.
807 (define_mode_iterator SWI24 [HI SI])
808
809 ;; Single word integer modes without QImode.
810 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
811
812 ;; Single word integer modes without QImode and HImode.
813 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
814
815 ;; All math-dependant single and double word integer modes.
816 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
817                              (HI "TARGET_HIMODE_MATH")
818                              SI DI (TI "TARGET_64BIT")])
819
820 ;; Math-dependant single word integer modes.
821 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
822                             (HI "TARGET_HIMODE_MATH")
823                             SI (DI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes without DImode.
826 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
827                                (HI "TARGET_HIMODE_MATH")
828                                SI])
829
830 ;; Math-dependant single word integer modes without QImode.
831 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
832                                SI (DI "TARGET_64BIT")])
833
834 ;; Double word integer modes.
835 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
836                            (TI "TARGET_64BIT")])
837
838 ;; Double word integer modes as mode attribute.
839 (define_mode_attr DWI [(SI "DI") (DI "TI")])
840 (define_mode_attr dwi [(SI "di") (DI "ti")])
841
842 ;; Half mode for double word integer modes.
843 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
844                             (DI "TARGET_64BIT")])
845
846 ;; Instruction suffix for integer modes.
847 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
848
849 ;; Pointer size prefix for integer modes (Intel asm dialect)
850 (define_mode_attr iptrsize [(QI "BYTE")
851                             (HI "WORD")
852                             (SI "DWORD")
853                             (DI "QWORD")])
854
855 ;; Register class for integer modes.
856 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
857
858 ;; Immediate operand constraint for integer modes.
859 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
860
861 ;; General operand constraint for word modes.
862 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
863
864 ;; Immediate operand constraint for double integer modes.
865 (define_mode_attr di [(SI "iF") (DI "e")])
866
867 ;; Immediate operand constraint for shifts.
868 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
869
870 ;; General operand predicate for integer modes.
871 (define_mode_attr general_operand
872         [(QI "general_operand")
873          (HI "general_operand")
874          (SI "general_operand")
875          (DI "x86_64_general_operand")
876          (TI "x86_64_general_operand")])
877
878 ;; General sign/zero extend operand predicate for integer modes.
879 (define_mode_attr general_szext_operand
880         [(QI "general_operand")
881          (HI "general_operand")
882          (SI "general_operand")
883          (DI "x86_64_szext_general_operand")])
884
885 ;; Immediate operand predicate for integer modes.
886 (define_mode_attr immediate_operand
887         [(QI "immediate_operand")
888          (HI "immediate_operand")
889          (SI "immediate_operand")
890          (DI "x86_64_immediate_operand")])
891
892 ;; Nonmemory operand predicate for integer modes.
893 (define_mode_attr nonmemory_operand
894         [(QI "nonmemory_operand")
895          (HI "nonmemory_operand")
896          (SI "nonmemory_operand")
897          (DI "x86_64_nonmemory_operand")])
898
899 ;; Operand predicate for shifts.
900 (define_mode_attr shift_operand
901         [(QI "nonimmediate_operand")
902          (HI "nonimmediate_operand")
903          (SI "nonimmediate_operand")
904          (DI "shiftdi_operand")
905          (TI "register_operand")])
906
907 ;; Operand predicate for shift argument.
908 (define_mode_attr shift_immediate_operand
909         [(QI "const_1_to_31_operand")
910          (HI "const_1_to_31_operand")
911          (SI "const_1_to_31_operand")
912          (DI "const_1_to_63_operand")])
913
914 ;; Input operand predicate for arithmetic left shifts.
915 (define_mode_attr ashl_input_operand
916         [(QI "nonimmediate_operand")
917          (HI "nonimmediate_operand")
918          (SI "nonimmediate_operand")
919          (DI "ashldi_input_operand")
920          (TI "reg_or_pm1_operand")])
921
922 ;; SSE and x87 SFmode and DFmode floating point modes
923 (define_mode_iterator MODEF [SF DF])
924
925 ;; All x87 floating point modes
926 (define_mode_iterator X87MODEF [SF DF XF])
927
928 ;; All integer modes handled by x87 fisttp operator.
929 (define_mode_iterator X87MODEI [HI SI DI])
930
931 ;; All integer modes handled by integer x87 operators.
932 (define_mode_iterator X87MODEI12 [HI SI])
933
934 ;; All integer modes handled by SSE cvtts?2si* operators.
935 (define_mode_iterator SSEMODEI24 [SI DI])
936
937 ;; SSE instruction suffix for various modes
938 (define_mode_attr ssemodesuffix
939   [(SF "ss") (DF "sd")
940    (V8SF "ps") (V4DF "pd")
941    (V4SF "ps") (V2DF "pd")
942    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
943    (V8SI "si")])
944
945 ;; SSE vector suffix for floating point modes
946 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
947
948 ;; SSE vector mode corresponding to a scalar mode
949 (define_mode_attr ssevecmode
950   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
951
952 ;; Instruction suffix for REX 64bit operators.
953 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
954
955 ;; This mode iterator allows :P to be used for patterns that operate on
956 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
957 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
958 \f
959 ;; Scheduling descriptions
960
961 (include "pentium.md")
962 (include "ppro.md")
963 (include "k6.md")
964 (include "athlon.md")
965 (include "bdver1.md")
966 (include "geode.md")
967 (include "atom.md")
968 (include "core2.md")
969
970 \f
971 ;; Operand and operator predicates and constraints
972
973 (include "predicates.md")
974 (include "constraints.md")
975
976 \f
977 ;; Compare and branch/compare and store instructions.
978
979 (define_expand "cbranch<mode>4"
980   [(set (reg:CC FLAGS_REG)
981         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
982                     (match_operand:SDWIM 2 "<general_operand>" "")))
983    (set (pc) (if_then_else
984                (match_operator 0 "ordered_comparison_operator"
985                 [(reg:CC FLAGS_REG) (const_int 0)])
986                (label_ref (match_operand 3 "" ""))
987                (pc)))]
988   ""
989 {
990   if (MEM_P (operands[1]) && MEM_P (operands[2]))
991     operands[1] = force_reg (<MODE>mode, operands[1]);
992   ix86_expand_branch (GET_CODE (operands[0]),
993                       operands[1], operands[2], operands[3]);
994   DONE;
995 })
996
997 (define_expand "cstore<mode>4"
998   [(set (reg:CC FLAGS_REG)
999         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1000                     (match_operand:SWIM 3 "<general_operand>" "")))
1001    (set (match_operand:QI 0 "register_operand" "")
1002         (match_operator 1 "ordered_comparison_operator"
1003           [(reg:CC FLAGS_REG) (const_int 0)]))]
1004   ""
1005 {
1006   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007     operands[2] = force_reg (<MODE>mode, operands[2]);
1008   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009                      operands[2], operands[3]);
1010   DONE;
1011 })
1012
1013 (define_expand "cmp<mode>_1"
1014   [(set (reg:CC FLAGS_REG)
1015         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1016                     (match_operand:SWI48 1 "<general_operand>" "")))])
1017
1018 (define_insn "*cmp<mode>_ccno_1"
1019   [(set (reg FLAGS_REG)
1020         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021                  (match_operand:SWI 1 "const0_operand" "")))]
1022   "ix86_match_ccmode (insn, CCNOmode)"
1023   "@
1024    test{<imodesuffix>}\t%0, %0
1025    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026   [(set_attr "type" "test,icmp")
1027    (set_attr "length_immediate" "0,1")
1028    (set_attr "mode" "<MODE>")])
1029
1030 (define_insn "*cmp<mode>_1"
1031   [(set (reg FLAGS_REG)
1032         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034   "ix86_match_ccmode (insn, CCmode)"
1035   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036   [(set_attr "type" "icmp")
1037    (set_attr "mode" "<MODE>")])
1038
1039 (define_insn "*cmp<mode>_minus_1"
1040   [(set (reg FLAGS_REG)
1041         (compare
1042           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1044           (const_int 0)))]
1045   "ix86_match_ccmode (insn, CCGOCmode)"
1046   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047   [(set_attr "type" "icmp")
1048    (set_attr "mode" "<MODE>")])
1049
1050 (define_insn "*cmpqi_ext_1"
1051   [(set (reg FLAGS_REG)
1052         (compare
1053           (match_operand:QI 0 "general_operand" "Qm")
1054           (subreg:QI
1055             (zero_extract:SI
1056               (match_operand 1 "ext_register_operand" "Q")
1057               (const_int 8)
1058               (const_int 8)) 0)))]
1059   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1060   "cmp{b}\t{%h1, %0|%0, %h1}"
1061   [(set_attr "type" "icmp")
1062    (set_attr "mode" "QI")])
1063
1064 (define_insn "*cmpqi_ext_1_rex64"
1065   [(set (reg FLAGS_REG)
1066         (compare
1067           (match_operand:QI 0 "register_operand" "Q")
1068           (subreg:QI
1069             (zero_extract:SI
1070               (match_operand 1 "ext_register_operand" "Q")
1071               (const_int 8)
1072               (const_int 8)) 0)))]
1073   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074   "cmp{b}\t{%h1, %0|%0, %h1}"
1075   [(set_attr "type" "icmp")
1076    (set_attr "mode" "QI")])
1077
1078 (define_insn "*cmpqi_ext_2"
1079   [(set (reg FLAGS_REG)
1080         (compare
1081           (subreg:QI
1082             (zero_extract:SI
1083               (match_operand 0 "ext_register_operand" "Q")
1084               (const_int 8)
1085               (const_int 8)) 0)
1086           (match_operand:QI 1 "const0_operand" "")))]
1087   "ix86_match_ccmode (insn, CCNOmode)"
1088   "test{b}\t%h0, %h0"
1089   [(set_attr "type" "test")
1090    (set_attr "length_immediate" "0")
1091    (set_attr "mode" "QI")])
1092
1093 (define_expand "cmpqi_ext_3"
1094   [(set (reg:CC FLAGS_REG)
1095         (compare:CC
1096           (subreg:QI
1097             (zero_extract:SI
1098               (match_operand 0 "ext_register_operand" "")
1099               (const_int 8)
1100               (const_int 8)) 0)
1101           (match_operand:QI 1 "immediate_operand" "")))])
1102
1103 (define_insn "*cmpqi_ext_3_insn"
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           (match_operand:QI 1 "general_operand" "Qmn")))]
1112   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1113   "cmp{b}\t{%1, %h0|%h0, %1}"
1114   [(set_attr "type" "icmp")
1115    (set_attr "modrm" "1")
1116    (set_attr "mode" "QI")])
1117
1118 (define_insn "*cmpqi_ext_3_insn_rex64"
1119   [(set (reg FLAGS_REG)
1120         (compare
1121           (subreg:QI
1122             (zero_extract:SI
1123               (match_operand 0 "ext_register_operand" "Q")
1124               (const_int 8)
1125               (const_int 8)) 0)
1126           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1127   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1128   "cmp{b}\t{%1, %h0|%h0, %1}"
1129   [(set_attr "type" "icmp")
1130    (set_attr "modrm" "1")
1131    (set_attr "mode" "QI")])
1132
1133 (define_insn "*cmpqi_ext_4"
1134   [(set (reg FLAGS_REG)
1135         (compare
1136           (subreg:QI
1137             (zero_extract:SI
1138               (match_operand 0 "ext_register_operand" "Q")
1139               (const_int 8)
1140               (const_int 8)) 0)
1141           (subreg:QI
1142             (zero_extract:SI
1143               (match_operand 1 "ext_register_operand" "Q")
1144               (const_int 8)
1145               (const_int 8)) 0)))]
1146   "ix86_match_ccmode (insn, CCmode)"
1147   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1148   [(set_attr "type" "icmp")
1149    (set_attr "mode" "QI")])
1150
1151 ;; These implement float point compares.
1152 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1153 ;; which would allow mix and match FP modes on the compares.  Which is what
1154 ;; the old patterns did, but with many more of them.
1155
1156 (define_expand "cbranchxf4"
1157   [(set (reg:CC FLAGS_REG)
1158         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1159                     (match_operand:XF 2 "nonmemory_operand" "")))
1160    (set (pc) (if_then_else
1161               (match_operator 0 "ix86_fp_comparison_operator"
1162                [(reg:CC FLAGS_REG)
1163                 (const_int 0)])
1164               (label_ref (match_operand 3 "" ""))
1165               (pc)))]
1166   "TARGET_80387"
1167 {
1168   ix86_expand_branch (GET_CODE (operands[0]),
1169                       operands[1], operands[2], operands[3]);
1170   DONE;
1171 })
1172
1173 (define_expand "cstorexf4"
1174   [(set (reg:CC FLAGS_REG)
1175         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1176                     (match_operand:XF 3 "nonmemory_operand" "")))
1177    (set (match_operand:QI 0 "register_operand" "")
1178               (match_operator 1 "ix86_fp_comparison_operator"
1179                [(reg:CC FLAGS_REG)
1180                 (const_int 0)]))]
1181   "TARGET_80387"
1182 {
1183   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184                      operands[2], operands[3]);
1185   DONE;
1186 })
1187
1188 (define_expand "cbranch<mode>4"
1189   [(set (reg:CC FLAGS_REG)
1190         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1191                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1192    (set (pc) (if_then_else
1193               (match_operator 0 "ix86_fp_comparison_operator"
1194                [(reg:CC FLAGS_REG)
1195                 (const_int 0)])
1196               (label_ref (match_operand 3 "" ""))
1197               (pc)))]
1198   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1199 {
1200   ix86_expand_branch (GET_CODE (operands[0]),
1201                       operands[1], operands[2], operands[3]);
1202   DONE;
1203 })
1204
1205 (define_expand "cstore<mode>4"
1206   [(set (reg:CC FLAGS_REG)
1207         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1208                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1209    (set (match_operand:QI 0 "register_operand" "")
1210               (match_operator 1 "ix86_fp_comparison_operator"
1211                [(reg:CC FLAGS_REG)
1212                 (const_int 0)]))]
1213   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1214 {
1215   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216                      operands[2], operands[3]);
1217   DONE;
1218 })
1219
1220 (define_expand "cbranchcc4"
1221   [(set (pc) (if_then_else
1222               (match_operator 0 "comparison_operator"
1223                [(match_operand 1 "flags_reg_operand" "")
1224                 (match_operand 2 "const0_operand" "")])
1225               (label_ref (match_operand 3 "" ""))
1226               (pc)))]
1227   ""
1228 {
1229   ix86_expand_branch (GET_CODE (operands[0]),
1230                       operands[1], operands[2], operands[3]);
1231   DONE;
1232 })
1233
1234 (define_expand "cstorecc4"
1235   [(set (match_operand:QI 0 "register_operand" "")
1236               (match_operator 1 "comparison_operator"
1237                [(match_operand 2 "flags_reg_operand" "")
1238                 (match_operand 3 "const0_operand" "")]))]
1239   ""
1240 {
1241   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1242                      operands[2], operands[3]);
1243   DONE;
1244 })
1245
1246
1247 ;; FP compares, step 1:
1248 ;; Set the FP condition codes.
1249 ;;
1250 ;; CCFPmode     compare with exceptions
1251 ;; CCFPUmode    compare with no exceptions
1252
1253 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1254 ;; used to manage the reg stack popping would not be preserved.
1255
1256 (define_insn "*cmpfp_0"
1257   [(set (match_operand:HI 0 "register_operand" "=a")
1258         (unspec:HI
1259           [(compare:CCFP
1260              (match_operand 1 "register_operand" "f")
1261              (match_operand 2 "const0_operand" ""))]
1262         UNSPEC_FNSTSW))]
1263   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265   "* return output_fp_compare (insn, operands, false, false);"
1266   [(set_attr "type" "multi")
1267    (set_attr "unit" "i387")
1268    (set (attr "mode")
1269      (cond [(match_operand:SF 1 "" "")
1270               (const_string "SF")
1271             (match_operand:DF 1 "" "")
1272               (const_string "DF")
1273            ]
1274            (const_string "XF")))])
1275
1276 (define_insn_and_split "*cmpfp_0_cc"
1277   [(set (reg:CCFP FLAGS_REG)
1278         (compare:CCFP
1279           (match_operand 1 "register_operand" "f")
1280           (match_operand 2 "const0_operand" "")))
1281    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283    && TARGET_SAHF && !TARGET_CMOVE
1284    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1285   "#"
1286   "&& reload_completed"
1287   [(set (match_dup 0)
1288         (unspec:HI
1289           [(compare:CCFP (match_dup 1)(match_dup 2))]
1290         UNSPEC_FNSTSW))
1291    (set (reg:CC FLAGS_REG)
1292         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293   ""
1294   [(set_attr "type" "multi")
1295    (set_attr "unit" "i387")
1296    (set (attr "mode")
1297      (cond [(match_operand:SF 1 "" "")
1298               (const_string "SF")
1299             (match_operand:DF 1 "" "")
1300               (const_string "DF")
1301            ]
1302            (const_string "XF")))])
1303
1304 (define_insn "*cmpfp_xf"
1305   [(set (match_operand:HI 0 "register_operand" "=a")
1306         (unspec:HI
1307           [(compare:CCFP
1308              (match_operand:XF 1 "register_operand" "f")
1309              (match_operand:XF 2 "register_operand" "f"))]
1310           UNSPEC_FNSTSW))]
1311   "TARGET_80387"
1312   "* return output_fp_compare (insn, operands, false, false);"
1313   [(set_attr "type" "multi")
1314    (set_attr "unit" "i387")
1315    (set_attr "mode" "XF")])
1316
1317 (define_insn_and_split "*cmpfp_xf_cc"
1318   [(set (reg:CCFP FLAGS_REG)
1319         (compare:CCFP
1320           (match_operand:XF 1 "register_operand" "f")
1321           (match_operand:XF 2 "register_operand" "f")))
1322    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323   "TARGET_80387
1324    && TARGET_SAHF && !TARGET_CMOVE"
1325   "#"
1326   "&& reload_completed"
1327   [(set (match_dup 0)
1328         (unspec:HI
1329           [(compare:CCFP (match_dup 1)(match_dup 2))]
1330         UNSPEC_FNSTSW))
1331    (set (reg:CC FLAGS_REG)
1332         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1333   ""
1334   [(set_attr "type" "multi")
1335    (set_attr "unit" "i387")
1336    (set_attr "mode" "XF")])
1337
1338 (define_insn "*cmpfp_<mode>"
1339   [(set (match_operand:HI 0 "register_operand" "=a")
1340         (unspec:HI
1341           [(compare:CCFP
1342              (match_operand:MODEF 1 "register_operand" "f")
1343              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1344           UNSPEC_FNSTSW))]
1345   "TARGET_80387"
1346   "* return output_fp_compare (insn, operands, false, false);"
1347   [(set_attr "type" "multi")
1348    (set_attr "unit" "i387")
1349    (set_attr "mode" "<MODE>")])
1350
1351 (define_insn_and_split "*cmpfp_<mode>_cc"
1352   [(set (reg:CCFP FLAGS_REG)
1353         (compare:CCFP
1354           (match_operand:MODEF 1 "register_operand" "f")
1355           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1356    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1357   "TARGET_80387
1358    && TARGET_SAHF && !TARGET_CMOVE"
1359   "#"
1360   "&& reload_completed"
1361   [(set (match_dup 0)
1362         (unspec:HI
1363           [(compare:CCFP (match_dup 1)(match_dup 2))]
1364         UNSPEC_FNSTSW))
1365    (set (reg:CC FLAGS_REG)
1366         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1367   ""
1368   [(set_attr "type" "multi")
1369    (set_attr "unit" "i387")
1370    (set_attr "mode" "<MODE>")])
1371
1372 (define_insn "*cmpfp_u"
1373   [(set (match_operand:HI 0 "register_operand" "=a")
1374         (unspec:HI
1375           [(compare:CCFPU
1376              (match_operand 1 "register_operand" "f")
1377              (match_operand 2 "register_operand" "f"))]
1378           UNSPEC_FNSTSW))]
1379   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1381   "* return output_fp_compare (insn, operands, false, true);"
1382   [(set_attr "type" "multi")
1383    (set_attr "unit" "i387")
1384    (set (attr "mode")
1385      (cond [(match_operand:SF 1 "" "")
1386               (const_string "SF")
1387             (match_operand:DF 1 "" "")
1388               (const_string "DF")
1389            ]
1390            (const_string "XF")))])
1391
1392 (define_insn_and_split "*cmpfp_u_cc"
1393   [(set (reg:CCFPU FLAGS_REG)
1394         (compare:CCFPU
1395           (match_operand 1 "register_operand" "f")
1396           (match_operand 2 "register_operand" "f")))
1397    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1398   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399    && TARGET_SAHF && !TARGET_CMOVE
1400    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1401   "#"
1402   "&& reload_completed"
1403   [(set (match_dup 0)
1404         (unspec:HI
1405           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1406         UNSPEC_FNSTSW))
1407    (set (reg:CC FLAGS_REG)
1408         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1409   ""
1410   [(set_attr "type" "multi")
1411    (set_attr "unit" "i387")
1412    (set (attr "mode")
1413      (cond [(match_operand:SF 1 "" "")
1414               (const_string "SF")
1415             (match_operand:DF 1 "" "")
1416               (const_string "DF")
1417            ]
1418            (const_string "XF")))])
1419
1420 (define_insn "*cmpfp_<mode>"
1421   [(set (match_operand:HI 0 "register_operand" "=a")
1422         (unspec:HI
1423           [(compare:CCFP
1424              (match_operand 1 "register_operand" "f")
1425              (match_operator 3 "float_operator"
1426                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1427           UNSPEC_FNSTSW))]
1428   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1430    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1431   "* return output_fp_compare (insn, operands, false, false);"
1432   [(set_attr "type" "multi")
1433    (set_attr "unit" "i387")
1434    (set_attr "fp_int_src" "true")
1435    (set_attr "mode" "<MODE>")])
1436
1437 (define_insn_and_split "*cmpfp_<mode>_cc"
1438   [(set (reg:CCFP FLAGS_REG)
1439         (compare:CCFP
1440           (match_operand 1 "register_operand" "f")
1441           (match_operator 3 "float_operator"
1442             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1443    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1444   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445    && TARGET_SAHF && !TARGET_CMOVE
1446    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1448   "#"
1449   "&& reload_completed"
1450   [(set (match_dup 0)
1451         (unspec:HI
1452           [(compare:CCFP
1453              (match_dup 1)
1454              (match_op_dup 3 [(match_dup 2)]))]
1455         UNSPEC_FNSTSW))
1456    (set (reg:CC FLAGS_REG)
1457         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1458   ""
1459   [(set_attr "type" "multi")
1460    (set_attr "unit" "i387")
1461    (set_attr "fp_int_src" "true")
1462    (set_attr "mode" "<MODE>")])
1463
1464 ;; FP compares, step 2
1465 ;; Move the fpsw to ax.
1466
1467 (define_insn "x86_fnstsw_1"
1468   [(set (match_operand:HI 0 "register_operand" "=a")
1469         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1470   "TARGET_80387"
1471   "fnstsw\t%0"
1472   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1473    (set_attr "mode" "SI")
1474    (set_attr "unit" "i387")])
1475
1476 ;; FP compares, step 3
1477 ;; Get ax into flags, general case.
1478
1479 (define_insn "x86_sahf_1"
1480   [(set (reg:CC FLAGS_REG)
1481         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1482                    UNSPEC_SAHF))]
1483   "TARGET_SAHF"
1484 {
1485 #ifndef HAVE_AS_IX86_SAHF
1486   if (TARGET_64BIT)
1487     return ASM_BYTE "0x9e";
1488   else
1489 #endif
1490   return "sahf";
1491 }
1492   [(set_attr "length" "1")
1493    (set_attr "athlon_decode" "vector")
1494    (set_attr "amdfam10_decode" "direct")
1495    (set_attr "bdver1_decode" "direct")
1496    (set_attr "mode" "SI")])
1497
1498 ;; Pentium Pro can do steps 1 through 3 in one go.
1499 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1500 (define_insn "*cmpfp_i_mixed"
1501   [(set (reg:CCFP FLAGS_REG)
1502         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1503                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1504   "TARGET_MIX_SSE_I387
1505    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1506    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507   "* return output_fp_compare (insn, operands, true, false);"
1508   [(set_attr "type" "fcmp,ssecomi")
1509    (set_attr "prefix" "orig,maybe_vex")
1510    (set (attr "mode")
1511      (if_then_else (match_operand:SF 1 "" "")
1512         (const_string "SF")
1513         (const_string "DF")))
1514    (set (attr "prefix_rep")
1515         (if_then_else (eq_attr "type" "ssecomi")
1516                       (const_string "0")
1517                       (const_string "*")))
1518    (set (attr "prefix_data16")
1519         (cond [(eq_attr "type" "fcmp")
1520                  (const_string "*")
1521                (eq_attr "mode" "DF")
1522                  (const_string "1")
1523               ]
1524               (const_string "0")))
1525    (set_attr "athlon_decode" "vector")
1526    (set_attr "amdfam10_decode" "direct")
1527    (set_attr "bdver1_decode" "double")])
1528
1529 (define_insn "*cmpfp_i_sse"
1530   [(set (reg:CCFP FLAGS_REG)
1531         (compare:CCFP (match_operand 0 "register_operand" "x")
1532                       (match_operand 1 "nonimmediate_operand" "xm")))]
1533   "TARGET_SSE_MATH
1534    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1535    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1536   "* return output_fp_compare (insn, operands, true, false);"
1537   [(set_attr "type" "ssecomi")
1538    (set_attr "prefix" "maybe_vex")
1539    (set (attr "mode")
1540      (if_then_else (match_operand:SF 1 "" "")
1541         (const_string "SF")
1542         (const_string "DF")))
1543    (set_attr "prefix_rep" "0")
1544    (set (attr "prefix_data16")
1545         (if_then_else (eq_attr "mode" "DF")
1546                       (const_string "1")
1547                       (const_string "0")))
1548    (set_attr "athlon_decode" "vector")
1549    (set_attr "amdfam10_decode" "direct")
1550    (set_attr "bdver1_decode" "double")])
1551
1552 (define_insn "*cmpfp_i_i387"
1553   [(set (reg:CCFP FLAGS_REG)
1554         (compare:CCFP (match_operand 0 "register_operand" "f")
1555                       (match_operand 1 "register_operand" "f")))]
1556   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1557    && TARGET_CMOVE
1558    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1559    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560   "* return output_fp_compare (insn, operands, true, false);"
1561   [(set_attr "type" "fcmp")
1562    (set (attr "mode")
1563      (cond [(match_operand:SF 1 "" "")
1564               (const_string "SF")
1565             (match_operand:DF 1 "" "")
1566               (const_string "DF")
1567            ]
1568            (const_string "XF")))
1569    (set_attr "athlon_decode" "vector")
1570    (set_attr "amdfam10_decode" "direct")
1571    (set_attr "bdver1_decode" "double")])
1572
1573 (define_insn "*cmpfp_iu_mixed"
1574   [(set (reg:CCFPU FLAGS_REG)
1575         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1576                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1577   "TARGET_MIX_SSE_I387
1578    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580   "* return output_fp_compare (insn, operands, true, true);"
1581   [(set_attr "type" "fcmp,ssecomi")
1582    (set_attr "prefix" "orig,maybe_vex")
1583    (set (attr "mode")
1584      (if_then_else (match_operand:SF 1 "" "")
1585         (const_string "SF")
1586         (const_string "DF")))
1587    (set (attr "prefix_rep")
1588         (if_then_else (eq_attr "type" "ssecomi")
1589                       (const_string "0")
1590                       (const_string "*")))
1591    (set (attr "prefix_data16")
1592         (cond [(eq_attr "type" "fcmp")
1593                  (const_string "*")
1594                (eq_attr "mode" "DF")
1595                  (const_string "1")
1596               ]
1597               (const_string "0")))
1598    (set_attr "athlon_decode" "vector")
1599    (set_attr "amdfam10_decode" "direct")
1600    (set_attr "bdver1_decode" "double")])
1601
1602 (define_insn "*cmpfp_iu_sse"
1603   [(set (reg:CCFPU FLAGS_REG)
1604         (compare:CCFPU (match_operand 0 "register_operand" "x")
1605                        (match_operand 1 "nonimmediate_operand" "xm")))]
1606   "TARGET_SSE_MATH
1607    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1608    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1609   "* return output_fp_compare (insn, operands, true, true);"
1610   [(set_attr "type" "ssecomi")
1611    (set_attr "prefix" "maybe_vex")
1612    (set (attr "mode")
1613      (if_then_else (match_operand:SF 1 "" "")
1614         (const_string "SF")
1615         (const_string "DF")))
1616    (set_attr "prefix_rep" "0")
1617    (set (attr "prefix_data16")
1618         (if_then_else (eq_attr "mode" "DF")
1619                       (const_string "1")
1620                       (const_string "0")))
1621    (set_attr "athlon_decode" "vector")
1622    (set_attr "amdfam10_decode" "direct")
1623    (set_attr "bdver1_decode" "double")])
1624
1625 (define_insn "*cmpfp_iu_387"
1626   [(set (reg:CCFPU FLAGS_REG)
1627         (compare:CCFPU (match_operand 0 "register_operand" "f")
1628                        (match_operand 1 "register_operand" "f")))]
1629   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1630    && TARGET_CMOVE
1631    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1632    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633   "* return output_fp_compare (insn, operands, true, true);"
1634   [(set_attr "type" "fcmp")
1635    (set (attr "mode")
1636      (cond [(match_operand:SF 1 "" "")
1637               (const_string "SF")
1638             (match_operand:DF 1 "" "")
1639               (const_string "DF")
1640            ]
1641            (const_string "XF")))
1642    (set_attr "athlon_decode" "vector")
1643    (set_attr "amdfam10_decode" "direct")
1644    (set_attr "bdver1_decode" "direct")])
1645 \f
1646 ;; Push/pop instructions.
1647
1648 (define_insn "*push<mode>2"
1649   [(set (match_operand:DWI 0 "push_operand" "=<")
1650         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1651   ""
1652   "#")
1653
1654 (define_split
1655   [(set (match_operand:TI 0 "push_operand" "")
1656         (match_operand:TI 1 "general_operand" ""))]
1657   "TARGET_64BIT && reload_completed
1658    && !SSE_REG_P (operands[1])"
1659   [(const_int 0)]
1660   "ix86_split_long_move (operands); DONE;")
1661
1662 (define_insn "*pushdi2_rex64"
1663   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665   "TARGET_64BIT"
1666   "@
1667    push{q}\t%1
1668    #"
1669   [(set_attr "type" "push,multi")
1670    (set_attr "mode" "DI")])
1671
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it.  In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1676 (define_peephole2
1677   [(match_scratch:DI 2 "r")
1678    (set (match_operand:DI 0 "push_operand" "")
1679         (match_operand:DI 1 "immediate_operand" ""))]
1680   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681    && !x86_64_immediate_operand (operands[1], DImode)"
1682   [(set (match_dup 2) (match_dup 1))
1683    (set (match_dup 0) (match_dup 2))])
1684
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1688 (define_peephole2
1689   [(set (match_operand:DI 0 "push_operand" "")
1690         (match_operand:DI 1 "immediate_operand" ""))]
1691   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693   [(set (match_dup 0) (match_dup 1))
1694    (set (match_dup 2) (match_dup 3))]
1695 {
1696   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1697
1698   operands[1] = gen_lowpart (DImode, operands[2]);
1699   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1700                                                    GEN_INT (4)));
1701 })
1702
1703 (define_split
1704   [(set (match_operand:DI 0 "push_operand" "")
1705         (match_operand:DI 1 "immediate_operand" ""))]
1706   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707                     ? epilogue_completed : reload_completed)
1708    && !symbolic_operand (operands[1], DImode)
1709    && !x86_64_immediate_operand (operands[1], DImode)"
1710   [(set (match_dup 0) (match_dup 1))
1711    (set (match_dup 2) (match_dup 3))]
1712 {
1713   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1714
1715   operands[1] = gen_lowpart (DImode, operands[2]);
1716   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1717                                                    GEN_INT (4)));
1718 })
1719
1720 (define_split
1721   [(set (match_operand:DI 0 "push_operand" "")
1722         (match_operand:DI 1 "general_operand" ""))]
1723   "!TARGET_64BIT && reload_completed
1724    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1725   [(const_int 0)]
1726   "ix86_split_long_move (operands); DONE;")
1727
1728 (define_insn "*pushsi2"
1729   [(set (match_operand:SI 0 "push_operand" "=<")
1730         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1731   "!TARGET_64BIT"
1732   "push{l}\t%1"
1733   [(set_attr "type" "push")
1734    (set_attr "mode" "SI")])
1735
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word".  But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1739
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742   [(set (match_operand:SWI124 0 "push_operand" "=X")
1743         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1744   "TARGET_64BIT"
1745   "push{q}\t%q1"
1746   [(set_attr "type" "push")
1747    (set_attr "mode" "DI")])
1748
1749 (define_insn "*push<mode>2"
1750   [(set (match_operand:SWI12 0 "push_operand" "=X")
1751         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1752   "!TARGET_64BIT"
1753   "push{l}\t%k1"
1754   [(set_attr "type" "push")
1755    (set_attr "mode" "SI")])
1756
1757 (define_insn "*push<mode>2_prologue"
1758   [(set (match_operand:P 0 "push_operand" "=<")
1759         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1760    (clobber (mem:BLK (scratch)))]
1761   ""
1762   "push{<imodesuffix>}\t%1"
1763   [(set_attr "type" "push")
1764    (set_attr "mode" "<MODE>")])
1765
1766 (define_insn "*pop<mode>1"
1767   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768         (match_operand:P 1 "pop_operand" ">"))]
1769   ""
1770   "pop{<imodesuffix>}\t%0"
1771   [(set_attr "type" "pop")
1772    (set_attr "mode" "<MODE>")])
1773
1774 (define_insn "*pop<mode>1_epilogue"
1775   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1776         (match_operand:P 1 "pop_operand" ">"))
1777    (clobber (mem:BLK (scratch)))]
1778   ""
1779   "pop{<imodesuffix>}\t%0"
1780   [(set_attr "type" "pop")
1781    (set_attr "mode" "<MODE>")])
1782 \f
1783 ;; Move instructions.
1784
1785 (define_expand "movoi"
1786   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1787         (match_operand:OI 1 "general_operand" ""))]
1788   "TARGET_AVX"
1789   "ix86_expand_move (OImode, operands); DONE;")
1790
1791 (define_expand "movti"
1792   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1793         (match_operand:TI 1 "nonimmediate_operand" ""))]
1794   "TARGET_64BIT || TARGET_SSE"
1795 {
1796   if (TARGET_64BIT)
1797     ix86_expand_move (TImode, operands);
1798   else if (push_operand (operands[0], TImode))
1799     ix86_expand_push (TImode, operands[1]);
1800   else
1801     ix86_expand_vector_move (TImode, operands);
1802   DONE;
1803 })
1804
1805 ;; This expands to what emit_move_complex would generate if we didn't
1806 ;; have a movti pattern.  Having this avoids problems with reload on
1807 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1808 ;; to have around all the time.
1809 (define_expand "movcdi"
1810   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1811         (match_operand:CDI 1 "general_operand" ""))]
1812   ""
1813 {
1814   if (push_operand (operands[0], CDImode))
1815     emit_move_complex_push (CDImode, operands[0], operands[1]);
1816   else
1817     emit_move_complex_parts (operands[0], operands[1]);
1818   DONE;
1819 })
1820
1821 (define_expand "mov<mode>"
1822   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1823         (match_operand:SWI1248x 1 "general_operand" ""))]
1824   ""
1825   "ix86_expand_move (<MODE>mode, operands); DONE;")
1826
1827 (define_insn "*mov<mode>_xor"
1828   [(set (match_operand:SWI48 0 "register_operand" "=r")
1829         (match_operand:SWI48 1 "const0_operand" ""))
1830    (clobber (reg:CC FLAGS_REG))]
1831   "reload_completed"
1832   "xor{l}\t%k0, %k0"
1833   [(set_attr "type" "alu1")
1834    (set_attr "mode" "SI")
1835    (set_attr "length_immediate" "0")])
1836
1837 (define_insn "*mov<mode>_or"
1838   [(set (match_operand:SWI48 0 "register_operand" "=r")
1839         (match_operand:SWI48 1 "const_int_operand" ""))
1840    (clobber (reg:CC FLAGS_REG))]
1841   "reload_completed
1842    && operands[1] == constm1_rtx"
1843   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1844   [(set_attr "type" "alu1")
1845    (set_attr "mode" "<MODE>")
1846    (set_attr "length_immediate" "1")])
1847
1848 (define_insn "*movoi_internal_avx"
1849   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1850         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1851   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852 {
1853   switch (which_alternative)
1854     {
1855     case 0:
1856       return "vxorps\t%0, %0, %0";
1857     case 1:
1858     case 2:
1859       if (misaligned_operand (operands[0], OImode)
1860           || misaligned_operand (operands[1], OImode))
1861         return "vmovdqu\t{%1, %0|%0, %1}";
1862       else
1863         return "vmovdqa\t{%1, %0|%0, %1}";
1864     default:
1865       gcc_unreachable ();
1866     }
1867 }
1868   [(set_attr "type" "sselog1,ssemov,ssemov")
1869    (set_attr "prefix" "vex")
1870    (set_attr "mode" "OI")])
1871
1872 (define_insn "*movti_internal_rex64"
1873   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1874         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1875   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1876 {
1877   switch (which_alternative)
1878     {
1879     case 0:
1880     case 1:
1881       return "#";
1882     case 2:
1883       if (get_attr_mode (insn) == MODE_V4SF)
1884         return "%vxorps\t%0, %d0";
1885       else
1886         return "%vpxor\t%0, %d0";
1887     case 3:
1888     case 4:
1889       /* TDmode values are passed as TImode on the stack.  Moving them
1890          to stack may result in unaligned memory access.  */
1891       if (misaligned_operand (operands[0], TImode)
1892           || misaligned_operand (operands[1], TImode))
1893         {
1894           if (get_attr_mode (insn) == MODE_V4SF)
1895             return "%vmovups\t{%1, %0|%0, %1}";
1896           else
1897             return "%vmovdqu\t{%1, %0|%0, %1}";
1898         }
1899       else
1900         {
1901           if (get_attr_mode (insn) == MODE_V4SF)
1902             return "%vmovaps\t{%1, %0|%0, %1}";
1903           else
1904             return "%vmovdqa\t{%1, %0|%0, %1}";
1905         }
1906     default:
1907       gcc_unreachable ();
1908     }
1909 }
1910   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1912    (set (attr "mode")
1913         (cond [(eq_attr "alternative" "2,3")
1914                  (if_then_else
1915                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1916                        (const_int 0))
1917                    (const_string "V4SF")
1918                    (const_string "TI"))
1919                (eq_attr "alternative" "4")
1920                  (if_then_else
1921                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1922                             (const_int 0))
1923                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1924                             (const_int 0)))
1925                    (const_string "V4SF")
1926                    (const_string "TI"))]
1927                (const_string "DI")))])
1928
1929 (define_split
1930   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931         (match_operand:TI 1 "general_operand" ""))]
1932   "reload_completed
1933    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1934   [(const_int 0)]
1935   "ix86_split_long_move (operands); DONE;")
1936
1937 (define_insn "*movti_internal_sse"
1938   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940   "TARGET_SSE && !TARGET_64BIT
1941    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 {
1943   switch (which_alternative)
1944     {
1945     case 0:
1946       if (get_attr_mode (insn) == MODE_V4SF)
1947         return "%vxorps\t%0, %d0";
1948       else
1949         return "%vpxor\t%0, %d0";
1950     case 1:
1951     case 2:
1952       /* TDmode values are passed as TImode on the stack.  Moving them
1953          to stack may result in unaligned memory access.  */
1954       if (misaligned_operand (operands[0], TImode)
1955           || misaligned_operand (operands[1], TImode))
1956         {
1957           if (get_attr_mode (insn) == MODE_V4SF)
1958             return "%vmovups\t{%1, %0|%0, %1}";
1959           else
1960             return "%vmovdqu\t{%1, %0|%0, %1}";
1961         }
1962       else
1963         {
1964           if (get_attr_mode (insn) == MODE_V4SF)
1965             return "%vmovaps\t{%1, %0|%0, %1}";
1966           else
1967             return "%vmovdqa\t{%1, %0|%0, %1}";
1968         }
1969     default:
1970       gcc_unreachable ();
1971     }
1972 }
1973   [(set_attr "type" "sselog1,ssemov,ssemov")
1974    (set_attr "prefix" "maybe_vex")
1975    (set (attr "mode")
1976         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1977                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1978                         (const_int 0)))
1979                  (const_string "V4SF")
1980                (and (eq_attr "alternative" "2")
1981                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1982                         (const_int 0)))
1983                  (const_string "V4SF")]
1984               (const_string "TI")))])
1985
1986 (define_insn "*movdi_internal_rex64"
1987   [(set (match_operand:DI 0 "nonimmediate_operand"
1988           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1989         (match_operand:DI 1 "general_operand"
1990           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1991   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 {
1993   switch (get_attr_type (insn))
1994     {
1995     case TYPE_SSECVT:
1996       if (SSE_REG_P (operands[0]))
1997         return "movq2dq\t{%1, %0|%0, %1}";
1998       else
1999         return "movdq2q\t{%1, %0|%0, %1}";
2000
2001     case TYPE_SSEMOV:
2002       if (get_attr_mode (insn) == MODE_TI)
2003         return "%vmovdqa\t{%1, %0|%0, %1}";
2004       /* Handle broken assemblers that require movd instead of movq.  */
2005       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006         return "%vmovd\t{%1, %0|%0, %1}";
2007       else
2008         return "%vmovq\t{%1, %0|%0, %1}";
2009
2010     case TYPE_MMXMOV:
2011       /* Handle broken assemblers that require movd instead of movq.  */
2012       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2013         return "movd\t{%1, %0|%0, %1}";
2014       else
2015         return "movq\t{%1, %0|%0, %1}";
2016
2017     case TYPE_SSELOG1:
2018       return "%vpxor\t%0, %d0";
2019
2020     case TYPE_MMX:
2021       return "pxor\t%0, %0";
2022
2023     case TYPE_MULTI:
2024       return "#";
2025
2026     case TYPE_LEA:
2027       return "lea{q}\t{%a1, %0|%0, %a1}";
2028
2029     default:
2030       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2031       if (get_attr_mode (insn) == MODE_SI)
2032         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2033       else if (which_alternative == 2)
2034         return "movabs{q}\t{%1, %0|%0, %1}";
2035       else
2036         return "mov{q}\t{%1, %0|%0, %1}";
2037     }
2038 }
2039   [(set (attr "type")
2040      (cond [(eq_attr "alternative" "5")
2041               (const_string "mmx")
2042             (eq_attr "alternative" "6,7,8,9,10")
2043               (const_string "mmxmov")
2044             (eq_attr "alternative" "11")
2045               (const_string "sselog1")
2046             (eq_attr "alternative" "12,13,14,15,16")
2047               (const_string "ssemov")
2048             (eq_attr "alternative" "17,18")
2049               (const_string "ssecvt")
2050             (eq_attr "alternative" "4")
2051               (const_string "multi")
2052             (match_operand:DI 1 "pic_32bit_operand" "")
2053               (const_string "lea")
2054            ]
2055            (const_string "imov")))
2056    (set (attr "modrm")
2057      (if_then_else
2058        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2059          (const_string "0")
2060          (const_string "*")))
2061    (set (attr "length_immediate")
2062      (if_then_else
2063        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2064          (const_string "8")
2065          (const_string "*")))
2066    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2067    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2068    (set (attr "prefix")
2069      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2070        (const_string "maybe_vex")
2071        (const_string "orig")))
2072    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2073
2074 ;; Convert impossible stores of immediate to existing instructions.
2075 ;; First try to get scratch register and go through it.  In case this
2076 ;; fails, move by 32bit parts.
2077 (define_peephole2
2078   [(match_scratch:DI 2 "r")
2079    (set (match_operand:DI 0 "memory_operand" "")
2080         (match_operand:DI 1 "immediate_operand" ""))]
2081   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2082    && !x86_64_immediate_operand (operands[1], DImode)"
2083   [(set (match_dup 2) (match_dup 1))
2084    (set (match_dup 0) (match_dup 2))])
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2089 (define_peephole2
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094   [(set (match_dup 2) (match_dup 3))
2095    (set (match_dup 4) (match_dup 5))]
2096   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2097
2098 (define_split
2099   [(set (match_operand:DI 0 "memory_operand" "")
2100         (match_operand:DI 1 "immediate_operand" ""))]
2101   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2102                     ? epilogue_completed : reload_completed)
2103    && !symbolic_operand (operands[1], DImode)
2104    && !x86_64_immediate_operand (operands[1], DImode)"
2105   [(set (match_dup 2) (match_dup 3))
2106    (set (match_dup 4) (match_dup 5))]
2107   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2108
2109 (define_insn "*movdi_internal"
2110   [(set (match_operand:DI 0 "nonimmediate_operand"
2111                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2112         (match_operand:DI 1 "general_operand"
2113                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2114   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2115   "@
2116    #
2117    #
2118    pxor\t%0, %0
2119    movq\t{%1, %0|%0, %1}
2120    movq\t{%1, %0|%0, %1}
2121    %vpxor\t%0, %d0
2122    %vmovq\t{%1, %0|%0, %1}
2123    %vmovdqa\t{%1, %0|%0, %1}
2124    %vmovq\t{%1, %0|%0, %1}
2125    xorps\t%0, %0
2126    movlps\t{%1, %0|%0, %1}
2127    movaps\t{%1, %0|%0, %1}
2128    movlps\t{%1, %0|%0, %1}"
2129   [(set (attr "isa")
2130      (if_then_else (eq_attr "alternative" "9,10,11,12")
2131        (const_string "noavx")
2132        (const_string "base")))
2133    (set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2134    (set (attr "prefix")
2135      (if_then_else (eq_attr "alternative" "5,6,7,8")
2136        (const_string "maybe_vex")
2137        (const_string "orig")))
2138    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2139
2140 (define_split
2141   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2142         (match_operand:DI 1 "general_operand" ""))]
2143   "!TARGET_64BIT && reload_completed
2144    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2145    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2146   [(const_int 0)]
2147   "ix86_split_long_move (operands); DONE;")
2148
2149 (define_insn "*movsi_internal"
2150   [(set (match_operand:SI 0 "nonimmediate_operand"
2151                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2152         (match_operand:SI 1 "general_operand"
2153                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2154   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2155 {
2156   switch (get_attr_type (insn))
2157     {
2158     case TYPE_SSELOG1:
2159       if (get_attr_mode (insn) == MODE_TI)
2160         return "%vpxor\t%0, %d0";
2161       return "%vxorps\t%0, %d0";
2162
2163     case TYPE_SSEMOV:
2164       switch (get_attr_mode (insn))
2165         {
2166         case MODE_TI:
2167           return "%vmovdqa\t{%1, %0|%0, %1}";
2168         case MODE_V4SF:
2169           return "%vmovaps\t{%1, %0|%0, %1}";
2170         case MODE_SI:
2171           return "%vmovd\t{%1, %0|%0, %1}";
2172         case MODE_SF:
2173           return "%vmovss\t{%1, %0|%0, %1}";
2174         default:
2175           gcc_unreachable ();
2176         }
2177
2178     case TYPE_MMX:
2179       return "pxor\t%0, %0";
2180
2181     case TYPE_MMXMOV:
2182       if (get_attr_mode (insn) == MODE_DI)
2183         return "movq\t{%1, %0|%0, %1}";
2184       return "movd\t{%1, %0|%0, %1}";
2185
2186     case TYPE_LEA:
2187       return "lea{l}\t{%a1, %0|%0, %a1}";
2188
2189     default:
2190       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2191       return "mov{l}\t{%1, %0|%0, %1}";
2192     }
2193 }
2194   [(set (attr "type")
2195      (cond [(eq_attr "alternative" "2")
2196               (const_string "mmx")
2197             (eq_attr "alternative" "3,4,5")
2198               (const_string "mmxmov")
2199             (eq_attr "alternative" "6")
2200               (const_string "sselog1")
2201             (eq_attr "alternative" "7,8,9,10,11")
2202               (const_string "ssemov")
2203             (match_operand:DI 1 "pic_32bit_operand" "")
2204               (const_string "lea")
2205            ]
2206            (const_string "imov")))
2207    (set (attr "prefix")
2208      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2209        (const_string "orig")
2210        (const_string "maybe_vex")))
2211    (set (attr "prefix_data16")
2212      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2213        (const_string "1")
2214        (const_string "*")))
2215    (set (attr "mode")
2216      (cond [(eq_attr "alternative" "2,3")
2217               (const_string "DI")
2218             (eq_attr "alternative" "6,7")
2219               (if_then_else
2220                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2221                 (const_string "V4SF")
2222                 (const_string "TI"))
2223             (and (eq_attr "alternative" "8,9,10,11")
2224                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2225               (const_string "SF")
2226            ]
2227            (const_string "SI")))])
2228
2229 (define_insn "*movhi_internal"
2230   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2231         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2232   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2233 {
2234   switch (get_attr_type (insn))
2235     {
2236     case TYPE_IMOVX:
2237       /* movzwl is faster than movw on p2 due to partial word stalls,
2238          though not as fast as an aligned movl.  */
2239       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2240     default:
2241       if (get_attr_mode (insn) == MODE_SI)
2242         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2243       else
2244         return "mov{w}\t{%1, %0|%0, %1}";
2245     }
2246 }
2247   [(set (attr "type")
2248      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2249                 (const_int 0))
2250               (const_string "imov")
2251             (and (eq_attr "alternative" "0")
2252                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2253                           (const_int 0))
2254                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2255                           (const_int 0))))
2256               (const_string "imov")
2257             (and (eq_attr "alternative" "1,2")
2258                  (match_operand:HI 1 "aligned_operand" ""))
2259               (const_string "imov")
2260             (and (ne (symbol_ref "TARGET_MOVX")
2261                      (const_int 0))
2262                  (eq_attr "alternative" "0,2"))
2263               (const_string "imovx")
2264            ]
2265            (const_string "imov")))
2266     (set (attr "mode")
2267       (cond [(eq_attr "type" "imovx")
2268                (const_string "SI")
2269              (and (eq_attr "alternative" "1,2")
2270                   (match_operand:HI 1 "aligned_operand" ""))
2271                (const_string "SI")
2272              (and (eq_attr "alternative" "0")
2273                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2274                            (const_int 0))
2275                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2276                            (const_int 0))))
2277                (const_string "SI")
2278             ]
2279             (const_string "HI")))])
2280
2281 ;; Situation is quite tricky about when to choose full sized (SImode) move
2282 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2283 ;; partial register dependency machines (such as AMD Athlon), where QImode
2284 ;; moves issue extra dependency and for partial register stalls machines
2285 ;; that don't use QImode patterns (and QImode move cause stall on the next
2286 ;; instruction).
2287 ;;
2288 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2289 ;; register stall machines with, where we use QImode instructions, since
2290 ;; partial register stall can be caused there.  Then we use movzx.
2291 (define_insn "*movqi_internal"
2292   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2293         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2294   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2295 {
2296   switch (get_attr_type (insn))
2297     {
2298     case TYPE_IMOVX:
2299       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2300       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2301     default:
2302       if (get_attr_mode (insn) == MODE_SI)
2303         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2304       else
2305         return "mov{b}\t{%1, %0|%0, %1}";
2306     }
2307 }
2308   [(set (attr "type")
2309      (cond [(and (eq_attr "alternative" "5")
2310                  (not (match_operand:QI 1 "aligned_operand" "")))
2311               (const_string "imovx")
2312             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2313                 (const_int 0))
2314               (const_string "imov")
2315             (and (eq_attr "alternative" "3")
2316                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2317                           (const_int 0))
2318                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2319                           (const_int 0))))
2320               (const_string "imov")
2321             (eq_attr "alternative" "3,5")
2322               (const_string "imovx")
2323             (and (ne (symbol_ref "TARGET_MOVX")
2324                      (const_int 0))
2325                  (eq_attr "alternative" "2"))
2326               (const_string "imovx")
2327            ]
2328            (const_string "imov")))
2329    (set (attr "mode")
2330       (cond [(eq_attr "alternative" "3,4,5")
2331                (const_string "SI")
2332              (eq_attr "alternative" "6")
2333                (const_string "QI")
2334              (eq_attr "type" "imovx")
2335                (const_string "SI")
2336              (and (eq_attr "type" "imov")
2337                   (and (eq_attr "alternative" "0,1")
2338                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2339                                 (const_int 0))
2340                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2341                                      (const_int 0))
2342                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2343                                      (const_int 0))))))
2344                (const_string "SI")
2345              ;; Avoid partial register stalls when not using QImode arithmetic
2346              (and (eq_attr "type" "imov")
2347                   (and (eq_attr "alternative" "0,1")
2348                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2349                                 (const_int 0))
2350                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2351                                 (const_int 0)))))
2352                (const_string "SI")
2353            ]
2354            (const_string "QI")))])
2355
2356 ;; Stores and loads of ax to arbitrary constant address.
2357 ;; We fake an second form of instruction to force reload to load address
2358 ;; into register when rax is not available
2359 (define_insn "*movabs<mode>_1"
2360   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2361         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2362   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2363   "@
2364    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2365    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2366   [(set_attr "type" "imov")
2367    (set_attr "modrm" "0,*")
2368    (set_attr "length_address" "8,0")
2369    (set_attr "length_immediate" "0,*")
2370    (set_attr "memory" "store")
2371    (set_attr "mode" "<MODE>")])
2372
2373 (define_insn "*movabs<mode>_2"
2374   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2375         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2376   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2377   "@
2378    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2379    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2380   [(set_attr "type" "imov")
2381    (set_attr "modrm" "0,*")
2382    (set_attr "length_address" "8,0")
2383    (set_attr "length_immediate" "0")
2384    (set_attr "memory" "load")
2385    (set_attr "mode" "<MODE>")])
2386
2387 (define_insn "*swap<mode>"
2388   [(set (match_operand:SWI48 0 "register_operand" "+r")
2389         (match_operand:SWI48 1 "register_operand" "+r"))
2390    (set (match_dup 1)
2391         (match_dup 0))]
2392   ""
2393   "xchg{<imodesuffix>}\t%1, %0"
2394   [(set_attr "type" "imov")
2395    (set_attr "mode" "<MODE>")
2396    (set_attr "pent_pair" "np")
2397    (set_attr "athlon_decode" "vector")
2398    (set_attr "amdfam10_decode" "double")
2399    (set_attr "bdver1_decode" "double")])
2400
2401 (define_insn "*swap<mode>_1"
2402   [(set (match_operand:SWI12 0 "register_operand" "+r")
2403         (match_operand:SWI12 1 "register_operand" "+r"))
2404    (set (match_dup 1)
2405         (match_dup 0))]
2406   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2407   "xchg{l}\t%k1, %k0"
2408   [(set_attr "type" "imov")
2409    (set_attr "mode" "SI")
2410    (set_attr "pent_pair" "np")
2411    (set_attr "athlon_decode" "vector")
2412    (set_attr "amdfam10_decode" "double")
2413    (set_attr "bdver1_decode" "double")])
2414
2415 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2416 ;; is disabled for AMDFAM10
2417 (define_insn "*swap<mode>_2"
2418   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2419         (match_operand:SWI12 1 "register_operand" "+<r>"))
2420    (set (match_dup 1)
2421         (match_dup 0))]
2422   "TARGET_PARTIAL_REG_STALL"
2423   "xchg{<imodesuffix>}\t%1, %0"
2424   [(set_attr "type" "imov")
2425    (set_attr "mode" "<MODE>")
2426    (set_attr "pent_pair" "np")
2427    (set_attr "athlon_decode" "vector")])
2428
2429 (define_expand "movstrict<mode>"
2430   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2431         (match_operand:SWI12 1 "general_operand" ""))]
2432   ""
2433 {
2434   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2435     FAIL;
2436   if (GET_CODE (operands[0]) == SUBREG
2437       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2438     FAIL;
2439   /* Don't generate memory->memory moves, go through a register */
2440   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2441     operands[1] = force_reg (<MODE>mode, operands[1]);
2442 })
2443
2444 (define_insn "*movstrict<mode>_1"
2445   [(set (strict_low_part
2446           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2447         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2448   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2451   [(set_attr "type" "imov")
2452    (set_attr "mode" "<MODE>")])
2453
2454 (define_insn "*movstrict<mode>_xor"
2455   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2456         (match_operand:SWI12 1 "const0_operand" ""))
2457    (clobber (reg:CC FLAGS_REG))]
2458   "reload_completed"
2459   "xor{<imodesuffix>}\t%0, %0"
2460   [(set_attr "type" "alu1")
2461    (set_attr "mode" "<MODE>")
2462    (set_attr "length_immediate" "0")])
2463
2464 (define_insn "*mov<mode>_extv_1"
2465   [(set (match_operand:SWI24 0 "register_operand" "=R")
2466         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2467                             (const_int 8)
2468                             (const_int 8)))]
2469   ""
2470   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2471   [(set_attr "type" "imovx")
2472    (set_attr "mode" "SI")])
2473
2474 (define_insn "*movqi_extv_1_rex64"
2475   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2476         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2477                          (const_int 8)
2478                          (const_int 8)))]
2479   "TARGET_64BIT"
2480 {
2481   switch (get_attr_type (insn))
2482     {
2483     case TYPE_IMOVX:
2484       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2485     default:
2486       return "mov{b}\t{%h1, %0|%0, %h1}";
2487     }
2488 }
2489   [(set (attr "type")
2490      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2491                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2492                              (ne (symbol_ref "TARGET_MOVX")
2493                                  (const_int 0))))
2494         (const_string "imovx")
2495         (const_string "imov")))
2496    (set (attr "mode")
2497      (if_then_else (eq_attr "type" "imovx")
2498         (const_string "SI")
2499         (const_string "QI")))])
2500
2501 (define_insn "*movqi_extv_1"
2502   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2503         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2504                          (const_int 8)
2505                          (const_int 8)))]
2506   "!TARGET_64BIT"
2507 {
2508   switch (get_attr_type (insn))
2509     {
2510     case TYPE_IMOVX:
2511       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2512     default:
2513       return "mov{b}\t{%h1, %0|%0, %h1}";
2514     }
2515 }
2516   [(set (attr "type")
2517      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2518                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2519                              (ne (symbol_ref "TARGET_MOVX")
2520                                  (const_int 0))))
2521         (const_string "imovx")
2522         (const_string "imov")))
2523    (set (attr "mode")
2524      (if_then_else (eq_attr "type" "imovx")
2525         (const_string "SI")
2526         (const_string "QI")))])
2527
2528 (define_insn "*mov<mode>_extzv_1"
2529   [(set (match_operand:SWI48 0 "register_operand" "=R")
2530         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2531                             (const_int 8)
2532                             (const_int 8)))]
2533   ""
2534   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535   [(set_attr "type" "imovx")
2536    (set_attr "mode" "SI")])
2537
2538 (define_insn "*movqi_extzv_2_rex64"
2539   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2540         (subreg:QI
2541           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2542                            (const_int 8)
2543                            (const_int 8)) 0))]
2544   "TARGET_64BIT"
2545 {
2546   switch (get_attr_type (insn))
2547     {
2548     case TYPE_IMOVX:
2549       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2550     default:
2551       return "mov{b}\t{%h1, %0|%0, %h1}";
2552     }
2553 }
2554   [(set (attr "type")
2555      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2556                         (ne (symbol_ref "TARGET_MOVX")
2557                             (const_int 0)))
2558         (const_string "imovx")
2559         (const_string "imov")))
2560    (set (attr "mode")
2561      (if_then_else (eq_attr "type" "imovx")
2562         (const_string "SI")
2563         (const_string "QI")))])
2564
2565 (define_insn "*movqi_extzv_2"
2566   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2567         (subreg:QI
2568           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2569                            (const_int 8)
2570                            (const_int 8)) 0))]
2571   "!TARGET_64BIT"
2572 {
2573   switch (get_attr_type (insn))
2574     {
2575     case TYPE_IMOVX:
2576       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2577     default:
2578       return "mov{b}\t{%h1, %0|%0, %h1}";
2579     }
2580 }
2581   [(set (attr "type")
2582      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2583                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2584                              (ne (symbol_ref "TARGET_MOVX")
2585                                  (const_int 0))))
2586         (const_string "imovx")
2587         (const_string "imov")))
2588    (set (attr "mode")
2589      (if_then_else (eq_attr "type" "imovx")
2590         (const_string "SI")
2591         (const_string "QI")))])
2592
2593 (define_expand "mov<mode>_insv_1"
2594   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2595                             (const_int 8)
2596                             (const_int 8))
2597         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2598
2599 (define_insn "*mov<mode>_insv_1_rex64"
2600   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2601                              (const_int 8)
2602                              (const_int 8))
2603         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2604   "TARGET_64BIT"
2605   "mov{b}\t{%b1, %h0|%h0, %b1}"
2606   [(set_attr "type" "imov")
2607    (set_attr "mode" "QI")])
2608
2609 (define_insn "*movsi_insv_1"
2610   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611                          (const_int 8)
2612                          (const_int 8))
2613         (match_operand:SI 1 "general_operand" "Qmn"))]
2614   "!TARGET_64BIT"
2615   "mov{b}\t{%b1, %h0|%h0, %b1}"
2616   [(set_attr "type" "imov")
2617    (set_attr "mode" "QI")])
2618
2619 (define_insn "*movqi_insv_2"
2620   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621                          (const_int 8)
2622                          (const_int 8))
2623         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2624                      (const_int 8)))]
2625   ""
2626   "mov{b}\t{%h1, %h0|%h0, %h1}"
2627   [(set_attr "type" "imov")
2628    (set_attr "mode" "QI")])
2629 \f
2630 ;; Floating point push instructions.
2631
2632 (define_insn "*pushtf"
2633   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2634         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2635   "TARGET_SSE2"
2636 {
2637   /* This insn should be already split before reg-stack.  */
2638   gcc_unreachable ();
2639 }
2640   [(set_attr "type" "multi")
2641    (set_attr "unit" "sse,*,*")
2642    (set_attr "mode" "TF,SI,SI")])
2643
2644 (define_split
2645   [(set (match_operand:TF 0 "push_operand" "")
2646         (match_operand:TF 1 "sse_reg_operand" ""))]
2647   "TARGET_SSE2 && reload_completed"
2648   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2649    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2650
2651 (define_split
2652   [(set (match_operand:TF 0 "push_operand" "")
2653         (match_operand:TF 1 "general_operand" ""))]
2654   "TARGET_SSE2 && reload_completed
2655    && !SSE_REG_P (operands[1])"
2656   [(const_int 0)]
2657   "ix86_split_long_move (operands); DONE;")
2658
2659 (define_insn "*pushxf"
2660   [(set (match_operand:XF 0 "push_operand" "=<,<")
2661         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2662   "optimize_function_for_speed_p (cfun)"
2663 {
2664   /* This insn should be already split before reg-stack.  */
2665   gcc_unreachable ();
2666 }
2667   [(set_attr "type" "multi")
2668    (set_attr "unit" "i387,*")
2669    (set_attr "mode" "XF,SI")])
2670
2671 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2673 ;; Pushing using integer instructions is longer except for constants
2674 ;; and direct memory references (assuming that any given constant is pushed
2675 ;; only once, but this ought to be handled elsewhere).
2676
2677 (define_insn "*pushxf_nointeger"
2678   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2679         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2680   "optimize_function_for_size_p (cfun)"
2681 {
2682   /* This insn should be already split before reg-stack.  */
2683   gcc_unreachable ();
2684 }
2685   [(set_attr "type" "multi")
2686    (set_attr "unit" "i387,*,*")
2687    (set_attr "mode" "XF,SI,SI")])
2688
2689 (define_split
2690   [(set (match_operand:XF 0 "push_operand" "")
2691         (match_operand:XF 1 "fp_register_operand" ""))]
2692   "reload_completed"
2693   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2694    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2695   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2696
2697 (define_split
2698   [(set (match_operand:XF 0 "push_operand" "")
2699         (match_operand:XF 1 "general_operand" ""))]
2700   "reload_completed
2701    && !FP_REG_P (operands[1])"
2702   [(const_int 0)]
2703   "ix86_split_long_move (operands); DONE;")
2704
2705 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter.
2708
2709 (define_insn "*pushdf"
2710   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2711         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2712   ""
2713 {
2714   /* This insn should be already split before reg-stack.  */
2715   gcc_unreachable ();
2716 }
2717   [(set_attr "type" "multi")
2718    (set_attr "unit" "i387,*,*")
2719    (set_attr "mode" "DF,SI,DF")])
2720
2721 ;; %%% Kill this when call knows how to work this out.
2722 (define_split
2723   [(set (match_operand:DF 0 "push_operand" "")
2724         (match_operand:DF 1 "any_fp_register_operand" ""))]
2725   "reload_completed"
2726   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2727    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2728
2729 (define_split
2730   [(set (match_operand:DF 0 "push_operand" "")
2731         (match_operand:DF 1 "general_operand" ""))]
2732   "reload_completed
2733    && !ANY_FP_REG_P (operands[1])"
2734   [(const_int 0)]
2735   "ix86_split_long_move (operands); DONE;")
2736
2737 (define_insn "*pushsf_rex64"
2738   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2739         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2740   "TARGET_64BIT"
2741 {
2742   /* Anything else should be already split before reg-stack.  */
2743   gcc_assert (which_alternative == 1);
2744   return "push{q}\t%q1";
2745 }
2746   [(set_attr "type" "multi,push,multi")
2747    (set_attr "unit" "i387,*,*")
2748    (set_attr "mode" "SF,DI,SF")])
2749
2750 (define_insn "*pushsf"
2751   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2752         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2753   "!TARGET_64BIT"
2754 {
2755   /* Anything else should be already split before reg-stack.  */
2756   gcc_assert (which_alternative == 1);
2757   return "push{l}\t%1";
2758 }
2759   [(set_attr "type" "multi,push,multi")
2760    (set_attr "unit" "i387,*,*")
2761    (set_attr "mode" "SF,SI,SF")])
2762
2763 (define_split
2764   [(set (match_operand:SF 0 "push_operand" "")
2765         (match_operand:SF 1 "memory_operand" ""))]
2766   "reload_completed
2767    && MEM_P (operands[1])
2768    && (operands[2] = find_constant_src (insn))"
2769   [(set (match_dup 0)
2770         (match_dup 2))])
2771
2772 ;; %%% Kill this when call knows how to work this out.
2773 (define_split
2774   [(set (match_operand:SF 0 "push_operand" "")
2775         (match_operand:SF 1 "any_fp_register_operand" ""))]
2776   "reload_completed"
2777   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2780 \f
2781 ;; Floating point move instructions.
2782
2783 (define_expand "movtf"
2784   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2785         (match_operand:TF 1 "nonimmediate_operand" ""))]
2786   "TARGET_SSE2"
2787 {
2788   ix86_expand_move (TFmode, operands);
2789   DONE;
2790 })
2791
2792 (define_expand "mov<mode>"
2793   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2794         (match_operand:X87MODEF 1 "general_operand" ""))]
2795   ""
2796   "ix86_expand_move (<MODE>mode, operands); DONE;")
2797
2798 (define_insn "*movtf_internal"
2799   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2800         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2801   "TARGET_SSE2
2802    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2803 {
2804   switch (which_alternative)
2805     {
2806     case 0:
2807     case 1:
2808       if (get_attr_mode (insn) == MODE_V4SF)
2809         return "%vmovaps\t{%1, %0|%0, %1}";
2810       else
2811         return "%vmovdqa\t{%1, %0|%0, %1}";
2812
2813     case 2:
2814       return standard_sse_constant_opcode (insn, operands[1]);
2815
2816     case 3:
2817     case 4:
2818         return "#";
2819
2820     default:
2821       gcc_unreachable ();
2822     }
2823 }
2824   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2825    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2826    (set (attr "mode")
2827         (cond [(eq_attr "alternative" "0,2")
2828                  (if_then_else
2829                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2830                        (const_int 0))
2831                    (const_string "V4SF")
2832                    (const_string "TI"))
2833                (eq_attr "alternative" "1")
2834                  (if_then_else
2835                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2836                             (const_int 0))
2837                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2838                             (const_int 0)))
2839                    (const_string "V4SF")
2840                    (const_string "TI"))]
2841                (const_string "DI")))])
2842
2843 (define_split
2844   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2845         (match_operand:TF 1 "general_operand" ""))]
2846   "reload_completed
2847    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2848   [(const_int 0)]
2849   "ix86_split_long_move (operands); DONE;")
2850
2851 (define_insn "*movxf_internal"
2852   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r  ,o")
2853         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2854   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2855    && (!can_create_pseudo_p ()
2856        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2857        || GET_CODE (operands[1]) != CONST_DOUBLE
2858        || (optimize_function_for_size_p (cfun)
2859            && standard_80387_constant_p (operands[1]) > 0)
2860        || memory_operand (operands[0], XFmode))"
2861 {
2862   switch (which_alternative)
2863     {
2864     case 0:
2865     case 1:
2866       return output_387_reg_move (insn, operands);
2867
2868     case 2:
2869       return standard_80387_constant_opcode (operands[1]);
2870
2871     case 3: case 4:
2872       return "#";
2873     default:
2874       gcc_unreachable ();
2875     }
2876 }
2877   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2878    (set_attr "mode" "XF,XF,XF,SI,SI")])
2879
2880 (define_split
2881   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2882         (match_operand:XF 1 "general_operand" ""))]
2883   "reload_completed
2884    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885    && ! (FP_REG_P (operands[0]) ||
2886          (GET_CODE (operands[0]) == SUBREG
2887           && FP_REG_P (SUBREG_REG (operands[0]))))
2888    && ! (FP_REG_P (operands[1]) ||
2889          (GET_CODE (operands[1]) == SUBREG
2890           && FP_REG_P (SUBREG_REG (operands[1]))))"
2891   [(const_int 0)]
2892   "ix86_split_long_move (operands); DONE;")
2893
2894 (define_insn "*movdf_internal_rex64"
2895   [(set (match_operand:DF 0 "nonimmediate_operand"
2896                 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2897         (match_operand:DF 1 "general_operand"
2898                 "fm,f,G,rm,r,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2899   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2900    && (!can_create_pseudo_p ()
2901        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2902        || GET_CODE (operands[1]) != CONST_DOUBLE
2903        || (optimize_function_for_size_p (cfun)
2904            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2905                 && standard_80387_constant_p (operands[1]) > 0)
2906                || (TARGET_SSE2 && TARGET_SSE_MATH
2907                    && standard_sse_constant_p (operands[1]))))
2908        || memory_operand (operands[0], DFmode))"
2909 {
2910   switch (which_alternative)
2911     {
2912     case 0:
2913     case 1:
2914       return output_387_reg_move (insn, operands);
2915
2916     case 2:
2917       return standard_80387_constant_opcode (operands[1]);
2918
2919     case 3:
2920     case 4:
2921       return "mov{q}\t{%1, %0|%0, %1}";
2922
2923     case 5:
2924       return "movabs{q}\t{%1, %0|%0, %1}";
2925
2926     case 6:
2927       return "#";
2928
2929     case 7:
2930       return standard_sse_constant_opcode (insn, operands[1]);
2931
2932     case 8:
2933     case 9:
2934     case 10:
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 && REG_P (operands[0]) && REG_P (operands[1]))
2953             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2954           else
2955             return "%vmovsd\t{%1, %0|%0, %1}";
2956         case MODE_V1DF:
2957           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2958         case MODE_V2SF:
2959           return "%vmovlps\t{%1, %d0|%d0, %1}";
2960         default:
2961           gcc_unreachable ();
2962         }
2963
2964     case 11:
2965     case 12:
2966       /* Handle broken assemblers that require movd instead of movq.  */
2967       return "%vmovd\t{%1, %0|%0, %1}";
2968
2969     default:
2970       gcc_unreachable();
2971     }
2972 }
2973   [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2974    (set (attr "modrm")
2975      (if_then_else
2976        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2977          (const_string "0")
2978          (const_string "*")))
2979    (set (attr "length_immediate")
2980      (if_then_else
2981        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2982          (const_string "8")
2983          (const_string "*")))
2984    (set (attr "prefix")
2985      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2986        (const_string "orig")
2987        (const_string "maybe_vex")))
2988    (set (attr "prefix_data16")
2989      (if_then_else (eq_attr "mode" "V1DF")
2990        (const_string "1")
2991        (const_string "*")))
2992    (set (attr "mode")
2993         (cond [(eq_attr "alternative" "0,1,2")
2994                  (const_string "DF")
2995                (eq_attr "alternative" "3,4,5,6,11,12")
2996                  (const_string "DI")
2997
2998                /* For SSE1, we have many fewer alternatives.  */
2999                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3000                  (cond [(eq_attr "alternative" "7,8")
3001                           (const_string "V4SF")
3002                        ]
3003                    (const_string "V2SF"))
3004
3005                /* xorps is one byte shorter.  */
3006                (eq_attr "alternative" "7")
3007                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3008                             (const_int 0))
3009                           (const_string "V4SF")
3010                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3011                             (const_int 0))
3012                           (const_string "TI")
3013                        ]
3014                        (const_string "V2DF"))
3015
3016                /* For architectures resolving dependencies on
3017                   whole SSE registers use APD move to break dependency
3018                   chains, otherwise use short move to avoid extra work.
3019
3020                   movaps encodes one byte shorter.  */
3021                (eq_attr "alternative" "8")
3022                  (cond
3023                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3024                         (const_int 0))
3025                       (const_string "V4SF")
3026                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3027                         (const_int 0))
3028                       (const_string "V2DF")
3029                    ]
3030                    (const_string "DF"))
3031                /* For architectures resolving dependencies on register
3032                   parts we may avoid extra work to zero out upper part
3033                   of register.  */
3034                (eq_attr "alternative" "9")
3035                  (if_then_else
3036                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3037                        (const_int 0))
3038                    (const_string "V1DF")
3039                    (const_string "DF"))
3040               ]
3041               (const_string "DF")))])
3042
3043 ;; Possible store forwarding (partial memory) stall in alternative 4.
3044 (define_insn "*movdf_internal"
3045   [(set (match_operand:DF 0 "nonimmediate_operand"
3046                 "=f,m,f,Yd*r  ,o    ,Y2*x,Y2*x,Y2*x,m  ")
3047         (match_operand:DF 1 "general_operand"
3048                 "fm,f,G,Yd*roF,FYd*r,C   ,Y2*x,m   ,Y2*x"))]
3049   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050    && (!can_create_pseudo_p ()
3051        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3052        || GET_CODE (operands[1]) != CONST_DOUBLE
3053        || (!TARGET_INTEGER_DFMODE_MOVES
3054            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3055                 && standard_80387_constant_p (operands[1]) > 0)
3056                || (TARGET_SSE2 && TARGET_SSE_MATH
3057                    && standard_sse_constant_p (operands[1])))
3058            && !memory_operand (operands[0], DFmode))
3059        || ((TARGET_INTEGER_DFMODE_MOVES
3060             || !TARGET_MEMORY_MISMATCH_STALL)
3061            && memory_operand (operands[0], DFmode)))"
3062 {
3063   switch (which_alternative)
3064     {
3065     case 0:
3066     case 1:
3067       return output_387_reg_move (insn, operands);
3068
3069     case 2:
3070       return standard_80387_constant_opcode (operands[1]);
3071
3072     case 3:
3073     case 4:
3074       return "#";
3075
3076     case 5:
3077       return standard_sse_constant_opcode (insn, operands[1]);
3078
3079     case 6:
3080     case 7:
3081     case 8:
3082       switch (get_attr_mode (insn))
3083         {
3084         case MODE_V4SF:
3085           return "%vmovaps\t{%1, %0|%0, %1}";
3086         case MODE_V2DF:
3087           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3088             return "%vmovaps\t{%1, %0|%0, %1}";
3089           else
3090             return "%vmovapd\t{%1, %0|%0, %1}";
3091         case MODE_TI:
3092           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093             return "%vmovaps\t{%1, %0|%0, %1}";
3094           else
3095             return "%vmovdqa\t{%1, %0|%0, %1}";
3096         case MODE_DI:
3097           return "%vmovq\t{%1, %0|%0, %1}";
3098         case MODE_DF:
3099           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3100             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3101           else
3102             return "%vmovsd\t{%1, %0|%0, %1}";
3103         case MODE_V1DF:
3104           if (TARGET_AVX && REG_P (operands[0]))
3105             return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3106           else
3107             return "%vmovlpd\t{%1, %0|%0, %1}";
3108         case MODE_V2SF:
3109           if (TARGET_AVX && REG_P (operands[0]))
3110             return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3111           else
3112             return "%vmovlps\t{%1, %0|%0, %1}";
3113         default:
3114           gcc_unreachable ();
3115         }
3116
3117     default:
3118       gcc_unreachable ();
3119     }
3120 }
3121   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3122    (set (attr "prefix")
3123      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3124        (const_string "orig")
3125        (const_string "maybe_vex")))
3126    (set (attr "prefix_data16")
3127      (if_then_else (eq_attr "mode" "V1DF")
3128        (const_string "1")
3129        (const_string "*")))
3130    (set (attr "mode")
3131         (cond [(eq_attr "alternative" "0,1,2")
3132                  (const_string "DF")
3133                (eq_attr "alternative" "3,4")
3134                  (const_string "SI")
3135
3136                /* For SSE1, we have many fewer alternatives.  */
3137                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138                  (cond [(eq_attr "alternative" "5,6")
3139                           (const_string "V4SF")
3140                        ]
3141                    (const_string "V2SF"))
3142
3143                /* xorps is one byte shorter.  */
3144                (eq_attr "alternative" "5")
3145                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146                             (const_int 0))
3147                           (const_string "V4SF")
3148                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3149                             (const_int 0))
3150                           (const_string "TI")
3151                        ]
3152                        (const_string "V2DF"))
3153
3154                /* For architectures resolving dependencies on
3155                   whole SSE registers use APD move to break dependency
3156                   chains, otherwise use short move to avoid extra work.
3157
3158                   movaps encodes one byte shorter.  */
3159                (eq_attr "alternative" "6")
3160                  (cond
3161                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162                         (const_int 0))
3163                       (const_string "V4SF")
3164                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165                         (const_int 0))
3166                       (const_string "V2DF")
3167                    ]
3168                    (const_string "DF"))
3169                /* For architectures resolving dependencies on register
3170                   parts we may avoid extra work to zero out upper part
3171                   of register.  */
3172                (eq_attr "alternative" "7")
3173                  (if_then_else
3174                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3175                        (const_int 0))
3176                    (const_string "V1DF")
3177                    (const_string "DF"))
3178               ]
3179               (const_string "DF")))])
3180
3181 (define_split
3182   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3183         (match_operand:DF 1 "general_operand" ""))]
3184   "reload_completed
3185    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3186    && ! (ANY_FP_REG_P (operands[0]) ||
3187          (GET_CODE (operands[0]) == SUBREG
3188           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3189    && ! (ANY_FP_REG_P (operands[1]) ||
3190          (GET_CODE (operands[1]) == SUBREG
3191           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3192   [(const_int 0)]
3193   "ix86_split_long_move (operands); DONE;")
3194
3195 (define_insn "*movsf_internal"
3196   [(set (match_operand:SF 0 "nonimmediate_operand"
3197           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3198         (match_operand:SF 1 "general_operand"
3199           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3200   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3201    && (!can_create_pseudo_p ()
3202        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3203        || GET_CODE (operands[1]) != CONST_DOUBLE
3204        || (optimize_function_for_size_p (cfun)
3205            && ((!TARGET_SSE_MATH
3206                 && standard_80387_constant_p (operands[1]) > 0)
3207                || (TARGET_SSE_MATH
3208                    && standard_sse_constant_p (operands[1]))))
3209        || memory_operand (operands[0], SFmode))"
3210 {
3211   switch (which_alternative)
3212     {
3213     case 0:
3214     case 1:
3215       return output_387_reg_move (insn, operands);
3216
3217     case 2:
3218       return standard_80387_constant_opcode (operands[1]);
3219
3220     case 3:
3221     case 4:
3222       return "mov{l}\t{%1, %0|%0, %1}";
3223
3224     case 5:
3225       return standard_sse_constant_opcode (insn, operands[1]);
3226
3227     case 6:
3228       if (get_attr_mode (insn) == MODE_V4SF)
3229         return "%vmovaps\t{%1, %0|%0, %1}";
3230       else
3231         return "%vmovss\t{%1, %d0|%d0, %1}";
3232     case 7:
3233       if (TARGET_AVX && REG_P (operands[1]))
3234         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3235       else
3236         return "%vmovss\t{%1, %0|%0, %1}";
3237     case 8:
3238       return "%vmovss\t{%1, %0|%0, %1}";
3239
3240     case 9: case 10: case 14: case 15:
3241       return "movd\t{%1, %0|%0, %1}";
3242
3243     case 11:
3244       return "movq\t{%1, %0|%0, %1}";
3245
3246     case 12: case 13:
3247       return "%vmovd\t{%1, %0|%0, %1}";
3248
3249     default:
3250       gcc_unreachable ();
3251     }
3252 }
3253   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3254    (set (attr "prefix")
3255      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256        (const_string "maybe_vex")
3257        (const_string "orig")))
3258    (set (attr "mode")
3259         (cond [(eq_attr "alternative" "3,4,9,10")
3260                  (const_string "SI")
3261                (eq_attr "alternative" "5")
3262                  (if_then_else
3263                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3264                                  (const_int 0))
3265                              (ne (symbol_ref "TARGET_SSE2")
3266                                  (const_int 0)))
3267                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3268                             (const_int 0)))
3269                    (const_string "TI")
3270                    (const_string "V4SF"))
3271                /* For architectures resolving dependencies on
3272                   whole SSE registers use APS move to break dependency
3273                   chains, otherwise use short move to avoid extra work.
3274
3275                   Do the same for architectures resolving dependencies on
3276                   the parts.  While in DF mode it is better to always handle
3277                   just register parts, the SF mode is different due to lack
3278                   of instructions to load just part of the register.  It is
3279                   better to maintain the whole registers in single format
3280                   to avoid problems on using packed logical operations.  */
3281                (eq_attr "alternative" "6")
3282                  (if_then_else
3283                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3284                             (const_int 0))
3285                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3286                             (const_int 0)))
3287                    (const_string "V4SF")
3288                    (const_string "SF"))
3289                (eq_attr "alternative" "11")
3290                  (const_string "DI")]
3291                (const_string "SF")))])
3292
3293 (define_split
3294   [(set (match_operand 0 "register_operand" "")
3295         (match_operand 1 "memory_operand" ""))]
3296   "reload_completed
3297    && MEM_P (operands[1])
3298    && (GET_MODE (operands[0]) == TFmode
3299        || GET_MODE (operands[0]) == XFmode
3300        || GET_MODE (operands[0]) == DFmode
3301        || GET_MODE (operands[0]) == SFmode)
3302    && (operands[2] = find_constant_src (insn))"
3303   [(set (match_dup 0) (match_dup 2))]
3304 {
3305   rtx c = operands[2];
3306   rtx r = operands[0];
3307
3308   if (GET_CODE (r) == SUBREG)
3309     r = SUBREG_REG (r);
3310
3311   if (SSE_REG_P (r))
3312     {
3313       if (!standard_sse_constant_p (c))
3314         FAIL;
3315     }
3316   else if (FP_REG_P (r))
3317     {
3318       if (standard_80387_constant_p (c) < 1)
3319         FAIL;
3320     }
3321   else if (MMX_REG_P (r))
3322     FAIL;
3323 })
3324
3325 (define_split
3326   [(set (match_operand 0 "register_operand" "")
3327         (float_extend (match_operand 1 "memory_operand" "")))]
3328   "reload_completed
3329    && MEM_P (operands[1])
3330    && (GET_MODE (operands[0]) == TFmode
3331        || GET_MODE (operands[0]) == XFmode
3332        || GET_MODE (operands[0]) == DFmode
3333        || GET_MODE (operands[0]) == SFmode)
3334    && (operands[2] = find_constant_src (insn))"
3335   [(set (match_dup 0) (match_dup 2))]
3336 {
3337   rtx c = operands[2];
3338   rtx r = operands[0];
3339
3340   if (GET_CODE (r) == SUBREG)
3341     r = SUBREG_REG (r);
3342
3343   if (SSE_REG_P (r))
3344     {
3345       if (!standard_sse_constant_p (c))
3346         FAIL;
3347     }
3348   else if (FP_REG_P (r))
3349     {
3350       if (standard_80387_constant_p (c) < 1)
3351         FAIL;
3352     }
3353   else if (MMX_REG_P (r))
3354     FAIL;
3355 })
3356
3357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3358 (define_split
3359   [(set (match_operand:X87MODEF 0 "register_operand" "")
3360         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3361   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3362    && (standard_80387_constant_p (operands[1]) == 8
3363        || standard_80387_constant_p (operands[1]) == 9)"
3364   [(set (match_dup 0)(match_dup 1))
3365    (set (match_dup 0)
3366         (neg:X87MODEF (match_dup 0)))]
3367 {
3368   REAL_VALUE_TYPE r;
3369
3370   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3371   if (real_isnegzero (&r))
3372     operands[1] = CONST0_RTX (<MODE>mode);
3373   else
3374     operands[1] = CONST1_RTX (<MODE>mode);
3375 })
3376
3377 (define_insn "swapxf"
3378   [(set (match_operand:XF 0 "register_operand" "+f")
3379         (match_operand:XF 1 "register_operand" "+f"))
3380    (set (match_dup 1)
3381         (match_dup 0))]
3382   "TARGET_80387"
3383 {
3384   if (STACK_TOP_P (operands[0]))
3385     return "fxch\t%1";
3386   else
3387     return "fxch\t%0";
3388 }
3389   [(set_attr "type" "fxch")
3390    (set_attr "mode" "XF")])
3391
3392 (define_insn "*swap<mode>"
3393   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3394         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3395    (set (match_dup 1)
3396         (match_dup 0))]
3397   "TARGET_80387 || reload_completed"
3398 {
3399   if (STACK_TOP_P (operands[0]))
3400     return "fxch\t%1";
3401   else
3402     return "fxch\t%0";
3403 }
3404   [(set_attr "type" "fxch")
3405    (set_attr "mode" "<MODE>")])
3406 \f
3407 ;; Zero extension instructions
3408
3409 (define_expand "zero_extendsidi2"
3410   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3411         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3412   ""
3413 {
3414   if (!TARGET_64BIT)
3415     {
3416       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3417       DONE;
3418     }
3419 })
3420
3421 (define_insn "*zero_extendsidi2_rex64"
3422   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3423         (zero_extend:DI
3424          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3425   "TARGET_64BIT"
3426   "@
3427    mov\t{%k1, %k0|%k0, %k1}
3428    #
3429    movd\t{%1, %0|%0, %1}
3430    movd\t{%1, %0|%0, %1}
3431    %vmovd\t{%1, %0|%0, %1}
3432    %vmovd\t{%1, %0|%0, %1}"
3433   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3434    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3435    (set_attr "prefix_0f" "0,*,*,*,*,*")
3436    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3437
3438 (define_split
3439   [(set (match_operand:DI 0 "memory_operand" "")
3440         (zero_extend:DI (match_dup 0)))]
3441   "TARGET_64BIT"
3442   [(set (match_dup 4) (const_int 0))]
3443   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3444
3445 ;; %%% Kill me once multi-word ops are sane.
3446 (define_insn "zero_extendsidi2_1"
3447   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3448         (zero_extend:DI
3449          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3450    (clobber (reg:CC FLAGS_REG))]
3451   "!TARGET_64BIT"
3452   "@
3453    #
3454    #
3455    #
3456    movd\t{%1, %0|%0, %1}
3457    movd\t{%1, %0|%0, %1}
3458    %vmovd\t{%1, %0|%0, %1}
3459    %vmovd\t{%1, %0|%0, %1}"
3460   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3461    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3462    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3463
3464 (define_split
3465   [(set (match_operand:DI 0 "register_operand" "")
3466         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3467    (clobber (reg:CC FLAGS_REG))]
3468   "!TARGET_64BIT && reload_completed
3469    && true_regnum (operands[0]) == true_regnum (operands[1])"
3470   [(set (match_dup 4) (const_int 0))]
3471   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3472
3473 (define_split
3474   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3475         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3476    (clobber (reg:CC FLAGS_REG))]
3477   "!TARGET_64BIT && reload_completed
3478    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3479   [(set (match_dup 3) (match_dup 1))
3480    (set (match_dup 4) (const_int 0))]
3481   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3482
3483 (define_insn "zero_extend<mode>di2"
3484   [(set (match_operand:DI 0 "register_operand" "=r")
3485         (zero_extend:DI
3486          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3487   "TARGET_64BIT"
3488   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3489   [(set_attr "type" "imovx")
3490    (set_attr "mode" "SI")])
3491
3492 (define_expand "zero_extendhisi2"
3493   [(set (match_operand:SI 0 "register_operand" "")
3494         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3495   ""
3496 {
3497   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3498     {
3499       operands[1] = force_reg (HImode, operands[1]);
3500       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3501       DONE;
3502     }
3503 })
3504
3505 (define_insn_and_split "zero_extendhisi2_and"
3506   [(set (match_operand:SI 0 "register_operand" "=r")
3507         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3508    (clobber (reg:CC FLAGS_REG))]
3509   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3510   "#"
3511   "&& reload_completed"
3512   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3513               (clobber (reg:CC FLAGS_REG))])]
3514   ""
3515   [(set_attr "type" "alu1")
3516    (set_attr "mode" "SI")])
3517
3518 (define_insn "*zero_extendhisi2_movzwl"
3519   [(set (match_operand:SI 0 "register_operand" "=r")
3520         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3521   "!TARGET_ZERO_EXTEND_WITH_AND
3522    || optimize_function_for_size_p (cfun)"
3523   "movz{wl|x}\t{%1, %0|%0, %1}"
3524   [(set_attr "type" "imovx")
3525    (set_attr "mode" "SI")])
3526
3527 (define_expand "zero_extendqi<mode>2"
3528   [(parallel
3529     [(set (match_operand:SWI24 0 "register_operand" "")
3530           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3531      (clobber (reg:CC FLAGS_REG))])])
3532
3533 (define_insn "*zero_extendqi<mode>2_and"
3534   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3535         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3536    (clobber (reg:CC FLAGS_REG))]
3537   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3538   "#"
3539   [(set_attr "type" "alu1")
3540    (set_attr "mode" "<MODE>")])
3541
3542 ;; When source and destination does not overlap, clear destination
3543 ;; first and then do the movb
3544 (define_split
3545   [(set (match_operand:SWI24 0 "register_operand" "")
3546         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3547    (clobber (reg:CC FLAGS_REG))]
3548   "reload_completed
3549    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550    && ANY_QI_REG_P (operands[0])
3551    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3552    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3553   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3554 {
3555   operands[2] = gen_lowpart (QImode, operands[0]);
3556   ix86_expand_clear (operands[0]);
3557 })
3558
3559 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3560   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3561         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3562    (clobber (reg:CC FLAGS_REG))]
3563   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3564   "#"
3565   [(set_attr "type" "imovx,alu1")
3566    (set_attr "mode" "<MODE>")])
3567
3568 ;; For the movzbl case strip only the clobber
3569 (define_split
3570   [(set (match_operand:SWI24 0 "register_operand" "")
3571         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3572    (clobber (reg:CC FLAGS_REG))]
3573   "reload_completed
3574    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3575    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3576   [(set (match_dup 0)
3577         (zero_extend:SWI24 (match_dup 1)))])
3578
3579 ; zero extend to SImode to avoid partial register stalls
3580 (define_insn "*zero_extendqi<mode>2_movzbl"
3581   [(set (match_operand:SWI24 0 "register_operand" "=r")
3582         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3583   "reload_completed
3584    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3585   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3586   [(set_attr "type" "imovx")
3587    (set_attr "mode" "SI")])
3588
3589 ;; Rest is handled by single and.
3590 (define_split
3591   [(set (match_operand:SWI24 0 "register_operand" "")
3592         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3593    (clobber (reg:CC FLAGS_REG))]
3594   "reload_completed
3595    && true_regnum (operands[0]) == true_regnum (operands[1])"
3596   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3597               (clobber (reg:CC FLAGS_REG))])])
3598 \f
3599 ;; Sign extension instructions
3600
3601 (define_expand "extendsidi2"
3602   [(set (match_operand:DI 0 "register_operand" "")
3603         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3604   ""
3605 {
3606   if (!TARGET_64BIT)
3607     {
3608       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3609       DONE;
3610     }
3611 })
3612
3613 (define_insn "*extendsidi2_rex64"
3614   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3615         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3616   "TARGET_64BIT"
3617   "@
3618    {cltq|cdqe}
3619    movs{lq|x}\t{%1, %0|%0, %1}"
3620   [(set_attr "type" "imovx")
3621    (set_attr "mode" "DI")
3622    (set_attr "prefix_0f" "0")
3623    (set_attr "modrm" "0,1")])
3624
3625 (define_insn "extendsidi2_1"
3626   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3627         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3628    (clobber (reg:CC FLAGS_REG))
3629    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3630   "!TARGET_64BIT"
3631   "#")
3632
3633 ;; Extend to memory case when source register does die.
3634 (define_split
3635   [(set (match_operand:DI 0 "memory_operand" "")
3636         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3637    (clobber (reg:CC FLAGS_REG))
3638    (clobber (match_operand:SI 2 "register_operand" ""))]
3639   "(reload_completed
3640     && dead_or_set_p (insn, operands[1])
3641     && !reg_mentioned_p (operands[1], operands[0]))"
3642   [(set (match_dup 3) (match_dup 1))
3643    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3644               (clobber (reg:CC FLAGS_REG))])
3645    (set (match_dup 4) (match_dup 1))]
3646   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3647
3648 ;; Extend to memory case when source register does not die.
3649 (define_split
3650   [(set (match_operand:DI 0 "memory_operand" "")
3651         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3652    (clobber (reg:CC FLAGS_REG))
3653    (clobber (match_operand:SI 2 "register_operand" ""))]
3654   "reload_completed"
3655   [(const_int 0)]
3656 {
3657   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3658
3659   emit_move_insn (operands[3], operands[1]);
3660
3661   /* Generate a cltd if possible and doing so it profitable.  */
3662   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3663       && true_regnum (operands[1]) == AX_REG
3664       && true_regnum (operands[2]) == DX_REG)
3665     {
3666       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3667     }
3668   else
3669     {
3670       emit_move_insn (operands[2], operands[1]);
3671       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3672     }
3673   emit_move_insn (operands[4], operands[2]);
3674   DONE;
3675 })
3676
3677 ;; Extend to register case.  Optimize case where source and destination
3678 ;; registers match and cases where we can use cltd.
3679 (define_split
3680   [(set (match_operand:DI 0 "register_operand" "")
3681         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3682    (clobber (reg:CC FLAGS_REG))
3683    (clobber (match_scratch:SI 2 ""))]
3684   "reload_completed"
3685   [(const_int 0)]
3686 {
3687   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3688
3689   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3690     emit_move_insn (operands[3], operands[1]);
3691
3692   /* Generate a cltd if possible and doing so it profitable.  */
3693   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3694       && true_regnum (operands[3]) == AX_REG
3695       && true_regnum (operands[4]) == DX_REG)
3696     {
3697       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3698       DONE;
3699     }
3700
3701   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3702     emit_move_insn (operands[4], operands[1]);
3703
3704   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3705   DONE;
3706 })
3707
3708 (define_insn "extend<mode>di2"
3709   [(set (match_operand:DI 0 "register_operand" "=r")
3710         (sign_extend:DI
3711          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3712   "TARGET_64BIT"
3713   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3714   [(set_attr "type" "imovx")
3715    (set_attr "mode" "DI")])
3716
3717 (define_insn "extendhisi2"
3718   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3719         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3720   ""
3721 {
3722   switch (get_attr_prefix_0f (insn))
3723     {
3724     case 0:
3725       return "{cwtl|cwde}";
3726     default:
3727       return "movs{wl|x}\t{%1, %0|%0, %1}";
3728     }
3729 }
3730   [(set_attr "type" "imovx")
3731    (set_attr "mode" "SI")
3732    (set (attr "prefix_0f")
3733      ;; movsx is short decodable while cwtl is vector decoded.
3734      (if_then_else (and (eq_attr "cpu" "!k6")
3735                         (eq_attr "alternative" "0"))
3736         (const_string "0")
3737         (const_string "1")))
3738    (set (attr "modrm")
3739      (if_then_else (eq_attr "prefix_0f" "0")
3740         (const_string "0")
3741         (const_string "1")))])
3742
3743 (define_insn "*extendhisi2_zext"
3744   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3745         (zero_extend:DI
3746          (sign_extend:SI
3747           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3748   "TARGET_64BIT"
3749 {
3750   switch (get_attr_prefix_0f (insn))
3751     {
3752     case 0:
3753       return "{cwtl|cwde}";
3754     default:
3755       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3756     }
3757 }
3758   [(set_attr "type" "imovx")
3759    (set_attr "mode" "SI")
3760    (set (attr "prefix_0f")
3761      ;; movsx is short decodable while cwtl is vector decoded.
3762      (if_then_else (and (eq_attr "cpu" "!k6")
3763                         (eq_attr "alternative" "0"))
3764         (const_string "0")
3765         (const_string "1")))
3766    (set (attr "modrm")
3767      (if_then_else (eq_attr "prefix_0f" "0")
3768         (const_string "0")
3769         (const_string "1")))])
3770
3771 (define_insn "extendqisi2"
3772   [(set (match_operand:SI 0 "register_operand" "=r")
3773         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3774   ""
3775   "movs{bl|x}\t{%1, %0|%0, %1}"
3776    [(set_attr "type" "imovx")
3777     (set_attr "mode" "SI")])
3778
3779 (define_insn "*extendqisi2_zext"
3780   [(set (match_operand:DI 0 "register_operand" "=r")
3781         (zero_extend:DI
3782           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3783   "TARGET_64BIT"
3784   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3785    [(set_attr "type" "imovx")
3786     (set_attr "mode" "SI")])
3787
3788 (define_insn "extendqihi2"
3789   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3790         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3791   ""
3792 {
3793   switch (get_attr_prefix_0f (insn))
3794     {
3795     case 0:
3796       return "{cbtw|cbw}";
3797     default:
3798       return "movs{bw|x}\t{%1, %0|%0, %1}";
3799     }
3800 }
3801   [(set_attr "type" "imovx")
3802    (set_attr "mode" "HI")
3803    (set (attr "prefix_0f")
3804      ;; movsx is short decodable while cwtl is vector decoded.
3805      (if_then_else (and (eq_attr "cpu" "!k6")
3806                         (eq_attr "alternative" "0"))
3807         (const_string "0")
3808         (const_string "1")))
3809    (set (attr "modrm")
3810      (if_then_else (eq_attr "prefix_0f" "0")
3811         (const_string "0")
3812         (const_string "1")))])
3813 \f
3814 ;; Conversions between float and double.
3815
3816 ;; These are all no-ops in the model used for the 80387.
3817 ;; So just emit moves.
3818
3819 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3820 (define_split
3821   [(set (match_operand:DF 0 "push_operand" "")
3822         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3823   "reload_completed"
3824   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3825    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3826
3827 (define_split
3828   [(set (match_operand:XF 0 "push_operand" "")
3829         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3830   "reload_completed"
3831   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3832    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3833   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3834
3835 (define_expand "extendsfdf2"
3836   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3837         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3838   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3839 {
3840   /* ??? Needed for compress_float_constant since all fp constants
3841      are TARGET_LEGITIMATE_CONSTANT_P.  */
3842   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3843     {
3844       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3845           && standard_80387_constant_p (operands[1]) > 0)
3846         {
3847           operands[1] = simplify_const_unary_operation
3848             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3849           emit_move_insn_1 (operands[0], operands[1]);
3850           DONE;
3851         }
3852       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3853     }
3854 })
3855
3856 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3857    cvtss2sd:
3858       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3859       cvtps2pd xmm2,xmm1
3860    We do the conversion post reload to avoid producing of 128bit spills
3861    that might lead to ICE on 32bit target.  The sequence unlikely combine
3862    anyway.  */
3863 (define_split
3864   [(set (match_operand:DF 0 "register_operand" "")
3865         (float_extend:DF
3866           (match_operand:SF 1 "nonimmediate_operand" "")))]
3867   "TARGET_USE_VECTOR_FP_CONVERTS
3868    && optimize_insn_for_speed_p ()
3869    && reload_completed && SSE_REG_P (operands[0])"
3870    [(set (match_dup 2)
3871          (float_extend:V2DF
3872            (vec_select:V2SF
3873              (match_dup 3)
3874              (parallel [(const_int 0) (const_int 1)]))))]
3875 {
3876   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3877   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3878   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3879      Try to avoid move when unpacking can be done in source.  */
3880   if (REG_P (operands[1]))
3881     {
3882       /* If it is unsafe to overwrite upper half of source, we need
3883          to move to destination and unpack there.  */
3884       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3885            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3886           && true_regnum (operands[0]) != true_regnum (operands[1]))
3887         {
3888           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3889           emit_move_insn (tmp, operands[1]);
3890         }
3891       else
3892         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3893       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3894                                              operands[3]));
3895     }
3896   else
3897     emit_insn (gen_vec_setv4sf_0 (operands[3],
3898                                   CONST0_RTX (V4SFmode), operands[1]));
3899 })
3900
3901 (define_insn "*extendsfdf2_mixed"
3902   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3903         (float_extend:DF
3904           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3905   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3906 {
3907   switch (which_alternative)
3908     {
3909     case 0:
3910     case 1:
3911       return output_387_reg_move (insn, operands);
3912
3913     case 2:
3914       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3915
3916     default:
3917       gcc_unreachable ();
3918     }
3919 }
3920   [(set_attr "type" "fmov,fmov,ssecvt")
3921    (set_attr "prefix" "orig,orig,maybe_vex")
3922    (set_attr "mode" "SF,XF,DF")])
3923
3924 (define_insn "*extendsfdf2_sse"
3925   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3926         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3927   "TARGET_SSE2 && TARGET_SSE_MATH"
3928   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3929   [(set_attr "type" "ssecvt")
3930    (set_attr "prefix" "maybe_vex")
3931    (set_attr "mode" "DF")])
3932
3933 (define_insn "*extendsfdf2_i387"
3934   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3935         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3936   "TARGET_80387"
3937   "* return output_387_reg_move (insn, operands);"
3938   [(set_attr "type" "fmov")
3939    (set_attr "mode" "SF,XF")])
3940
3941 (define_expand "extend<mode>xf2"
3942   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3943         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3944   "TARGET_80387"
3945 {
3946   /* ??? Needed for compress_float_constant since all fp constants
3947      are TARGET_LEGITIMATE_CONSTANT_P.  */
3948   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3949     {
3950       if (standard_80387_constant_p (operands[1]) > 0)
3951         {
3952           operands[1] = simplify_const_unary_operation
3953             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3954           emit_move_insn_1 (operands[0], operands[1]);
3955           DONE;
3956         }
3957       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3958     }
3959 })
3960
3961 (define_insn "*extend<mode>xf2_i387"
3962   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3963         (float_extend:XF
3964           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3965   "TARGET_80387"
3966   "* return output_387_reg_move (insn, operands);"
3967   [(set_attr "type" "fmov")
3968    (set_attr "mode" "<MODE>,XF")])
3969
3970 ;; %%% This seems bad bad news.
3971 ;; This cannot output into an f-reg because there is no way to be sure
3972 ;; of truncating in that case.  Otherwise this is just like a simple move
3973 ;; insn.  So we pretend we can output to a reg in order to get better
3974 ;; register preferencing, but we really use a stack slot.
3975
3976 ;; Conversion from DFmode to SFmode.
3977
3978 (define_expand "truncdfsf2"
3979   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3980         (float_truncate:SF
3981           (match_operand:DF 1 "nonimmediate_operand" "")))]
3982   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3983 {
3984   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3985     ;
3986   else if (flag_unsafe_math_optimizations)
3987     ;
3988   else
3989     {
3990       enum ix86_stack_slot slot = (virtuals_instantiated
3991                                    ? SLOT_TEMP
3992                                    : SLOT_VIRTUAL);
3993       rtx temp = assign_386_stack_local (SFmode, slot);
3994       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3995       DONE;
3996     }
3997 })
3998
3999 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4000    cvtsd2ss:
4001       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4002       cvtpd2ps xmm2,xmm1
4003    We do the conversion post reload to avoid producing of 128bit spills
4004    that might lead to ICE on 32bit target.  The sequence unlikely combine
4005    anyway.  */
4006 (define_split
4007   [(set (match_operand:SF 0 "register_operand" "")
4008         (float_truncate:SF
4009           (match_operand:DF 1 "nonimmediate_operand" "")))]
4010   "TARGET_USE_VECTOR_FP_CONVERTS
4011    && optimize_insn_for_speed_p ()
4012    && reload_completed && SSE_REG_P (operands[0])"
4013    [(set (match_dup 2)
4014          (vec_concat:V4SF
4015            (float_truncate:V2SF
4016              (match_dup 4))
4017            (match_dup 3)))]
4018 {
4019   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4020   operands[3] = CONST0_RTX (V2SFmode);
4021   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4022   /* Use movsd for loading from memory, unpcklpd for registers.
4023      Try to avoid move when unpacking can be done in source, or SSE3
4024      movddup is available.  */
4025   if (REG_P (operands[1]))
4026     {
4027       if (!TARGET_SSE3
4028           && true_regnum (operands[0]) != true_regnum (operands[1])
4029           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4030               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4031         {
4032           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4033           emit_move_insn (tmp, operands[1]);
4034           operands[1] = tmp;
4035         }
4036       else if (!TARGET_SSE3)
4037         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4038       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4039     }
4040   else
4041     emit_insn (gen_sse2_loadlpd (operands[4],
4042                                  CONST0_RTX (V2DFmode), operands[1]));
4043 })
4044
4045 (define_expand "truncdfsf2_with_temp"
4046   [(parallel [(set (match_operand:SF 0 "" "")
4047                    (float_truncate:SF (match_operand:DF 1 "" "")))
4048               (clobber (match_operand:SF 2 "" ""))])])
4049
4050 (define_insn "*truncdfsf_fast_mixed"
4051   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4052         (float_truncate:SF
4053           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4054   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4055 {
4056   switch (which_alternative)
4057     {
4058     case 0:
4059       return output_387_reg_move (insn, operands);
4060     case 1:
4061       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4062     default:
4063       gcc_unreachable ();
4064     }
4065 }
4066   [(set_attr "type" "fmov,ssecvt")
4067    (set_attr "prefix" "orig,maybe_vex")
4068    (set_attr "mode" "SF")])
4069
4070 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4071 ;; because nothing we do here is unsafe.
4072 (define_insn "*truncdfsf_fast_sse"
4073   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4074         (float_truncate:SF
4075           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4076   "TARGET_SSE2 && TARGET_SSE_MATH"
4077   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4078   [(set_attr "type" "ssecvt")
4079    (set_attr "prefix" "maybe_vex")
4080    (set_attr "mode" "SF")])
4081
4082 (define_insn "*truncdfsf_fast_i387"
4083   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4084         (float_truncate:SF
4085           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4086   "TARGET_80387 && flag_unsafe_math_optimizations"
4087   "* return output_387_reg_move (insn, operands);"
4088   [(set_attr "type" "fmov")
4089    (set_attr "mode" "SF")])
4090
4091 (define_insn "*truncdfsf_mixed"
4092   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4093         (float_truncate:SF
4094           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4095    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4096   "TARGET_MIX_SSE_I387"
4097 {
4098   switch (which_alternative)
4099     {
4100     case 0:
4101       return output_387_reg_move (insn, operands);
4102     case 1:
4103       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4104
4105     default:
4106       return "#";
4107     }
4108 }
4109   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4110    (set_attr "unit" "*,*,i387,i387,i387")
4111    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4112    (set_attr "mode" "SF")])
4113
4114 (define_insn "*truncdfsf_i387"
4115   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4116         (float_truncate:SF
4117           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4118    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4119   "TARGET_80387"
4120 {
4121   switch (which_alternative)
4122     {
4123     case 0:
4124       return output_387_reg_move (insn, operands);
4125
4126     default:
4127       return "#";
4128     }
4129 }
4130   [(set_attr "type" "fmov,multi,multi,multi")
4131    (set_attr "unit" "*,i387,i387,i387")
4132    (set_attr "mode" "SF")])
4133
4134 (define_insn "*truncdfsf2_i387_1"
4135   [(set (match_operand:SF 0 "memory_operand" "=m")
4136         (float_truncate:SF
4137           (match_operand:DF 1 "register_operand" "f")))]
4138   "TARGET_80387
4139    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4140    && !TARGET_MIX_SSE_I387"
4141   "* return output_387_reg_move (insn, operands);"
4142   [(set_attr "type" "fmov")
4143    (set_attr "mode" "SF")])
4144
4145 (define_split
4146   [(set (match_operand:SF 0 "register_operand" "")
4147         (float_truncate:SF
4148          (match_operand:DF 1 "fp_register_operand" "")))
4149    (clobber (match_operand 2 "" ""))]
4150   "reload_completed"
4151   [(set (match_dup 2) (match_dup 1))
4152    (set (match_dup 0) (match_dup 2))]
4153   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4154
4155 ;; Conversion from XFmode to {SF,DF}mode
4156
4157 (define_expand "truncxf<mode>2"
4158   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4159                    (float_truncate:MODEF
4160                      (match_operand:XF 1 "register_operand" "")))
4161               (clobber (match_dup 2))])]
4162   "TARGET_80387"
4163 {
4164   if (flag_unsafe_math_optimizations)
4165     {
4166       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4167       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4168       if (reg != operands[0])
4169         emit_move_insn (operands[0], reg);
4170       DONE;
4171     }
4172   else
4173     {
4174       enum ix86_stack_slot slot = (virtuals_instantiated
4175                                    ? SLOT_TEMP
4176                                    : SLOT_VIRTUAL);
4177       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4178     }
4179 })
4180
4181 (define_insn "*truncxfsf2_mixed"
4182   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4183         (float_truncate:SF
4184           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4185    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4186   "TARGET_80387"
4187 {
4188   gcc_assert (!which_alternative);
4189   return output_387_reg_move (insn, operands);
4190 }
4191   [(set_attr "type" "fmov,multi,multi,multi")
4192    (set_attr "unit" "*,i387,i387,i387")
4193    (set_attr "mode" "SF")])
4194
4195 (define_insn "*truncxfdf2_mixed"
4196   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4197         (float_truncate:DF
4198           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4199    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4200   "TARGET_80387"
4201 {
4202   gcc_assert (!which_alternative);
4203   return output_387_reg_move (insn, operands);
4204 }
4205   [(set_attr "type" "fmov,multi,multi,multi")
4206    (set_attr "unit" "*,i387,i387,i387")
4207    (set_attr "mode" "DF")])
4208
4209 (define_insn "truncxf<mode>2_i387_noop"
4210   [(set (match_operand:MODEF 0 "register_operand" "=f")
4211         (float_truncate:MODEF
4212           (match_operand:XF 1 "register_operand" "f")))]
4213   "TARGET_80387 && flag_unsafe_math_optimizations"
4214   "* return output_387_reg_move (insn, operands);"
4215   [(set_attr "type" "fmov")
4216    (set_attr "mode" "<MODE>")])
4217
4218 (define_insn "*truncxf<mode>2_i387"
4219   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4220         (float_truncate:MODEF
4221           (match_operand:XF 1 "register_operand" "f")))]
4222   "TARGET_80387"
4223   "* return output_387_reg_move (insn, operands);"
4224   [(set_attr "type" "fmov")
4225    (set_attr "mode" "<MODE>")])
4226
4227 (define_split
4228   [(set (match_operand:MODEF 0 "register_operand" "")
4229         (float_truncate:MODEF
4230           (match_operand:XF 1 "register_operand" "")))
4231    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4232   "TARGET_80387 && reload_completed"
4233   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4234    (set (match_dup 0) (match_dup 2))])
4235
4236 (define_split
4237   [(set (match_operand:MODEF 0 "memory_operand" "")
4238         (float_truncate:MODEF
4239           (match_operand:XF 1 "register_operand" "")))
4240    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4241   "TARGET_80387"
4242   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387"
4251 {
4252   if (TARGET_FISTTP)
4253    {
4254      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255      DONE;
4256    }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4262               (clobber (reg:CC FLAGS_REG))])]
4263   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265   if (TARGET_FISTTP
4266       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267    {
4268      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269      DONE;
4270    }
4271   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272    {
4273      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275      if (out != operands[0])
4276         emit_move_insn (operands[0], out);
4277      DONE;
4278    }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4286               (clobber (reg:CC FLAGS_REG))])]
4287   "TARGET_80387"
4288 {
4289   if (TARGET_FISTTP)
4290    {
4291      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292      DONE;
4293    }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4299               (clobber (reg:CC FLAGS_REG))])]
4300   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302   if (TARGET_FISTTP
4303       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304    {
4305      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306      DONE;
4307    }
4308   if (SSE_FLOAT_MODE_P (<MODE>mode))
4309    {
4310      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312      if (out != operands[0])
4313         emit_move_insn (operands[0], out);
4314      DONE;
4315    }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323               (clobber (reg:CC FLAGS_REG))])]
4324   "TARGET_80387
4325    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327   if (TARGET_FISTTP)
4328    {
4329      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330      DONE;
4331    }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337   [(parallel
4338     [(set (match_operand:SI 0 "register_operand" "")
4339           (unsigned_fix:SI
4340             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4341      (use (match_dup 2))
4342      (clobber (match_scratch:<ssevecmode> 3 ""))
4343      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4345 {
4346   enum machine_mode mode = <MODE>mode;
4347   enum machine_mode vecmode = <ssevecmode>mode;
4348   REAL_VALUE_TYPE TWO31r;
4349   rtx two31;
4350
4351   if (optimize_insn_for_size_p ())
4352     FAIL;
4353
4354   real_ldexp (&TWO31r, &dconst1, 31);
4355   two31 = const_double_from_real_value (TWO31r, mode);
4356   two31 = ix86_build_const_vector (vecmode, true, two31);
4357   operands[2] = force_reg (vecmode, two31);
4358 })
4359
4360 (define_insn_and_split "*fixuns_trunc<mode>_1"
4361   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4362         (unsigned_fix:SI
4363           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4364    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4365    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4366    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4367   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4368    && optimize_function_for_speed_p (cfun)"
4369   "#"
4370   "&& reload_completed"
4371   [(const_int 0)]
4372 {
4373   ix86_split_convert_uns_si_sse (operands);
4374   DONE;
4375 })
4376
4377 ;; Unsigned conversion to HImode.
4378 ;; Without these patterns, we'll try the unsigned SI conversion which
4379 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4380
4381 (define_expand "fixuns_trunc<mode>hi2"
4382   [(set (match_dup 2)
4383         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4384    (set (match_operand:HI 0 "nonimmediate_operand" "")
4385         (subreg:HI (match_dup 2) 0))]
4386   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4387   "operands[2] = gen_reg_rtx (SImode);")
4388
4389 ;; When SSE is available, it is always faster to use it!
4390 (define_insn "fix_trunc<mode>di_sse"
4391   [(set (match_operand:DI 0 "register_operand" "=r,r")
4392         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4393   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4394    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4395   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4396   [(set_attr "type" "sseicvt")
4397    (set_attr "prefix" "maybe_vex")
4398    (set_attr "prefix_rex" "1")
4399    (set_attr "mode" "<MODE>")
4400    (set_attr "athlon_decode" "double,vector")
4401    (set_attr "amdfam10_decode" "double,double")
4402    (set_attr "bdver1_decode" "double,double")])
4403
4404 (define_insn "fix_trunc<mode>si_sse"
4405   [(set (match_operand:SI 0 "register_operand" "=r,r")
4406         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4407   "SSE_FLOAT_MODE_P (<MODE>mode)
4408    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4409   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4410   [(set_attr "type" "sseicvt")
4411    (set_attr "prefix" "maybe_vex")
4412    (set_attr "mode" "<MODE>")
4413    (set_attr "athlon_decode" "double,vector")
4414    (set_attr "amdfam10_decode" "double,double")
4415    (set_attr "bdver1_decode" "double,double")])
4416
4417 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4418 (define_peephole2
4419   [(set (match_operand:MODEF 0 "register_operand" "")
4420         (match_operand:MODEF 1 "memory_operand" ""))
4421    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422         (fix:SSEMODEI24 (match_dup 0)))]
4423   "TARGET_SHORTEN_X87_SSE
4424    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4425    && peep2_reg_dead_p (2, operands[0])"
4426   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4427
4428 ;; Avoid vector decoded forms of the instruction.
4429 (define_peephole2
4430   [(match_scratch:DF 2 "Y2")
4431    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4434   [(set (match_dup 2) (match_dup 1))
4435    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4436
4437 (define_peephole2
4438   [(match_scratch:SF 2 "x")
4439    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4440         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4441   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4442   [(set (match_dup 2) (match_dup 1))
4443    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4444
4445 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4446   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4447         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4448   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4449    && TARGET_FISTTP
4450    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4451          && (TARGET_64BIT || <MODE>mode != DImode))
4452         && TARGET_SSE_MATH)
4453    && can_create_pseudo_p ()"
4454   "#"
4455   "&& 1"
4456   [(const_int 0)]
4457 {
4458   if (memory_operand (operands[0], VOIDmode))
4459     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4460   else
4461     {
4462       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4463       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4464                                                             operands[1],
4465                                                             operands[2]));
4466     }
4467   DONE;
4468 }
4469   [(set_attr "type" "fisttp")
4470    (set_attr "mode" "<MODE>")])
4471
4472 (define_insn "fix_trunc<mode>_i387_fisttp"
4473   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4474         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4475    (clobber (match_scratch:XF 2 "=&1f"))]
4476   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4477    && TARGET_FISTTP
4478    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4479          && (TARGET_64BIT || <MODE>mode != DImode))
4480         && TARGET_SSE_MATH)"
4481   "* return output_fix_trunc (insn, operands, true);"
4482   [(set_attr "type" "fisttp")
4483    (set_attr "mode" "<MODE>")])
4484
4485 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4486   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4487         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4488    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4489    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4490   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4491    && TARGET_FISTTP
4492    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493         && (TARGET_64BIT || <MODE>mode != DImode))
4494         && TARGET_SSE_MATH)"
4495   "#"
4496   [(set_attr "type" "fisttp")
4497    (set_attr "mode" "<MODE>")])
4498
4499 (define_split
4500   [(set (match_operand:X87MODEI 0 "register_operand" "")
4501         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4502    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4503    (clobber (match_scratch 3 ""))]
4504   "reload_completed"
4505   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4506               (clobber (match_dup 3))])
4507    (set (match_dup 0) (match_dup 2))])
4508
4509 (define_split
4510   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4511         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4512    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4513    (clobber (match_scratch 3 ""))]
4514   "reload_completed"
4515   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4516               (clobber (match_dup 3))])])
4517
4518 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4519 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4520 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4521 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4522 ;; function in i386.c.
4523 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4524   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4525         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4526    (clobber (reg:CC FLAGS_REG))]
4527   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528    && !TARGET_FISTTP
4529    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530          && (TARGET_64BIT || <MODE>mode != DImode))
4531    && can_create_pseudo_p ()"
4532   "#"
4533   "&& 1"
4534   [(const_int 0)]
4535 {
4536   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4537
4538   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4539   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4540   if (memory_operand (operands[0], VOIDmode))
4541     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4542                                          operands[2], operands[3]));
4543   else
4544     {
4545       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4546       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4547                                                      operands[2], operands[3],
4548                                                      operands[4]));
4549     }
4550   DONE;
4551 }
4552   [(set_attr "type" "fistp")
4553    (set_attr "i387_cw" "trunc")
4554    (set_attr "mode" "<MODE>")])
4555
4556 (define_insn "fix_truncdi_i387"
4557   [(set (match_operand:DI 0 "memory_operand" "=m")
4558         (fix:DI (match_operand 1 "register_operand" "f")))
4559    (use (match_operand:HI 2 "memory_operand" "m"))
4560    (use (match_operand:HI 3 "memory_operand" "m"))
4561    (clobber (match_scratch:XF 4 "=&1f"))]
4562   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563    && !TARGET_FISTTP
4564    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4565   "* return output_fix_trunc (insn, operands, false);"
4566   [(set_attr "type" "fistp")
4567    (set_attr "i387_cw" "trunc")
4568    (set_attr "mode" "DI")])
4569
4570 (define_insn "fix_truncdi_i387_with_temp"
4571   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4572         (fix:DI (match_operand 1 "register_operand" "f,f")))
4573    (use (match_operand:HI 2 "memory_operand" "m,m"))
4574    (use (match_operand:HI 3 "memory_operand" "m,m"))
4575    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4576    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4577   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4578    && !TARGET_FISTTP
4579    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4580   "#"
4581   [(set_attr "type" "fistp")
4582    (set_attr "i387_cw" "trunc")
4583    (set_attr "mode" "DI")])
4584
4585 (define_split
4586   [(set (match_operand:DI 0 "register_operand" "")
4587         (fix:DI (match_operand 1 "register_operand" "")))
4588    (use (match_operand:HI 2 "memory_operand" ""))
4589    (use (match_operand:HI 3 "memory_operand" ""))
4590    (clobber (match_operand:DI 4 "memory_operand" ""))
4591    (clobber (match_scratch 5 ""))]
4592   "reload_completed"
4593   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4594               (use (match_dup 2))
4595               (use (match_dup 3))
4596               (clobber (match_dup 5))])
4597    (set (match_dup 0) (match_dup 4))])
4598
4599 (define_split
4600   [(set (match_operand:DI 0 "memory_operand" "")
4601         (fix:DI (match_operand 1 "register_operand" "")))
4602    (use (match_operand:HI 2 "memory_operand" ""))
4603    (use (match_operand:HI 3 "memory_operand" ""))
4604    (clobber (match_operand:DI 4 "memory_operand" ""))
4605    (clobber (match_scratch 5 ""))]
4606   "reload_completed"
4607   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4608               (use (match_dup 2))
4609               (use (match_dup 3))
4610               (clobber (match_dup 5))])])
4611
4612 (define_insn "fix_trunc<mode>_i387"
4613   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4614         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4615    (use (match_operand:HI 2 "memory_operand" "m"))
4616    (use (match_operand:HI 3 "memory_operand" "m"))]
4617   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4618    && !TARGET_FISTTP
4619    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4620   "* return output_fix_trunc (insn, operands, false);"
4621   [(set_attr "type" "fistp")
4622    (set_attr "i387_cw" "trunc")
4623    (set_attr "mode" "<MODE>")])
4624
4625 (define_insn "fix_trunc<mode>_i387_with_temp"
4626   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4627         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4628    (use (match_operand:HI 2 "memory_operand" "m,m"))
4629    (use (match_operand:HI 3 "memory_operand" "m,m"))
4630    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4631   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632    && !TARGET_FISTTP
4633    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4634   "#"
4635   [(set_attr "type" "fistp")
4636    (set_attr "i387_cw" "trunc")
4637    (set_attr "mode" "<MODE>")])
4638
4639 (define_split
4640   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4641         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4642    (use (match_operand:HI 2 "memory_operand" ""))
4643    (use (match_operand:HI 3 "memory_operand" ""))
4644    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4645   "reload_completed"
4646   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4647               (use (match_dup 2))
4648               (use (match_dup 3))])
4649    (set (match_dup 0) (match_dup 4))])
4650
4651 (define_split
4652   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4653         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4654    (use (match_operand:HI 2 "memory_operand" ""))
4655    (use (match_operand:HI 3 "memory_operand" ""))
4656    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4657   "reload_completed"
4658   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4659               (use (match_dup 2))
4660               (use (match_dup 3))])])
4661
4662 (define_insn "x86_fnstcw_1"
4663   [(set (match_operand:HI 0 "memory_operand" "=m")
4664         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4665   "TARGET_80387"
4666   "fnstcw\t%0"
4667   [(set (attr "length")
4668         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4669    (set_attr "mode" "HI")
4670    (set_attr "unit" "i387")
4671    (set_attr "bdver1_decode" "vector")])
4672
4673 (define_insn "x86_fldcw_1"
4674   [(set (reg:HI FPCR_REG)
4675         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4676   "TARGET_80387"
4677   "fldcw\t%0"
4678   [(set (attr "length")
4679         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4680    (set_attr "mode" "HI")
4681    (set_attr "unit" "i387")
4682    (set_attr "athlon_decode" "vector")
4683    (set_attr "amdfam10_decode" "vector")
4684    (set_attr "bdver1_decode" "vector")])
4685 \f
4686 ;; Conversion between fixed point and floating point.
4687
4688 ;; Even though we only accept memory inputs, the backend _really_
4689 ;; wants to be able to do this between registers.
4690
4691 (define_expand "floathi<mode>2"
4692   [(set (match_operand:X87MODEF 0 "register_operand" "")
4693         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4694   "TARGET_80387
4695    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696        || TARGET_MIX_SSE_I387)")
4697
4698 ;; Pre-reload splitter to add memory clobber to the pattern.
4699 (define_insn_and_split "*floathi<mode>2_1"
4700   [(set (match_operand:X87MODEF 0 "register_operand" "")
4701         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4702   "TARGET_80387
4703    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4704        || TARGET_MIX_SSE_I387)
4705    && can_create_pseudo_p ()"
4706   "#"
4707   "&& 1"
4708   [(parallel [(set (match_dup 0)
4709               (float:X87MODEF (match_dup 1)))
4710    (clobber (match_dup 2))])]
4711   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4712
4713 (define_insn "*floathi<mode>2_i387_with_temp"
4714   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4715         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4716   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4717   "TARGET_80387
4718    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719        || TARGET_MIX_SSE_I387)"
4720   "#"
4721   [(set_attr "type" "fmov,multi")
4722    (set_attr "mode" "<MODE>")
4723    (set_attr "unit" "*,i387")
4724    (set_attr "fp_int_src" "true")])
4725
4726 (define_insn "*floathi<mode>2_i387"
4727   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4728         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4729   "TARGET_80387
4730    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4731        || TARGET_MIX_SSE_I387)"
4732   "fild%Z1\t%1"
4733   [(set_attr "type" "fmov")
4734    (set_attr "mode" "<MODE>")
4735    (set_attr "fp_int_src" "true")])
4736
4737 (define_split
4738   [(set (match_operand:X87MODEF 0 "register_operand" "")
4739         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4740    (clobber (match_operand:HI 2 "memory_operand" ""))]
4741   "TARGET_80387
4742    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4743        || TARGET_MIX_SSE_I387)
4744    && reload_completed"
4745   [(set (match_dup 2) (match_dup 1))
4746    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4747
4748 (define_split
4749   [(set (match_operand:X87MODEF 0 "register_operand" "")
4750         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4751    (clobber (match_operand:HI 2 "memory_operand" ""))]
4752    "TARGET_80387
4753     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4754         || TARGET_MIX_SSE_I387)
4755     && reload_completed"
4756   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4757
4758 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4759   [(set (match_operand:X87MODEF 0 "register_operand" "")
4760         (float:X87MODEF
4761           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4762   "TARGET_80387
4763    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4764        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4765 {
4766   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4767         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4768       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4769     {
4770       rtx reg = gen_reg_rtx (XFmode);
4771       rtx (*insn)(rtx, rtx);
4772
4773       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4774
4775       if (<X87MODEF:MODE>mode == SFmode)
4776         insn = gen_truncxfsf2;
4777       else if (<X87MODEF:MODE>mode == DFmode)
4778         insn = gen_truncxfdf2;
4779       else
4780         gcc_unreachable ();
4781
4782       emit_insn (insn (operands[0], reg));
4783       DONE;
4784     }
4785 })
4786
4787 ;; Pre-reload splitter to add memory clobber to the pattern.
4788 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4789   [(set (match_operand:X87MODEF 0 "register_operand" "")
4790         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4791   "((TARGET_80387
4792      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4793      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4794            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4795          || TARGET_MIX_SSE_I387))
4796     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4797         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4798         && ((<SSEMODEI24:MODE>mode == SImode
4799              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4800              && optimize_function_for_speed_p (cfun)
4801              && flag_trapping_math)
4802             || !(TARGET_INTER_UNIT_CONVERSIONS
4803                  || optimize_function_for_size_p (cfun)))))
4804    && can_create_pseudo_p ()"
4805   "#"
4806   "&& 1"
4807   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4808               (clobber (match_dup 2))])]
4809 {
4810   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4811
4812   /* Avoid store forwarding (partial memory) stall penalty
4813      by passing DImode value through XMM registers.  */
4814   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4815       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4816       && optimize_function_for_speed_p (cfun))
4817     {
4818       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4819                                                             operands[1],
4820                                                             operands[2]));
4821       DONE;
4822     }
4823 })
4824
4825 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4826   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4827         (float:MODEF
4828           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4829    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4830   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4831    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4832   "#"
4833   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4834    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4835    (set_attr "unit" "*,i387,*,*,*")
4836    (set_attr "athlon_decode" "*,*,double,direct,double")
4837    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4838    (set_attr "bdver1_decode" "*,*,double,direct,double")
4839    (set_attr "fp_int_src" "true")])
4840
4841 (define_insn "*floatsi<mode>2_vector_mixed"
4842   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4843         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4844   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4845    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4846   "@
4847    fild%Z1\t%1
4848    #"
4849   [(set_attr "type" "fmov,sseicvt")
4850    (set_attr "mode" "<MODE>,<ssevecmode>")
4851    (set_attr "unit" "i387,*")
4852    (set_attr "athlon_decode" "*,direct")
4853    (set_attr "amdfam10_decode" "*,double")
4854    (set_attr "bdver1_decode" "*,direct")
4855    (set_attr "fp_int_src" "true")])
4856
4857 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4858   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4859         (float:MODEF
4860           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4861   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4862   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4863    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4864   "#"
4865   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4866    (set_attr "mode" "<MODEF:MODE>")
4867    (set_attr "unit" "*,i387,*,*")
4868    (set_attr "athlon_decode" "*,*,double,direct")
4869    (set_attr "amdfam10_decode" "*,*,vector,double")
4870    (set_attr "bdver1_decode" "*,*,double,direct")
4871    (set_attr "fp_int_src" "true")])
4872
4873 (define_split
4874   [(set (match_operand:MODEF 0 "register_operand" "")
4875         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4876    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4877   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4878    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4879    && TARGET_INTER_UNIT_CONVERSIONS
4880    && reload_completed
4881    && (SSE_REG_P (operands[0])
4882        || (GET_CODE (operands[0]) == SUBREG
4883            && SSE_REG_P (operands[0])))"
4884   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4885
4886 (define_split
4887   [(set (match_operand:MODEF 0 "register_operand" "")
4888         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4889    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4890   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4891    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4892    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4893    && reload_completed
4894    && (SSE_REG_P (operands[0])
4895        || (GET_CODE (operands[0]) == SUBREG
4896            && SSE_REG_P (operands[0])))"
4897   [(set (match_dup 2) (match_dup 1))
4898    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4899
4900 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4901   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4902         (float:MODEF
4903           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
4904   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4905    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4906    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4907   "@
4908    fild%Z1\t%1
4909    %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
4910    %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4911   [(set_attr "type" "fmov,sseicvt,sseicvt")
4912    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4913    (set_attr "mode" "<MODEF:MODE>")
4914    (set (attr "prefix_rex")
4915      (if_then_else
4916        (and (eq_attr "prefix" "maybe_vex")
4917             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4918        (const_string "1")
4919        (const_string "*")))
4920    (set_attr "unit" "i387,*,*")
4921    (set_attr "athlon_decode" "*,double,direct")
4922    (set_attr "amdfam10_decode" "*,vector,double")
4923    (set_attr "bdver1_decode" "*,double,direct")
4924    (set_attr "fp_int_src" "true")])
4925
4926 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
4927   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4928         (float:MODEF
4929           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
4930   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4931    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4933   "@
4934    fild%Z1\t%1
4935    %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4936   [(set_attr "type" "fmov,sseicvt")
4937    (set_attr "prefix" "orig,maybe_vex")
4938    (set_attr "mode" "<MODEF:MODE>")
4939    (set (attr "prefix_rex")
4940      (if_then_else
4941        (and (eq_attr "prefix" "maybe_vex")
4942             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4943        (const_string "1")
4944        (const_string "*")))
4945    (set_attr "athlon_decode" "*,direct")
4946    (set_attr "amdfam10_decode" "*,double")
4947    (set_attr "bdver1_decode" "*,direct")
4948    (set_attr "fp_int_src" "true")])
4949
4950 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4951   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4952         (float:MODEF
4953           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4954    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4955   "TARGET_SSE2 && TARGET_SSE_MATH
4956    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4957   "#"
4958   [(set_attr "type" "sseicvt")
4959    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4960    (set_attr "athlon_decode" "double,direct,double")
4961    (set_attr "amdfam10_decode" "vector,double,double")
4962    (set_attr "bdver1_decode" "double,direct,double")
4963    (set_attr "fp_int_src" "true")])
4964
4965 (define_insn "*floatsi<mode>2_vector_sse"
4966   [(set (match_operand:MODEF 0 "register_operand" "=x")
4967         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4968   "TARGET_SSE2 && TARGET_SSE_MATH
4969    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4970   "#"
4971   [(set_attr "type" "sseicvt")
4972    (set_attr "mode" "<MODE>")
4973    (set_attr "athlon_decode" "direct")
4974    (set_attr "amdfam10_decode" "double")
4975    (set_attr "bdver1_decode" "direct")
4976    (set_attr "fp_int_src" "true")])
4977
4978 (define_split
4979   [(set (match_operand:MODEF 0 "register_operand" "")
4980         (float:MODEF (match_operand:SI 1 "register_operand" "")))
4981    (clobber (match_operand:SI 2 "memory_operand" ""))]
4982   "TARGET_SSE2 && TARGET_SSE_MATH
4983    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4984    && reload_completed
4985    && (SSE_REG_P (operands[0])
4986        || (GET_CODE (operands[0]) == SUBREG
4987            && SSE_REG_P (operands[0])))"
4988   [(const_int 0)]
4989 {
4990   rtx op1 = operands[1];
4991
4992   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4993                                      <MODE>mode, 0);
4994   if (GET_CODE (op1) == SUBREG)
4995     op1 = SUBREG_REG (op1);
4996
4997   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4998     {
4999       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5000       emit_insn (gen_sse2_loadld (operands[4],
5001                                   CONST0_RTX (V4SImode), operands[1]));
5002     }
5003   /* We can ignore possible trapping value in the
5004      high part of SSE register for non-trapping math. */
5005   else if (SSE_REG_P (op1) && !flag_trapping_math)
5006     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5007   else
5008     {
5009       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5010       emit_move_insn (operands[2], operands[1]);
5011       emit_insn (gen_sse2_loadld (operands[4],
5012                                   CONST0_RTX (V4SImode), operands[2]));
5013     }
5014   emit_insn
5015     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5016   DONE;
5017 })
5018
5019 (define_split
5020   [(set (match_operand:MODEF 0 "register_operand" "")
5021         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5022    (clobber (match_operand:SI 2 "memory_operand" ""))]
5023   "TARGET_SSE2 && TARGET_SSE_MATH
5024    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5025    && reload_completed
5026    && (SSE_REG_P (operands[0])
5027        || (GET_CODE (operands[0]) == SUBREG
5028            && SSE_REG_P (operands[0])))"
5029   [(const_int 0)]
5030 {
5031   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5032                                      <MODE>mode, 0);
5033   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5034
5035   emit_insn (gen_sse2_loadld (operands[4],
5036                               CONST0_RTX (V4SImode), operands[1]));
5037   emit_insn
5038     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5039   DONE;
5040 })
5041
5042 (define_split
5043   [(set (match_operand:MODEF 0 "register_operand" "")
5044         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5045   "TARGET_SSE2 && TARGET_SSE_MATH
5046    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047    && reload_completed
5048    && (SSE_REG_P (operands[0])
5049        || (GET_CODE (operands[0]) == SUBREG
5050            && SSE_REG_P (operands[0])))"
5051   [(const_int 0)]
5052 {
5053   rtx op1 = operands[1];
5054
5055   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5056                                      <MODE>mode, 0);
5057   if (GET_CODE (op1) == SUBREG)
5058     op1 = SUBREG_REG (op1);
5059
5060   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5061     {
5062       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5063       emit_insn (gen_sse2_loadld (operands[4],
5064                                   CONST0_RTX (V4SImode), operands[1]));
5065     }
5066   /* We can ignore possible trapping value in the
5067      high part of SSE register for non-trapping math. */
5068   else if (SSE_REG_P (op1) && !flag_trapping_math)
5069     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5070   else
5071     gcc_unreachable ();
5072   emit_insn
5073     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5074   DONE;
5075 })
5076
5077 (define_split
5078   [(set (match_operand:MODEF 0 "register_operand" "")
5079         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5080   "TARGET_SSE2 && TARGET_SSE_MATH
5081    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5082    && reload_completed
5083    && (SSE_REG_P (operands[0])
5084        || (GET_CODE (operands[0]) == SUBREG
5085            && SSE_REG_P (operands[0])))"
5086   [(const_int 0)]
5087 {
5088   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5089                                      <MODE>mode, 0);
5090   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5091
5092   emit_insn (gen_sse2_loadld (operands[4],
5093                               CONST0_RTX (V4SImode), operands[1]));
5094   emit_insn
5095     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5096   DONE;
5097 })
5098
5099 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5100   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5101         (float:MODEF
5102           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5103   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5104   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5106   "#"
5107   [(set_attr "type" "sseicvt")
5108    (set_attr "mode" "<MODEF:MODE>")
5109    (set_attr "athlon_decode" "double,direct")
5110    (set_attr "amdfam10_decode" "vector,double")
5111    (set_attr "bdver1_decode" "double,direct")
5112    (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5115   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5116         (float:MODEF
5117           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5118   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5119    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121   "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5122   [(set_attr "type" "sseicvt")
5123    (set_attr "prefix" "maybe_vex")
5124    (set_attr "mode" "<MODEF:MODE>")
5125    (set (attr "prefix_rex")
5126      (if_then_else
5127        (and (eq_attr "prefix" "maybe_vex")
5128             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5129        (const_string "1")
5130        (const_string "*")))
5131    (set_attr "athlon_decode" "double,direct")
5132    (set_attr "amdfam10_decode" "vector,double")
5133    (set_attr "bdver1_decode" "double,direct")
5134    (set_attr "fp_int_src" "true")])
5135
5136 (define_split
5137   [(set (match_operand:MODEF 0 "register_operand" "")
5138         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5139    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5140   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5141    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5143    && reload_completed
5144    && (SSE_REG_P (operands[0])
5145        || (GET_CODE (operands[0]) == SUBREG
5146            && SSE_REG_P (operands[0])))"
5147   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5148
5149 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5150   [(set (match_operand:MODEF 0 "register_operand" "=x")
5151         (float:MODEF
5152           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5153   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5154    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5155    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5156   "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5157   [(set_attr "type" "sseicvt")
5158    (set_attr "prefix" "maybe_vex")
5159    (set_attr "mode" "<MODEF:MODE>")
5160    (set (attr "prefix_rex")
5161      (if_then_else
5162        (and (eq_attr "prefix" "maybe_vex")
5163             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5164        (const_string "1")
5165        (const_string "*")))
5166    (set_attr "athlon_decode" "direct")
5167    (set_attr "amdfam10_decode" "double")
5168    (set_attr "bdver1_decode" "direct")
5169    (set_attr "fp_int_src" "true")])
5170
5171 (define_split
5172   [(set (match_operand:MODEF 0 "register_operand" "")
5173         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5174    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5175   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5176    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5178    && reload_completed
5179    && (SSE_REG_P (operands[0])
5180        || (GET_CODE (operands[0]) == SUBREG
5181            && SSE_REG_P (operands[0])))"
5182   [(set (match_dup 2) (match_dup 1))
5183    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5184
5185 (define_split
5186   [(set (match_operand:MODEF 0 "register_operand" "")
5187         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5188    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5189   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5190    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5191    && reload_completed
5192    && (SSE_REG_P (operands[0])
5193        || (GET_CODE (operands[0]) == SUBREG
5194            && SSE_REG_P (operands[0])))"
5195   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5196
5197 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5198   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5199         (float:X87MODEF
5200           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5201   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5202   "TARGET_80387
5203    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5204   "@
5205    fild%Z1\t%1
5206    #"
5207   [(set_attr "type" "fmov,multi")
5208    (set_attr "mode" "<X87MODEF:MODE>")
5209    (set_attr "unit" "*,i387")
5210    (set_attr "fp_int_src" "true")])
5211
5212 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5213   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5214         (float:X87MODEF
5215           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5216   "TARGET_80387
5217    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5218   "fild%Z1\t%1"
5219   [(set_attr "type" "fmov")
5220    (set_attr "mode" "<X87MODEF:MODE>")
5221    (set_attr "fp_int_src" "true")])
5222
5223 (define_split
5224   [(set (match_operand:X87MODEF 0 "register_operand" "")
5225         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5227   "TARGET_80387
5228    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5229    && reload_completed
5230    && FP_REG_P (operands[0])"
5231   [(set (match_dup 2) (match_dup 1))
5232    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5233
5234 (define_split
5235   [(set (match_operand:X87MODEF 0 "register_operand" "")
5236         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5237    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5238   "TARGET_80387
5239    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5240    && reload_completed
5241    && FP_REG_P (operands[0])"
5242   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5243
5244 ;; Avoid store forwarding (partial memory) stall penalty
5245 ;; by passing DImode value through XMM registers.  */
5246
5247 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5248   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5249         (float:X87MODEF
5250           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5251    (clobber (match_scratch:V4SI 3 "=X,x"))
5252    (clobber (match_scratch:V4SI 4 "=X,x"))
5253    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5254   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5255    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5256    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5257   "#"
5258   [(set_attr "type" "multi")
5259    (set_attr "mode" "<X87MODEF:MODE>")
5260    (set_attr "unit" "i387")
5261    (set_attr "fp_int_src" "true")])
5262
5263 (define_split
5264   [(set (match_operand:X87MODEF 0 "register_operand" "")
5265         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5266    (clobber (match_scratch:V4SI 3 ""))
5267    (clobber (match_scratch:V4SI 4 ""))
5268    (clobber (match_operand:DI 2 "memory_operand" ""))]
5269   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5270    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5271    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5272    && reload_completed
5273    && FP_REG_P (operands[0])"
5274   [(set (match_dup 2) (match_dup 3))
5275    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5276 {
5277   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5278      Assemble the 64-bit DImode value in an xmm register.  */
5279   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5280                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5281   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5282                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5283   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5284                                          operands[4]));
5285
5286   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5287 })
5288
5289 (define_split
5290   [(set (match_operand:X87MODEF 0 "register_operand" "")
5291         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5292    (clobber (match_scratch:V4SI 3 ""))
5293    (clobber (match_scratch:V4SI 4 ""))
5294    (clobber (match_operand:DI 2 "memory_operand" ""))]
5295   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5296    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5297    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5298    && reload_completed
5299    && FP_REG_P (operands[0])"
5300   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5301
5302 ;; Avoid store forwarding (partial memory) stall penalty by extending
5303 ;; SImode value to DImode through XMM register instead of pushing two
5304 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5305 ;; targets benefit from this optimization. Also note that fild
5306 ;; loads from memory only.
5307
5308 (define_insn "*floatunssi<mode>2_1"
5309   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5310         (unsigned_float:X87MODEF
5311           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5312    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5313    (clobber (match_scratch:SI 3 "=X,x"))]
5314   "!TARGET_64BIT
5315    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5316    && TARGET_SSE"
5317   "#"
5318   [(set_attr "type" "multi")
5319    (set_attr "mode" "<MODE>")])
5320
5321 (define_split
5322   [(set (match_operand:X87MODEF 0 "register_operand" "")
5323         (unsigned_float:X87MODEF
5324           (match_operand:SI 1 "register_operand" "")))
5325    (clobber (match_operand:DI 2 "memory_operand" ""))
5326    (clobber (match_scratch:SI 3 ""))]
5327   "!TARGET_64BIT
5328    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5329    && TARGET_SSE
5330    && reload_completed"
5331   [(set (match_dup 2) (match_dup 1))
5332    (set (match_dup 0)
5333         (float:X87MODEF (match_dup 2)))]
5334   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5335
5336 (define_split
5337   [(set (match_operand:X87MODEF 0 "register_operand" "")
5338         (unsigned_float:X87MODEF
5339           (match_operand:SI 1 "memory_operand" "")))
5340    (clobber (match_operand:DI 2 "memory_operand" ""))
5341    (clobber (match_scratch:SI 3 ""))]
5342   "!TARGET_64BIT
5343    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5344    && TARGET_SSE
5345    && reload_completed"
5346   [(set (match_dup 2) (match_dup 3))
5347    (set (match_dup 0)
5348         (float:X87MODEF (match_dup 2)))]
5349 {
5350   emit_move_insn (operands[3], operands[1]);
5351   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5352 })
5353
5354 (define_expand "floatunssi<mode>2"
5355   [(parallel
5356      [(set (match_operand:X87MODEF 0 "register_operand" "")
5357            (unsigned_float:X87MODEF
5358              (match_operand:SI 1 "nonimmediate_operand" "")))
5359       (clobber (match_dup 2))
5360       (clobber (match_scratch:SI 3 ""))])]
5361   "!TARGET_64BIT
5362    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5363         && TARGET_SSE)
5364        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5365 {
5366   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5367     {
5368       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5369       DONE;
5370     }
5371   else
5372     {
5373       enum ix86_stack_slot slot = (virtuals_instantiated
5374                                    ? SLOT_TEMP
5375                                    : SLOT_VIRTUAL);
5376       operands[2] = assign_386_stack_local (DImode, slot);
5377     }
5378 })
5379
5380 (define_expand "floatunsdisf2"
5381   [(use (match_operand:SF 0 "register_operand" ""))
5382    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5383   "TARGET_64BIT && TARGET_SSE_MATH"
5384   "x86_emit_floatuns (operands); DONE;")
5385
5386 (define_expand "floatunsdidf2"
5387   [(use (match_operand:DF 0 "register_operand" ""))
5388    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5389   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5390    && TARGET_SSE2 && TARGET_SSE_MATH"
5391 {
5392   if (TARGET_64BIT)
5393     x86_emit_floatuns (operands);
5394   else
5395     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5396   DONE;
5397 })
5398 \f
5399 ;; Add instructions
5400
5401 (define_expand "add<mode>3"
5402   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5403         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5404                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5405   ""
5406   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5407
5408 (define_insn_and_split "*add<dwi>3_doubleword"
5409   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5410         (plus:<DWI>
5411           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5412           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5413    (clobber (reg:CC FLAGS_REG))]
5414   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5415   "#"
5416   "reload_completed"
5417   [(parallel [(set (reg:CC FLAGS_REG)
5418                    (unspec:CC [(match_dup 1) (match_dup 2)]
5419                               UNSPEC_ADD_CARRY))
5420               (set (match_dup 0)
5421                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5422    (parallel [(set (match_dup 3)
5423                    (plus:DWIH
5424                      (match_dup 4)
5425                      (plus:DWIH
5426                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5427                        (match_dup 5))))
5428               (clobber (reg:CC FLAGS_REG))])]
5429   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5430
5431 (define_insn "*add<mode>3_cc"
5432   [(set (reg:CC FLAGS_REG)
5433         (unspec:CC
5434           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5435            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5436           UNSPEC_ADD_CARRY))
5437    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5438         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5439   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5440   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5441   [(set_attr "type" "alu")
5442    (set_attr "mode" "<MODE>")])
5443
5444 (define_insn "addqi3_cc"
5445   [(set (reg:CC FLAGS_REG)
5446         (unspec:CC
5447           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5448            (match_operand:QI 2 "general_operand" "qn,qm")]
5449           UNSPEC_ADD_CARRY))
5450    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5451         (plus:QI (match_dup 1) (match_dup 2)))]
5452   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5453   "add{b}\t{%2, %0|%0, %2}"
5454   [(set_attr "type" "alu")
5455    (set_attr "mode" "QI")])
5456
5457 (define_insn "*lea_1"
5458   [(set (match_operand:P 0 "register_operand" "=r")
5459         (match_operand:P 1 "no_seg_address_operand" "p"))]
5460   ""
5461   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5462   [(set_attr "type" "lea")
5463    (set_attr "mode" "<MODE>")])
5464
5465 (define_insn "*lea_2"
5466   [(set (match_operand:SI 0 "register_operand" "=r")
5467         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5468   "TARGET_64BIT"
5469   "lea{l}\t{%a1, %0|%0, %a1}"
5470   [(set_attr "type" "lea")
5471    (set_attr "mode" "SI")])
5472
5473 (define_insn "*lea_2_zext"
5474   [(set (match_operand:DI 0 "register_operand" "=r")
5475         (zero_extend:DI
5476           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5477   "TARGET_64BIT"
5478   "lea{l}\t{%a1, %k0|%k0, %a1}"
5479   [(set_attr "type" "lea")
5480    (set_attr "mode" "SI")])
5481
5482 (define_insn "*add<mode>_1"
5483   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5484         (plus:SWI48
5485           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5486           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5487    (clobber (reg:CC FLAGS_REG))]
5488   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5489 {
5490   switch (get_attr_type (insn))
5491     {
5492     case TYPE_LEA:
5493       return "#";
5494
5495     case TYPE_INCDEC:
5496       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5497       if (operands[2] == const1_rtx)
5498         return "inc{<imodesuffix>}\t%0";
5499       else
5500         {
5501           gcc_assert (operands[2] == constm1_rtx);
5502           return "dec{<imodesuffix>}\t%0";
5503         }
5504
5505     default:
5506       /* For most processors, ADD is faster than LEA.  This alternative
5507          was added to use ADD as much as possible.  */
5508       if (which_alternative == 2)
5509         {
5510           rtx tmp;
5511           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5512         }
5513         
5514       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5516         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5517
5518       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5519     }
5520 }
5521   [(set (attr "type")
5522      (cond [(eq_attr "alternative" "3")
5523               (const_string "lea")
5524             (match_operand:SWI48 2 "incdec_operand" "")
5525               (const_string "incdec")
5526            ]
5527            (const_string "alu")))
5528    (set (attr "length_immediate")
5529       (if_then_else
5530         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5531         (const_string "1")
5532         (const_string "*")))
5533    (set_attr "mode" "<MODE>")])
5534
5535 ;; It may seem that nonimmediate operand is proper one for operand 1.
5536 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5537 ;; we take care in ix86_binary_operator_ok to not allow two memory
5538 ;; operands so proper swapping will be done in reload.  This allow
5539 ;; patterns constructed from addsi_1 to match.
5540
5541 (define_insn "*addsi_1_zext"
5542   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5543         (zero_extend:DI
5544           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5545                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5546    (clobber (reg:CC FLAGS_REG))]
5547   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5548 {
5549   switch (get_attr_type (insn))
5550     {
5551     case TYPE_LEA:
5552       return "#";
5553
5554     case TYPE_INCDEC:
5555       if (operands[2] == const1_rtx)
5556         return "inc{l}\t%k0";
5557       else
5558         {
5559           gcc_assert (operands[2] == constm1_rtx);
5560           return "dec{l}\t%k0";
5561         }
5562
5563     default:
5564       /* For most processors, ADD is faster than LEA.  This alternative
5565          was added to use ADD as much as possible.  */
5566       if (which_alternative == 1)
5567         {
5568           rtx tmp;
5569           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5570         }
5571
5572       if (x86_maybe_negate_const_int (&operands[2], SImode))
5573         return "sub{l}\t{%2, %k0|%k0, %2}";
5574
5575       return "add{l}\t{%2, %k0|%k0, %2}";
5576     }
5577 }
5578   [(set (attr "type")
5579      (cond [(eq_attr "alternative" "2")
5580               (const_string "lea")
5581             (match_operand:SI 2 "incdec_operand" "")
5582               (const_string "incdec")
5583            ]
5584            (const_string "alu")))
5585    (set (attr "length_immediate")
5586       (if_then_else
5587         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5588         (const_string "1")
5589         (const_string "*")))
5590    (set_attr "mode" "SI")])
5591
5592 (define_insn "*addhi_1"
5593   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5594         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5595                  (match_operand:HI 2 "general_operand" "rn,rm")))
5596    (clobber (reg:CC FLAGS_REG))]
5597   "TARGET_PARTIAL_REG_STALL
5598    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5599 {
5600   switch (get_attr_type (insn))
5601     {
5602     case TYPE_INCDEC:
5603       if (operands[2] == const1_rtx)
5604         return "inc{w}\t%0";
5605       else
5606         {
5607           gcc_assert (operands[2] == constm1_rtx);
5608           return "dec{w}\t%0";
5609         }
5610
5611     default:
5612       if (x86_maybe_negate_const_int (&operands[2], HImode))
5613         return "sub{w}\t{%2, %0|%0, %2}";
5614
5615       return "add{w}\t{%2, %0|%0, %2}";
5616     }
5617 }
5618   [(set (attr "type")
5619      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5620         (const_string "incdec")
5621         (const_string "alu")))
5622    (set (attr "length_immediate")
5623       (if_then_else
5624         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5625         (const_string "1")
5626         (const_string "*")))
5627    (set_attr "mode" "HI")])
5628
5629 (define_insn "*addhi_1_lea"
5630   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5631         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5632                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5633    (clobber (reg:CC FLAGS_REG))]
5634   "!TARGET_PARTIAL_REG_STALL
5635    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5636 {
5637   switch (get_attr_type (insn))
5638     {
5639     case TYPE_LEA:
5640       return "#";
5641
5642     case TYPE_INCDEC:
5643       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644       if (operands[2] == const1_rtx)
5645         return "inc{w}\t%0";
5646       else
5647         {
5648           gcc_assert (operands[2] == constm1_rtx);
5649           return "dec{w}\t%0";
5650         }
5651
5652     default:
5653       /* For most processors, ADD is faster than LEA.  This alternative
5654          was added to use ADD as much as possible.  */
5655       if (which_alternative == 2)
5656         {
5657           rtx tmp;
5658           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5659         }
5660
5661       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5662       if (x86_maybe_negate_const_int (&operands[2], HImode))
5663         return "sub{w}\t{%2, %0|%0, %2}";
5664
5665       return "add{w}\t{%2, %0|%0, %2}";
5666     }
5667 }
5668   [(set (attr "type")
5669      (cond [(eq_attr "alternative" "3")
5670               (const_string "lea")
5671             (match_operand:HI 2 "incdec_operand" "")
5672               (const_string "incdec")
5673            ]
5674            (const_string "alu")))
5675    (set (attr "length_immediate")
5676       (if_then_else
5677         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5678         (const_string "1")
5679         (const_string "*")))
5680    (set_attr "mode" "HI,HI,HI,SI")])
5681
5682 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5683 (define_insn "*addqi_1"
5684   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5685         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5686                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5687    (clobber (reg:CC FLAGS_REG))]
5688   "TARGET_PARTIAL_REG_STALL
5689    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5690 {
5691   int widen = (which_alternative == 2);
5692   switch (get_attr_type (insn))
5693     {
5694     case TYPE_INCDEC:
5695       if (operands[2] == const1_rtx)
5696         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5697       else
5698         {
5699           gcc_assert (operands[2] == constm1_rtx);
5700           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5701         }
5702
5703     default:
5704       if (x86_maybe_negate_const_int (&operands[2], QImode))
5705         {
5706           if (widen)
5707             return "sub{l}\t{%2, %k0|%k0, %2}";
5708           else
5709             return "sub{b}\t{%2, %0|%0, %2}";
5710         }
5711       if (widen)
5712         return "add{l}\t{%k2, %k0|%k0, %k2}";
5713       else
5714         return "add{b}\t{%2, %0|%0, %2}";
5715     }
5716 }
5717   [(set (attr "type")
5718      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5719         (const_string "incdec")
5720         (const_string "alu")))
5721    (set (attr "length_immediate")
5722       (if_then_else
5723         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5724         (const_string "1")
5725         (const_string "*")))
5726    (set_attr "mode" "QI,QI,SI")])
5727
5728 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5729 (define_insn "*addqi_1_lea"
5730   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5731         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5732                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5733    (clobber (reg:CC FLAGS_REG))]
5734   "!TARGET_PARTIAL_REG_STALL
5735    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5736 {
5737   int widen = (which_alternative == 3 || which_alternative == 4);
5738
5739   switch (get_attr_type (insn))
5740     {
5741     case TYPE_LEA:
5742       return "#";
5743
5744     case TYPE_INCDEC:
5745       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746       if (operands[2] == const1_rtx)
5747         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5748       else
5749         {
5750           gcc_assert (operands[2] == constm1_rtx);
5751           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5752         }
5753
5754     default:
5755       /* For most processors, ADD is faster than LEA.  These alternatives
5756          were added to use ADD as much as possible.  */
5757       if (which_alternative == 2 || which_alternative == 4)
5758         {
5759           rtx tmp;
5760           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5761         }
5762
5763       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5764       if (x86_maybe_negate_const_int (&operands[2], QImode))
5765         {
5766           if (widen)
5767             return "sub{l}\t{%2, %k0|%k0, %2}";
5768           else
5769             return "sub{b}\t{%2, %0|%0, %2}";
5770         }
5771       if (widen)
5772         return "add{l}\t{%k2, %k0|%k0, %k2}";
5773       else
5774         return "add{b}\t{%2, %0|%0, %2}";
5775     }
5776 }
5777   [(set (attr "type")
5778      (cond [(eq_attr "alternative" "5")
5779               (const_string "lea")
5780             (match_operand:QI 2 "incdec_operand" "")
5781               (const_string "incdec")
5782            ]
5783            (const_string "alu")))
5784    (set (attr "length_immediate")
5785       (if_then_else
5786         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5787         (const_string "1")
5788         (const_string "*")))
5789    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5790
5791 (define_insn "*addqi_1_slp"
5792   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5793         (plus:QI (match_dup 0)
5794                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5795    (clobber (reg:CC FLAGS_REG))]
5796   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5797    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5798 {
5799   switch (get_attr_type (insn))
5800     {
5801     case TYPE_INCDEC:
5802       if (operands[1] == const1_rtx)
5803         return "inc{b}\t%0";
5804       else
5805         {
5806           gcc_assert (operands[1] == constm1_rtx);
5807           return "dec{b}\t%0";
5808         }
5809
5810     default:
5811       if (x86_maybe_negate_const_int (&operands[1], QImode))
5812         return "sub{b}\t{%1, %0|%0, %1}";
5813
5814       return "add{b}\t{%1, %0|%0, %1}";
5815     }
5816 }
5817   [(set (attr "type")
5818      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5819         (const_string "incdec")
5820         (const_string "alu1")))
5821    (set (attr "memory")
5822      (if_then_else (match_operand 1 "memory_operand" "")
5823         (const_string "load")
5824         (const_string "none")))
5825    (set_attr "mode" "QI")])
5826
5827 ;; Convert lea to the lea pattern to avoid flags dependency.
5828 (define_split
5829   [(set (match_operand 0 "register_operand" "")
5830         (plus (match_operand 1 "register_operand" "")
5831               (match_operand 2 "nonmemory_operand" "")))
5832    (clobber (reg:CC FLAGS_REG))]
5833   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5834   [(const_int 0)]
5835 {
5836   rtx pat;
5837   enum machine_mode mode = GET_MODE (operands[0]);
5838
5839   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5840      may confuse gen_lowpart.  */
5841   if (mode != Pmode)
5842     {
5843       operands[1] = gen_lowpart (Pmode, operands[1]);
5844       operands[2] = gen_lowpart (Pmode, operands[2]);
5845     }
5846
5847   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5848
5849   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5850     operands[0] = gen_lowpart (SImode, operands[0]);
5851
5852   if (TARGET_64BIT && mode != Pmode)
5853     pat = gen_rtx_SUBREG (SImode, pat, 0);
5854
5855   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5856   DONE;
5857 })
5858
5859 ;; Convert lea to the lea pattern to avoid flags dependency.
5860 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5861 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5862 (define_split
5863   [(set (match_operand:DI 0 "register_operand" "")
5864         (plus:DI (match_operand:DI 1 "register_operand" "")
5865                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
5866    (clobber (reg:CC FLAGS_REG))]
5867   "TARGET_64BIT && reload_completed 
5868    && true_regnum (operands[0]) != true_regnum (operands[1])"
5869   [(set (match_dup 0)
5870         (plus:DI (match_dup 1) (match_dup 2)))])
5871
5872 ;; Convert lea to the lea pattern to avoid flags dependency.
5873 (define_split
5874   [(set (match_operand:DI 0 "register_operand" "")
5875         (zero_extend:DI
5876           (plus:SI (match_operand:SI 1 "register_operand" "")
5877                    (match_operand:SI 2 "nonmemory_operand" ""))))
5878    (clobber (reg:CC FLAGS_REG))]
5879   "TARGET_64BIT && reload_completed
5880    && ix86_lea_for_add_ok (insn, operands)"
5881   [(set (match_dup 0)
5882         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5883 {
5884   operands[1] = gen_lowpart (DImode, operands[1]);
5885   operands[2] = gen_lowpart (DImode, operands[2]);
5886 })
5887
5888 (define_insn "*add<mode>_2"
5889   [(set (reg FLAGS_REG)
5890         (compare
5891           (plus:SWI
5892             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5893             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5894           (const_int 0)))
5895    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5896         (plus:SWI (match_dup 1) (match_dup 2)))]
5897   "ix86_match_ccmode (insn, CCGOCmode)
5898    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5899 {
5900   switch (get_attr_type (insn))
5901     {
5902     case TYPE_INCDEC:
5903       if (operands[2] == const1_rtx)
5904         return "inc{<imodesuffix>}\t%0";
5905       else
5906         {
5907           gcc_assert (operands[2] == constm1_rtx);
5908           return "dec{<imodesuffix>}\t%0";
5909         }
5910
5911     default:
5912       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5913         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5914
5915       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5916     }
5917 }
5918   [(set (attr "type")
5919      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5920         (const_string "incdec")
5921         (const_string "alu")))
5922    (set (attr "length_immediate")
5923       (if_then_else
5924         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5925         (const_string "1")
5926         (const_string "*")))
5927    (set_attr "mode" "<MODE>")])
5928
5929 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5930 (define_insn "*addsi_2_zext"
5931   [(set (reg FLAGS_REG)
5932         (compare
5933           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5934                    (match_operand:SI 2 "general_operand" "g"))
5935           (const_int 0)))
5936    (set (match_operand:DI 0 "register_operand" "=r")
5937         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5939    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5940 {
5941   switch (get_attr_type (insn))
5942     {
5943     case TYPE_INCDEC:
5944       if (operands[2] == const1_rtx)
5945         return "inc{l}\t%k0";
5946       else
5947         {
5948           gcc_assert (operands[2] == constm1_rtx);
5949           return "dec{l}\t%k0";
5950         }
5951
5952     default:
5953       if (x86_maybe_negate_const_int (&operands[2], SImode))
5954         return "sub{l}\t{%2, %k0|%k0, %2}";
5955
5956       return "add{l}\t{%2, %k0|%k0, %2}";
5957     }
5958 }
5959   [(set (attr "type")
5960      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961         (const_string "incdec")
5962         (const_string "alu")))
5963    (set (attr "length_immediate")
5964       (if_then_else
5965         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5966         (const_string "1")
5967         (const_string "*")))
5968    (set_attr "mode" "SI")])
5969
5970 (define_insn "*add<mode>_3"
5971   [(set (reg FLAGS_REG)
5972         (compare
5973           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5974           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5975    (clobber (match_scratch:SWI 0 "=<r>"))]
5976   "ix86_match_ccmode (insn, CCZmode)
5977    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5978 {
5979   switch (get_attr_type (insn))
5980     {
5981     case TYPE_INCDEC:
5982       if (operands[2] == const1_rtx)
5983         return "inc{<imodesuffix>}\t%0";
5984       else
5985         {
5986           gcc_assert (operands[2] == constm1_rtx);
5987           return "dec{<imodesuffix>}\t%0";
5988         }
5989
5990     default:
5991       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5992         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5993
5994       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5995     }
5996 }
5997   [(set (attr "type")
5998      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5999         (const_string "incdec")
6000         (const_string "alu")))
6001    (set (attr "length_immediate")
6002       (if_then_else
6003         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6004         (const_string "1")
6005         (const_string "*")))
6006    (set_attr "mode" "<MODE>")])
6007
6008 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6009 (define_insn "*addsi_3_zext"
6010   [(set (reg FLAGS_REG)
6011         (compare
6012           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6013           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6014    (set (match_operand:DI 0 "register_operand" "=r")
6015         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6016   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6017    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6018 {
6019   switch (get_attr_type (insn))
6020     {
6021     case TYPE_INCDEC:
6022       if (operands[2] == const1_rtx)
6023         return "inc{l}\t%k0";
6024       else
6025         {
6026           gcc_assert (operands[2] == constm1_rtx);
6027           return "dec{l}\t%k0";
6028         }
6029
6030     default:
6031       if (x86_maybe_negate_const_int (&operands[2], SImode))
6032         return "sub{l}\t{%2, %k0|%k0, %2}";
6033
6034       return "add{l}\t{%2, %k0|%k0, %2}";
6035     }
6036 }
6037   [(set (attr "type")
6038      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6039         (const_string "incdec")
6040         (const_string "alu")))
6041    (set (attr "length_immediate")
6042       (if_then_else
6043         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6044         (const_string "1")
6045         (const_string "*")))
6046    (set_attr "mode" "SI")])
6047
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6050 ; is matched then.  We can't accept general immediate, because for
6051 ; case of overflows,  the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6054
6055 (define_insn "*adddi_4"
6056   [(set (reg FLAGS_REG)
6057         (compare
6058           (match_operand:DI 1 "nonimmediate_operand" "0")
6059           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6060    (clobber (match_scratch:DI 0 "=rm"))]
6061   "TARGET_64BIT
6062    && ix86_match_ccmode (insn, CCGCmode)"
6063 {
6064   switch (get_attr_type (insn))
6065     {
6066     case TYPE_INCDEC:
6067       if (operands[2] == constm1_rtx)
6068         return "inc{q}\t%0";
6069       else
6070         {
6071           gcc_assert (operands[2] == const1_rtx);
6072           return "dec{q}\t%0";
6073         }
6074
6075     default:
6076       if (x86_maybe_negate_const_int (&operands[2], DImode))
6077         return "add{q}\t{%2, %0|%0, %2}";
6078
6079       return "sub{q}\t{%2, %0|%0, %2}";
6080     }
6081 }
6082   [(set (attr "type")
6083      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6084         (const_string "incdec")
6085         (const_string "alu")))
6086    (set (attr "length_immediate")
6087       (if_then_else
6088         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6089         (const_string "1")
6090         (const_string "*")))
6091    (set_attr "mode" "DI")])
6092
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6095 ; is matched then.  We can't accept general immediate, because for
6096 ; case of overflows,  the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6099
6100 (define_insn "*add<mode>_4"
6101   [(set (reg FLAGS_REG)
6102         (compare
6103           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6104           (match_operand:SWI124 2 "const_int_operand" "n")))
6105    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6106   "ix86_match_ccmode (insn, CCGCmode)"
6107 {
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_INCDEC:
6111       if (operands[2] == constm1_rtx)
6112         return "inc{<imodesuffix>}\t%0";
6113       else
6114         {
6115           gcc_assert (operands[2] == const1_rtx);
6116           return "dec{<imodesuffix>}\t%0";
6117         }
6118
6119     default:
6120       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6122
6123       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6124     }
6125 }
6126   [(set (attr "type")
6127      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6128         (const_string "incdec")
6129         (const_string "alu")))
6130    (set (attr "length_immediate")
6131       (if_then_else
6132         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6133         (const_string "1")
6134         (const_string "*")))
6135    (set_attr "mode" "<MODE>")])
6136
6137 (define_insn "*add<mode>_5"
6138   [(set (reg FLAGS_REG)
6139         (compare
6140           (plus:SWI
6141             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6142             (match_operand:SWI 2 "<general_operand>" "<g>"))
6143           (const_int 0)))
6144    (clobber (match_scratch:SWI 0 "=<r>"))]
6145   "ix86_match_ccmode (insn, CCGOCmode)
6146    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6147 {
6148   switch (get_attr_type (insn))
6149     {
6150     case TYPE_INCDEC:
6151       if (operands[2] == const1_rtx)
6152         return "inc{<imodesuffix>}\t%0";
6153       else
6154         {
6155           gcc_assert (operands[2] == constm1_rtx);
6156           return "dec{<imodesuffix>}\t%0";
6157         }
6158
6159     default:
6160       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6161         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6162
6163       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6164     }
6165 }
6166   [(set (attr "type")
6167      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6168         (const_string "incdec")
6169         (const_string "alu")))
6170    (set (attr "length_immediate")
6171       (if_then_else
6172         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6173         (const_string "1")
6174         (const_string "*")))
6175    (set_attr "mode" "<MODE>")])
6176
6177 (define_insn "*addqi_ext_1_rex64"
6178   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6179                          (const_int 8)
6180                          (const_int 8))
6181         (plus:SI
6182           (zero_extract:SI
6183             (match_operand 1 "ext_register_operand" "0")
6184             (const_int 8)
6185             (const_int 8))
6186           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6187    (clobber (reg:CC FLAGS_REG))]
6188   "TARGET_64BIT"
6189 {
6190   switch (get_attr_type (insn))
6191     {
6192     case TYPE_INCDEC:
6193       if (operands[2] == const1_rtx)
6194         return "inc{b}\t%h0";
6195       else
6196         {
6197           gcc_assert (operands[2] == constm1_rtx);
6198           return "dec{b}\t%h0";
6199         }
6200
6201     default:
6202       return "add{b}\t{%2, %h0|%h0, %2}";
6203     }
6204 }
6205   [(set (attr "type")
6206      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6207         (const_string "incdec")
6208         (const_string "alu")))
6209    (set_attr "modrm" "1")
6210    (set_attr "mode" "QI")])
6211
6212 (define_insn "addqi_ext_1"
6213   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6214                          (const_int 8)
6215                          (const_int 8))
6216         (plus:SI
6217           (zero_extract:SI
6218             (match_operand 1 "ext_register_operand" "0")
6219             (const_int 8)
6220             (const_int 8))
6221           (match_operand:QI 2 "general_operand" "Qmn")))
6222    (clobber (reg:CC FLAGS_REG))]
6223   "!TARGET_64BIT"
6224 {
6225   switch (get_attr_type (insn))
6226     {
6227     case TYPE_INCDEC:
6228       if (operands[2] == const1_rtx)
6229         return "inc{b}\t%h0";
6230       else
6231         {
6232           gcc_assert (operands[2] == constm1_rtx);
6233           return "dec{b}\t%h0";
6234         }
6235
6236     default:
6237       return "add{b}\t{%2, %h0|%h0, %2}";
6238     }
6239 }
6240   [(set (attr "type")
6241      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242         (const_string "incdec")
6243         (const_string "alu")))
6244    (set_attr "modrm" "1")
6245    (set_attr "mode" "QI")])
6246
6247 (define_insn "*addqi_ext_2"
6248   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6249                          (const_int 8)
6250                          (const_int 8))
6251         (plus:SI
6252           (zero_extract:SI
6253             (match_operand 1 "ext_register_operand" "%0")
6254             (const_int 8)
6255             (const_int 8))
6256           (zero_extract:SI
6257             (match_operand 2 "ext_register_operand" "Q")
6258             (const_int 8)
6259             (const_int 8))))
6260    (clobber (reg:CC FLAGS_REG))]
6261   ""
6262   "add{b}\t{%h2, %h0|%h0, %h2}"
6263   [(set_attr "type" "alu")
6264    (set_attr "mode" "QI")])
6265
6266 ;; The lea patterns for non-Pmodes needs to be matched by
6267 ;; several insns converted to real lea by splitters.
6268
6269 (define_insn_and_split "*lea_general_1"
6270   [(set (match_operand 0 "register_operand" "=r")
6271         (plus (plus (match_operand 1 "index_register_operand" "l")
6272                     (match_operand 2 "register_operand" "r"))
6273               (match_operand 3 "immediate_operand" "i")))]
6274   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6275     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6276    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6277    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6278    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6279    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6280        || GET_MODE (operands[3]) == VOIDmode)"
6281   "#"
6282   "&& reload_completed"
6283   [(const_int 0)]
6284 {
6285   rtx pat;
6286   operands[0] = gen_lowpart (SImode, operands[0]);
6287   operands[1] = gen_lowpart (Pmode, operands[1]);
6288   operands[2] = gen_lowpart (Pmode, operands[2]);
6289   operands[3] = gen_lowpart (Pmode, operands[3]);
6290   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6291                       operands[3]);
6292   if (Pmode != SImode)
6293     pat = gen_rtx_SUBREG (SImode, pat, 0);
6294   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6295   DONE;
6296 }
6297   [(set_attr "type" "lea")
6298    (set_attr "mode" "SI")])
6299
6300 (define_insn_and_split "*lea_general_1_zext"
6301   [(set (match_operand:DI 0 "register_operand" "=r")
6302         (zero_extend:DI
6303           (plus:SI (plus:SI
6304                      (match_operand:SI 1 "index_register_operand" "l")
6305                      (match_operand:SI 2 "register_operand" "r"))
6306                    (match_operand:SI 3 "immediate_operand" "i"))))]
6307   "TARGET_64BIT"
6308   "#"
6309   "&& reload_completed"
6310   [(set (match_dup 0)
6311         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6312                                                      (match_dup 2))
6313                                             (match_dup 3)) 0)))]
6314 {
6315   operands[1] = gen_lowpart (Pmode, operands[1]);
6316   operands[2] = gen_lowpart (Pmode, operands[2]);
6317   operands[3] = gen_lowpart (Pmode, operands[3]);
6318 }
6319   [(set_attr "type" "lea")
6320    (set_attr "mode" "SI")])
6321
6322 (define_insn_and_split "*lea_general_2"
6323   [(set (match_operand 0 "register_operand" "=r")
6324         (plus (mult (match_operand 1 "index_register_operand" "l")
6325                     (match_operand 2 "const248_operand" "i"))
6326               (match_operand 3 "nonmemory_operand" "ri")))]
6327   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6328     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6329    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6330    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6331    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6332        || GET_MODE (operands[3]) == VOIDmode)"
6333   "#"
6334   "&& reload_completed"
6335   [(const_int 0)]
6336 {
6337   rtx pat;
6338   operands[0] = gen_lowpart (SImode, operands[0]);
6339   operands[1] = gen_lowpart (Pmode, operands[1]);
6340   operands[3] = gen_lowpart (Pmode, operands[3]);
6341   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6342                       operands[3]);
6343   if (Pmode != SImode)
6344     pat = gen_rtx_SUBREG (SImode, pat, 0);
6345   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6346   DONE;
6347 }
6348   [(set_attr "type" "lea")
6349    (set_attr "mode" "SI")])
6350
6351 (define_insn_and_split "*lea_general_2_zext"
6352   [(set (match_operand:DI 0 "register_operand" "=r")
6353         (zero_extend:DI
6354           (plus:SI (mult:SI
6355                      (match_operand:SI 1 "index_register_operand" "l")
6356                      (match_operand:SI 2 "const248_operand" "n"))
6357                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6358   "TARGET_64BIT"
6359   "#"
6360   "&& reload_completed"
6361   [(set (match_dup 0)
6362         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6363                                                      (match_dup 2))
6364                                             (match_dup 3)) 0)))]
6365 {
6366   operands[1] = gen_lowpart (Pmode, operands[1]);
6367   operands[3] = gen_lowpart (Pmode, operands[3]);
6368 }
6369   [(set_attr "type" "lea")
6370    (set_attr "mode" "SI")])
6371
6372 (define_insn_and_split "*lea_general_3"
6373   [(set (match_operand 0 "register_operand" "=r")
6374         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6375                           (match_operand 2 "const248_operand" "i"))
6376                     (match_operand 3 "register_operand" "r"))
6377               (match_operand 4 "immediate_operand" "i")))]
6378   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6379     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6380    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6381    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6382    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6383   "#"
6384   "&& reload_completed"
6385   [(const_int 0)]
6386 {
6387   rtx pat;
6388   operands[0] = gen_lowpart (SImode, operands[0]);
6389   operands[1] = gen_lowpart (Pmode, operands[1]);
6390   operands[3] = gen_lowpart (Pmode, operands[3]);
6391   operands[4] = gen_lowpart (Pmode, operands[4]);
6392   pat = gen_rtx_PLUS (Pmode,
6393                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6394                                                          operands[2]),
6395                                     operands[3]),
6396                       operands[4]);
6397   if (Pmode != SImode)
6398     pat = gen_rtx_SUBREG (SImode, pat, 0);
6399   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6400   DONE;
6401 }
6402   [(set_attr "type" "lea")
6403    (set_attr "mode" "SI")])
6404
6405 (define_insn_and_split "*lea_general_3_zext"
6406   [(set (match_operand:DI 0 "register_operand" "=r")
6407         (zero_extend:DI
6408           (plus:SI (plus:SI
6409                      (mult:SI
6410                        (match_operand:SI 1 "index_register_operand" "l")
6411                        (match_operand:SI 2 "const248_operand" "n"))
6412                      (match_operand:SI 3 "register_operand" "r"))
6413                    (match_operand:SI 4 "immediate_operand" "i"))))]
6414   "TARGET_64BIT"
6415   "#"
6416   "&& reload_completed"
6417   [(set (match_dup 0)
6418         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6419                                                               (match_dup 2))
6420                                                      (match_dup 3))
6421                                             (match_dup 4)) 0)))]
6422 {
6423   operands[1] = gen_lowpart (Pmode, operands[1]);
6424   operands[3] = gen_lowpart (Pmode, operands[3]);
6425   operands[4] = gen_lowpart (Pmode, operands[4]);
6426 }
6427   [(set_attr "type" "lea")
6428    (set_attr "mode" "SI")])
6429 \f
6430 ;; Subtract instructions
6431
6432 (define_expand "sub<mode>3"
6433   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6434         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6435                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6436   ""
6437   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6438
6439 (define_insn_and_split "*sub<dwi>3_doubleword"
6440   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6441         (minus:<DWI>
6442           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6443           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6444    (clobber (reg:CC FLAGS_REG))]
6445   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6446   "#"
6447   "reload_completed"
6448   [(parallel [(set (reg:CC FLAGS_REG)
6449                    (compare:CC (match_dup 1) (match_dup 2)))
6450               (set (match_dup 0)
6451                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6452    (parallel [(set (match_dup 3)
6453                    (minus:DWIH
6454                      (match_dup 4)
6455                      (plus:DWIH
6456                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6457                        (match_dup 5))))
6458               (clobber (reg:CC FLAGS_REG))])]
6459   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6460
6461 (define_insn "*sub<mode>_1"
6462   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463         (minus:SWI
6464           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6465           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6466    (clobber (reg:CC FLAGS_REG))]
6467   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6468   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6469   [(set_attr "type" "alu")
6470    (set_attr "mode" "<MODE>")])
6471
6472 (define_insn "*subsi_1_zext"
6473   [(set (match_operand:DI 0 "register_operand" "=r")
6474         (zero_extend:DI
6475           (minus:SI (match_operand:SI 1 "register_operand" "0")
6476                     (match_operand:SI 2 "general_operand" "g"))))
6477    (clobber (reg:CC FLAGS_REG))]
6478   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6479   "sub{l}\t{%2, %k0|%k0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "mode" "SI")])
6482
6483 (define_insn "*subqi_1_slp"
6484   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6485         (minus:QI (match_dup 0)
6486                   (match_operand:QI 1 "general_operand" "qn,qm")))
6487    (clobber (reg:CC FLAGS_REG))]
6488   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6489    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6490   "sub{b}\t{%1, %0|%0, %1}"
6491   [(set_attr "type" "alu1")
6492    (set_attr "mode" "QI")])
6493
6494 (define_insn "*sub<mode>_2"
6495   [(set (reg FLAGS_REG)
6496         (compare
6497           (minus:SWI
6498             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6499             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6500           (const_int 0)))
6501    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6502         (minus:SWI (match_dup 1) (match_dup 2)))]
6503   "ix86_match_ccmode (insn, CCGOCmode)
6504    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506   [(set_attr "type" "alu")
6507    (set_attr "mode" "<MODE>")])
6508
6509 (define_insn "*subsi_2_zext"
6510   [(set (reg FLAGS_REG)
6511         (compare
6512           (minus:SI (match_operand:SI 1 "register_operand" "0")
6513                     (match_operand:SI 2 "general_operand" "g"))
6514           (const_int 0)))
6515    (set (match_operand:DI 0 "register_operand" "=r")
6516         (zero_extend:DI
6517           (minus:SI (match_dup 1)
6518                     (match_dup 2))))]
6519   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6520    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6521   "sub{l}\t{%2, %k0|%k0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "mode" "SI")])
6524
6525 (define_insn "*sub<mode>_3"
6526   [(set (reg FLAGS_REG)
6527         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6528                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6529    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530         (minus:SWI (match_dup 1) (match_dup 2)))]
6531   "ix86_match_ccmode (insn, CCmode)
6532    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6533   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6534   [(set_attr "type" "alu")
6535    (set_attr "mode" "<MODE>")])
6536
6537 (define_insn "*subsi_3_zext"
6538   [(set (reg FLAGS_REG)
6539         (compare (match_operand:SI 1 "register_operand" "0")
6540                  (match_operand:SI 2 "general_operand" "g")))
6541    (set (match_operand:DI 0 "register_operand" "=r")
6542         (zero_extend:DI
6543           (minus:SI (match_dup 1)
6544                     (match_dup 2))))]
6545   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6546    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6547   "sub{l}\t{%2, %1|%1, %2}"
6548   [(set_attr "type" "alu")
6549    (set_attr "mode" "SI")])
6550 \f
6551 ;; Add with carry and subtract with borrow
6552
6553 (define_expand "<plusminus_insn><mode>3_carry"
6554   [(parallel
6555     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6556           (plusminus:SWI
6557             (match_operand:SWI 1 "nonimmediate_operand" "")
6558             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6559                        [(match_operand 3 "flags_reg_operand" "")
6560                         (const_int 0)])
6561                       (match_operand:SWI 2 "<general_operand>" ""))))
6562      (clobber (reg:CC FLAGS_REG))])]
6563   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6564
6565 (define_insn "*<plusminus_insn><mode>3_carry"
6566   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6567         (plusminus:SWI
6568           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6569           (plus:SWI
6570             (match_operator 3 "ix86_carry_flag_operator"
6571              [(reg FLAGS_REG) (const_int 0)])
6572             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6573    (clobber (reg:CC FLAGS_REG))]
6574   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6575   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "use_carry" "1")
6578    (set_attr "pent_pair" "pu")
6579    (set_attr "mode" "<MODE>")])
6580
6581 (define_insn "*addsi3_carry_zext"
6582   [(set (match_operand:DI 0 "register_operand" "=r")
6583         (zero_extend:DI
6584           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6585                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6586                              [(reg FLAGS_REG) (const_int 0)])
6587                             (match_operand:SI 2 "general_operand" "g")))))
6588    (clobber (reg:CC FLAGS_REG))]
6589   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6590   "adc{l}\t{%2, %k0|%k0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "use_carry" "1")
6593    (set_attr "pent_pair" "pu")
6594    (set_attr "mode" "SI")])
6595
6596 (define_insn "*subsi3_carry_zext"
6597   [(set (match_operand:DI 0 "register_operand" "=r")
6598         (zero_extend:DI
6599           (minus:SI (match_operand:SI 1 "register_operand" "0")
6600                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6601                               [(reg FLAGS_REG) (const_int 0)])
6602                              (match_operand:SI 2 "general_operand" "g")))))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6605   "sbb{l}\t{%2, %k0|%k0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "pent_pair" "pu")
6608    (set_attr "mode" "SI")])
6609 \f
6610 ;; Overflow setting add and subtract instructions
6611
6612 (define_insn "*add<mode>3_cconly_overflow"
6613   [(set (reg:CCC FLAGS_REG)
6614         (compare:CCC
6615           (plus:SWI
6616             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6617             (match_operand:SWI 2 "<general_operand>" "<g>"))
6618           (match_dup 1)))
6619    (clobber (match_scratch:SWI 0 "=<r>"))]
6620   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6621   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "mode" "<MODE>")])
6624
6625 (define_insn "*sub<mode>3_cconly_overflow"
6626   [(set (reg:CCC FLAGS_REG)
6627         (compare:CCC
6628           (minus:SWI
6629             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6630             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6631           (match_dup 0)))]
6632   ""
6633   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6634   [(set_attr "type" "icmp")
6635    (set_attr "mode" "<MODE>")])
6636
6637 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6638   [(set (reg:CCC FLAGS_REG)
6639         (compare:CCC
6640             (plusminus:SWI
6641                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6642                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6643             (match_dup 1)))
6644    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6645         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6646   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6647   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6648   [(set_attr "type" "alu")
6649    (set_attr "mode" "<MODE>")])
6650
6651 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6652   [(set (reg:CCC FLAGS_REG)
6653         (compare:CCC
6654           (plusminus:SI
6655             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6656             (match_operand:SI 2 "general_operand" "g"))
6657           (match_dup 1)))
6658    (set (match_operand:DI 0 "register_operand" "=r")
6659         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6660   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6661   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "mode" "SI")])
6664
6665 ;; The patterns that match these are at the end of this file.
6666
6667 (define_expand "<plusminus_insn>xf3"
6668   [(set (match_operand:XF 0 "register_operand" "")
6669         (plusminus:XF
6670           (match_operand:XF 1 "register_operand" "")
6671           (match_operand:XF 2 "register_operand" "")))]
6672   "TARGET_80387")
6673
6674 (define_expand "<plusminus_insn><mode>3"
6675   [(set (match_operand:MODEF 0 "register_operand" "")
6676         (plusminus:MODEF
6677           (match_operand:MODEF 1 "register_operand" "")
6678           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6679   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6680     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6681 \f
6682 ;; Multiply instructions
6683
6684 (define_expand "mul<mode>3"
6685   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6686                    (mult:SWIM248
6687                      (match_operand:SWIM248 1 "register_operand" "")
6688                      (match_operand:SWIM248 2 "<general_operand>" "")))
6689               (clobber (reg:CC FLAGS_REG))])])
6690
6691 (define_expand "mulqi3"
6692   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6693                    (mult:QI
6694                      (match_operand:QI 1 "register_operand" "")
6695                      (match_operand:QI 2 "nonimmediate_operand" "")))
6696               (clobber (reg:CC FLAGS_REG))])]
6697   "TARGET_QIMODE_MATH")
6698
6699 ;; On AMDFAM10
6700 ;; IMUL reg32/64, reg32/64, imm8        Direct
6701 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6702 ;; IMUL reg32/64, reg32/64, imm32       Direct
6703 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6704 ;; IMUL reg32/64, reg32/64              Direct
6705 ;; IMUL reg32/64, mem32/64              Direct
6706 ;;
6707 ;; On BDVER1, all above IMULs use DirectPath
6708
6709 (define_insn "*mul<mode>3_1"
6710   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6711         (mult:SWI48
6712           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6713           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6714    (clobber (reg:CC FLAGS_REG))]
6715   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716   "@
6717    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6718    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6719    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "imul")
6721    (set_attr "prefix_0f" "0,0,1")
6722    (set (attr "athlon_decode")
6723         (cond [(eq_attr "cpu" "athlon")
6724                   (const_string "vector")
6725                (eq_attr "alternative" "1")
6726                   (const_string "vector")
6727                (and (eq_attr "alternative" "2")
6728                     (match_operand 1 "memory_operand" ""))
6729                   (const_string "vector")]
6730               (const_string "direct")))
6731    (set (attr "amdfam10_decode")
6732         (cond [(and (eq_attr "alternative" "0,1")
6733                     (match_operand 1 "memory_operand" ""))
6734                   (const_string "vector")]
6735               (const_string "direct")))
6736    (set_attr "bdver1_decode" "direct")
6737    (set_attr "mode" "<MODE>")])
6738
6739 (define_insn "*mulsi3_1_zext"
6740   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6741         (zero_extend:DI
6742           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6743                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6744    (clobber (reg:CC FLAGS_REG))]
6745   "TARGET_64BIT
6746    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6747   "@
6748    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6749    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6750    imul{l}\t{%2, %k0|%k0, %2}"
6751   [(set_attr "type" "imul")
6752    (set_attr "prefix_0f" "0,0,1")
6753    (set (attr "athlon_decode")
6754         (cond [(eq_attr "cpu" "athlon")
6755                   (const_string "vector")
6756                (eq_attr "alternative" "1")
6757                   (const_string "vector")
6758                (and (eq_attr "alternative" "2")
6759                     (match_operand 1 "memory_operand" ""))
6760                   (const_string "vector")]
6761               (const_string "direct")))
6762    (set (attr "amdfam10_decode")
6763         (cond [(and (eq_attr "alternative" "0,1")
6764                     (match_operand 1 "memory_operand" ""))
6765                   (const_string "vector")]
6766               (const_string "direct")))
6767    (set_attr "bdver1_decode" "direct")
6768    (set_attr "mode" "SI")])
6769
6770 ;; On AMDFAM10
6771 ;; IMUL reg16, reg16, imm8      VectorPath
6772 ;; IMUL reg16, mem16, imm8      VectorPath
6773 ;; IMUL reg16, reg16, imm16     VectorPath
6774 ;; IMUL reg16, mem16, imm16     VectorPath
6775 ;; IMUL reg16, reg16            Direct
6776 ;; IMUL reg16, mem16            Direct
6777 ;;
6778 ;; On BDVER1, all HI MULs use DoublePath
6779
6780 (define_insn "*mulhi3_1"
6781   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6782         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6783                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6784    (clobber (reg:CC FLAGS_REG))]
6785   "TARGET_HIMODE_MATH
6786    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6787   "@
6788    imul{w}\t{%2, %1, %0|%0, %1, %2}
6789    imul{w}\t{%2, %1, %0|%0, %1, %2}
6790    imul{w}\t{%2, %0|%0, %2}"
6791   [(set_attr "type" "imul")
6792    (set_attr "prefix_0f" "0,0,1")
6793    (set (attr "athlon_decode")
6794         (cond [(eq_attr "cpu" "athlon")
6795                   (const_string "vector")
6796                (eq_attr "alternative" "1,2")
6797                   (const_string "vector")]
6798               (const_string "direct")))
6799    (set (attr "amdfam10_decode")
6800         (cond [(eq_attr "alternative" "0,1")
6801                   (const_string "vector")]
6802               (const_string "direct")))
6803    (set_attr "bdver1_decode" "double")
6804    (set_attr "mode" "HI")])
6805
6806 ;;On AMDFAM10 and BDVER1
6807 ;; MUL reg8     Direct
6808 ;; MUL mem8     Direct
6809
6810 (define_insn "*mulqi3_1"
6811   [(set (match_operand:QI 0 "register_operand" "=a")
6812         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6813                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6814    (clobber (reg:CC FLAGS_REG))]
6815   "TARGET_QIMODE_MATH
6816    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6817   "mul{b}\t%2"
6818   [(set_attr "type" "imul")
6819    (set_attr "length_immediate" "0")
6820    (set (attr "athlon_decode")
6821      (if_then_else (eq_attr "cpu" "athlon")
6822         (const_string "vector")
6823         (const_string "direct")))
6824    (set_attr "amdfam10_decode" "direct")
6825    (set_attr "bdver1_decode" "direct")
6826    (set_attr "mode" "QI")])
6827
6828 (define_expand "<u>mul<mode><dwi>3"
6829   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6830                    (mult:<DWI>
6831                      (any_extend:<DWI>
6832                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6833                      (any_extend:<DWI>
6834                        (match_operand:DWIH 2 "register_operand" ""))))
6835               (clobber (reg:CC FLAGS_REG))])])
6836
6837 (define_expand "<u>mulqihi3"
6838   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6839                    (mult:HI
6840                      (any_extend:HI
6841                        (match_operand:QI 1 "nonimmediate_operand" ""))
6842                      (any_extend:HI
6843                        (match_operand:QI 2 "register_operand" ""))))
6844               (clobber (reg:CC FLAGS_REG))])]
6845   "TARGET_QIMODE_MATH")
6846
6847 (define_insn "*<u>mul<mode><dwi>3_1"
6848   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6849         (mult:<DWI>
6850           (any_extend:<DWI>
6851             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6852           (any_extend:<DWI>
6853             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6854    (clobber (reg:CC FLAGS_REG))]
6855   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856   "<sgnprefix>mul{<imodesuffix>}\t%2"
6857   [(set_attr "type" "imul")
6858    (set_attr "length_immediate" "0")
6859    (set (attr "athlon_decode")
6860      (if_then_else (eq_attr "cpu" "athlon")
6861         (const_string "vector")
6862         (const_string "double")))
6863    (set_attr "amdfam10_decode" "double")
6864    (set_attr "bdver1_decode" "direct")
6865    (set_attr "mode" "<MODE>")])
6866
6867 (define_insn "*<u>mulqihi3_1"
6868   [(set (match_operand:HI 0 "register_operand" "=a")
6869         (mult:HI
6870           (any_extend:HI
6871             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6872           (any_extend:HI
6873             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6874    (clobber (reg:CC FLAGS_REG))]
6875   "TARGET_QIMODE_MATH
6876    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6877   "<sgnprefix>mul{b}\t%2"
6878   [(set_attr "type" "imul")
6879    (set_attr "length_immediate" "0")
6880    (set (attr "athlon_decode")
6881      (if_then_else (eq_attr "cpu" "athlon")
6882         (const_string "vector")
6883         (const_string "direct")))
6884    (set_attr "amdfam10_decode" "direct")
6885    (set_attr "bdver1_decode" "direct")
6886    (set_attr "mode" "QI")])
6887
6888 (define_expand "<s>mul<mode>3_highpart"
6889   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6890                    (truncate:SWI48
6891                      (lshiftrt:<DWI>
6892                        (mult:<DWI>
6893                          (any_extend:<DWI>
6894                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6895                          (any_extend:<DWI>
6896                            (match_operand:SWI48 2 "register_operand" "")))
6897                        (match_dup 4))))
6898               (clobber (match_scratch:SWI48 3 ""))
6899               (clobber (reg:CC FLAGS_REG))])]
6900   ""
6901   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6902
6903 (define_insn "*<s>muldi3_highpart_1"
6904   [(set (match_operand:DI 0 "register_operand" "=d")
6905         (truncate:DI
6906           (lshiftrt:TI
6907             (mult:TI
6908               (any_extend:TI
6909                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6910               (any_extend:TI
6911                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6912             (const_int 64))))
6913    (clobber (match_scratch:DI 3 "=1"))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "TARGET_64BIT
6916    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917   "<sgnprefix>mul{q}\t%2"
6918   [(set_attr "type" "imul")
6919    (set_attr "length_immediate" "0")
6920    (set (attr "athlon_decode")
6921      (if_then_else (eq_attr "cpu" "athlon")
6922         (const_string "vector")
6923         (const_string "double")))
6924    (set_attr "amdfam10_decode" "double")
6925    (set_attr "bdver1_decode" "direct")
6926    (set_attr "mode" "DI")])
6927
6928 (define_insn "*<s>mulsi3_highpart_1"
6929   [(set (match_operand:SI 0 "register_operand" "=d")
6930         (truncate:SI
6931           (lshiftrt:DI
6932             (mult:DI
6933               (any_extend:DI
6934                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6935               (any_extend:DI
6936                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6937             (const_int 32))))
6938    (clobber (match_scratch:SI 3 "=1"))
6939    (clobber (reg:CC FLAGS_REG))]
6940   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941   "<sgnprefix>mul{l}\t%2"
6942   [(set_attr "type" "imul")
6943    (set_attr "length_immediate" "0")
6944    (set (attr "athlon_decode")
6945      (if_then_else (eq_attr "cpu" "athlon")
6946         (const_string "vector")
6947         (const_string "double")))
6948    (set_attr "amdfam10_decode" "double")
6949    (set_attr "bdver1_decode" "direct")
6950    (set_attr "mode" "SI")])
6951
6952 (define_insn "*<s>mulsi3_highpart_zext"
6953   [(set (match_operand:DI 0 "register_operand" "=d")
6954         (zero_extend:DI (truncate:SI
6955           (lshiftrt:DI
6956             (mult:DI (any_extend:DI
6957                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6958                      (any_extend:DI
6959                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6960             (const_int 32)))))
6961    (clobber (match_scratch:SI 3 "=1"))
6962    (clobber (reg:CC FLAGS_REG))]
6963   "TARGET_64BIT
6964    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965   "<sgnprefix>mul{l}\t%2"
6966   [(set_attr "type" "imul")
6967    (set_attr "length_immediate" "0")
6968    (set (attr "athlon_decode")
6969      (if_then_else (eq_attr "cpu" "athlon")
6970         (const_string "vector")
6971         (const_string "double")))
6972    (set_attr "amdfam10_decode" "double")
6973    (set_attr "bdver1_decode" "direct")
6974    (set_attr "mode" "SI")])
6975
6976 ;; The patterns that match these are at the end of this file.
6977
6978 (define_expand "mulxf3"
6979   [(set (match_operand:XF 0 "register_operand" "")
6980         (mult:XF (match_operand:XF 1 "register_operand" "")
6981                  (match_operand:XF 2 "register_operand" "")))]
6982   "TARGET_80387")
6983
6984 (define_expand "mul<mode>3"
6985   [(set (match_operand:MODEF 0 "register_operand" "")
6986         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6987                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6988   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6989     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6990 \f
6991 ;; Divide instructions
6992
6993 ;; The patterns that match these are at the end of this file.
6994
6995 (define_expand "divxf3"
6996   [(set (match_operand:XF 0 "register_operand" "")
6997         (div:XF (match_operand:XF 1 "register_operand" "")
6998                 (match_operand:XF 2 "register_operand" "")))]
6999   "TARGET_80387")
7000
7001 (define_expand "divdf3"
7002   [(set (match_operand:DF 0 "register_operand" "")
7003         (div:DF (match_operand:DF 1 "register_operand" "")
7004                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7005    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7006     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7007
7008 (define_expand "divsf3"
7009   [(set (match_operand:SF 0 "register_operand" "")
7010         (div:SF (match_operand:SF 1 "register_operand" "")
7011                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7012   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7013     || TARGET_SSE_MATH"
7014 {
7015   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7016       && flag_finite_math_only && !flag_trapping_math
7017       && flag_unsafe_math_optimizations)
7018     {
7019       ix86_emit_swdivsf (operands[0], operands[1],
7020                          operands[2], SFmode);
7021       DONE;
7022     }
7023 })
7024 \f
7025 ;; Divmod instructions.
7026
7027 (define_expand "divmod<mode>4"
7028   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7029                    (div:SWIM248
7030                      (match_operand:SWIM248 1 "register_operand" "")
7031                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7032               (set (match_operand:SWIM248 3 "register_operand" "")
7033                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7034               (clobber (reg:CC FLAGS_REG))])])
7035
7036 ;; Split with 8bit unsigned divide:
7037 ;;      if (dividend an divisor are in [0-255])
7038 ;;         use 8bit unsigned integer divide
7039 ;;       else
7040 ;;         use original integer divide
7041 (define_split
7042   [(set (match_operand:SWI48 0 "register_operand" "")
7043         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7044                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7045    (set (match_operand:SWI48 1 "register_operand" "")
7046         (mod:SWI48 (match_dup 2) (match_dup 3)))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "TARGET_USE_8BIT_IDIV
7049    && TARGET_QIMODE_MATH
7050    && can_create_pseudo_p ()
7051    && !optimize_insn_for_size_p ()"
7052   [(const_int 0)]
7053   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7054
7055 (define_insn_and_split "divmod<mode>4_1"
7056   [(set (match_operand:SWI48 0 "register_operand" "=a")
7057         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7058                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7059    (set (match_operand:SWI48 1 "register_operand" "=&d")
7060         (mod:SWI48 (match_dup 2) (match_dup 3)))
7061    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7062    (clobber (reg:CC FLAGS_REG))]
7063   ""
7064   "#"
7065   "reload_completed"
7066   [(parallel [(set (match_dup 1)
7067                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7068               (clobber (reg:CC FLAGS_REG))])
7069    (parallel [(set (match_dup 0)
7070                    (div:SWI48 (match_dup 2) (match_dup 3)))
7071               (set (match_dup 1)
7072                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7073               (use (match_dup 1))
7074               (clobber (reg:CC FLAGS_REG))])]
7075 {
7076   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7077
7078   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7079     operands[4] = operands[2];
7080   else
7081     {
7082       /* Avoid use of cltd in favor of a mov+shift.  */
7083       emit_move_insn (operands[1], operands[2]);
7084       operands[4] = operands[1];
7085     }
7086 }
7087   [(set_attr "type" "multi")
7088    (set_attr "mode" "<MODE>")])
7089
7090 (define_insn_and_split "*divmod<mode>4"
7091   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7092         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7093                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7094    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7095         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7096    (clobber (reg:CC FLAGS_REG))]
7097   ""
7098   "#"
7099   "reload_completed"
7100   [(parallel [(set (match_dup 1)
7101                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7102               (clobber (reg:CC FLAGS_REG))])
7103    (parallel [(set (match_dup 0)
7104                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7105               (set (match_dup 1)
7106                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7107               (use (match_dup 1))
7108               (clobber (reg:CC FLAGS_REG))])]
7109 {
7110   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7111
7112   if (<MODE>mode != HImode
7113       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7114     operands[4] = operands[2];
7115   else
7116     {
7117       /* Avoid use of cltd in favor of a mov+shift.  */
7118       emit_move_insn (operands[1], operands[2]);
7119       operands[4] = operands[1];
7120     }
7121 }
7122   [(set_attr "type" "multi")
7123    (set_attr "mode" "<MODE>")])
7124
7125 (define_insn "*divmod<mode>4_noext"
7126   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129    (set (match_operand:SWIM248 1 "register_operand" "=d")
7130         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7131    (use (match_operand:SWIM248 4 "register_operand" "1"))
7132    (clobber (reg:CC FLAGS_REG))]
7133   ""
7134   "idiv{<imodesuffix>}\t%3"
7135   [(set_attr "type" "idiv")
7136    (set_attr "mode" "<MODE>")])
7137
7138 (define_expand "divmodqi4"
7139   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7140                    (div:QI
7141                      (match_operand:QI 1 "register_operand" "")
7142                      (match_operand:QI 2 "nonimmediate_operand" "")))
7143               (set (match_operand:QI 3 "register_operand" "")
7144                    (mod:QI (match_dup 1) (match_dup 2)))
7145               (clobber (reg:CC FLAGS_REG))])]
7146   "TARGET_QIMODE_MATH"
7147 {
7148   rtx div, mod, insn;
7149   rtx tmp0, tmp1;
7150   
7151   tmp0 = gen_reg_rtx (HImode);
7152   tmp1 = gen_reg_rtx (HImode);
7153
7154   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7155      in AX.  */
7156   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7157   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7158
7159   /* Extract remainder from AH.  */
7160   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7161   insn = emit_move_insn (operands[3], tmp1);
7162
7163   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7164   set_unique_reg_note (insn, REG_EQUAL, mod);
7165
7166   /* Extract quotient from AL.  */
7167   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7168
7169   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7170   set_unique_reg_note (insn, REG_EQUAL, div);
7171
7172   DONE;
7173 })
7174
7175 ;; Divide AX by r/m8, with result stored in
7176 ;; AL <- Quotient
7177 ;; AH <- Remainder
7178 ;; Change div/mod to HImode and extend the second argument to HImode
7179 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7180 ;; combine may fail.
7181 (define_insn "divmodhiqi3"
7182   [(set (match_operand:HI 0 "register_operand" "=a")
7183         (ior:HI
7184           (ashift:HI
7185             (zero_extend:HI
7186               (truncate:QI
7187                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7188                         (sign_extend:HI
7189                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7190             (const_int 8))
7191           (zero_extend:HI
7192             (truncate:QI
7193               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7194    (clobber (reg:CC FLAGS_REG))]
7195   "TARGET_QIMODE_MATH"
7196   "idiv{b}\t%2"
7197   [(set_attr "type" "idiv")
7198    (set_attr "mode" "QI")])
7199
7200 (define_expand "udivmod<mode>4"
7201   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7202                    (udiv:SWIM248
7203                      (match_operand:SWIM248 1 "register_operand" "")
7204                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7205               (set (match_operand:SWIM248 3 "register_operand" "")
7206                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7207               (clobber (reg:CC FLAGS_REG))])])
7208
7209 ;; Split with 8bit unsigned divide:
7210 ;;      if (dividend an divisor are in [0-255])
7211 ;;         use 8bit unsigned integer divide
7212 ;;       else
7213 ;;         use original integer divide
7214 (define_split
7215   [(set (match_operand:SWI48 0 "register_operand" "")
7216         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7217                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7218    (set (match_operand:SWI48 1 "register_operand" "")
7219         (umod:SWI48 (match_dup 2) (match_dup 3)))
7220    (clobber (reg:CC FLAGS_REG))]
7221   "TARGET_USE_8BIT_IDIV
7222    && TARGET_QIMODE_MATH
7223    && can_create_pseudo_p ()
7224    && !optimize_insn_for_size_p ()"
7225   [(const_int 0)]
7226   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7227
7228 (define_insn_and_split "udivmod<mode>4_1"
7229   [(set (match_operand:SWI48 0 "register_operand" "=a")
7230         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7231                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7232    (set (match_operand:SWI48 1 "register_operand" "=&d")
7233         (umod:SWI48 (match_dup 2) (match_dup 3)))
7234    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7235    (clobber (reg:CC FLAGS_REG))]
7236   ""
7237   "#"
7238   "reload_completed"
7239   [(set (match_dup 1) (const_int 0))
7240    (parallel [(set (match_dup 0)
7241                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7242               (set (match_dup 1)
7243                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7244               (use (match_dup 1))
7245               (clobber (reg:CC FLAGS_REG))])]
7246   ""
7247   [(set_attr "type" "multi")
7248    (set_attr "mode" "<MODE>")])
7249
7250 (define_insn_and_split "*udivmod<mode>4"
7251   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7252         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7253                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7254    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7255         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7256    (clobber (reg:CC FLAGS_REG))]
7257   ""
7258   "#"
7259   "reload_completed"
7260   [(set (match_dup 1) (const_int 0))
7261    (parallel [(set (match_dup 0)
7262                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7263               (set (match_dup 1)
7264                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7265               (use (match_dup 1))
7266               (clobber (reg:CC FLAGS_REG))])]
7267   ""
7268   [(set_attr "type" "multi")
7269    (set_attr "mode" "<MODE>")])
7270
7271 (define_insn "*udivmod<mode>4_noext"
7272   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7273         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7274                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7275    (set (match_operand:SWIM248 1 "register_operand" "=d")
7276         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7277    (use (match_operand:SWIM248 4 "register_operand" "1"))
7278    (clobber (reg:CC FLAGS_REG))]
7279   ""
7280   "div{<imodesuffix>}\t%3"
7281   [(set_attr "type" "idiv")
7282    (set_attr "mode" "<MODE>")])
7283
7284 (define_expand "udivmodqi4"
7285   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7286                    (udiv:QI
7287                      (match_operand:QI 1 "register_operand" "")
7288                      (match_operand:QI 2 "nonimmediate_operand" "")))
7289               (set (match_operand:QI 3 "register_operand" "")
7290                    (umod:QI (match_dup 1) (match_dup 2)))
7291               (clobber (reg:CC FLAGS_REG))])]
7292   "TARGET_QIMODE_MATH"
7293 {
7294   rtx div, mod, insn;
7295   rtx tmp0, tmp1;
7296   
7297   tmp0 = gen_reg_rtx (HImode);
7298   tmp1 = gen_reg_rtx (HImode);
7299
7300   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7301      in AX.  */
7302   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7303   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7304
7305   /* Extract remainder from AH.  */
7306   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7307   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7308   insn = emit_move_insn (operands[3], tmp1);
7309
7310   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7311   set_unique_reg_note (insn, REG_EQUAL, mod);
7312
7313   /* Extract quotient from AL.  */
7314   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7315
7316   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7317   set_unique_reg_note (insn, REG_EQUAL, div);
7318
7319   DONE;
7320 })
7321
7322 (define_insn "udivmodhiqi3"
7323   [(set (match_operand:HI 0 "register_operand" "=a")
7324         (ior:HI
7325           (ashift:HI
7326             (zero_extend:HI
7327               (truncate:QI
7328                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7329                         (zero_extend:HI
7330                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7331             (const_int 8))
7332           (zero_extend:HI
7333             (truncate:QI
7334               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7335    (clobber (reg:CC FLAGS_REG))]
7336   "TARGET_QIMODE_MATH"
7337   "div{b}\t%2"
7338   [(set_attr "type" "idiv")
7339    (set_attr "mode" "QI")])
7340
7341 ;; We cannot use div/idiv for double division, because it causes
7342 ;; "division by zero" on the overflow and that's not what we expect
7343 ;; from truncate.  Because true (non truncating) double division is
7344 ;; never generated, we can't create this insn anyway.
7345 ;
7346 ;(define_insn ""
7347 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7348 ;       (truncate:SI
7349 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7350 ;                  (zero_extend:DI
7351 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7352 ;   (set (match_operand:SI 3 "register_operand" "=d")
7353 ;       (truncate:SI
7354 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7355 ;   (clobber (reg:CC FLAGS_REG))]
7356 ;  ""
7357 ;  "div{l}\t{%2, %0|%0, %2}"
7358 ;  [(set_attr "type" "idiv")])
7359 \f
7360 ;;- Logical AND instructions
7361
7362 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7363 ;; Note that this excludes ah.
7364
7365 (define_expand "testsi_ccno_1"
7366   [(set (reg:CCNO FLAGS_REG)
7367         (compare:CCNO
7368           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7369                   (match_operand:SI 1 "nonmemory_operand" ""))
7370           (const_int 0)))])
7371
7372 (define_expand "testqi_ccz_1"
7373   [(set (reg:CCZ FLAGS_REG)
7374         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7375                              (match_operand:QI 1 "nonmemory_operand" ""))
7376                  (const_int 0)))])
7377
7378 (define_expand "testdi_ccno_1"
7379   [(set (reg:CCNO FLAGS_REG)
7380         (compare:CCNO
7381           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7382                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7383           (const_int 0)))]
7384   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7385
7386 (define_insn "*testdi_1"
7387   [(set (reg FLAGS_REG)
7388         (compare
7389          (and:DI
7390           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7391           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7392          (const_int 0)))]
7393   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7394    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7395   "@
7396    test{l}\t{%k1, %k0|%k0, %k1}
7397    test{l}\t{%k1, %k0|%k0, %k1}
7398    test{q}\t{%1, %0|%0, %1}
7399    test{q}\t{%1, %0|%0, %1}
7400    test{q}\t{%1, %0|%0, %1}"
7401   [(set_attr "type" "test")
7402    (set_attr "modrm" "0,1,0,1,1")
7403    (set_attr "mode" "SI,SI,DI,DI,DI")])
7404
7405 (define_insn "*testqi_1_maybe_si"
7406   [(set (reg FLAGS_REG)
7407         (compare
7408           (and:QI
7409             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7410             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7411           (const_int 0)))]
7412    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7413     && ix86_match_ccmode (insn,
7414                          CONST_INT_P (operands[1])
7415                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7416 {
7417   if (which_alternative == 3)
7418     {
7419       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7420         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7421       return "test{l}\t{%1, %k0|%k0, %1}";
7422     }
7423   return "test{b}\t{%1, %0|%0, %1}";
7424 }
7425   [(set_attr "type" "test")
7426    (set_attr "modrm" "0,1,1,1")
7427    (set_attr "mode" "QI,QI,QI,SI")
7428    (set_attr "pent_pair" "uv,np,uv,np")])
7429
7430 (define_insn "*test<mode>_1"
7431   [(set (reg FLAGS_REG)
7432         (compare
7433          (and:SWI124
7434           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7435           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7436          (const_int 0)))]
7437   "ix86_match_ccmode (insn, CCNOmode)
7438    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7439   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7440   [(set_attr "type" "test")
7441    (set_attr "modrm" "0,1,1")
7442    (set_attr "mode" "<MODE>")
7443    (set_attr "pent_pair" "uv,np,uv")])
7444
7445 (define_expand "testqi_ext_ccno_0"
7446   [(set (reg:CCNO FLAGS_REG)
7447         (compare:CCNO
7448           (and:SI
7449             (zero_extract:SI
7450               (match_operand 0 "ext_register_operand" "")
7451               (const_int 8)
7452               (const_int 8))
7453             (match_operand 1 "const_int_operand" ""))
7454           (const_int 0)))])
7455
7456 (define_insn "*testqi_ext_0"
7457   [(set (reg FLAGS_REG)
7458         (compare
7459           (and:SI
7460             (zero_extract:SI
7461               (match_operand 0 "ext_register_operand" "Q")
7462               (const_int 8)
7463               (const_int 8))
7464             (match_operand 1 "const_int_operand" "n"))
7465           (const_int 0)))]
7466   "ix86_match_ccmode (insn, CCNOmode)"
7467   "test{b}\t{%1, %h0|%h0, %1}"
7468   [(set_attr "type" "test")
7469    (set_attr "mode" "QI")
7470    (set_attr "length_immediate" "1")
7471    (set_attr "modrm" "1")
7472    (set_attr "pent_pair" "np")])
7473
7474 (define_insn "*testqi_ext_1_rex64"
7475   [(set (reg FLAGS_REG)
7476         (compare
7477           (and:SI
7478             (zero_extract:SI
7479               (match_operand 0 "ext_register_operand" "Q")
7480               (const_int 8)
7481               (const_int 8))
7482             (zero_extend:SI
7483               (match_operand:QI 1 "register_operand" "Q")))
7484           (const_int 0)))]
7485   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7486   "test{b}\t{%1, %h0|%h0, %1}"
7487   [(set_attr "type" "test")
7488    (set_attr "mode" "QI")])
7489
7490 (define_insn "*testqi_ext_1"
7491   [(set (reg FLAGS_REG)
7492         (compare
7493           (and:SI
7494             (zero_extract:SI
7495               (match_operand 0 "ext_register_operand" "Q")
7496               (const_int 8)
7497               (const_int 8))
7498             (zero_extend:SI
7499               (match_operand:QI 1 "general_operand" "Qm")))
7500           (const_int 0)))]
7501   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7502   "test{b}\t{%1, %h0|%h0, %1}"
7503   [(set_attr "type" "test")
7504    (set_attr "mode" "QI")])
7505
7506 (define_insn "*testqi_ext_2"
7507   [(set (reg FLAGS_REG)
7508         (compare
7509           (and:SI
7510             (zero_extract:SI
7511               (match_operand 0 "ext_register_operand" "Q")
7512               (const_int 8)
7513               (const_int 8))
7514             (zero_extract:SI
7515               (match_operand 1 "ext_register_operand" "Q")
7516               (const_int 8)
7517               (const_int 8)))
7518           (const_int 0)))]
7519   "ix86_match_ccmode (insn, CCNOmode)"
7520   "test{b}\t{%h1, %h0|%h0, %h1}"
7521   [(set_attr "type" "test")
7522    (set_attr "mode" "QI")])
7523
7524 (define_insn "*testqi_ext_3_rex64"
7525   [(set (reg FLAGS_REG)
7526         (compare (zero_extract:DI
7527                    (match_operand 0 "nonimmediate_operand" "rm")
7528                    (match_operand:DI 1 "const_int_operand" "")
7529                    (match_operand:DI 2 "const_int_operand" ""))
7530                  (const_int 0)))]
7531   "TARGET_64BIT
7532    && ix86_match_ccmode (insn, CCNOmode)
7533    && INTVAL (operands[1]) > 0
7534    && INTVAL (operands[2]) >= 0
7535    /* Ensure that resulting mask is zero or sign extended operand.  */
7536    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7537        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7538            && INTVAL (operands[1]) > 32))
7539    && (GET_MODE (operands[0]) == SImode
7540        || GET_MODE (operands[0]) == DImode
7541        || GET_MODE (operands[0]) == HImode
7542        || GET_MODE (operands[0]) == QImode)"
7543   "#")
7544
7545 ;; Combine likes to form bit extractions for some tests.  Humor it.
7546 (define_insn "*testqi_ext_3"
7547   [(set (reg FLAGS_REG)
7548         (compare (zero_extract:SI
7549                    (match_operand 0 "nonimmediate_operand" "rm")
7550                    (match_operand:SI 1 "const_int_operand" "")
7551                    (match_operand:SI 2 "const_int_operand" ""))
7552                  (const_int 0)))]
7553   "ix86_match_ccmode (insn, CCNOmode)
7554    && INTVAL (operands[1]) > 0
7555    && INTVAL (operands[2]) >= 0
7556    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7557    && (GET_MODE (operands[0]) == SImode
7558        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7559        || GET_MODE (operands[0]) == HImode
7560        || GET_MODE (operands[0]) == QImode)"
7561   "#")
7562
7563 (define_split
7564   [(set (match_operand 0 "flags_reg_operand" "")
7565         (match_operator 1 "compare_operator"
7566           [(zero_extract
7567              (match_operand 2 "nonimmediate_operand" "")
7568              (match_operand 3 "const_int_operand" "")
7569              (match_operand 4 "const_int_operand" ""))
7570            (const_int 0)]))]
7571   "ix86_match_ccmode (insn, CCNOmode)"
7572   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7573 {
7574   rtx val = operands[2];
7575   HOST_WIDE_INT len = INTVAL (operands[3]);
7576   HOST_WIDE_INT pos = INTVAL (operands[4]);
7577   HOST_WIDE_INT mask;
7578   enum machine_mode mode, submode;
7579
7580   mode = GET_MODE (val);
7581   if (MEM_P (val))
7582     {
7583       /* ??? Combine likes to put non-volatile mem extractions in QImode
7584          no matter the size of the test.  So find a mode that works.  */
7585       if (! MEM_VOLATILE_P (val))
7586         {
7587           mode = smallest_mode_for_size (pos + len, MODE_INT);
7588           val = adjust_address (val, mode, 0);
7589         }
7590     }
7591   else if (GET_CODE (val) == SUBREG
7592            && (submode = GET_MODE (SUBREG_REG (val)),
7593                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7594            && pos + len <= GET_MODE_BITSIZE (submode)
7595            && GET_MODE_CLASS (submode) == MODE_INT)
7596     {
7597       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7598       mode = submode;
7599       val = SUBREG_REG (val);
7600     }
7601   else if (mode == HImode && pos + len <= 8)
7602     {
7603       /* Small HImode tests can be converted to QImode.  */
7604       mode = QImode;
7605       val = gen_lowpart (QImode, val);
7606     }
7607
7608   if (len == HOST_BITS_PER_WIDE_INT)
7609     mask = -1;
7610   else
7611     mask = ((HOST_WIDE_INT)1 << len) - 1;
7612   mask <<= pos;
7613
7614   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7615 })
7616
7617 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7618 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7619 ;; this is relatively important trick.
7620 ;; Do the conversion only post-reload to avoid limiting of the register class
7621 ;; to QI regs.
7622 (define_split
7623   [(set (match_operand 0 "flags_reg_operand" "")
7624         (match_operator 1 "compare_operator"
7625           [(and (match_operand 2 "register_operand" "")
7626                 (match_operand 3 "const_int_operand" ""))
7627            (const_int 0)]))]
7628    "reload_completed
7629     && QI_REG_P (operands[2])
7630     && GET_MODE (operands[2]) != QImode
7631     && ((ix86_match_ccmode (insn, CCZmode)
7632          && !(INTVAL (operands[3]) & ~(255 << 8)))
7633         || (ix86_match_ccmode (insn, CCNOmode)
7634             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7635   [(set (match_dup 0)
7636         (match_op_dup 1
7637           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7638                    (match_dup 3))
7639            (const_int 0)]))]
7640   "operands[2] = gen_lowpart (SImode, operands[2]);
7641    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7642
7643 (define_split
7644   [(set (match_operand 0 "flags_reg_operand" "")
7645         (match_operator 1 "compare_operator"
7646           [(and (match_operand 2 "nonimmediate_operand" "")
7647                 (match_operand 3 "const_int_operand" ""))
7648            (const_int 0)]))]
7649    "reload_completed
7650     && GET_MODE (operands[2]) != QImode
7651     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7652     && ((ix86_match_ccmode (insn, CCZmode)
7653          && !(INTVAL (operands[3]) & ~255))
7654         || (ix86_match_ccmode (insn, CCNOmode)
7655             && !(INTVAL (operands[3]) & ~127)))"
7656   [(set (match_dup 0)
7657         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7658                          (const_int 0)]))]
7659   "operands[2] = gen_lowpart (QImode, operands[2]);
7660    operands[3] = gen_lowpart (QImode, operands[3]);")
7661
7662 ;; %%% This used to optimize known byte-wide and operations to memory,
7663 ;; and sometimes to QImode registers.  If this is considered useful,
7664 ;; it should be done with splitters.
7665
7666 (define_expand "and<mode>3"
7667   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7668         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7669                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7670   ""
7671   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7672
7673 (define_insn "*anddi_1"
7674   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7675         (and:DI
7676          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7677          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7678    (clobber (reg:CC FLAGS_REG))]
7679   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7680 {
7681   switch (get_attr_type (insn))
7682     {
7683     case TYPE_IMOVX:
7684       {
7685         enum machine_mode mode;
7686
7687         gcc_assert (CONST_INT_P (operands[2]));
7688         if (INTVAL (operands[2]) == 0xff)
7689           mode = QImode;
7690         else
7691           {
7692             gcc_assert (INTVAL (operands[2]) == 0xffff);
7693             mode = HImode;
7694           }
7695
7696         operands[1] = gen_lowpart (mode, operands[1]);
7697         if (mode == QImode)
7698           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7699         else
7700           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7701       }
7702
7703     default:
7704       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705       if (get_attr_mode (insn) == MODE_SI)
7706         return "and{l}\t{%k2, %k0|%k0, %k2}";
7707       else
7708         return "and{q}\t{%2, %0|%0, %2}";
7709     }
7710 }
7711   [(set_attr "type" "alu,alu,alu,imovx")
7712    (set_attr "length_immediate" "*,*,*,0")
7713    (set (attr "prefix_rex")
7714      (if_then_else
7715        (and (eq_attr "type" "imovx")
7716             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7717                  (match_operand 1 "ext_QIreg_operand" "")))
7718        (const_string "1")
7719        (const_string "*")))
7720    (set_attr "mode" "SI,DI,DI,SI")])
7721
7722 (define_insn "*andsi_1"
7723   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7724         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7725                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7726    (clobber (reg:CC FLAGS_REG))]
7727   "ix86_binary_operator_ok (AND, SImode, operands)"
7728 {
7729   switch (get_attr_type (insn))
7730     {
7731     case TYPE_IMOVX:
7732       {
7733         enum machine_mode mode;
7734
7735         gcc_assert (CONST_INT_P (operands[2]));
7736         if (INTVAL (operands[2]) == 0xff)
7737           mode = QImode;
7738         else
7739           {
7740             gcc_assert (INTVAL (operands[2]) == 0xffff);
7741             mode = HImode;
7742           }
7743
7744         operands[1] = gen_lowpart (mode, operands[1]);
7745         if (mode == QImode)
7746           return "movz{bl|x}\t{%1, %0|%0, %1}";
7747         else
7748           return "movz{wl|x}\t{%1, %0|%0, %1}";
7749       }
7750
7751     default:
7752       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7753       return "and{l}\t{%2, %0|%0, %2}";
7754     }
7755 }
7756   [(set_attr "type" "alu,alu,imovx")
7757    (set (attr "prefix_rex")
7758      (if_then_else
7759        (and (eq_attr "type" "imovx")
7760             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7761                  (match_operand 1 "ext_QIreg_operand" "")))
7762        (const_string "1")
7763        (const_string "*")))
7764    (set_attr "length_immediate" "*,*,0")
7765    (set_attr "mode" "SI")])
7766
7767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7768 (define_insn "*andsi_1_zext"
7769   [(set (match_operand:DI 0 "register_operand" "=r")
7770         (zero_extend:DI
7771           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7772                   (match_operand:SI 2 "general_operand" "g"))))
7773    (clobber (reg:CC FLAGS_REG))]
7774   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7775   "and{l}\t{%2, %k0|%k0, %2}"
7776   [(set_attr "type" "alu")
7777    (set_attr "mode" "SI")])
7778
7779 (define_insn "*andhi_1"
7780   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7781         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7782                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7783    (clobber (reg:CC FLAGS_REG))]
7784   "ix86_binary_operator_ok (AND, HImode, operands)"
7785 {
7786   switch (get_attr_type (insn))
7787     {
7788     case TYPE_IMOVX:
7789       gcc_assert (CONST_INT_P (operands[2]));
7790       gcc_assert (INTVAL (operands[2]) == 0xff);
7791       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7792
7793     default:
7794       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7795
7796       return "and{w}\t{%2, %0|%0, %2}";
7797     }
7798 }
7799   [(set_attr "type" "alu,alu,imovx")
7800    (set_attr "length_immediate" "*,*,0")
7801    (set (attr "prefix_rex")
7802      (if_then_else
7803        (and (eq_attr "type" "imovx")
7804             (match_operand 1 "ext_QIreg_operand" ""))
7805        (const_string "1")
7806        (const_string "*")))
7807    (set_attr "mode" "HI,HI,SI")])
7808
7809 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7810 (define_insn "*andqi_1"
7811   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7812         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7813                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7814    (clobber (reg:CC FLAGS_REG))]
7815   "ix86_binary_operator_ok (AND, QImode, operands)"
7816   "@
7817    and{b}\t{%2, %0|%0, %2}
7818    and{b}\t{%2, %0|%0, %2}
7819    and{l}\t{%k2, %k0|%k0, %k2}"
7820   [(set_attr "type" "alu")
7821    (set_attr "mode" "QI,QI,SI")])
7822
7823 (define_insn "*andqi_1_slp"
7824   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7825         (and:QI (match_dup 0)
7826                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7827    (clobber (reg:CC FLAGS_REG))]
7828   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7829    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7830   "and{b}\t{%1, %0|%0, %1}"
7831   [(set_attr "type" "alu1")
7832    (set_attr "mode" "QI")])
7833
7834 (define_split
7835   [(set (match_operand 0 "register_operand" "")
7836         (and (match_dup 0)
7837              (const_int -65536)))
7838    (clobber (reg:CC FLAGS_REG))]
7839   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7840     || optimize_function_for_size_p (cfun)"
7841   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7842   "operands[1] = gen_lowpart (HImode, operands[0]);")
7843
7844 (define_split
7845   [(set (match_operand 0 "ext_register_operand" "")
7846         (and (match_dup 0)
7847              (const_int -256)))
7848    (clobber (reg:CC FLAGS_REG))]
7849   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7850    && reload_completed"
7851   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7852   "operands[1] = gen_lowpart (QImode, operands[0]);")
7853
7854 (define_split
7855   [(set (match_operand 0 "ext_register_operand" "")
7856         (and (match_dup 0)
7857              (const_int -65281)))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7860    && reload_completed"
7861   [(parallel [(set (zero_extract:SI (match_dup 0)
7862                                     (const_int 8)
7863                                     (const_int 8))
7864                    (xor:SI
7865                      (zero_extract:SI (match_dup 0)
7866                                       (const_int 8)
7867                                       (const_int 8))
7868                      (zero_extract:SI (match_dup 0)
7869                                       (const_int 8)
7870                                       (const_int 8))))
7871               (clobber (reg:CC FLAGS_REG))])]
7872   "operands[0] = gen_lowpart (SImode, operands[0]);")
7873
7874 (define_insn "*anddi_2"
7875   [(set (reg FLAGS_REG)
7876         (compare
7877          (and:DI
7878           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7879           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7880          (const_int 0)))
7881    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7882         (and:DI (match_dup 1) (match_dup 2)))]
7883   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7884    && ix86_binary_operator_ok (AND, DImode, operands)"
7885   "@
7886    and{l}\t{%k2, %k0|%k0, %k2}
7887    and{q}\t{%2, %0|%0, %2}
7888    and{q}\t{%2, %0|%0, %2}"
7889   [(set_attr "type" "alu")
7890    (set_attr "mode" "SI,DI,DI")])
7891
7892 (define_insn "*andqi_2_maybe_si"
7893   [(set (reg FLAGS_REG)
7894         (compare (and:QI
7895                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7896                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7897                  (const_int 0)))
7898    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7899         (and:QI (match_dup 1) (match_dup 2)))]
7900   "ix86_binary_operator_ok (AND, QImode, operands)
7901    && ix86_match_ccmode (insn,
7902                          CONST_INT_P (operands[2])
7903                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7904 {
7905   if (which_alternative == 2)
7906     {
7907       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7908         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7909       return "and{l}\t{%2, %k0|%k0, %2}";
7910     }
7911   return "and{b}\t{%2, %0|%0, %2}";
7912 }
7913   [(set_attr "type" "alu")
7914    (set_attr "mode" "QI,QI,SI")])
7915
7916 (define_insn "*and<mode>_2"
7917   [(set (reg FLAGS_REG)
7918         (compare (and:SWI124
7919                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7920                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7921                  (const_int 0)))
7922    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7923         (and:SWI124 (match_dup 1) (match_dup 2)))]
7924   "ix86_match_ccmode (insn, CCNOmode)
7925    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7926   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7927   [(set_attr "type" "alu")
7928    (set_attr "mode" "<MODE>")])
7929
7930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7931 (define_insn "*andsi_2_zext"
7932   [(set (reg FLAGS_REG)
7933         (compare (and:SI
7934                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7935                   (match_operand:SI 2 "general_operand" "g"))
7936                  (const_int 0)))
7937    (set (match_operand:DI 0 "register_operand" "=r")
7938         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7939   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7940    && ix86_binary_operator_ok (AND, SImode, operands)"
7941   "and{l}\t{%2, %k0|%k0, %2}"
7942   [(set_attr "type" "alu")
7943    (set_attr "mode" "SI")])
7944
7945 (define_insn "*andqi_2_slp"
7946   [(set (reg FLAGS_REG)
7947         (compare (and:QI
7948                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7949                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7950                  (const_int 0)))
7951    (set (strict_low_part (match_dup 0))
7952         (and:QI (match_dup 0) (match_dup 1)))]
7953   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7954    && ix86_match_ccmode (insn, CCNOmode)
7955    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7956   "and{b}\t{%1, %0|%0, %1}"
7957   [(set_attr "type" "alu1")
7958    (set_attr "mode" "QI")])
7959
7960 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7961 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7962 ;; for a QImode operand, which of course failed.
7963 (define_insn "andqi_ext_0"
7964   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7965                          (const_int 8)
7966                          (const_int 8))
7967         (and:SI
7968           (zero_extract:SI
7969             (match_operand 1 "ext_register_operand" "0")
7970             (const_int 8)
7971             (const_int 8))
7972           (match_operand 2 "const_int_operand" "n")))
7973    (clobber (reg:CC FLAGS_REG))]
7974   ""
7975   "and{b}\t{%2, %h0|%h0, %2}"
7976   [(set_attr "type" "alu")
7977    (set_attr "length_immediate" "1")
7978    (set_attr "modrm" "1")
7979    (set_attr "mode" "QI")])
7980
7981 ;; Generated by peephole translating test to and.  This shows up
7982 ;; often in fp comparisons.
7983 (define_insn "*andqi_ext_0_cc"
7984   [(set (reg FLAGS_REG)
7985         (compare
7986           (and:SI
7987             (zero_extract:SI
7988               (match_operand 1 "ext_register_operand" "0")
7989               (const_int 8)
7990               (const_int 8))
7991             (match_operand 2 "const_int_operand" "n"))
7992           (const_int 0)))
7993    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7994                          (const_int 8)
7995                          (const_int 8))
7996         (and:SI
7997           (zero_extract:SI
7998             (match_dup 1)
7999             (const_int 8)
8000             (const_int 8))
8001           (match_dup 2)))]
8002   "ix86_match_ccmode (insn, CCNOmode)"
8003   "and{b}\t{%2, %h0|%h0, %2}"
8004   [(set_attr "type" "alu")
8005    (set_attr "length_immediate" "1")
8006    (set_attr "modrm" "1")
8007    (set_attr "mode" "QI")])
8008
8009 (define_insn "*andqi_ext_1_rex64"
8010   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8011                          (const_int 8)
8012                          (const_int 8))
8013         (and:SI
8014           (zero_extract:SI
8015             (match_operand 1 "ext_register_operand" "0")
8016             (const_int 8)
8017             (const_int 8))
8018           (zero_extend:SI
8019             (match_operand 2 "ext_register_operand" "Q"))))
8020    (clobber (reg:CC FLAGS_REG))]
8021   "TARGET_64BIT"
8022   "and{b}\t{%2, %h0|%h0, %2}"
8023   [(set_attr "type" "alu")
8024    (set_attr "length_immediate" "0")
8025    (set_attr "mode" "QI")])
8026
8027 (define_insn "*andqi_ext_1"
8028   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8029                          (const_int 8)
8030                          (const_int 8))
8031         (and:SI
8032           (zero_extract:SI
8033             (match_operand 1 "ext_register_operand" "0")
8034             (const_int 8)
8035             (const_int 8))
8036           (zero_extend:SI
8037             (match_operand:QI 2 "general_operand" "Qm"))))
8038    (clobber (reg:CC FLAGS_REG))]
8039   "!TARGET_64BIT"
8040   "and{b}\t{%2, %h0|%h0, %2}"
8041   [(set_attr "type" "alu")
8042    (set_attr "length_immediate" "0")
8043    (set_attr "mode" "QI")])
8044
8045 (define_insn "*andqi_ext_2"
8046   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8047                          (const_int 8)
8048                          (const_int 8))
8049         (and:SI
8050           (zero_extract:SI
8051             (match_operand 1 "ext_register_operand" "%0")
8052             (const_int 8)
8053             (const_int 8))
8054           (zero_extract:SI
8055             (match_operand 2 "ext_register_operand" "Q")
8056             (const_int 8)
8057             (const_int 8))))
8058    (clobber (reg:CC FLAGS_REG))]
8059   ""
8060   "and{b}\t{%h2, %h0|%h0, %h2}"
8061   [(set_attr "type" "alu")
8062    (set_attr "length_immediate" "0")
8063    (set_attr "mode" "QI")])
8064
8065 ;; Convert wide AND instructions with immediate operand to shorter QImode
8066 ;; equivalents when possible.
8067 ;; Don't do the splitting with memory operands, since it introduces risk
8068 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8069 ;; for size, but that can (should?) be handled by generic code instead.
8070 (define_split
8071   [(set (match_operand 0 "register_operand" "")
8072         (and (match_operand 1 "register_operand" "")
8073              (match_operand 2 "const_int_operand" "")))
8074    (clobber (reg:CC FLAGS_REG))]
8075    "reload_completed
8076     && QI_REG_P (operands[0])
8077     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078     && !(~INTVAL (operands[2]) & ~(255 << 8))
8079     && GET_MODE (operands[0]) != QImode"
8080   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8081                    (and:SI (zero_extract:SI (match_dup 1)
8082                                             (const_int 8) (const_int 8))
8083                            (match_dup 2)))
8084               (clobber (reg:CC FLAGS_REG))])]
8085   "operands[0] = gen_lowpart (SImode, operands[0]);
8086    operands[1] = gen_lowpart (SImode, operands[1]);
8087    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8088
8089 ;; Since AND can be encoded with sign extended immediate, this is only
8090 ;; profitable when 7th bit is not set.
8091 (define_split
8092   [(set (match_operand 0 "register_operand" "")
8093         (and (match_operand 1 "general_operand" "")
8094              (match_operand 2 "const_int_operand" "")))
8095    (clobber (reg:CC FLAGS_REG))]
8096    "reload_completed
8097     && ANY_QI_REG_P (operands[0])
8098     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8099     && !(~INTVAL (operands[2]) & ~255)
8100     && !(INTVAL (operands[2]) & 128)
8101     && GET_MODE (operands[0]) != QImode"
8102   [(parallel [(set (strict_low_part (match_dup 0))
8103                    (and:QI (match_dup 1)
8104                            (match_dup 2)))
8105               (clobber (reg:CC FLAGS_REG))])]
8106   "operands[0] = gen_lowpart (QImode, operands[0]);
8107    operands[1] = gen_lowpart (QImode, operands[1]);
8108    operands[2] = gen_lowpart (QImode, operands[2]);")
8109 \f
8110 ;; Logical inclusive and exclusive OR instructions
8111
8112 ;; %%% This used to optimize known byte-wide and operations to memory.
8113 ;; If this is considered useful, it should be done with splitters.
8114
8115 (define_expand "<code><mode>3"
8116   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8117         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8118                      (match_operand:SWIM 2 "<general_operand>" "")))]
8119   ""
8120   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8121
8122 (define_insn "*<code><mode>_1"
8123   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8124         (any_or:SWI248
8125          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8126          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8127    (clobber (reg:CC FLAGS_REG))]
8128   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8129   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8130   [(set_attr "type" "alu")
8131    (set_attr "mode" "<MODE>")])
8132
8133 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8134 (define_insn "*<code>qi_1"
8135   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8136         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8137                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8138    (clobber (reg:CC FLAGS_REG))]
8139   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8140   "@
8141    <logic>{b}\t{%2, %0|%0, %2}
8142    <logic>{b}\t{%2, %0|%0, %2}
8143    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8144   [(set_attr "type" "alu")
8145    (set_attr "mode" "QI,QI,SI")])
8146
8147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8148 (define_insn "*<code>si_1_zext"
8149   [(set (match_operand:DI 0 "register_operand" "=r")
8150         (zero_extend:DI
8151          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8152                     (match_operand:SI 2 "general_operand" "g"))))
8153    (clobber (reg:CC FLAGS_REG))]
8154   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8155   "<logic>{l}\t{%2, %k0|%k0, %2}"
8156   [(set_attr "type" "alu")
8157    (set_attr "mode" "SI")])
8158
8159 (define_insn "*<code>si_1_zext_imm"
8160   [(set (match_operand:DI 0 "register_operand" "=r")
8161         (any_or:DI
8162          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8163          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8164    (clobber (reg:CC FLAGS_REG))]
8165   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8166   "<logic>{l}\t{%2, %k0|%k0, %2}"
8167   [(set_attr "type" "alu")
8168    (set_attr "mode" "SI")])
8169
8170 (define_insn "*<code>qi_1_slp"
8171   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8172         (any_or:QI (match_dup 0)
8173                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8174    (clobber (reg:CC FLAGS_REG))]
8175   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8176    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8177   "<logic>{b}\t{%1, %0|%0, %1}"
8178   [(set_attr "type" "alu1")
8179    (set_attr "mode" "QI")])
8180
8181 (define_insn "*<code><mode>_2"
8182   [(set (reg FLAGS_REG)
8183         (compare (any_or:SWI
8184                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8185                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8186                  (const_int 0)))
8187    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8188         (any_or:SWI (match_dup 1) (match_dup 2)))]
8189   "ix86_match_ccmode (insn, CCNOmode)
8190    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8191   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "<MODE>")])
8194
8195 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8196 ;; ??? Special case for immediate operand is missing - it is tricky.
8197 (define_insn "*<code>si_2_zext"
8198   [(set (reg FLAGS_REG)
8199         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8200                             (match_operand:SI 2 "general_operand" "g"))
8201                  (const_int 0)))
8202    (set (match_operand:DI 0 "register_operand" "=r")
8203         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8204   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8205    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8206   "<logic>{l}\t{%2, %k0|%k0, %2}"
8207   [(set_attr "type" "alu")
8208    (set_attr "mode" "SI")])
8209
8210 (define_insn "*<code>si_2_zext_imm"
8211   [(set (reg FLAGS_REG)
8212         (compare (any_or:SI
8213                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8214                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8215                  (const_int 0)))
8216    (set (match_operand:DI 0 "register_operand" "=r")
8217         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8218   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8219    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8220   "<logic>{l}\t{%2, %k0|%k0, %2}"
8221   [(set_attr "type" "alu")
8222    (set_attr "mode" "SI")])
8223
8224 (define_insn "*<code>qi_2_slp"
8225   [(set (reg FLAGS_REG)
8226         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8227                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8228                  (const_int 0)))
8229    (set (strict_low_part (match_dup 0))
8230         (any_or:QI (match_dup 0) (match_dup 1)))]
8231   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232    && ix86_match_ccmode (insn, CCNOmode)
8233    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234   "<logic>{b}\t{%1, %0|%0, %1}"
8235   [(set_attr "type" "alu1")
8236    (set_attr "mode" "QI")])
8237
8238 (define_insn "*<code><mode>_3"
8239   [(set (reg FLAGS_REG)
8240         (compare (any_or:SWI
8241                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8242                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8243                  (const_int 0)))
8244    (clobber (match_scratch:SWI 0 "=<r>"))]
8245   "ix86_match_ccmode (insn, CCNOmode)
8246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8247   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "<MODE>")])
8250
8251 (define_insn "*<code>qi_ext_0"
8252   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253                          (const_int 8)
8254                          (const_int 8))
8255         (any_or:SI
8256           (zero_extract:SI
8257             (match_operand 1 "ext_register_operand" "0")
8258             (const_int 8)
8259             (const_int 8))
8260           (match_operand 2 "const_int_operand" "n")))
8261    (clobber (reg:CC FLAGS_REG))]
8262   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8263   "<logic>{b}\t{%2, %h0|%h0, %2}"
8264   [(set_attr "type" "alu")
8265    (set_attr "length_immediate" "1")
8266    (set_attr "modrm" "1")
8267    (set_attr "mode" "QI")])
8268
8269 (define_insn "*<code>qi_ext_1_rex64"
8270   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8271                          (const_int 8)
8272                          (const_int 8))
8273         (any_or:SI
8274           (zero_extract:SI
8275             (match_operand 1 "ext_register_operand" "0")
8276             (const_int 8)
8277             (const_int 8))
8278           (zero_extend:SI
8279             (match_operand 2 "ext_register_operand" "Q"))))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "TARGET_64BIT
8282    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8283   "<logic>{b}\t{%2, %h0|%h0, %2}"
8284   [(set_attr "type" "alu")
8285    (set_attr "length_immediate" "0")
8286    (set_attr "mode" "QI")])
8287
8288 (define_insn "*<code>qi_ext_1"
8289   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290                          (const_int 8)
8291                          (const_int 8))
8292         (any_or:SI
8293           (zero_extract:SI
8294             (match_operand 1 "ext_register_operand" "0")
8295             (const_int 8)
8296             (const_int 8))
8297           (zero_extend:SI
8298             (match_operand:QI 2 "general_operand" "Qm"))))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "!TARGET_64BIT
8301    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8302   "<logic>{b}\t{%2, %h0|%h0, %2}"
8303   [(set_attr "type" "alu")
8304    (set_attr "length_immediate" "0")
8305    (set_attr "mode" "QI")])
8306
8307 (define_insn "*<code>qi_ext_2"
8308   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309                          (const_int 8)
8310                          (const_int 8))
8311         (any_or:SI
8312           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8313                            (const_int 8)
8314                            (const_int 8))
8315           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8316                            (const_int 8)
8317                            (const_int 8))))
8318    (clobber (reg:CC FLAGS_REG))]
8319   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8321   [(set_attr "type" "alu")
8322    (set_attr "length_immediate" "0")
8323    (set_attr "mode" "QI")])
8324
8325 (define_split
8326   [(set (match_operand 0 "register_operand" "")
8327         (any_or (match_operand 1 "register_operand" "")
8328                 (match_operand 2 "const_int_operand" "")))
8329    (clobber (reg:CC FLAGS_REG))]
8330    "reload_completed
8331     && QI_REG_P (operands[0])
8332     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8333     && !(INTVAL (operands[2]) & ~(255 << 8))
8334     && GET_MODE (operands[0]) != QImode"
8335   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8336                    (any_or:SI (zero_extract:SI (match_dup 1)
8337                                                (const_int 8) (const_int 8))
8338                               (match_dup 2)))
8339               (clobber (reg:CC FLAGS_REG))])]
8340   "operands[0] = gen_lowpart (SImode, operands[0]);
8341    operands[1] = gen_lowpart (SImode, operands[1]);
8342    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8343
8344 ;; Since OR can be encoded with sign extended immediate, this is only
8345 ;; profitable when 7th bit is set.
8346 (define_split
8347   [(set (match_operand 0 "register_operand" "")
8348         (any_or (match_operand 1 "general_operand" "")
8349                 (match_operand 2 "const_int_operand" "")))
8350    (clobber (reg:CC FLAGS_REG))]
8351    "reload_completed
8352     && ANY_QI_REG_P (operands[0])
8353     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8354     && !(INTVAL (operands[2]) & ~255)
8355     && (INTVAL (operands[2]) & 128)
8356     && GET_MODE (operands[0]) != QImode"
8357   [(parallel [(set (strict_low_part (match_dup 0))
8358                    (any_or:QI (match_dup 1)
8359                               (match_dup 2)))
8360               (clobber (reg:CC FLAGS_REG))])]
8361   "operands[0] = gen_lowpart (QImode, operands[0]);
8362    operands[1] = gen_lowpart (QImode, operands[1]);
8363    operands[2] = gen_lowpart (QImode, operands[2]);")
8364
8365 (define_expand "xorqi_cc_ext_1"
8366   [(parallel [
8367      (set (reg:CCNO FLAGS_REG)
8368           (compare:CCNO
8369             (xor:SI
8370               (zero_extract:SI
8371                 (match_operand 1 "ext_register_operand" "")
8372                 (const_int 8)
8373                 (const_int 8))
8374               (match_operand:QI 2 "general_operand" ""))
8375             (const_int 0)))
8376      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8377                            (const_int 8)
8378                            (const_int 8))
8379           (xor:SI
8380             (zero_extract:SI
8381              (match_dup 1)
8382              (const_int 8)
8383              (const_int 8))
8384             (match_dup 2)))])])
8385
8386 (define_insn "*xorqi_cc_ext_1_rex64"
8387   [(set (reg FLAGS_REG)
8388         (compare
8389           (xor:SI
8390             (zero_extract:SI
8391               (match_operand 1 "ext_register_operand" "0")
8392               (const_int 8)
8393               (const_int 8))
8394             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8395           (const_int 0)))
8396    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8397                          (const_int 8)
8398                          (const_int 8))
8399         (xor:SI
8400           (zero_extract:SI
8401            (match_dup 1)
8402            (const_int 8)
8403            (const_int 8))
8404           (match_dup 2)))]
8405   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8406   "xor{b}\t{%2, %h0|%h0, %2}"
8407   [(set_attr "type" "alu")
8408    (set_attr "modrm" "1")
8409    (set_attr "mode" "QI")])
8410
8411 (define_insn "*xorqi_cc_ext_1"
8412   [(set (reg FLAGS_REG)
8413         (compare
8414           (xor:SI
8415             (zero_extract:SI
8416               (match_operand 1 "ext_register_operand" "0")
8417               (const_int 8)
8418               (const_int 8))
8419             (match_operand:QI 2 "general_operand" "qmn"))
8420           (const_int 0)))
8421    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8422                          (const_int 8)
8423                          (const_int 8))
8424         (xor:SI
8425           (zero_extract:SI
8426            (match_dup 1)
8427            (const_int 8)
8428            (const_int 8))
8429           (match_dup 2)))]
8430   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8431   "xor{b}\t{%2, %h0|%h0, %2}"
8432   [(set_attr "type" "alu")
8433    (set_attr "modrm" "1")
8434    (set_attr "mode" "QI")])
8435 \f
8436 ;; Negation instructions
8437
8438 (define_expand "neg<mode>2"
8439   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8440         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8441   ""
8442   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8443
8444 (define_insn_and_split "*neg<dwi>2_doubleword"
8445   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8446         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8449   "#"
8450   "reload_completed"
8451   [(parallel
8452     [(set (reg:CCZ FLAGS_REG)
8453           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8454      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8455    (parallel
8456     [(set (match_dup 2)
8457           (plus:DWIH (match_dup 3)
8458                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8459                                 (const_int 0))))
8460      (clobber (reg:CC FLAGS_REG))])
8461    (parallel
8462     [(set (match_dup 2)
8463           (neg:DWIH (match_dup 2)))
8464      (clobber (reg:CC FLAGS_REG))])]
8465   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8466
8467 (define_insn "*neg<mode>2_1"
8468   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8469         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8470    (clobber (reg:CC FLAGS_REG))]
8471   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8472   "neg{<imodesuffix>}\t%0"
8473   [(set_attr "type" "negnot")
8474    (set_attr "mode" "<MODE>")])
8475
8476 ;; Combine is quite creative about this pattern.
8477 (define_insn "*negsi2_1_zext"
8478   [(set (match_operand:DI 0 "register_operand" "=r")
8479         (lshiftrt:DI
8480           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8481                              (const_int 32)))
8482         (const_int 32)))
8483    (clobber (reg:CC FLAGS_REG))]
8484   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8485   "neg{l}\t%k0"
8486   [(set_attr "type" "negnot")
8487    (set_attr "mode" "SI")])
8488
8489 ;; The problem with neg is that it does not perform (compare x 0),
8490 ;; it really performs (compare 0 x), which leaves us with the zero
8491 ;; flag being the only useful item.
8492
8493 (define_insn "*neg<mode>2_cmpz"
8494   [(set (reg:CCZ FLAGS_REG)
8495         (compare:CCZ
8496           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8497                    (const_int 0)))
8498    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8499         (neg:SWI (match_dup 1)))]
8500   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8501   "neg{<imodesuffix>}\t%0"
8502   [(set_attr "type" "negnot")
8503    (set_attr "mode" "<MODE>")])
8504
8505 (define_insn "*negsi2_cmpz_zext"
8506   [(set (reg:CCZ FLAGS_REG)
8507         (compare:CCZ
8508           (lshiftrt:DI
8509             (neg:DI (ashift:DI
8510                       (match_operand:DI 1 "register_operand" "0")
8511                       (const_int 32)))
8512             (const_int 32))
8513           (const_int 0)))
8514    (set (match_operand:DI 0 "register_operand" "=r")
8515         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8516                                         (const_int 32)))
8517                      (const_int 32)))]
8518   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8519   "neg{l}\t%k0"
8520   [(set_attr "type" "negnot")
8521    (set_attr "mode" "SI")])
8522
8523 ;; Changing of sign for FP values is doable using integer unit too.
8524
8525 (define_expand "<code><mode>2"
8526   [(set (match_operand:X87MODEF 0 "register_operand" "")
8527         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8528   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8529   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8530
8531 (define_insn "*absneg<mode>2_mixed"
8532   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8533         (match_operator:MODEF 3 "absneg_operator"
8534           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8535    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8538   "#")
8539
8540 (define_insn "*absneg<mode>2_sse"
8541   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8542         (match_operator:MODEF 3 "absneg_operator"
8543           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8544    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8545    (clobber (reg:CC FLAGS_REG))]
8546   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8547   "#")
8548
8549 (define_insn "*absneg<mode>2_i387"
8550   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8551         (match_operator:X87MODEF 3 "absneg_operator"
8552           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8553    (use (match_operand 2 "" ""))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8556   "#")
8557
8558 (define_expand "<code>tf2"
8559   [(set (match_operand:TF 0 "register_operand" "")
8560         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8561   "TARGET_SSE2"
8562   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8563
8564 (define_insn "*absnegtf2_sse"
8565   [(set (match_operand:TF 0 "register_operand" "=x,x")
8566         (match_operator:TF 3 "absneg_operator"
8567           [(match_operand:TF 1 "register_operand" "0,x")]))
8568    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8569    (clobber (reg:CC FLAGS_REG))]
8570   "TARGET_SSE2"
8571   "#")
8572
8573 ;; Splitters for fp abs and neg.
8574
8575 (define_split
8576   [(set (match_operand 0 "fp_register_operand" "")
8577         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8578    (use (match_operand 2 "" ""))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "reload_completed"
8581   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8582
8583 (define_split
8584   [(set (match_operand 0 "register_operand" "")
8585         (match_operator 3 "absneg_operator"
8586           [(match_operand 1 "register_operand" "")]))
8587    (use (match_operand 2 "nonimmediate_operand" ""))
8588    (clobber (reg:CC FLAGS_REG))]
8589   "reload_completed && SSE_REG_P (operands[0])"
8590   [(set (match_dup 0) (match_dup 3))]
8591 {
8592   enum machine_mode mode = GET_MODE (operands[0]);
8593   enum machine_mode vmode = GET_MODE (operands[2]);
8594   rtx tmp;
8595
8596   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8597   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8598   if (operands_match_p (operands[0], operands[2]))
8599     {
8600       tmp = operands[1];
8601       operands[1] = operands[2];
8602       operands[2] = tmp;
8603     }
8604   if (GET_CODE (operands[3]) == ABS)
8605     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8606   else
8607     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8608   operands[3] = tmp;
8609 })
8610
8611 (define_split
8612   [(set (match_operand:SF 0 "register_operand" "")
8613         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8614    (use (match_operand:V4SF 2 "" ""))
8615    (clobber (reg:CC FLAGS_REG))]
8616   "reload_completed"
8617   [(parallel [(set (match_dup 0) (match_dup 1))
8618               (clobber (reg:CC FLAGS_REG))])]
8619 {
8620   rtx tmp;
8621   operands[0] = gen_lowpart (SImode, operands[0]);
8622   if (GET_CODE (operands[1]) == ABS)
8623     {
8624       tmp = gen_int_mode (0x7fffffff, SImode);
8625       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8626     }
8627   else
8628     {
8629       tmp = gen_int_mode (0x80000000, SImode);
8630       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8631     }
8632   operands[1] = tmp;
8633 })
8634
8635 (define_split
8636   [(set (match_operand:DF 0 "register_operand" "")
8637         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8638    (use (match_operand 2 "" ""))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "reload_completed"
8641   [(parallel [(set (match_dup 0) (match_dup 1))
8642               (clobber (reg:CC FLAGS_REG))])]
8643 {
8644   rtx tmp;
8645   if (TARGET_64BIT)
8646     {
8647       tmp = gen_lowpart (DImode, operands[0]);
8648       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8649       operands[0] = tmp;
8650
8651       if (GET_CODE (operands[1]) == ABS)
8652         tmp = const0_rtx;
8653       else
8654         tmp = gen_rtx_NOT (DImode, tmp);
8655     }
8656   else
8657     {
8658       operands[0] = gen_highpart (SImode, operands[0]);
8659       if (GET_CODE (operands[1]) == ABS)
8660         {
8661           tmp = gen_int_mode (0x7fffffff, SImode);
8662           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8663         }
8664       else
8665         {
8666           tmp = gen_int_mode (0x80000000, SImode);
8667           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8668         }
8669     }
8670   operands[1] = tmp;
8671 })
8672
8673 (define_split
8674   [(set (match_operand:XF 0 "register_operand" "")
8675         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8676    (use (match_operand 2 "" ""))
8677    (clobber (reg:CC FLAGS_REG))]
8678   "reload_completed"
8679   [(parallel [(set (match_dup 0) (match_dup 1))
8680               (clobber (reg:CC FLAGS_REG))])]
8681 {
8682   rtx tmp;
8683   operands[0] = gen_rtx_REG (SImode,
8684                              true_regnum (operands[0])
8685                              + (TARGET_64BIT ? 1 : 2));
8686   if (GET_CODE (operands[1]) == ABS)
8687     {
8688       tmp = GEN_INT (0x7fff);
8689       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8690     }
8691   else
8692     {
8693       tmp = GEN_INT (0x8000);
8694       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8695     }
8696   operands[1] = tmp;
8697 })
8698
8699 ;; Conditionalize these after reload. If they match before reload, we
8700 ;; lose the clobber and ability to use integer instructions.
8701
8702 (define_insn "*<code><mode>2_1"
8703   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8704         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8705   "TARGET_80387
8706    && (reload_completed
8707        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8708   "f<absneg_mnemonic>"
8709   [(set_attr "type" "fsgn")
8710    (set_attr "mode" "<MODE>")])
8711
8712 (define_insn "*<code>extendsfdf2"
8713   [(set (match_operand:DF 0 "register_operand" "=f")
8714         (absneg:DF (float_extend:DF
8715                      (match_operand:SF 1 "register_operand" "0"))))]
8716   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8717   "f<absneg_mnemonic>"
8718   [(set_attr "type" "fsgn")
8719    (set_attr "mode" "DF")])
8720
8721 (define_insn "*<code>extendsfxf2"
8722   [(set (match_operand:XF 0 "register_operand" "=f")
8723         (absneg:XF (float_extend:XF
8724                      (match_operand:SF 1 "register_operand" "0"))))]
8725   "TARGET_80387"
8726   "f<absneg_mnemonic>"
8727   [(set_attr "type" "fsgn")
8728    (set_attr "mode" "XF")])
8729
8730 (define_insn "*<code>extenddfxf2"
8731   [(set (match_operand:XF 0 "register_operand" "=f")
8732         (absneg:XF (float_extend:XF
8733                      (match_operand:DF 1 "register_operand" "0"))))]
8734   "TARGET_80387"
8735   "f<absneg_mnemonic>"
8736   [(set_attr "type" "fsgn")
8737    (set_attr "mode" "XF")])
8738
8739 ;; Copysign instructions
8740
8741 (define_mode_iterator CSGNMODE [SF DF TF])
8742 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8743
8744 (define_expand "copysign<mode>3"
8745   [(match_operand:CSGNMODE 0 "register_operand" "")
8746    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8747    (match_operand:CSGNMODE 2 "register_operand" "")]
8748   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8749    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8750   "ix86_expand_copysign (operands); DONE;")
8751
8752 (define_insn_and_split "copysign<mode>3_const"
8753   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8754         (unspec:CSGNMODE
8755           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8756            (match_operand:CSGNMODE 2 "register_operand" "0")
8757            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8758           UNSPEC_COPYSIGN))]
8759   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8760    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8761   "#"
8762   "&& reload_completed"
8763   [(const_int 0)]
8764   "ix86_split_copysign_const (operands); DONE;")
8765
8766 (define_insn "copysign<mode>3_var"
8767   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8768         (unspec:CSGNMODE
8769           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8770            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8771            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8772            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8773           UNSPEC_COPYSIGN))
8774    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8775   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8777   "#")
8778
8779 (define_split
8780   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8781         (unspec:CSGNMODE
8782           [(match_operand:CSGNMODE 2 "register_operand" "")
8783            (match_operand:CSGNMODE 3 "register_operand" "")
8784            (match_operand:<CSGNVMODE> 4 "" "")
8785            (match_operand:<CSGNVMODE> 5 "" "")]
8786           UNSPEC_COPYSIGN))
8787    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8788   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8789     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8790    && reload_completed"
8791   [(const_int 0)]
8792   "ix86_split_copysign_var (operands); DONE;")
8793 \f
8794 ;; One complement instructions
8795
8796 (define_expand "one_cmpl<mode>2"
8797   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8798         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8799   ""
8800   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8801
8802 (define_insn "*one_cmpl<mode>2_1"
8803   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8804         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8805   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8806   "not{<imodesuffix>}\t%0"
8807   [(set_attr "type" "negnot")
8808    (set_attr "mode" "<MODE>")])
8809
8810 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8811 (define_insn "*one_cmplqi2_1"
8812   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8813         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8814   "ix86_unary_operator_ok (NOT, QImode, operands)"
8815   "@
8816    not{b}\t%0
8817    not{l}\t%k0"
8818   [(set_attr "type" "negnot")
8819    (set_attr "mode" "QI,SI")])
8820
8821 ;; ??? Currently never generated - xor is used instead.
8822 (define_insn "*one_cmplsi2_1_zext"
8823   [(set (match_operand:DI 0 "register_operand" "=r")
8824         (zero_extend:DI
8825           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8826   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8827   "not{l}\t%k0"
8828   [(set_attr "type" "negnot")
8829    (set_attr "mode" "SI")])
8830
8831 (define_insn "*one_cmpl<mode>2_2"
8832   [(set (reg FLAGS_REG)
8833         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8834                  (const_int 0)))
8835    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8836         (not:SWI (match_dup 1)))]
8837   "ix86_match_ccmode (insn, CCNOmode)
8838    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8839   "#"
8840   [(set_attr "type" "alu1")
8841    (set_attr "mode" "<MODE>")])
8842
8843 (define_split
8844   [(set (match_operand 0 "flags_reg_operand" "")
8845         (match_operator 2 "compare_operator"
8846           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8847            (const_int 0)]))
8848    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8849         (not:SWI (match_dup 3)))]
8850   "ix86_match_ccmode (insn, CCNOmode)"
8851   [(parallel [(set (match_dup 0)
8852                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8853                                     (const_int 0)]))
8854               (set (match_dup 1)
8855                    (xor:SWI (match_dup 3) (const_int -1)))])])
8856
8857 ;; ??? Currently never generated - xor is used instead.
8858 (define_insn "*one_cmplsi2_2_zext"
8859   [(set (reg FLAGS_REG)
8860         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8861                  (const_int 0)))
8862    (set (match_operand:DI 0 "register_operand" "=r")
8863         (zero_extend:DI (not:SI (match_dup 1))))]
8864   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865    && ix86_unary_operator_ok (NOT, SImode, operands)"
8866   "#"
8867   [(set_attr "type" "alu1")
8868    (set_attr "mode" "SI")])
8869
8870 (define_split
8871   [(set (match_operand 0 "flags_reg_operand" "")
8872         (match_operator 2 "compare_operator"
8873           [(not:SI (match_operand:SI 3 "register_operand" ""))
8874            (const_int 0)]))
8875    (set (match_operand:DI 1 "register_operand" "")
8876         (zero_extend:DI (not:SI (match_dup 3))))]
8877   "ix86_match_ccmode (insn, CCNOmode)"
8878   [(parallel [(set (match_dup 0)
8879                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8880                                     (const_int 0)]))
8881               (set (match_dup 1)
8882                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8883 \f
8884 ;; Shift instructions
8885
8886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8889 ;; from the assembler input.
8890 ;;
8891 ;; This instruction shifts the target reg/mem as usual, but instead of
8892 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8893 ;; is a left shift double, bits are taken from the high order bits of
8894 ;; reg, else if the insn is a shift right double, bits are taken from the
8895 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8897 ;;
8898 ;; Since sh[lr]d does not change the `reg' operand, that is done
8899 ;; separately, making all shifts emit pairs of shift double and normal
8900 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8901 ;; support a 63 bit shift, each shift where the count is in a reg expands
8902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8903 ;;
8904 ;; If the shift count is a constant, we need never emit more than one
8905 ;; shift pair, instead using moves and sign extension for counts greater
8906 ;; than 31.
8907
8908 (define_expand "ashl<mode>3"
8909   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8910         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8911                       (match_operand:QI 2 "nonmemory_operand" "")))]
8912   ""
8913   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8914
8915 (define_insn "*ashl<mode>3_doubleword"
8916   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8917         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8918                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8919    (clobber (reg:CC FLAGS_REG))]
8920   ""
8921   "#"
8922   [(set_attr "type" "multi")])
8923
8924 (define_split
8925   [(set (match_operand:DWI 0 "register_operand" "")
8926         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8927                     (match_operand:QI 2 "nonmemory_operand" "")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8930   [(const_int 0)]
8931   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8932
8933 ;; By default we don't ask for a scratch register, because when DWImode
8934 ;; values are manipulated, registers are already at a premium.  But if
8935 ;; we have one handy, we won't turn it away.
8936
8937 (define_peephole2
8938   [(match_scratch:DWIH 3 "r")
8939    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8940                    (ashift:<DWI>
8941                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8942                      (match_operand:QI 2 "nonmemory_operand" "")))
8943               (clobber (reg:CC FLAGS_REG))])
8944    (match_dup 3)]
8945   "TARGET_CMOVE"
8946   [(const_int 0)]
8947   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8948
8949 (define_insn "x86_64_shld"
8950   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8951         (ior:DI (ashift:DI (match_dup 0)
8952                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8953                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8954                   (minus:QI (const_int 64) (match_dup 2)))))
8955    (clobber (reg:CC FLAGS_REG))]
8956   "TARGET_64BIT"
8957   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8958   [(set_attr "type" "ishift")
8959    (set_attr "prefix_0f" "1")
8960    (set_attr "mode" "DI")
8961    (set_attr "athlon_decode" "vector")
8962    (set_attr "amdfam10_decode" "vector")
8963    (set_attr "bdver1_decode" "vector")])
8964
8965 (define_insn "x86_shld"
8966   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8967         (ior:SI (ashift:SI (match_dup 0)
8968                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8969                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8970                   (minus:QI (const_int 32) (match_dup 2)))))
8971    (clobber (reg:CC FLAGS_REG))]
8972   ""
8973   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8974   [(set_attr "type" "ishift")
8975    (set_attr "prefix_0f" "1")
8976    (set_attr "mode" "SI")
8977    (set_attr "pent_pair" "np")
8978    (set_attr "athlon_decode" "vector")
8979    (set_attr "amdfam10_decode" "vector")
8980    (set_attr "bdver1_decode" "vector")])
8981
8982 (define_expand "x86_shift<mode>_adj_1"
8983   [(set (reg:CCZ FLAGS_REG)
8984         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8985                              (match_dup 4))
8986                      (const_int 0)))
8987    (set (match_operand:SWI48 0 "register_operand" "")
8988         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8989                             (match_operand:SWI48 1 "register_operand" "")
8990                             (match_dup 0)))
8991    (set (match_dup 1)
8992         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8993                             (match_operand:SWI48 3 "register_operand" "r")
8994                             (match_dup 1)))]
8995   "TARGET_CMOVE"
8996   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8997
8998 (define_expand "x86_shift<mode>_adj_2"
8999   [(use (match_operand:SWI48 0 "register_operand" ""))
9000    (use (match_operand:SWI48 1 "register_operand" ""))
9001    (use (match_operand:QI 2 "register_operand" ""))]
9002   ""
9003 {
9004   rtx label = gen_label_rtx ();
9005   rtx tmp;
9006
9007   emit_insn (gen_testqi_ccz_1 (operands[2],
9008                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9009
9010   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9011   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9012   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9013                               gen_rtx_LABEL_REF (VOIDmode, label),
9014                               pc_rtx);
9015   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9016   JUMP_LABEL (tmp) = label;
9017
9018   emit_move_insn (operands[0], operands[1]);
9019   ix86_expand_clear (operands[1]);
9020
9021   emit_label (label);
9022   LABEL_NUSES (label) = 1;
9023
9024   DONE;
9025 })
9026
9027 ;; Avoid useless masking of count operand.
9028 (define_insn_and_split "*ashl<mode>3_mask"
9029   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9030         (ashift:SWI48
9031           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9032           (subreg:QI
9033             (and:SI
9034               (match_operand:SI 2 "nonimmediate_operand" "c")
9035               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9036    (clobber (reg:CC FLAGS_REG))]
9037   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9038    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9039       == GET_MODE_BITSIZE (<MODE>mode)-1"
9040   "#"
9041   "&& 1"
9042   [(parallel [(set (match_dup 0)
9043                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9044               (clobber (reg:CC FLAGS_REG))])]
9045 {
9046   if (can_create_pseudo_p ())
9047     operands [2] = force_reg (SImode, operands[2]);
9048
9049   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9050 }
9051   [(set_attr "type" "ishift")
9052    (set_attr "mode" "<MODE>")])
9053
9054 (define_insn "*ashl<mode>3_1"
9055   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9056         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9057                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9058    (clobber (reg:CC FLAGS_REG))]
9059   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9060 {
9061   switch (get_attr_type (insn))
9062     {
9063     case TYPE_LEA:
9064       return "#";
9065
9066     case TYPE_ALU:
9067       gcc_assert (operands[2] == const1_rtx);
9068       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9069       return "add{<imodesuffix>}\t%0, %0";
9070
9071     default:
9072       if (operands[2] == const1_rtx
9073           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9074         return "sal{<imodesuffix>}\t%0";
9075       else
9076         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9077     }
9078 }
9079   [(set (attr "type")
9080      (cond [(eq_attr "alternative" "1")
9081               (const_string "lea")
9082             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9083                           (const_int 0))
9084                       (match_operand 0 "register_operand" ""))
9085                  (match_operand 2 "const1_operand" ""))
9086               (const_string "alu")
9087            ]
9088            (const_string "ishift")))
9089    (set (attr "length_immediate")
9090      (if_then_else
9091        (ior (eq_attr "type" "alu")
9092             (and (eq_attr "type" "ishift")
9093                  (and (match_operand 2 "const1_operand" "")
9094                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9095                           (const_int 0)))))
9096        (const_string "0")
9097        (const_string "*")))
9098    (set_attr "mode" "<MODE>")])
9099
9100 (define_insn "*ashlsi3_1_zext"
9101   [(set (match_operand:DI 0 "register_operand" "=r,r")
9102         (zero_extend:DI
9103           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9104                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9105    (clobber (reg:CC FLAGS_REG))]
9106   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9107 {
9108   switch (get_attr_type (insn))
9109     {
9110     case TYPE_LEA:
9111       return "#";
9112
9113     case TYPE_ALU:
9114       gcc_assert (operands[2] == const1_rtx);
9115       return "add{l}\t%k0, %k0";
9116
9117     default:
9118       if (operands[2] == const1_rtx
9119           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9120         return "sal{l}\t%k0";
9121       else
9122         return "sal{l}\t{%2, %k0|%k0, %2}";
9123     }
9124 }
9125   [(set (attr "type")
9126      (cond [(eq_attr "alternative" "1")
9127               (const_string "lea")
9128             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9129                      (const_int 0))
9130                  (match_operand 2 "const1_operand" ""))
9131               (const_string "alu")
9132            ]
9133            (const_string "ishift")))
9134    (set (attr "length_immediate")
9135      (if_then_else
9136        (ior (eq_attr "type" "alu")
9137             (and (eq_attr "type" "ishift")
9138                  (and (match_operand 2 "const1_operand" "")
9139                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9140                           (const_int 0)))))
9141        (const_string "0")
9142        (const_string "*")))
9143    (set_attr "mode" "SI")])
9144
9145 (define_insn "*ashlhi3_1"
9146   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9147         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9148                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "TARGET_PARTIAL_REG_STALL
9151    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9152 {
9153   switch (get_attr_type (insn))
9154     {
9155     case TYPE_ALU:
9156       gcc_assert (operands[2] == const1_rtx);
9157       return "add{w}\t%0, %0";
9158
9159     default:
9160       if (operands[2] == const1_rtx
9161           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9162         return "sal{w}\t%0";
9163       else
9164         return "sal{w}\t{%2, %0|%0, %2}";
9165     }
9166 }
9167   [(set (attr "type")
9168      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9169                           (const_int 0))
9170                       (match_operand 0 "register_operand" ""))
9171                  (match_operand 2 "const1_operand" ""))
9172               (const_string "alu")
9173            ]
9174            (const_string "ishift")))
9175    (set (attr "length_immediate")
9176      (if_then_else
9177        (ior (eq_attr "type" "alu")
9178             (and (eq_attr "type" "ishift")
9179                  (and (match_operand 2 "const1_operand" "")
9180                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9181                           (const_int 0)))))
9182        (const_string "0")
9183        (const_string "*")))
9184    (set_attr "mode" "HI")])
9185
9186 (define_insn "*ashlhi3_1_lea"
9187   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9188         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9189                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9190    (clobber (reg:CC FLAGS_REG))]
9191   "!TARGET_PARTIAL_REG_STALL
9192    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9193 {
9194   switch (get_attr_type (insn))
9195     {
9196     case TYPE_LEA:
9197       return "#";
9198
9199     case TYPE_ALU:
9200       gcc_assert (operands[2] == const1_rtx);
9201       return "add{w}\t%0, %0";
9202
9203     default:
9204       if (operands[2] == const1_rtx
9205           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206         return "sal{w}\t%0";
9207       else
9208         return "sal{w}\t{%2, %0|%0, %2}";
9209     }
9210 }
9211   [(set (attr "type")
9212      (cond [(eq_attr "alternative" "1")
9213               (const_string "lea")
9214             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9215                           (const_int 0))
9216                       (match_operand 0 "register_operand" ""))
9217                  (match_operand 2 "const1_operand" ""))
9218               (const_string "alu")
9219            ]
9220            (const_string "ishift")))
9221    (set (attr "length_immediate")
9222      (if_then_else
9223        (ior (eq_attr "type" "alu")
9224             (and (eq_attr "type" "ishift")
9225                  (and (match_operand 2 "const1_operand" "")
9226                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9227                           (const_int 0)))))
9228        (const_string "0")
9229        (const_string "*")))
9230    (set_attr "mode" "HI,SI")])
9231
9232 (define_insn "*ashlqi3_1"
9233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9234         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9235                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9236    (clobber (reg:CC FLAGS_REG))]
9237   "TARGET_PARTIAL_REG_STALL
9238    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9239 {
9240   switch (get_attr_type (insn))
9241     {
9242     case TYPE_ALU:
9243       gcc_assert (operands[2] == const1_rtx);
9244       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9245         return "add{l}\t%k0, %k0";
9246       else
9247         return "add{b}\t%0, %0";
9248
9249     default:
9250       if (operands[2] == const1_rtx
9251           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9252         {
9253           if (get_attr_mode (insn) == MODE_SI)
9254             return "sal{l}\t%k0";
9255           else
9256             return "sal{b}\t%0";
9257         }
9258       else
9259         {
9260           if (get_attr_mode (insn) == MODE_SI)
9261             return "sal{l}\t{%2, %k0|%k0, %2}";
9262           else
9263             return "sal{b}\t{%2, %0|%0, %2}";
9264         }
9265     }
9266 }
9267   [(set (attr "type")
9268      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9269                           (const_int 0))
9270                       (match_operand 0 "register_operand" ""))
9271                  (match_operand 2 "const1_operand" ""))
9272               (const_string "alu")
9273            ]
9274            (const_string "ishift")))
9275    (set (attr "length_immediate")
9276      (if_then_else
9277        (ior (eq_attr "type" "alu")
9278             (and (eq_attr "type" "ishift")
9279                  (and (match_operand 2 "const1_operand" "")
9280                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9281                           (const_int 0)))))
9282        (const_string "0")
9283        (const_string "*")))
9284    (set_attr "mode" "QI,SI")])
9285
9286 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9287 (define_insn "*ashlqi3_1_lea"
9288   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9289         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9290                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9291    (clobber (reg:CC FLAGS_REG))]
9292   "!TARGET_PARTIAL_REG_STALL
9293    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9294 {
9295   switch (get_attr_type (insn))
9296     {
9297     case TYPE_LEA:
9298       return "#";
9299
9300     case TYPE_ALU:
9301       gcc_assert (operands[2] == const1_rtx);
9302       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9303         return "add{l}\t%k0, %k0";
9304       else
9305         return "add{b}\t%0, %0";
9306
9307     default:
9308       if (operands[2] == const1_rtx
9309           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9310         {
9311           if (get_attr_mode (insn) == MODE_SI)
9312             return "sal{l}\t%k0";
9313           else
9314             return "sal{b}\t%0";
9315         }
9316       else
9317         {
9318           if (get_attr_mode (insn) == MODE_SI)
9319             return "sal{l}\t{%2, %k0|%k0, %2}";
9320           else
9321             return "sal{b}\t{%2, %0|%0, %2}";
9322         }
9323     }
9324 }
9325   [(set (attr "type")
9326      (cond [(eq_attr "alternative" "2")
9327               (const_string "lea")
9328             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9329                           (const_int 0))
9330                       (match_operand 0 "register_operand" ""))
9331                  (match_operand 2 "const1_operand" ""))
9332               (const_string "alu")
9333            ]
9334            (const_string "ishift")))
9335    (set (attr "length_immediate")
9336      (if_then_else
9337        (ior (eq_attr "type" "alu")
9338             (and (eq_attr "type" "ishift")
9339                  (and (match_operand 2 "const1_operand" "")
9340                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9341                           (const_int 0)))))
9342        (const_string "0")
9343        (const_string "*")))
9344    (set_attr "mode" "QI,SI,SI")])
9345
9346 (define_insn "*ashlqi3_1_slp"
9347   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9348         (ashift:QI (match_dup 0)
9349                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9350    (clobber (reg:CC FLAGS_REG))]
9351   "(optimize_function_for_size_p (cfun)
9352     || !TARGET_PARTIAL_FLAG_REG_STALL
9353     || (operands[1] == const1_rtx
9354         && (TARGET_SHIFT1
9355             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9356 {
9357   switch (get_attr_type (insn))
9358     {
9359     case TYPE_ALU:
9360       gcc_assert (operands[1] == const1_rtx);
9361       return "add{b}\t%0, %0";
9362
9363     default:
9364       if (operands[1] == const1_rtx
9365           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9366         return "sal{b}\t%0";
9367       else
9368         return "sal{b}\t{%1, %0|%0, %1}";
9369     }
9370 }
9371   [(set (attr "type")
9372      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9373                           (const_int 0))
9374                       (match_operand 0 "register_operand" ""))
9375                  (match_operand 1 "const1_operand" ""))
9376               (const_string "alu")
9377            ]
9378            (const_string "ishift1")))
9379    (set (attr "length_immediate")
9380      (if_then_else
9381        (ior (eq_attr "type" "alu")
9382             (and (eq_attr "type" "ishift1")
9383                  (and (match_operand 1 "const1_operand" "")
9384                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9385                           (const_int 0)))))
9386        (const_string "0")
9387        (const_string "*")))
9388    (set_attr "mode" "QI")])
9389
9390 ;; Convert lea to the lea pattern to avoid flags dependency.
9391 (define_split
9392   [(set (match_operand 0 "register_operand" "")
9393         (ashift (match_operand 1 "index_register_operand" "")
9394                 (match_operand:QI 2 "const_int_operand" "")))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "reload_completed
9397    && true_regnum (operands[0]) != true_regnum (operands[1])"
9398   [(const_int 0)]
9399 {
9400   rtx pat;
9401   enum machine_mode mode = GET_MODE (operands[0]);
9402
9403   if (mode != Pmode)
9404     operands[1] = gen_lowpart (Pmode, operands[1]);
9405   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9406
9407   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9408
9409   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9410     operands[0] = gen_lowpart (SImode, operands[0]);
9411
9412   if (TARGET_64BIT && mode != Pmode)
9413     pat = gen_rtx_SUBREG (SImode, pat, 0);
9414
9415   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9416   DONE;
9417 })
9418
9419 ;; Convert lea to the lea pattern to avoid flags dependency.
9420 (define_split
9421   [(set (match_operand:DI 0 "register_operand" "")
9422         (zero_extend:DI
9423           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9424                      (match_operand:QI 2 "const_int_operand" ""))))
9425    (clobber (reg:CC FLAGS_REG))]
9426   "TARGET_64BIT && reload_completed
9427    && true_regnum (operands[0]) != true_regnum (operands[1])"
9428   [(set (match_dup 0)
9429         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9430 {
9431   operands[1] = gen_lowpart (DImode, operands[1]);
9432   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9433 })
9434
9435 ;; This pattern can't accept a variable shift count, since shifts by
9436 ;; zero don't affect the flags.  We assume that shifts by constant
9437 ;; zero are optimized away.
9438 (define_insn "*ashl<mode>3_cmp"
9439   [(set (reg FLAGS_REG)
9440         (compare
9441           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9442                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9443           (const_int 0)))
9444    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9445         (ashift:SWI (match_dup 1) (match_dup 2)))]
9446   "(optimize_function_for_size_p (cfun)
9447     || !TARGET_PARTIAL_FLAG_REG_STALL
9448     || (operands[2] == const1_rtx
9449         && (TARGET_SHIFT1
9450             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9451    && ix86_match_ccmode (insn, CCGOCmode)
9452    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9453 {
9454   switch (get_attr_type (insn))
9455     {
9456     case TYPE_ALU:
9457       gcc_assert (operands[2] == const1_rtx);
9458       return "add{<imodesuffix>}\t%0, %0";
9459
9460     default:
9461       if (operands[2] == const1_rtx
9462           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9463         return "sal{<imodesuffix>}\t%0";
9464       else
9465         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9466     }
9467 }
9468   [(set (attr "type")
9469      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9470                           (const_int 0))
9471                       (match_operand 0 "register_operand" ""))
9472                  (match_operand 2 "const1_operand" ""))
9473               (const_string "alu")
9474            ]
9475            (const_string "ishift")))
9476    (set (attr "length_immediate")
9477      (if_then_else
9478        (ior (eq_attr "type" "alu")
9479             (and (eq_attr "type" "ishift")
9480                  (and (match_operand 2 "const1_operand" "")
9481                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9482                           (const_int 0)))))
9483        (const_string "0")
9484        (const_string "*")))
9485    (set_attr "mode" "<MODE>")])
9486
9487 (define_insn "*ashlsi3_cmp_zext"
9488   [(set (reg FLAGS_REG)
9489         (compare
9490           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9492           (const_int 0)))
9493    (set (match_operand:DI 0 "register_operand" "=r")
9494         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9495   "TARGET_64BIT
9496    && (optimize_function_for_size_p (cfun)
9497        || !TARGET_PARTIAL_FLAG_REG_STALL
9498        || (operands[2] == const1_rtx
9499            && (TARGET_SHIFT1
9500                || TARGET_DOUBLE_WITH_ADD)))
9501    && ix86_match_ccmode (insn, CCGOCmode)
9502    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9503 {
9504   switch (get_attr_type (insn))
9505     {
9506     case TYPE_ALU:
9507       gcc_assert (operands[2] == const1_rtx);
9508       return "add{l}\t%k0, %k0";
9509
9510     default:
9511       if (operands[2] == const1_rtx
9512           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513         return "sal{l}\t%k0";
9514       else
9515         return "sal{l}\t{%2, %k0|%k0, %2}";
9516     }
9517 }
9518   [(set (attr "type")
9519      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9520                      (const_int 0))
9521                  (match_operand 2 "const1_operand" ""))
9522               (const_string "alu")
9523            ]
9524            (const_string "ishift")))
9525    (set (attr "length_immediate")
9526      (if_then_else
9527        (ior (eq_attr "type" "alu")
9528             (and (eq_attr "type" "ishift")
9529                  (and (match_operand 2 "const1_operand" "")
9530                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9531                           (const_int 0)))))
9532        (const_string "0")
9533        (const_string "*")))
9534    (set_attr "mode" "SI")])
9535
9536 (define_insn "*ashl<mode>3_cconly"
9537   [(set (reg FLAGS_REG)
9538         (compare
9539           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9541           (const_int 0)))
9542    (clobber (match_scratch:SWI 0 "=<r>"))]
9543   "(optimize_function_for_size_p (cfun)
9544     || !TARGET_PARTIAL_FLAG_REG_STALL
9545     || (operands[2] == const1_rtx
9546         && (TARGET_SHIFT1
9547             || TARGET_DOUBLE_WITH_ADD)))
9548    && ix86_match_ccmode (insn, CCGOCmode)"
9549 {
9550   switch (get_attr_type (insn))
9551     {
9552     case TYPE_ALU:
9553       gcc_assert (operands[2] == const1_rtx);
9554       return "add{<imodesuffix>}\t%0, %0";
9555
9556     default:
9557       if (operands[2] == const1_rtx
9558           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559         return "sal{<imodesuffix>}\t%0";
9560       else
9561         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9562     }
9563 }
9564   [(set (attr "type")
9565      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9566                           (const_int 0))
9567                       (match_operand 0 "register_operand" ""))
9568                  (match_operand 2 "const1_operand" ""))
9569               (const_string "alu")
9570            ]
9571            (const_string "ishift")))
9572    (set (attr "length_immediate")
9573      (if_then_else
9574        (ior (eq_attr "type" "alu")
9575             (and (eq_attr "type" "ishift")
9576                  (and (match_operand 2 "const1_operand" "")
9577                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9578                           (const_int 0)))))
9579        (const_string "0")
9580        (const_string "*")))
9581    (set_attr "mode" "<MODE>")])
9582
9583 ;; See comment above `ashl<mode>3' about how this works.
9584
9585 (define_expand "<shiftrt_insn><mode>3"
9586   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9587         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9588                            (match_operand:QI 2 "nonmemory_operand" "")))]
9589   ""
9590   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9591
9592 ;; Avoid useless masking of count operand.
9593 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9594   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9595         (any_shiftrt:SWI48
9596           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9597           (subreg:QI
9598             (and:SI
9599               (match_operand:SI 2 "nonimmediate_operand" "c")
9600               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9601    (clobber (reg:CC FLAGS_REG))]
9602   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9603    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9604       == GET_MODE_BITSIZE (<MODE>mode)-1"
9605   "#"
9606   "&& 1"
9607   [(parallel [(set (match_dup 0)
9608                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9609               (clobber (reg:CC FLAGS_REG))])]
9610 {
9611   if (can_create_pseudo_p ())
9612     operands [2] = force_reg (SImode, operands[2]);
9613
9614   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9615 }
9616   [(set_attr "type" "ishift")
9617    (set_attr "mode" "<MODE>")])
9618
9619 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9620   [(set (match_operand:DWI 0 "register_operand" "=r")
9621         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9622                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9623    (clobber (reg:CC FLAGS_REG))]
9624   ""
9625   "#"
9626   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9627   [(const_int 0)]
9628   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9629   [(set_attr "type" "multi")])
9630
9631 ;; By default we don't ask for a scratch register, because when DWImode
9632 ;; values are manipulated, registers are already at a premium.  But if
9633 ;; we have one handy, we won't turn it away.
9634
9635 (define_peephole2
9636   [(match_scratch:DWIH 3 "r")
9637    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9638                    (any_shiftrt:<DWI>
9639                      (match_operand:<DWI> 1 "register_operand" "")
9640                      (match_operand:QI 2 "nonmemory_operand" "")))
9641               (clobber (reg:CC FLAGS_REG))])
9642    (match_dup 3)]
9643   "TARGET_CMOVE"
9644   [(const_int 0)]
9645   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9646
9647 (define_insn "x86_64_shrd"
9648   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9649         (ior:DI (ashiftrt:DI (match_dup 0)
9650                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9651                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9652                   (minus:QI (const_int 64) (match_dup 2)))))
9653    (clobber (reg:CC FLAGS_REG))]
9654   "TARGET_64BIT"
9655   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9656   [(set_attr "type" "ishift")
9657    (set_attr "prefix_0f" "1")
9658    (set_attr "mode" "DI")
9659    (set_attr "athlon_decode" "vector")
9660    (set_attr "amdfam10_decode" "vector")
9661    (set_attr "bdver1_decode" "vector")])
9662
9663 (define_insn "x86_shrd"
9664   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9665         (ior:SI (ashiftrt:SI (match_dup 0)
9666                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9667                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9668                   (minus:QI (const_int 32) (match_dup 2)))))
9669    (clobber (reg:CC FLAGS_REG))]
9670   ""
9671   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9672   [(set_attr "type" "ishift")
9673    (set_attr "prefix_0f" "1")
9674    (set_attr "mode" "SI")
9675    (set_attr "pent_pair" "np")
9676    (set_attr "athlon_decode" "vector")
9677    (set_attr "amdfam10_decode" "vector")
9678    (set_attr "bdver1_decode" "vector")])
9679
9680 (define_insn "ashrdi3_cvt"
9681   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9682         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9683                      (match_operand:QI 2 "const_int_operand" "")))
9684    (clobber (reg:CC FLAGS_REG))]
9685   "TARGET_64BIT && INTVAL (operands[2]) == 63
9686    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9687    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9688   "@
9689    {cqto|cqo}
9690    sar{q}\t{%2, %0|%0, %2}"
9691   [(set_attr "type" "imovx,ishift")
9692    (set_attr "prefix_0f" "0,*")
9693    (set_attr "length_immediate" "0,*")
9694    (set_attr "modrm" "0,1")
9695    (set_attr "mode" "DI")])
9696
9697 (define_insn "ashrsi3_cvt"
9698   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9699         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9700                      (match_operand:QI 2 "const_int_operand" "")))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "INTVAL (operands[2]) == 31
9703    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9704    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9705   "@
9706    {cltd|cdq}
9707    sar{l}\t{%2, %0|%0, %2}"
9708   [(set_attr "type" "imovx,ishift")
9709    (set_attr "prefix_0f" "0,*")
9710    (set_attr "length_immediate" "0,*")
9711    (set_attr "modrm" "0,1")
9712    (set_attr "mode" "SI")])
9713
9714 (define_insn "*ashrsi3_cvt_zext"
9715   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9716         (zero_extend:DI
9717           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9718                        (match_operand:QI 2 "const_int_operand" ""))))
9719    (clobber (reg:CC FLAGS_REG))]
9720   "TARGET_64BIT && INTVAL (operands[2]) == 31
9721    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9722    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9723   "@
9724    {cltd|cdq}
9725    sar{l}\t{%2, %k0|%k0, %2}"
9726   [(set_attr "type" "imovx,ishift")
9727    (set_attr "prefix_0f" "0,*")
9728    (set_attr "length_immediate" "0,*")
9729    (set_attr "modrm" "0,1")
9730    (set_attr "mode" "SI")])
9731
9732 (define_expand "x86_shift<mode>_adj_3"
9733   [(use (match_operand:SWI48 0 "register_operand" ""))
9734    (use (match_operand:SWI48 1 "register_operand" ""))
9735    (use (match_operand:QI 2 "register_operand" ""))]
9736   ""
9737 {
9738   rtx label = gen_label_rtx ();
9739   rtx tmp;
9740
9741   emit_insn (gen_testqi_ccz_1 (operands[2],
9742                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9743
9744   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9745   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9746   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9747                               gen_rtx_LABEL_REF (VOIDmode, label),
9748                               pc_rtx);
9749   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9750   JUMP_LABEL (tmp) = label;
9751
9752   emit_move_insn (operands[0], operands[1]);
9753   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9754                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9755   emit_label (label);
9756   LABEL_NUSES (label) = 1;
9757
9758   DONE;
9759 })
9760
9761 (define_insn "*<shiftrt_insn><mode>3_1"
9762   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9763         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9764                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9765    (clobber (reg:CC FLAGS_REG))]
9766   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9767 {
9768   if (operands[2] == const1_rtx
9769       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9770     return "<shiftrt>{<imodesuffix>}\t%0";
9771   else
9772     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9773 }
9774   [(set_attr "type" "ishift")
9775    (set (attr "length_immediate")
9776      (if_then_else
9777        (and (match_operand 2 "const1_operand" "")
9778             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9779                 (const_int 0)))
9780        (const_string "0")
9781        (const_string "*")))
9782    (set_attr "mode" "<MODE>")])
9783
9784 (define_insn "*<shiftrt_insn>si3_1_zext"
9785   [(set (match_operand:DI 0 "register_operand" "=r")
9786         (zero_extend:DI
9787           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9788                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9789    (clobber (reg:CC FLAGS_REG))]
9790   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9791 {
9792   if (operands[2] == const1_rtx
9793       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9794     return "<shiftrt>{l}\t%k0";
9795   else
9796     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9797 }
9798   [(set_attr "type" "ishift")
9799    (set (attr "length_immediate")
9800      (if_then_else
9801        (and (match_operand 2 "const1_operand" "")
9802             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9803                 (const_int 0)))
9804        (const_string "0")
9805        (const_string "*")))
9806    (set_attr "mode" "SI")])
9807
9808 (define_insn "*<shiftrt_insn>qi3_1_slp"
9809   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9810         (any_shiftrt:QI (match_dup 0)
9811                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9812    (clobber (reg:CC FLAGS_REG))]
9813   "(optimize_function_for_size_p (cfun)
9814     || !TARGET_PARTIAL_REG_STALL
9815     || (operands[1] == const1_rtx
9816         && TARGET_SHIFT1))"
9817 {
9818   if (operands[1] == const1_rtx
9819       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9820     return "<shiftrt>{b}\t%0";
9821   else
9822     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9823 }
9824   [(set_attr "type" "ishift1")
9825    (set (attr "length_immediate")
9826      (if_then_else
9827        (and (match_operand 1 "const1_operand" "")
9828             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9829                 (const_int 0)))
9830        (const_string "0")
9831        (const_string "*")))
9832    (set_attr "mode" "QI")])
9833
9834 ;; This pattern can't accept a variable shift count, since shifts by
9835 ;; zero don't affect the flags.  We assume that shifts by constant
9836 ;; zero are optimized away.
9837 (define_insn "*<shiftrt_insn><mode>3_cmp"
9838   [(set (reg FLAGS_REG)
9839         (compare
9840           (any_shiftrt:SWI
9841             (match_operand:SWI 1 "nonimmediate_operand" "0")
9842             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9843           (const_int 0)))
9844    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9845         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9846   "(optimize_function_for_size_p (cfun)
9847     || !TARGET_PARTIAL_FLAG_REG_STALL
9848     || (operands[2] == const1_rtx
9849         && TARGET_SHIFT1))
9850    && ix86_match_ccmode (insn, CCGOCmode)
9851    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9852 {
9853   if (operands[2] == const1_rtx
9854       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9855     return "<shiftrt>{<imodesuffix>}\t%0";
9856   else
9857     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9858 }
9859   [(set_attr "type" "ishift")
9860    (set (attr "length_immediate")
9861      (if_then_else
9862        (and (match_operand 2 "const1_operand" "")
9863             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9864                 (const_int 0)))
9865        (const_string "0")
9866        (const_string "*")))
9867    (set_attr "mode" "<MODE>")])
9868
9869 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9870   [(set (reg FLAGS_REG)
9871         (compare
9872           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9873                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9874           (const_int 0)))
9875    (set (match_operand:DI 0 "register_operand" "=r")
9876         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9877   "TARGET_64BIT
9878    && (optimize_function_for_size_p (cfun)
9879        || !TARGET_PARTIAL_FLAG_REG_STALL
9880        || (operands[2] == const1_rtx
9881            && TARGET_SHIFT1))
9882    && ix86_match_ccmode (insn, CCGOCmode)
9883    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9884 {
9885   if (operands[2] == const1_rtx
9886       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887     return "<shiftrt>{l}\t%k0";
9888   else
9889     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9890 }
9891   [(set_attr "type" "ishift")
9892    (set (attr "length_immediate")
9893      (if_then_else
9894        (and (match_operand 2 "const1_operand" "")
9895             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9896                 (const_int 0)))
9897        (const_string "0")
9898        (const_string "*")))
9899    (set_attr "mode" "SI")])
9900
9901 (define_insn "*<shiftrt_insn><mode>3_cconly"
9902   [(set (reg FLAGS_REG)
9903         (compare
9904           (any_shiftrt:SWI
9905             (match_operand:SWI 1 "register_operand" "0")
9906             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9907           (const_int 0)))
9908    (clobber (match_scratch:SWI 0 "=<r>"))]
9909   "(optimize_function_for_size_p (cfun)
9910     || !TARGET_PARTIAL_FLAG_REG_STALL
9911     || (operands[2] == const1_rtx
9912         && TARGET_SHIFT1))
9913    && ix86_match_ccmode (insn, CCGOCmode)"
9914 {
9915   if (operands[2] == const1_rtx
9916       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9917     return "<shiftrt>{<imodesuffix>}\t%0";
9918   else
9919     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9920 }
9921   [(set_attr "type" "ishift")
9922    (set (attr "length_immediate")
9923      (if_then_else
9924        (and (match_operand 2 "const1_operand" "")
9925             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9926                 (const_int 0)))
9927        (const_string "0")
9928        (const_string "*")))
9929    (set_attr "mode" "<MODE>")])
9930 \f
9931 ;; Rotate instructions
9932
9933 (define_expand "<rotate_insn>ti3"
9934   [(set (match_operand:TI 0 "register_operand" "")
9935         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9936                        (match_operand:QI 2 "nonmemory_operand" "")))]
9937   "TARGET_64BIT"
9938 {
9939   if (const_1_to_63_operand (operands[2], VOIDmode))
9940     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9941                 (operands[0], operands[1], operands[2]));
9942   else
9943     FAIL;
9944
9945   DONE;
9946 })
9947
9948 (define_expand "<rotate_insn>di3"
9949   [(set (match_operand:DI 0 "shiftdi_operand" "")
9950         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9951                        (match_operand:QI 2 "nonmemory_operand" "")))]
9952  ""
9953 {
9954   if (TARGET_64BIT)
9955     ix86_expand_binary_operator (<CODE>, DImode, operands);
9956   else if (const_1_to_31_operand (operands[2], VOIDmode))
9957     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9958                 (operands[0], operands[1], operands[2]));
9959   else
9960     FAIL;
9961
9962   DONE;
9963 })
9964
9965 (define_expand "<rotate_insn><mode>3"
9966   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9967         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9968                             (match_operand:QI 2 "nonmemory_operand" "")))]
9969   ""
9970   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9971
9972 ;; Avoid useless masking of count operand.
9973 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9974   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9975         (any_rotate:SWI48
9976           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9977           (subreg:QI
9978             (and:SI
9979               (match_operand:SI 2 "nonimmediate_operand" "c")
9980               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9981    (clobber (reg:CC FLAGS_REG))]
9982   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9983    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9984       == GET_MODE_BITSIZE (<MODE>mode)-1"
9985   "#"
9986   "&& 1"
9987   [(parallel [(set (match_dup 0)
9988                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9989               (clobber (reg:CC FLAGS_REG))])]
9990 {
9991   if (can_create_pseudo_p ())
9992     operands [2] = force_reg (SImode, operands[2]);
9993
9994   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9995 }
9996   [(set_attr "type" "rotate")
9997    (set_attr "mode" "<MODE>")])
9998
9999 ;; Implement rotation using two double-precision
10000 ;; shift instructions and a scratch register.
10001
10002 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10003  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10004        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10005                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10006   (clobber (reg:CC FLAGS_REG))
10007   (clobber (match_scratch:DWIH 3 "=&r"))]
10008  ""
10009  "#"
10010  "reload_completed"
10011  [(set (match_dup 3) (match_dup 4))
10012   (parallel
10013    [(set (match_dup 4)
10014          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10015                    (lshiftrt:DWIH (match_dup 5)
10016                                   (minus:QI (match_dup 6) (match_dup 2)))))
10017     (clobber (reg:CC FLAGS_REG))])
10018   (parallel
10019    [(set (match_dup 5)
10020          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10021                    (lshiftrt:DWIH (match_dup 3)
10022                                   (minus:QI (match_dup 6) (match_dup 2)))))
10023     (clobber (reg:CC FLAGS_REG))])]
10024 {
10025   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10026
10027   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10028 })
10029
10030 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10031  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10032        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10033                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10034   (clobber (reg:CC FLAGS_REG))
10035   (clobber (match_scratch:DWIH 3 "=&r"))]
10036  ""
10037  "#"
10038  "reload_completed"
10039  [(set (match_dup 3) (match_dup 4))
10040   (parallel
10041    [(set (match_dup 4)
10042          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10043                    (ashift:DWIH (match_dup 5)
10044                                 (minus:QI (match_dup 6) (match_dup 2)))))
10045     (clobber (reg:CC FLAGS_REG))])
10046   (parallel
10047    [(set (match_dup 5)
10048          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10049                    (ashift:DWIH (match_dup 3)
10050                                 (minus:QI (match_dup 6) (match_dup 2)))))
10051     (clobber (reg:CC FLAGS_REG))])]
10052 {
10053   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10054
10055   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10056 })
10057
10058 (define_insn "*<rotate_insn><mode>3_1"
10059   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10060         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10061                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10062    (clobber (reg:CC FLAGS_REG))]
10063   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10064 {
10065   if (operands[2] == const1_rtx
10066       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10067     return "<rotate>{<imodesuffix>}\t%0";
10068   else
10069     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10070 }
10071   [(set_attr "type" "rotate")
10072    (set (attr "length_immediate")
10073      (if_then_else
10074        (and (match_operand 2 "const1_operand" "")
10075             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10076                 (const_int 0)))
10077        (const_string "0")
10078        (const_string "*")))
10079    (set_attr "mode" "<MODE>")])
10080
10081 (define_insn "*<rotate_insn>si3_1_zext"
10082   [(set (match_operand:DI 0 "register_operand" "=r")
10083         (zero_extend:DI
10084           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10085                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10086    (clobber (reg:CC FLAGS_REG))]
10087   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10088 {
10089     if (operands[2] == const1_rtx
10090         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10091     return "<rotate>{l}\t%k0";
10092   else
10093     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10094 }
10095   [(set_attr "type" "rotate")
10096    (set (attr "length_immediate")
10097      (if_then_else
10098        (and (match_operand 2 "const1_operand" "")
10099             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10100                 (const_int 0)))
10101        (const_string "0")
10102        (const_string "*")))
10103    (set_attr "mode" "SI")])
10104
10105 (define_insn "*<rotate_insn>qi3_1_slp"
10106   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10107         (any_rotate:QI (match_dup 0)
10108                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "(optimize_function_for_size_p (cfun)
10111     || !TARGET_PARTIAL_REG_STALL
10112     || (operands[1] == const1_rtx
10113         && TARGET_SHIFT1))"
10114 {
10115   if (operands[1] == const1_rtx
10116       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10117     return "<rotate>{b}\t%0";
10118   else
10119     return "<rotate>{b}\t{%1, %0|%0, %1}";
10120 }
10121   [(set_attr "type" "rotate1")
10122    (set (attr "length_immediate")
10123      (if_then_else
10124        (and (match_operand 1 "const1_operand" "")
10125             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10126                 (const_int 0)))
10127        (const_string "0")
10128        (const_string "*")))
10129    (set_attr "mode" "QI")])
10130
10131 (define_split
10132  [(set (match_operand:HI 0 "register_operand" "")
10133        (any_rotate:HI (match_dup 0) (const_int 8)))
10134   (clobber (reg:CC FLAGS_REG))]
10135  "reload_completed
10136   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10137  [(parallel [(set (strict_low_part (match_dup 0))
10138                   (bswap:HI (match_dup 0)))
10139              (clobber (reg:CC FLAGS_REG))])])
10140 \f
10141 ;; Bit set / bit test instructions
10142
10143 (define_expand "extv"
10144   [(set (match_operand:SI 0 "register_operand" "")
10145         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10146                          (match_operand:SI 2 "const8_operand" "")
10147                          (match_operand:SI 3 "const8_operand" "")))]
10148   ""
10149 {
10150   /* Handle extractions from %ah et al.  */
10151   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10152     FAIL;
10153
10154   /* From mips.md: extract_bit_field doesn't verify that our source
10155      matches the predicate, so check it again here.  */
10156   if (! ext_register_operand (operands[1], VOIDmode))
10157     FAIL;
10158 })
10159
10160 (define_expand "extzv"
10161   [(set (match_operand:SI 0 "register_operand" "")
10162         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10163                          (match_operand:SI 2 "const8_operand" "")
10164                          (match_operand:SI 3 "const8_operand" "")))]
10165   ""
10166 {
10167   /* Handle extractions from %ah et al.  */
10168   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10169     FAIL;
10170
10171   /* From mips.md: extract_bit_field doesn't verify that our source
10172      matches the predicate, so check it again here.  */
10173   if (! ext_register_operand (operands[1], VOIDmode))
10174     FAIL;
10175 })
10176
10177 (define_expand "insv"
10178   [(set (zero_extract (match_operand 0 "register_operand" "")
10179                       (match_operand 1 "const_int_operand" "")
10180                       (match_operand 2 "const_int_operand" ""))
10181         (match_operand 3 "register_operand" ""))]
10182   ""
10183 {
10184   rtx (*gen_mov_insv_1) (rtx, rtx);
10185
10186   if (ix86_expand_pinsr (operands))
10187     DONE;
10188
10189   /* Handle insertions to %ah et al.  */
10190   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10191     FAIL;
10192
10193   /* From mips.md: insert_bit_field doesn't verify that our source
10194      matches the predicate, so check it again here.  */
10195   if (! ext_register_operand (operands[0], VOIDmode))
10196     FAIL;
10197
10198   gen_mov_insv_1 = (TARGET_64BIT
10199                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10200
10201   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10202   DONE;
10203 })
10204
10205 ;; %%% bts, btr, btc, bt.
10206 ;; In general these instructions are *slow* when applied to memory,
10207 ;; since they enforce atomic operation.  When applied to registers,
10208 ;; it depends on the cpu implementation.  They're never faster than
10209 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10210 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10211 ;; within the instruction itself, so operating on bits in the high
10212 ;; 32-bits of a register becomes easier.
10213 ;;
10214 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10215 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10216 ;; negdf respectively, so they can never be disabled entirely.
10217
10218 (define_insn "*btsq"
10219   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10220                          (const_int 1)
10221                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10222         (const_int 1))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10225   "bts{q}\t{%1, %0|%0, %1}"
10226   [(set_attr "type" "alu1")
10227    (set_attr "prefix_0f" "1")
10228    (set_attr "mode" "DI")])
10229
10230 (define_insn "*btrq"
10231   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10232                          (const_int 1)
10233                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10234         (const_int 0))
10235    (clobber (reg:CC FLAGS_REG))]
10236   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10237   "btr{q}\t{%1, %0|%0, %1}"
10238   [(set_attr "type" "alu1")
10239    (set_attr "prefix_0f" "1")
10240    (set_attr "mode" "DI")])
10241
10242 (define_insn "*btcq"
10243   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10244                          (const_int 1)
10245                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10246         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10247    (clobber (reg:CC FLAGS_REG))]
10248   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10249   "btc{q}\t{%1, %0|%0, %1}"
10250   [(set_attr "type" "alu1")
10251    (set_attr "prefix_0f" "1")
10252    (set_attr "mode" "DI")])
10253
10254 ;; Allow Nocona to avoid these instructions if a register is available.
10255
10256 (define_peephole2
10257   [(match_scratch:DI 2 "r")
10258    (parallel [(set (zero_extract:DI
10259                      (match_operand:DI 0 "register_operand" "")
10260                      (const_int 1)
10261                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10262                    (const_int 1))
10263               (clobber (reg:CC FLAGS_REG))])]
10264   "TARGET_64BIT && !TARGET_USE_BT"
10265   [(const_int 0)]
10266 {
10267   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10268   rtx op1;
10269
10270   if (HOST_BITS_PER_WIDE_INT >= 64)
10271     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272   else if (i < HOST_BITS_PER_WIDE_INT)
10273     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10274   else
10275     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10276
10277   op1 = immed_double_const (lo, hi, DImode);
10278   if (i >= 31)
10279     {
10280       emit_move_insn (operands[2], op1);
10281       op1 = operands[2];
10282     }
10283
10284   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10285   DONE;
10286 })
10287
10288 (define_peephole2
10289   [(match_scratch:DI 2 "r")
10290    (parallel [(set (zero_extract:DI
10291                      (match_operand:DI 0 "register_operand" "")
10292                      (const_int 1)
10293                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10294                    (const_int 0))
10295               (clobber (reg:CC FLAGS_REG))])]
10296   "TARGET_64BIT && !TARGET_USE_BT"
10297   [(const_int 0)]
10298 {
10299   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10300   rtx op1;
10301
10302   if (HOST_BITS_PER_WIDE_INT >= 64)
10303     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10304   else if (i < HOST_BITS_PER_WIDE_INT)
10305     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10306   else
10307     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10308
10309   op1 = immed_double_const (~lo, ~hi, DImode);
10310   if (i >= 32)
10311     {
10312       emit_move_insn (operands[2], op1);
10313       op1 = operands[2];
10314     }
10315
10316   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10317   DONE;
10318 })
10319
10320 (define_peephole2
10321   [(match_scratch:DI 2 "r")
10322    (parallel [(set (zero_extract:DI
10323                      (match_operand:DI 0 "register_operand" "")
10324                      (const_int 1)
10325                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10326               (not:DI (zero_extract:DI
10327                         (match_dup 0) (const_int 1) (match_dup 1))))
10328               (clobber (reg:CC FLAGS_REG))])]
10329   "TARGET_64BIT && !TARGET_USE_BT"
10330   [(const_int 0)]
10331 {
10332   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10333   rtx op1;
10334
10335   if (HOST_BITS_PER_WIDE_INT >= 64)
10336     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10337   else if (i < HOST_BITS_PER_WIDE_INT)
10338     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10339   else
10340     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10341
10342   op1 = immed_double_const (lo, hi, DImode);
10343   if (i >= 31)
10344     {
10345       emit_move_insn (operands[2], op1);
10346       op1 = operands[2];
10347     }
10348
10349   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10350   DONE;
10351 })
10352
10353 (define_insn "*bt<mode>"
10354   [(set (reg:CCC FLAGS_REG)
10355         (compare:CCC
10356           (zero_extract:SWI48
10357             (match_operand:SWI48 0 "register_operand" "r")
10358             (const_int 1)
10359             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10360           (const_int 0)))]
10361   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10362   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10363   [(set_attr "type" "alu1")
10364    (set_attr "prefix_0f" "1")
10365    (set_attr "mode" "<MODE>")])
10366 \f
10367 ;; Store-flag instructions.
10368
10369 ;; For all sCOND expanders, also expand the compare or test insn that
10370 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10371
10372 (define_insn_and_split "*setcc_di_1"
10373   [(set (match_operand:DI 0 "register_operand" "=q")
10374         (match_operator:DI 1 "ix86_comparison_operator"
10375           [(reg FLAGS_REG) (const_int 0)]))]
10376   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10377   "#"
10378   "&& reload_completed"
10379   [(set (match_dup 2) (match_dup 1))
10380    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10381 {
10382   PUT_MODE (operands[1], QImode);
10383   operands[2] = gen_lowpart (QImode, operands[0]);
10384 })
10385
10386 (define_insn_and_split "*setcc_si_1_and"
10387   [(set (match_operand:SI 0 "register_operand" "=q")
10388         (match_operator:SI 1 "ix86_comparison_operator"
10389           [(reg FLAGS_REG) (const_int 0)]))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "!TARGET_PARTIAL_REG_STALL
10392    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10393   "#"
10394   "&& reload_completed"
10395   [(set (match_dup 2) (match_dup 1))
10396    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10397               (clobber (reg:CC FLAGS_REG))])]
10398 {
10399   PUT_MODE (operands[1], QImode);
10400   operands[2] = gen_lowpart (QImode, operands[0]);
10401 })
10402
10403 (define_insn_and_split "*setcc_si_1_movzbl"
10404   [(set (match_operand:SI 0 "register_operand" "=q")
10405         (match_operator:SI 1 "ix86_comparison_operator"
10406           [(reg FLAGS_REG) (const_int 0)]))]
10407   "!TARGET_PARTIAL_REG_STALL
10408    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10409   "#"
10410   "&& reload_completed"
10411   [(set (match_dup 2) (match_dup 1))
10412    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10413 {
10414   PUT_MODE (operands[1], QImode);
10415   operands[2] = gen_lowpart (QImode, operands[0]);
10416 })
10417
10418 (define_insn "*setcc_qi"
10419   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10420         (match_operator:QI 1 "ix86_comparison_operator"
10421           [(reg FLAGS_REG) (const_int 0)]))]
10422   ""
10423   "set%C1\t%0"
10424   [(set_attr "type" "setcc")
10425    (set_attr "mode" "QI")])
10426
10427 (define_insn "*setcc_qi_slp"
10428   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10429         (match_operator:QI 1 "ix86_comparison_operator"
10430           [(reg FLAGS_REG) (const_int 0)]))]
10431   ""
10432   "set%C1\t%0"
10433   [(set_attr "type" "setcc")
10434    (set_attr "mode" "QI")])
10435
10436 ;; In general it is not safe to assume too much about CCmode registers,
10437 ;; so simplify-rtx stops when it sees a second one.  Under certain
10438 ;; conditions this is safe on x86, so help combine not create
10439 ;;
10440 ;;      seta    %al
10441 ;;      testb   %al, %al
10442 ;;      sete    %al
10443
10444 (define_split
10445   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10446         (ne:QI (match_operator 1 "ix86_comparison_operator"
10447                  [(reg FLAGS_REG) (const_int 0)])
10448             (const_int 0)))]
10449   ""
10450   [(set (match_dup 0) (match_dup 1))]
10451   "PUT_MODE (operands[1], QImode);")
10452
10453 (define_split
10454   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10455         (ne:QI (match_operator 1 "ix86_comparison_operator"
10456                  [(reg FLAGS_REG) (const_int 0)])
10457             (const_int 0)))]
10458   ""
10459   [(set (match_dup 0) (match_dup 1))]
10460   "PUT_MODE (operands[1], QImode);")
10461
10462 (define_split
10463   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10464         (eq:QI (match_operator 1 "ix86_comparison_operator"
10465                  [(reg FLAGS_REG) (const_int 0)])
10466             (const_int 0)))]
10467   ""
10468   [(set (match_dup 0) (match_dup 1))]
10469 {
10470   rtx new_op1 = copy_rtx (operands[1]);
10471   operands[1] = new_op1;
10472   PUT_MODE (new_op1, QImode);
10473   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10474                                              GET_MODE (XEXP (new_op1, 0))));
10475
10476   /* Make sure that (a) the CCmode we have for the flags is strong
10477      enough for the reversed compare or (b) we have a valid FP compare.  */
10478   if (! ix86_comparison_operator (new_op1, VOIDmode))
10479     FAIL;
10480 })
10481
10482 (define_split
10483   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10484         (eq:QI (match_operator 1 "ix86_comparison_operator"
10485                  [(reg FLAGS_REG) (const_int 0)])
10486             (const_int 0)))]
10487   ""
10488   [(set (match_dup 0) (match_dup 1))]
10489 {
10490   rtx new_op1 = copy_rtx (operands[1]);
10491   operands[1] = new_op1;
10492   PUT_MODE (new_op1, QImode);
10493   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10494                                              GET_MODE (XEXP (new_op1, 0))));
10495
10496   /* Make sure that (a) the CCmode we have for the flags is strong
10497      enough for the reversed compare or (b) we have a valid FP compare.  */
10498   if (! ix86_comparison_operator (new_op1, VOIDmode))
10499     FAIL;
10500 })
10501
10502 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10503 ;; subsequent logical operations are used to imitate conditional moves.
10504 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10505 ;; it directly.
10506
10507 (define_insn "setcc_<mode>_sse"
10508   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10509         (match_operator:MODEF 3 "sse_comparison_operator"
10510           [(match_operand:MODEF 1 "register_operand" "0,x")
10511            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10512   "SSE_FLOAT_MODE_P (<MODE>mode)"
10513   "@
10514    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10515    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10516   [(set_attr "isa" "noavx,avx")
10517    (set_attr "type" "ssecmp")
10518    (set_attr "length_immediate" "1")
10519    (set_attr "prefix" "orig,vex")
10520    (set_attr "mode" "<MODE>")])
10521 \f
10522 ;; Basic conditional jump instructions.
10523 ;; We ignore the overflow flag for signed branch instructions.
10524
10525 (define_insn "*jcc_1"
10526   [(set (pc)
10527         (if_then_else (match_operator 1 "ix86_comparison_operator"
10528                                       [(reg FLAGS_REG) (const_int 0)])
10529                       (label_ref (match_operand 0 "" ""))
10530                       (pc)))]
10531   ""
10532   "%+j%C1\t%l0"
10533   [(set_attr "type" "ibr")
10534    (set_attr "modrm" "0")
10535    (set (attr "length")
10536            (if_then_else (and (ge (minus (match_dup 0) (pc))
10537                                   (const_int -126))
10538                               (lt (minus (match_dup 0) (pc))
10539                                   (const_int 128)))
10540              (const_int 2)
10541              (const_int 6)))])
10542
10543 (define_insn "*jcc_2"
10544   [(set (pc)
10545         (if_then_else (match_operator 1 "ix86_comparison_operator"
10546                                       [(reg FLAGS_REG) (const_int 0)])
10547                       (pc)
10548                       (label_ref (match_operand 0 "" ""))))]
10549   ""
10550   "%+j%c1\t%l0"
10551   [(set_attr "type" "ibr")
10552    (set_attr "modrm" "0")
10553    (set (attr "length")
10554            (if_then_else (and (ge (minus (match_dup 0) (pc))
10555                                   (const_int -126))
10556                               (lt (minus (match_dup 0) (pc))
10557                                   (const_int 128)))
10558              (const_int 2)
10559              (const_int 6)))])
10560
10561 ;; In general it is not safe to assume too much about CCmode registers,
10562 ;; so simplify-rtx stops when it sees a second one.  Under certain
10563 ;; conditions this is safe on x86, so help combine not create
10564 ;;
10565 ;;      seta    %al
10566 ;;      testb   %al, %al
10567 ;;      je      Lfoo
10568
10569 (define_split
10570   [(set (pc)
10571         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10572                                       [(reg FLAGS_REG) (const_int 0)])
10573                           (const_int 0))
10574                       (label_ref (match_operand 1 "" ""))
10575                       (pc)))]
10576   ""
10577   [(set (pc)
10578         (if_then_else (match_dup 0)
10579                       (label_ref (match_dup 1))
10580                       (pc)))]
10581   "PUT_MODE (operands[0], VOIDmode);")
10582
10583 (define_split
10584   [(set (pc)
10585         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10586                                       [(reg FLAGS_REG) (const_int 0)])
10587                           (const_int 0))
10588                       (label_ref (match_operand 1 "" ""))
10589                       (pc)))]
10590   ""
10591   [(set (pc)
10592         (if_then_else (match_dup 0)
10593                       (label_ref (match_dup 1))
10594                       (pc)))]
10595 {
10596   rtx new_op0 = copy_rtx (operands[0]);
10597   operands[0] = new_op0;
10598   PUT_MODE (new_op0, VOIDmode);
10599   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10600                                              GET_MODE (XEXP (new_op0, 0))));
10601
10602   /* Make sure that (a) the CCmode we have for the flags is strong
10603      enough for the reversed compare or (b) we have a valid FP compare.  */
10604   if (! ix86_comparison_operator (new_op0, VOIDmode))
10605     FAIL;
10606 })
10607
10608 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10609 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10610 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10611 ;; appropriate modulo of the bit offset value.
10612
10613 (define_insn_and_split "*jcc_bt<mode>"
10614   [(set (pc)
10615         (if_then_else (match_operator 0 "bt_comparison_operator"
10616                         [(zero_extract:SWI48
10617                            (match_operand:SWI48 1 "register_operand" "r")
10618                            (const_int 1)
10619                            (zero_extend:SI
10620                              (match_operand:QI 2 "register_operand" "r")))
10621                          (const_int 0)])
10622                       (label_ref (match_operand 3 "" ""))
10623                       (pc)))
10624    (clobber (reg:CC FLAGS_REG))]
10625   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10626   "#"
10627   "&& 1"
10628   [(set (reg:CCC FLAGS_REG)
10629         (compare:CCC
10630           (zero_extract:SWI48
10631             (match_dup 1)
10632             (const_int 1)
10633             (match_dup 2))
10634           (const_int 0)))
10635    (set (pc)
10636         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10637                       (label_ref (match_dup 3))
10638                       (pc)))]
10639 {
10640   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10641
10642   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10643 })
10644
10645 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10646 ;; also for DImode, this is what combine produces.
10647 (define_insn_and_split "*jcc_bt<mode>_mask"
10648   [(set (pc)
10649         (if_then_else (match_operator 0 "bt_comparison_operator"
10650                         [(zero_extract:SWI48
10651                            (match_operand:SWI48 1 "register_operand" "r")
10652                            (const_int 1)
10653                            (and:SI
10654                              (match_operand:SI 2 "register_operand" "r")
10655                              (match_operand:SI 3 "const_int_operand" "n")))])
10656                       (label_ref (match_operand 4 "" ""))
10657                       (pc)))
10658    (clobber (reg:CC FLAGS_REG))]
10659   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10660    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10661       == GET_MODE_BITSIZE (<MODE>mode)-1"
10662   "#"
10663   "&& 1"
10664   [(set (reg:CCC FLAGS_REG)
10665         (compare:CCC
10666           (zero_extract:SWI48
10667             (match_dup 1)
10668             (const_int 1)
10669             (match_dup 2))
10670           (const_int 0)))
10671    (set (pc)
10672         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10673                       (label_ref (match_dup 4))
10674                       (pc)))]
10675 {
10676   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10677
10678   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10679 })
10680
10681 (define_insn_and_split "*jcc_btsi_1"
10682   [(set (pc)
10683         (if_then_else (match_operator 0 "bt_comparison_operator"
10684                         [(and:SI
10685                            (lshiftrt:SI
10686                              (match_operand:SI 1 "register_operand" "r")
10687                              (match_operand:QI 2 "register_operand" "r"))
10688                            (const_int 1))
10689                          (const_int 0)])
10690                       (label_ref (match_operand 3 "" ""))
10691                       (pc)))
10692    (clobber (reg:CC FLAGS_REG))]
10693   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10694   "#"
10695   "&& 1"
10696   [(set (reg:CCC FLAGS_REG)
10697         (compare:CCC
10698           (zero_extract:SI
10699             (match_dup 1)
10700             (const_int 1)
10701             (match_dup 2))
10702           (const_int 0)))
10703    (set (pc)
10704         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10705                       (label_ref (match_dup 3))
10706                       (pc)))]
10707 {
10708   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10709
10710   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10711 })
10712
10713 ;; avoid useless masking of bit offset operand
10714 (define_insn_and_split "*jcc_btsi_mask_1"
10715   [(set (pc)
10716         (if_then_else
10717           (match_operator 0 "bt_comparison_operator"
10718             [(and:SI
10719                (lshiftrt:SI
10720                  (match_operand:SI 1 "register_operand" "r")
10721                  (subreg:QI
10722                    (and:SI
10723                      (match_operand:SI 2 "register_operand" "r")
10724                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10725                (const_int 1))
10726              (const_int 0)])
10727           (label_ref (match_operand 4 "" ""))
10728           (pc)))
10729    (clobber (reg:CC FLAGS_REG))]
10730   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10731    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10732   "#"
10733   "&& 1"
10734   [(set (reg:CCC FLAGS_REG)
10735         (compare:CCC
10736           (zero_extract:SI
10737             (match_dup 1)
10738             (const_int 1)
10739             (match_dup 2))
10740           (const_int 0)))
10741    (set (pc)
10742         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10743                       (label_ref (match_dup 4))
10744                       (pc)))]
10745   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10746
10747 ;; Define combination compare-and-branch fp compare instructions to help
10748 ;; combine.
10749
10750 (define_insn "*fp_jcc_1_387"
10751   [(set (pc)
10752         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10753                         [(match_operand 1 "register_operand" "f")
10754                          (match_operand 2 "nonimmediate_operand" "fm")])
10755           (label_ref (match_operand 3 "" ""))
10756           (pc)))
10757    (clobber (reg:CCFP FPSR_REG))
10758    (clobber (reg:CCFP FLAGS_REG))
10759    (clobber (match_scratch:HI 4 "=a"))]
10760   "TARGET_80387
10761    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10762    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10763    && SELECT_CC_MODE (GET_CODE (operands[0]),
10764                       operands[1], operands[2]) == CCFPmode
10765    && !TARGET_CMOVE"
10766   "#")
10767
10768 (define_insn "*fp_jcc_1r_387"
10769   [(set (pc)
10770         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10771                         [(match_operand 1 "register_operand" "f")
10772                          (match_operand 2 "nonimmediate_operand" "fm")])
10773           (pc)
10774           (label_ref (match_operand 3 "" ""))))
10775    (clobber (reg:CCFP FPSR_REG))
10776    (clobber (reg:CCFP FLAGS_REG))
10777    (clobber (match_scratch:HI 4 "=a"))]
10778   "TARGET_80387
10779    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10780    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10781    && SELECT_CC_MODE (GET_CODE (operands[0]),
10782                       operands[1], operands[2]) == CCFPmode
10783    && !TARGET_CMOVE"
10784   "#")
10785
10786 (define_insn "*fp_jcc_2_387"
10787   [(set (pc)
10788         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10789                         [(match_operand 1 "register_operand" "f")
10790                          (match_operand 2 "register_operand" "f")])
10791           (label_ref (match_operand 3 "" ""))
10792           (pc)))
10793    (clobber (reg:CCFP FPSR_REG))
10794    (clobber (reg:CCFP FLAGS_REG))
10795    (clobber (match_scratch:HI 4 "=a"))]
10796   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10797    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10798    && !TARGET_CMOVE"
10799   "#")
10800
10801 (define_insn "*fp_jcc_2r_387"
10802   [(set (pc)
10803         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10804                         [(match_operand 1 "register_operand" "f")
10805                          (match_operand 2 "register_operand" "f")])
10806           (pc)
10807           (label_ref (match_operand 3 "" ""))))
10808    (clobber (reg:CCFP FPSR_REG))
10809    (clobber (reg:CCFP FLAGS_REG))
10810    (clobber (match_scratch:HI 4 "=a"))]
10811   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10812    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10813    && !TARGET_CMOVE"
10814   "#")
10815
10816 (define_insn "*fp_jcc_3_387"
10817   [(set (pc)
10818         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10819                         [(match_operand 1 "register_operand" "f")
10820                          (match_operand 2 "const0_operand" "")])
10821           (label_ref (match_operand 3 "" ""))
10822           (pc)))
10823    (clobber (reg:CCFP FPSR_REG))
10824    (clobber (reg:CCFP FLAGS_REG))
10825    (clobber (match_scratch:HI 4 "=a"))]
10826   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10827    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10828    && SELECT_CC_MODE (GET_CODE (operands[0]),
10829                       operands[1], operands[2]) == CCFPmode
10830    && !TARGET_CMOVE"
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 "nonimmediate_operand" "")])
10838           (match_operand 3 "" "")
10839           (match_operand 4 "" "")))
10840    (clobber (reg:CCFP FPSR_REG))
10841    (clobber (reg:CCFP FLAGS_REG))]
10842   "reload_completed"
10843   [(const_int 0)]
10844 {
10845   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10846                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10847   DONE;
10848 })
10849
10850 (define_split
10851   [(set (pc)
10852         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10853                         [(match_operand 1 "register_operand" "")
10854                          (match_operand 2 "general_operand" "")])
10855           (match_operand 3 "" "")
10856           (match_operand 4 "" "")))
10857    (clobber (reg:CCFP FPSR_REG))
10858    (clobber (reg:CCFP FLAGS_REG))
10859    (clobber (match_scratch:HI 5 "=a"))]
10860   "reload_completed"
10861   [(const_int 0)]
10862 {
10863   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10864                         operands[3], operands[4], operands[5], NULL_RTX);
10865   DONE;
10866 })
10867
10868 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10869 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10870 ;; with a precedence over other operators and is always put in the first
10871 ;; place. Swap condition and operands to match ficom instruction.
10872
10873 (define_insn "*fp_jcc_4_<mode>_387"
10874   [(set (pc)
10875         (if_then_else
10876           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10877             [(match_operator 1 "float_operator"
10878               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10879              (match_operand 3 "register_operand" "f,f")])
10880           (label_ref (match_operand 4 "" ""))
10881           (pc)))
10882    (clobber (reg:CCFP FPSR_REG))
10883    (clobber (reg:CCFP FLAGS_REG))
10884    (clobber (match_scratch:HI 5 "=a,a"))]
10885   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10886    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10887    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10888    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10889    && !TARGET_CMOVE"
10890   "#")
10891
10892 (define_split
10893   [(set (pc)
10894         (if_then_else
10895           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10896             [(match_operator 1 "float_operator"
10897               [(match_operand:X87MODEI12 2 "memory_operand" "")])
10898              (match_operand 3 "register_operand" "")])
10899           (match_operand 4 "" "")
10900           (match_operand 5 "" "")))
10901    (clobber (reg:CCFP FPSR_REG))
10902    (clobber (reg:CCFP FLAGS_REG))
10903    (clobber (match_scratch:HI 6 "=a"))]
10904   "reload_completed"
10905   [(const_int 0)]
10906 {
10907   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10908
10909   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10910                         operands[3], operands[7],
10911                         operands[4], operands[5], operands[6], NULL_RTX);
10912   DONE;
10913 })
10914
10915 ;; %%% Kill this when reload knows how to do it.
10916 (define_split
10917   [(set (pc)
10918         (if_then_else
10919           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10920             [(match_operator 1 "float_operator"
10921               [(match_operand:X87MODEI12 2 "register_operand" "")])
10922              (match_operand 3 "register_operand" "")])
10923           (match_operand 4 "" "")
10924           (match_operand 5 "" "")))
10925    (clobber (reg:CCFP FPSR_REG))
10926    (clobber (reg:CCFP FLAGS_REG))
10927    (clobber (match_scratch:HI 6 "=a"))]
10928   "reload_completed"
10929   [(const_int 0)]
10930 {
10931   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10932   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10933
10934   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10935                         operands[3], operands[7],
10936                         operands[4], operands[5], operands[6], operands[2]);
10937   DONE;
10938 })
10939 \f
10940 ;; Unconditional and other jump instructions
10941
10942 (define_insn "jump"
10943   [(set (pc)
10944         (label_ref (match_operand 0 "" "")))]
10945   ""
10946   "jmp\t%l0"
10947   [(set_attr "type" "ibr")
10948    (set (attr "length")
10949            (if_then_else (and (ge (minus (match_dup 0) (pc))
10950                                   (const_int -126))
10951                               (lt (minus (match_dup 0) (pc))
10952                                   (const_int 128)))
10953              (const_int 2)
10954              (const_int 5)))
10955    (set_attr "modrm" "0")])
10956
10957 (define_expand "indirect_jump"
10958   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10959   ""
10960   "")
10961
10962 (define_insn "*indirect_jump"
10963   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10964   ""
10965   "jmp\t%A0"
10966   [(set_attr "type" "ibr")
10967    (set_attr "length_immediate" "0")])
10968
10969 (define_expand "tablejump"
10970   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10971               (use (label_ref (match_operand 1 "" "")))])]
10972   ""
10973 {
10974   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10975      relative.  Convert the relative address to an absolute address.  */
10976   if (flag_pic)
10977     {
10978       rtx op0, op1;
10979       enum rtx_code code;
10980
10981       /* We can't use @GOTOFF for text labels on VxWorks;
10982          see gotoff_operand.  */
10983       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10984         {
10985           code = PLUS;
10986           op0 = operands[0];
10987           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10988         }
10989       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10990         {
10991           code = PLUS;
10992           op0 = operands[0];
10993           op1 = pic_offset_table_rtx;
10994         }
10995       else
10996         {
10997           code = MINUS;
10998           op0 = pic_offset_table_rtx;
10999           op1 = operands[0];
11000         }
11001
11002       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11003                                          OPTAB_DIRECT);
11004     }
11005 })
11006
11007 (define_insn "*tablejump_1"
11008   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11009    (use (label_ref (match_operand 1 "" "")))]
11010   ""
11011   "jmp\t%A0"
11012   [(set_attr "type" "ibr")
11013    (set_attr "length_immediate" "0")])
11014 \f
11015 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11016
11017 (define_peephole2
11018   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11019    (set (match_operand:QI 1 "register_operand" "")
11020         (match_operator:QI 2 "ix86_comparison_operator"
11021           [(reg FLAGS_REG) (const_int 0)]))
11022    (set (match_operand 3 "q_regs_operand" "")
11023         (zero_extend (match_dup 1)))]
11024   "(peep2_reg_dead_p (3, operands[1])
11025     || operands_match_p (operands[1], operands[3]))
11026    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11027   [(set (match_dup 4) (match_dup 0))
11028    (set (strict_low_part (match_dup 5))
11029         (match_dup 2))]
11030 {
11031   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11032   operands[5] = gen_lowpart (QImode, operands[3]);
11033   ix86_expand_clear (operands[3]);
11034 })
11035
11036 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11037
11038 (define_peephole2
11039   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11040    (set (match_operand:QI 1 "register_operand" "")
11041         (match_operator:QI 2 "ix86_comparison_operator"
11042           [(reg FLAGS_REG) (const_int 0)]))
11043    (parallel [(set (match_operand 3 "q_regs_operand" "")
11044                    (zero_extend (match_dup 1)))
11045               (clobber (reg:CC FLAGS_REG))])]
11046   "(peep2_reg_dead_p (3, operands[1])
11047     || operands_match_p (operands[1], operands[3]))
11048    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11049   [(set (match_dup 4) (match_dup 0))
11050    (set (strict_low_part (match_dup 5))
11051         (match_dup 2))]
11052 {
11053   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11054   operands[5] = gen_lowpart (QImode, operands[3]);
11055   ix86_expand_clear (operands[3]);
11056 })
11057 \f
11058 ;; Call instructions.
11059
11060 ;; The predicates normally associated with named expanders are not properly
11061 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11062 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11063
11064 ;; P6 processors will jump to the address after the decrement when %esp
11065 ;; is used as a call operand, so they will execute return address as a code.
11066 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11067
11068 ;; Register constraint for call instruction.
11069 (define_mode_attr c [(SI "l") (DI "r")])
11070
11071 ;; Call subroutine returning no value.
11072
11073 (define_expand "call"
11074   [(call (match_operand:QI 0 "" "")
11075          (match_operand 1 "" ""))
11076    (use (match_operand 2 "" ""))]
11077   ""
11078 {
11079   ix86_expand_call (NULL, operands[0], operands[1],
11080                     operands[2], NULL, false);
11081   DONE;
11082 })
11083
11084 (define_expand "sibcall"
11085   [(call (match_operand:QI 0 "" "")
11086          (match_operand 1 "" ""))
11087    (use (match_operand 2 "" ""))]
11088   ""
11089 {
11090   ix86_expand_call (NULL, operands[0], operands[1],
11091                     operands[2], NULL, true);
11092   DONE;
11093 })
11094
11095 (define_insn_and_split "*call_vzeroupper"
11096   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11097          (match_operand 1 "" ""))
11098    (unspec [(match_operand 2 "const_int_operand" "")]
11099            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11100   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11101   "#"
11102   "&& reload_completed"
11103   [(const_int 0)]
11104   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11105   [(set_attr "type" "call")])
11106
11107 (define_insn "*call"
11108   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11109          (match_operand 1 "" ""))]
11110   "!SIBLING_CALL_P (insn)"
11111   "* return ix86_output_call_insn (insn, operands[0]);"
11112   [(set_attr "type" "call")])
11113
11114 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11115   [(parallel
11116     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11117            (match_operand 1 "" ""))
11118      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11119      (clobber (reg:TI XMM6_REG))
11120      (clobber (reg:TI XMM7_REG))
11121      (clobber (reg:TI XMM8_REG))
11122      (clobber (reg:TI XMM9_REG))
11123      (clobber (reg:TI XMM10_REG))
11124      (clobber (reg:TI XMM11_REG))
11125      (clobber (reg:TI XMM12_REG))
11126      (clobber (reg:TI XMM13_REG))
11127      (clobber (reg:TI XMM14_REG))
11128      (clobber (reg:TI XMM15_REG))
11129      (clobber (reg:DI SI_REG))
11130      (clobber (reg:DI DI_REG))])
11131    (unspec [(match_operand 2 "const_int_operand" "")]
11132            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11133   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11134   "#"
11135   "&& reload_completed"
11136   [(const_int 0)]
11137   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11138   [(set_attr "type" "call")])
11139
11140 (define_insn "*call_rex64_ms_sysv"
11141   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11142          (match_operand 1 "" ""))
11143    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11144    (clobber (reg:TI XMM6_REG))
11145    (clobber (reg:TI XMM7_REG))
11146    (clobber (reg:TI XMM8_REG))
11147    (clobber (reg:TI XMM9_REG))
11148    (clobber (reg:TI XMM10_REG))
11149    (clobber (reg:TI XMM11_REG))
11150    (clobber (reg:TI XMM12_REG))
11151    (clobber (reg:TI XMM13_REG))
11152    (clobber (reg:TI XMM14_REG))
11153    (clobber (reg:TI XMM15_REG))
11154    (clobber (reg:DI SI_REG))
11155    (clobber (reg:DI DI_REG))]
11156   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11157   "* return ix86_output_call_insn (insn, operands[0]);"
11158   [(set_attr "type" "call")])
11159
11160 (define_insn_and_split "*sibcall_vzeroupper"
11161   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11162          (match_operand 1 "" ""))
11163    (unspec [(match_operand 2 "const_int_operand" "")]
11164            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11165   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11166   "#"
11167   "&& reload_completed"
11168   [(const_int 0)]
11169   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11170   [(set_attr "type" "call")])
11171
11172 (define_insn "*sibcall"
11173   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11174          (match_operand 1 "" ""))]
11175   "SIBLING_CALL_P (insn)"
11176   "* return ix86_output_call_insn (insn, operands[0]);"
11177   [(set_attr "type" "call")])
11178
11179 (define_expand "call_pop"
11180   [(parallel [(call (match_operand:QI 0 "" "")
11181                     (match_operand:SI 1 "" ""))
11182               (set (reg:SI SP_REG)
11183                    (plus:SI (reg:SI SP_REG)
11184                             (match_operand:SI 3 "" "")))])]
11185   "!TARGET_64BIT"
11186 {
11187   ix86_expand_call (NULL, operands[0], operands[1],
11188                     operands[2], operands[3], false);
11189   DONE;
11190 })
11191
11192 (define_insn_and_split "*call_pop_vzeroupper"
11193   [(parallel
11194     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11195            (match_operand:SI 1 "" ""))
11196      (set (reg:SI SP_REG)
11197           (plus:SI (reg:SI SP_REG)
11198                    (match_operand:SI 2 "immediate_operand" "i")))])
11199    (unspec [(match_operand 3 "const_int_operand" "")]
11200            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11201   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11202   "#"
11203   "&& reload_completed"
11204   [(const_int 0)]
11205   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11206   [(set_attr "type" "call")])
11207
11208 (define_insn "*call_pop"
11209   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11210          (match_operand 1 "" ""))
11211    (set (reg:SI SP_REG)
11212         (plus:SI (reg:SI SP_REG)
11213                  (match_operand:SI 2 "immediate_operand" "i")))]
11214   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11215   "* return ix86_output_call_insn (insn, operands[0]);"
11216   [(set_attr "type" "call")])
11217
11218 (define_insn_and_split "*sibcall_pop_vzeroupper"
11219  [(parallel
11220    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11221           (match_operand 1 "" ""))
11222      (set (reg:SI SP_REG)
11223           (plus:SI (reg:SI SP_REG)
11224                    (match_operand:SI 2 "immediate_operand" "i")))])
11225    (unspec [(match_operand 3 "const_int_operand" "")]
11226            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11227   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11228   "#"
11229   "&& reload_completed"
11230   [(const_int 0)]
11231   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11232   [(set_attr "type" "call")])
11233
11234 (define_insn "*sibcall_pop"
11235   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11236          (match_operand 1 "" ""))
11237    (set (reg:SI SP_REG)
11238         (plus:SI (reg:SI SP_REG)
11239                  (match_operand:SI 2 "immediate_operand" "i")))]
11240   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11241   "* return ix86_output_call_insn (insn, operands[0]);"
11242   [(set_attr "type" "call")])
11243
11244 ;; Call subroutine, returning value in operand 0
11245
11246 (define_expand "call_value"
11247   [(set (match_operand 0 "" "")
11248         (call (match_operand:QI 1 "" "")
11249               (match_operand 2 "" "")))
11250    (use (match_operand 3 "" ""))]
11251   ""
11252 {
11253   ix86_expand_call (operands[0], operands[1], operands[2],
11254                     operands[3], NULL, false);
11255   DONE;
11256 })
11257
11258 (define_expand "sibcall_value"
11259   [(set (match_operand 0 "" "")
11260         (call (match_operand:QI 1 "" "")
11261               (match_operand 2 "" "")))
11262    (use (match_operand 3 "" ""))]
11263   ""
11264 {
11265   ix86_expand_call (operands[0], operands[1], operands[2],
11266                     operands[3], NULL, true);
11267   DONE;
11268 })
11269
11270 (define_insn_and_split "*call_value_vzeroupper"
11271   [(set (match_operand 0 "" "")
11272         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11273               (match_operand 2 "" "")))
11274    (unspec [(match_operand 3 "const_int_operand" "")]
11275            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11276   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11277   "#"
11278   "&& reload_completed"
11279   [(const_int 0)]
11280   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11281   [(set_attr "type" "callv")])
11282
11283 (define_insn "*call_value"
11284   [(set (match_operand 0 "" "")
11285         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11286               (match_operand 2 "" "")))]
11287   "!SIBLING_CALL_P (insn)"
11288   "* return ix86_output_call_insn (insn, operands[1]);"
11289   [(set_attr "type" "callv")])
11290
11291 (define_insn_and_split "*sibcall_value_vzeroupper"
11292   [(set (match_operand 0 "" "")
11293         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11294               (match_operand 2 "" "")))
11295    (unspec [(match_operand 3 "const_int_operand" "")]
11296            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11297   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11298   "#"
11299   "&& reload_completed"
11300   [(const_int 0)]
11301   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11302   [(set_attr "type" "callv")])
11303
11304 (define_insn "*sibcall_value"
11305   [(set (match_operand 0 "" "")
11306         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11307               (match_operand 2 "" "")))]
11308   "SIBLING_CALL_P (insn)"
11309   "* return ix86_output_call_insn (insn, operands[1]);"
11310   [(set_attr "type" "callv")])
11311
11312 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11313   [(parallel
11314     [(set (match_operand 0 "" "")
11315           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11316                 (match_operand 2 "" "")))
11317      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11318      (clobber (reg:TI XMM6_REG))
11319      (clobber (reg:TI XMM7_REG))
11320      (clobber (reg:TI XMM8_REG))
11321      (clobber (reg:TI XMM9_REG))
11322      (clobber (reg:TI XMM10_REG))
11323      (clobber (reg:TI XMM11_REG))
11324      (clobber (reg:TI XMM12_REG))
11325      (clobber (reg:TI XMM13_REG))
11326      (clobber (reg:TI XMM14_REG))
11327      (clobber (reg:TI XMM15_REG))
11328      (clobber (reg:DI SI_REG))
11329      (clobber (reg:DI DI_REG))])
11330    (unspec [(match_operand 3 "const_int_operand" "")]
11331            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11332   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11333   "#"
11334   "&& reload_completed"
11335   [(const_int 0)]
11336   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11337   [(set_attr "type" "callv")])
11338
11339 (define_insn "*call_value_rex64_ms_sysv"
11340   [(set (match_operand 0 "" "")
11341         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11342               (match_operand 2 "" "")))
11343    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11344    (clobber (reg:TI XMM6_REG))
11345    (clobber (reg:TI XMM7_REG))
11346    (clobber (reg:TI XMM8_REG))
11347    (clobber (reg:TI XMM9_REG))
11348    (clobber (reg:TI XMM10_REG))
11349    (clobber (reg:TI XMM11_REG))
11350    (clobber (reg:TI XMM12_REG))
11351    (clobber (reg:TI XMM13_REG))
11352    (clobber (reg:TI XMM14_REG))
11353    (clobber (reg:TI XMM15_REG))
11354    (clobber (reg:DI SI_REG))
11355    (clobber (reg:DI DI_REG))]
11356   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11357   "* return ix86_output_call_insn (insn, operands[1]);"
11358   [(set_attr "type" "callv")])
11359
11360 (define_expand "call_value_pop"
11361   [(parallel [(set (match_operand 0 "" "")
11362                    (call (match_operand:QI 1 "" "")
11363                          (match_operand:SI 2 "" "")))
11364               (set (reg:SI SP_REG)
11365                    (plus:SI (reg:SI SP_REG)
11366                             (match_operand:SI 4 "" "")))])]
11367   "!TARGET_64BIT"
11368 {
11369   ix86_expand_call (operands[0], operands[1], operands[2],
11370                     operands[3], operands[4], false);
11371   DONE;
11372 })
11373
11374 (define_insn_and_split "*call_value_pop_vzeroupper"
11375   [(parallel
11376     [(set (match_operand 0 "" "")
11377           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11378                 (match_operand 2 "" "")))
11379      (set (reg:SI SP_REG)
11380           (plus:SI (reg:SI SP_REG)
11381                    (match_operand:SI 3 "immediate_operand" "i")))])
11382    (unspec [(match_operand 4 "const_int_operand" "")]
11383            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11384   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11385   "#"
11386   "&& reload_completed"
11387   [(const_int 0)]
11388   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11389   [(set_attr "type" "callv")])
11390
11391 (define_insn "*call_value_pop"
11392   [(set (match_operand 0 "" "")
11393         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11394               (match_operand 2 "" "")))
11395    (set (reg:SI SP_REG)
11396         (plus:SI (reg:SI SP_REG)
11397                  (match_operand:SI 3 "immediate_operand" "i")))]
11398   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11399   "* return ix86_output_call_insn (insn, operands[1]);"
11400   [(set_attr "type" "callv")])
11401
11402 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11403  [(parallel
11404    [(set (match_operand 0 "" "")
11405           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11406                 (match_operand 2 "" "")))
11407      (set (reg:SI SP_REG)
11408           (plus:SI (reg:SI SP_REG)
11409                    (match_operand:SI 3 "immediate_operand" "i")))])
11410    (unspec [(match_operand 4 "const_int_operand" "")]
11411            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11412   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11413   "#"
11414   "&& reload_completed"
11415   [(const_int 0)]
11416   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11417   [(set_attr "type" "callv")])
11418
11419 (define_insn "*sibcall_value_pop"
11420   [(set (match_operand 0 "" "")
11421         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11422               (match_operand 2 "" "")))
11423    (set (reg:SI SP_REG)
11424         (plus:SI (reg:SI SP_REG)
11425                  (match_operand:SI 3 "immediate_operand" "i")))]
11426   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11427   "* return ix86_output_call_insn (insn, operands[1]);"
11428   [(set_attr "type" "callv")])
11429
11430 ;; Call subroutine returning any type.
11431
11432 (define_expand "untyped_call"
11433   [(parallel [(call (match_operand 0 "" "")
11434                     (const_int 0))
11435               (match_operand 1 "" "")
11436               (match_operand 2 "" "")])]
11437   ""
11438 {
11439   int i;
11440
11441   /* In order to give reg-stack an easier job in validating two
11442      coprocessor registers as containing a possible return value,
11443      simply pretend the untyped call returns a complex long double
11444      value. 
11445
11446      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11447      and should have the default ABI.  */
11448
11449   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11450                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11451                     operands[0], const0_rtx,
11452                     GEN_INT ((TARGET_64BIT
11453                               ? (ix86_abi == SYSV_ABI
11454                                  ? X86_64_SSE_REGPARM_MAX
11455                                  : X86_64_MS_SSE_REGPARM_MAX)
11456                               : X86_32_SSE_REGPARM_MAX)
11457                              - 1),
11458                     NULL, false);
11459
11460   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11461     {
11462       rtx set = XVECEXP (operands[2], 0, i);
11463       emit_move_insn (SET_DEST (set), SET_SRC (set));
11464     }
11465
11466   /* The optimizer does not know that the call sets the function value
11467      registers we stored in the result block.  We avoid problems by
11468      claiming that all hard registers are used and clobbered at this
11469      point.  */
11470   emit_insn (gen_blockage ());
11471
11472   DONE;
11473 })
11474 \f
11475 ;; Prologue and epilogue instructions
11476
11477 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11478 ;; all of memory.  This blocks insns from being moved across this point.
11479
11480 (define_insn "blockage"
11481   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11482   ""
11483   ""
11484   [(set_attr "length" "0")])
11485
11486 ;; Do not schedule instructions accessing memory across this point.
11487
11488 (define_expand "memory_blockage"
11489   [(set (match_dup 0)
11490         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11491   ""
11492 {
11493   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11494   MEM_VOLATILE_P (operands[0]) = 1;
11495 })
11496
11497 (define_insn "*memory_blockage"
11498   [(set (match_operand:BLK 0 "" "")
11499         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11500   ""
11501   ""
11502   [(set_attr "length" "0")])
11503
11504 ;; As USE insns aren't meaningful after reload, this is used instead
11505 ;; to prevent deleting instructions setting registers for PIC code
11506 (define_insn "prologue_use"
11507   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11508   ""
11509   ""
11510   [(set_attr "length" "0")])
11511
11512 ;; Insn emitted into the body of a function to return from a function.
11513 ;; This is only done if the function's epilogue is known to be simple.
11514 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11515
11516 (define_expand "return"
11517   [(return)]
11518   "ix86_can_use_return_insn_p ()"
11519 {
11520   if (crtl->args.pops_args)
11521     {
11522       rtx popc = GEN_INT (crtl->args.pops_args);
11523       emit_jump_insn (gen_return_pop_internal (popc));
11524       DONE;
11525     }
11526 })
11527
11528 (define_insn "return_internal"
11529   [(return)]
11530   "reload_completed"
11531   "ret"
11532   [(set_attr "length" "1")
11533    (set_attr "atom_unit" "jeu")
11534    (set_attr "length_immediate" "0")
11535    (set_attr "modrm" "0")])
11536
11537 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11538 ;; instruction Athlon and K8 have.
11539
11540 (define_insn "return_internal_long"
11541   [(return)
11542    (unspec [(const_int 0)] UNSPEC_REP)]
11543   "reload_completed"
11544   "rep\;ret"
11545   [(set_attr "length" "2")
11546    (set_attr "atom_unit" "jeu")
11547    (set_attr "length_immediate" "0")
11548    (set_attr "prefix_rep" "1")
11549    (set_attr "modrm" "0")])
11550
11551 (define_insn "return_pop_internal"
11552   [(return)
11553    (use (match_operand:SI 0 "const_int_operand" ""))]
11554   "reload_completed"
11555   "ret\t%0"
11556   [(set_attr "length" "3")
11557    (set_attr "atom_unit" "jeu")
11558    (set_attr "length_immediate" "2")
11559    (set_attr "modrm" "0")])
11560
11561 (define_insn "return_indirect_internal"
11562   [(return)
11563    (use (match_operand:SI 0 "register_operand" "r"))]
11564   "reload_completed"
11565   "jmp\t%A0"
11566   [(set_attr "type" "ibr")
11567    (set_attr "length_immediate" "0")])
11568
11569 (define_insn "nop"
11570   [(const_int 0)]
11571   ""
11572   "nop"
11573   [(set_attr "length" "1")
11574    (set_attr "length_immediate" "0")
11575    (set_attr "modrm" "0")])
11576
11577 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11578 (define_insn "nops"
11579   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11580                     UNSPECV_NOPS)]
11581   "reload_completed"
11582 {
11583   int num = INTVAL (operands[0]);
11584
11585   gcc_assert (num >= 1 && num <= 8);
11586
11587   while (num--)
11588     fputs ("\tnop\n", asm_out_file);
11589
11590   return "";
11591 }
11592   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11593    (set_attr "length_immediate" "0")
11594    (set_attr "modrm" "0")])
11595
11596 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11597 ;; branch prediction penalty for the third jump in a 16-byte
11598 ;; block on K8.
11599
11600 (define_insn "pad"
11601   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11602   ""
11603 {
11604 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11605   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11606 #else
11607   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11608      The align insn is used to avoid 3 jump instructions in the row to improve
11609      branch prediction and the benefits hardly outweigh the cost of extra 8
11610      nops on the average inserted by full alignment pseudo operation.  */
11611 #endif
11612   return "";
11613 }
11614   [(set_attr "length" "16")])
11615
11616 (define_expand "prologue"
11617   [(const_int 0)]
11618   ""
11619   "ix86_expand_prologue (); DONE;")
11620
11621 (define_insn "set_got"
11622   [(set (match_operand:SI 0 "register_operand" "=r")
11623         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11624    (clobber (reg:CC FLAGS_REG))]
11625   "!TARGET_64BIT"
11626   "* return output_set_got (operands[0], NULL_RTX);"
11627   [(set_attr "type" "multi")
11628    (set_attr "length" "12")])
11629
11630 (define_insn "set_got_labelled"
11631   [(set (match_operand:SI 0 "register_operand" "=r")
11632         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11633          UNSPEC_SET_GOT))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "!TARGET_64BIT"
11636   "* return output_set_got (operands[0], operands[1]);"
11637   [(set_attr "type" "multi")
11638    (set_attr "length" "12")])
11639
11640 (define_insn "set_got_rex64"
11641   [(set (match_operand:DI 0 "register_operand" "=r")
11642         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11643   "TARGET_64BIT"
11644   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11645   [(set_attr "type" "lea")
11646    (set_attr "length_address" "4")
11647    (set_attr "mode" "DI")])
11648
11649 (define_insn "set_rip_rex64"
11650   [(set (match_operand:DI 0 "register_operand" "=r")
11651         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11652   "TARGET_64BIT"
11653   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11654   [(set_attr "type" "lea")
11655    (set_attr "length_address" "4")
11656    (set_attr "mode" "DI")])
11657
11658 (define_insn "set_got_offset_rex64"
11659   [(set (match_operand:DI 0 "register_operand" "=r")
11660         (unspec:DI
11661           [(label_ref (match_operand 1 "" ""))]
11662           UNSPEC_SET_GOT_OFFSET))]
11663   "TARGET_64BIT"
11664   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11665   [(set_attr "type" "imov")
11666    (set_attr "length_immediate" "0")
11667    (set_attr "length_address" "8")
11668    (set_attr "mode" "DI")])
11669
11670 (define_expand "epilogue"
11671   [(const_int 0)]
11672   ""
11673   "ix86_expand_epilogue (1); DONE;")
11674
11675 (define_expand "sibcall_epilogue"
11676   [(const_int 0)]
11677   ""
11678   "ix86_expand_epilogue (0); DONE;")
11679
11680 (define_expand "eh_return"
11681   [(use (match_operand 0 "register_operand" ""))]
11682   ""
11683 {
11684   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11685
11686   /* Tricky bit: we write the address of the handler to which we will
11687      be returning into someone else's stack frame, one word below the
11688      stack address we wish to restore.  */
11689   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11690   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11691   tmp = gen_rtx_MEM (Pmode, tmp);
11692   emit_move_insn (tmp, ra);
11693
11694   emit_jump_insn (gen_eh_return_internal ());
11695   emit_barrier ();
11696   DONE;
11697 })
11698
11699 (define_insn_and_split "eh_return_internal"
11700   [(eh_return)]
11701   ""
11702   "#"
11703   "epilogue_completed"
11704   [(const_int 0)]
11705   "ix86_expand_epilogue (2); DONE;")
11706
11707 (define_insn "leave"
11708   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11709    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11710    (clobber (mem:BLK (scratch)))]
11711   "!TARGET_64BIT"
11712   "leave"
11713   [(set_attr "type" "leave")])
11714
11715 (define_insn "leave_rex64"
11716   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11717    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11718    (clobber (mem:BLK (scratch)))]
11719   "TARGET_64BIT"
11720   "leave"
11721   [(set_attr "type" "leave")])
11722 \f
11723 ;; Handle -fsplit-stack.
11724
11725 (define_expand "split_stack_prologue"
11726   [(const_int 0)]
11727   ""
11728 {
11729   ix86_expand_split_stack_prologue ();
11730   DONE;
11731 })
11732
11733 ;; In order to support the call/return predictor, we use a return
11734 ;; instruction which the middle-end doesn't see.
11735 (define_insn "split_stack_return"
11736   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11737                      UNSPECV_SPLIT_STACK_RETURN)]
11738   ""
11739 {
11740   if (operands[0] == const0_rtx)
11741     return "ret";
11742   else
11743     return "ret\t%0";
11744 }
11745   [(set_attr "atom_unit" "jeu")
11746    (set_attr "modrm" "0")
11747    (set (attr "length")
11748         (if_then_else (match_operand:SI 0 "const0_operand" "")
11749                       (const_int 1)
11750                       (const_int 3)))
11751    (set (attr "length_immediate")
11752         (if_then_else (match_operand:SI 0 "const0_operand" "")
11753                       (const_int 0)
11754                       (const_int 2)))])
11755
11756 ;; If there are operand 0 bytes available on the stack, jump to
11757 ;; operand 1.
11758
11759 (define_expand "split_stack_space_check"
11760   [(set (pc) (if_then_else
11761               (ltu (minus (reg SP_REG)
11762                           (match_operand 0 "register_operand" ""))
11763                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11764               (label_ref (match_operand 1 "" ""))
11765               (pc)))]
11766   ""
11767 {
11768   rtx reg, size, limit;
11769
11770   reg = gen_reg_rtx (Pmode);
11771   size = force_reg (Pmode, operands[0]);
11772   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11773   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11774                           UNSPEC_STACK_CHECK);
11775   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11776   ix86_expand_branch (GEU, reg, limit, operands[1]);
11777
11778   DONE;
11779 })
11780 \f
11781 ;; Bit manipulation instructions.
11782
11783 (define_expand "ffs<mode>2"
11784   [(set (match_dup 2) (const_int -1))
11785    (parallel [(set (reg:CCZ FLAGS_REG)
11786                    (compare:CCZ
11787                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11788                      (const_int 0)))
11789               (set (match_operand:SWI48 0 "register_operand" "")
11790                    (ctz:SWI48 (match_dup 1)))])
11791    (set (match_dup 0) (if_then_else:SWI48
11792                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11793                         (match_dup 2)
11794                         (match_dup 0)))
11795    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11796               (clobber (reg:CC FLAGS_REG))])]
11797   ""
11798 {
11799   if (<MODE>mode == SImode && !TARGET_CMOVE)
11800     {
11801       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11802       DONE;
11803     }
11804   operands[2] = gen_reg_rtx (<MODE>mode);
11805 })
11806
11807 (define_insn_and_split "ffssi2_no_cmove"
11808   [(set (match_operand:SI 0 "register_operand" "=r")
11809         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11810    (clobber (match_scratch:SI 2 "=&q"))
11811    (clobber (reg:CC FLAGS_REG))]
11812   "!TARGET_CMOVE"
11813   "#"
11814   "&& reload_completed"
11815   [(parallel [(set (reg:CCZ FLAGS_REG)
11816                    (compare:CCZ (match_dup 1) (const_int 0)))
11817               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11818    (set (strict_low_part (match_dup 3))
11819         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11820    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11821               (clobber (reg:CC FLAGS_REG))])
11822    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11823               (clobber (reg:CC FLAGS_REG))])
11824    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11825               (clobber (reg:CC FLAGS_REG))])]
11826 {
11827   operands[3] = gen_lowpart (QImode, operands[2]);
11828   ix86_expand_clear (operands[2]);
11829 })
11830
11831 (define_insn "*ffs<mode>_1"
11832   [(set (reg:CCZ FLAGS_REG)
11833         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11834                      (const_int 0)))
11835    (set (match_operand:SWI48 0 "register_operand" "=r")
11836         (ctz:SWI48 (match_dup 1)))]
11837   ""
11838   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11839   [(set_attr "type" "alu1")
11840    (set_attr "prefix_0f" "1")
11841    (set_attr "mode" "<MODE>")])
11842
11843 (define_insn "ctz<mode>2"
11844   [(set (match_operand:SWI248 0 "register_operand" "=r")
11845         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11846    (clobber (reg:CC FLAGS_REG))]
11847   ""
11848 {
11849   if (TARGET_BMI)
11850     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11851   else
11852     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11853 }
11854   [(set_attr "type" "alu1")
11855    (set_attr "prefix_0f" "1")
11856    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11857    (set_attr "mode" "<MODE>")])
11858
11859 (define_expand "clz<mode>2"
11860   [(parallel
11861      [(set (match_operand:SWI248 0 "register_operand" "")
11862            (minus:SWI248
11863              (match_dup 2)
11864              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11865       (clobber (reg:CC FLAGS_REG))])
11866    (parallel
11867      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11868       (clobber (reg:CC FLAGS_REG))])]
11869   ""
11870 {
11871   if (TARGET_ABM)
11872     {
11873       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11874       DONE;
11875     }
11876   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11877 })
11878
11879 (define_insn "clz<mode>2_abm"
11880   [(set (match_operand:SWI248 0 "register_operand" "=r")
11881         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11882    (clobber (reg:CC FLAGS_REG))]
11883   "TARGET_ABM || TARGET_BMI"
11884   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11885   [(set_attr "prefix_rep" "1")
11886    (set_attr "type" "bitmanip")
11887    (set_attr "mode" "<MODE>")])
11888
11889 ;; BMI instructions.
11890 (define_insn "*bmi_andn_<mode>"
11891   [(set (match_operand:SWI48 0 "register_operand" "=r")
11892         (and:SWI48
11893           (not:SWI48
11894             (match_operand:SWI48 1 "register_operand" "r"))
11895             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11896    (clobber (reg:CC FLAGS_REG))]
11897   "TARGET_BMI"
11898   "andn\t{%2, %1, %0|%0, %1, %2}"
11899   [(set_attr "type" "bitmanip")
11900    (set_attr "mode" "<MODE>")])
11901
11902 (define_insn "bmi_bextr_<mode>"
11903   [(set (match_operand:SWI48 0 "register_operand" "=r")
11904         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11905                        (match_operand:SWI48 2 "register_operand" "r")]
11906                        UNSPEC_BEXTR))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "TARGET_BMI"
11909   "bextr\t{%2, %1, %0|%0, %1, %2}"
11910   [(set_attr "type" "bitmanip")
11911    (set_attr "mode" "<MODE>")])
11912
11913 (define_insn "*bmi_blsi_<mode>"
11914   [(set (match_operand:SWI48 0 "register_operand" "=r")
11915         (and:SWI48
11916           (neg:SWI48
11917             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11918           (match_dup 1)))
11919    (clobber (reg:CC FLAGS_REG))]
11920   "TARGET_BMI"
11921   "blsi\t{%1, %0|%0, %1}"
11922   [(set_attr "type" "bitmanip")
11923    (set_attr "mode" "<MODE>")])
11924
11925 (define_insn "*bmi_blsmsk_<mode>"
11926   [(set (match_operand:SWI48 0 "register_operand" "=r")
11927         (xor:SWI48
11928           (plus:SWI48
11929             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11930             (const_int -1))
11931           (match_dup 1)))
11932    (clobber (reg:CC FLAGS_REG))]
11933   "TARGET_BMI"
11934   "blsmsk\t{%1, %0|%0, %1}"
11935   [(set_attr "type" "bitmanip")
11936    (set_attr "mode" "<MODE>")])
11937
11938 (define_insn "*bmi_blsr_<mode>"
11939   [(set (match_operand:SWI48 0 "register_operand" "=r")
11940         (and:SWI48
11941           (plus:SWI48
11942             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11943             (const_int -1))
11944           (match_dup 1)))
11945    (clobber (reg:CC FLAGS_REG))]
11946    "TARGET_BMI"
11947    "blsr\t{%1, %0|%0, %1}"
11948   [(set_attr "type" "bitmanip")
11949    (set_attr "mode" "<MODE>")])
11950
11951 ;; TBM instructions.
11952 (define_insn "tbm_bextri_<mode>"
11953   [(set (match_operand:SWI48 0 "register_operand" "=r")
11954         (zero_extract:SWI48
11955           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11956           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11957           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11958    (clobber (reg:CC FLAGS_REG))]
11959    "TARGET_TBM"
11960 {
11961   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11962   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11963 }
11964   [(set_attr "type" "bitmanip")
11965    (set_attr "mode" "<MODE>")])
11966
11967 (define_insn "*tbm_blcfill_<mode>"
11968   [(set (match_operand:SWI48 0 "register_operand" "=r")
11969         (and:SWI48
11970           (plus:SWI48
11971             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11972             (const_int 1))
11973           (match_dup 1)))
11974    (clobber (reg:CC FLAGS_REG))]
11975    "TARGET_TBM"
11976    "blcfill\t{%1, %0|%0, %1}"
11977   [(set_attr "type" "bitmanip")
11978    (set_attr "mode" "<MODE>")])
11979
11980 (define_insn "*tbm_blci_<mode>"
11981   [(set (match_operand:SWI48 0 "register_operand" "=r")
11982         (ior:SWI48
11983           (not:SWI48
11984             (plus:SWI48
11985               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11986               (const_int 1)))
11987           (match_dup 1)))
11988    (clobber (reg:CC FLAGS_REG))]
11989    "TARGET_TBM"
11990    "blci\t{%1, %0|%0, %1}"
11991   [(set_attr "type" "bitmanip")
11992    (set_attr "mode" "<MODE>")])
11993
11994 (define_insn "*tbm_blcic_<mode>"
11995   [(set (match_operand:SWI48 0 "register_operand" "=r")
11996         (and:SWI48
11997           (plus:SWI48
11998             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11999             (const_int 1))
12000           (not:SWI48
12001             (match_dup 1))))
12002    (clobber (reg:CC FLAGS_REG))]
12003    "TARGET_TBM"
12004    "blcic\t{%1, %0|%0, %1}"
12005   [(set_attr "type" "bitmanip")
12006    (set_attr "mode" "<MODE>")])
12007
12008 (define_insn "*tbm_blcmsk_<mode>"
12009   [(set (match_operand:SWI48 0 "register_operand" "=r")
12010         (xor:SWI48
12011           (plus:SWI48
12012             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12013             (const_int 1))
12014           (match_dup 1)))
12015    (clobber (reg:CC FLAGS_REG))]
12016    "TARGET_TBM"
12017    "blcmsk\t{%1, %0|%0, %1}"
12018   [(set_attr "type" "bitmanip")
12019    (set_attr "mode" "<MODE>")])
12020
12021 (define_insn "*tbm_blcs_<mode>"
12022   [(set (match_operand:SWI48 0 "register_operand" "=r")
12023         (ior:SWI48
12024           (plus:SWI48
12025             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12026             (const_int 1))
12027           (match_dup 1)))
12028    (clobber (reg:CC FLAGS_REG))]
12029    "TARGET_TBM"
12030    "blcs\t{%1, %0|%0, %1}"
12031   [(set_attr "type" "bitmanip")
12032    (set_attr "mode" "<MODE>")])
12033
12034 (define_insn "*tbm_blsfill_<mode>"
12035   [(set (match_operand:SWI48 0 "register_operand" "=r")
12036         (ior:SWI48
12037           (plus:SWI48
12038             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12039             (const_int -1))
12040           (match_dup 1)))
12041    (clobber (reg:CC FLAGS_REG))]
12042    "TARGET_TBM"
12043    "blsfill\t{%1, %0|%0, %1}"
12044   [(set_attr "type" "bitmanip")
12045    (set_attr "mode" "<MODE>")])
12046
12047 (define_insn "*tbm_blsic_<mode>"
12048   [(set (match_operand:SWI48 0 "register_operand" "=r")
12049         (ior:SWI48
12050           (plus:SWI48
12051             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12052             (const_int -1))
12053           (not:SWI48
12054             (match_dup 1))))
12055    (clobber (reg:CC FLAGS_REG))]
12056    "TARGET_TBM"
12057    "blsic\t{%1, %0|%0, %1}"
12058   [(set_attr "type" "bitmanip")
12059    (set_attr "mode" "<MODE>")])
12060
12061 (define_insn "*tbm_t1mskc_<mode>"
12062   [(set (match_operand:SWI48 0 "register_operand" "=r")
12063         (ior:SWI48
12064           (plus:SWI48
12065             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12066             (const_int 1))
12067           (not:SWI48
12068             (match_dup 1))))
12069    (clobber (reg:CC FLAGS_REG))]
12070    "TARGET_TBM"
12071    "t1mskc\t{%1, %0|%0, %1}"
12072   [(set_attr "type" "bitmanip")
12073    (set_attr "mode" "<MODE>")])
12074
12075 (define_insn "*tbm_tzmsk_<mode>"
12076   [(set (match_operand:SWI48 0 "register_operand" "=r")
12077         (and:SWI48
12078           (plus:SWI48
12079             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12080             (const_int -1))
12081           (not:SWI48
12082             (match_dup 1))))
12083    (clobber (reg:CC FLAGS_REG))]
12084    "TARGET_TBM"
12085    "tzmsk\t{%1, %0|%0, %1}"
12086   [(set_attr "type" "bitmanip")
12087    (set_attr "mode" "<MODE>")])
12088
12089 (define_insn "bsr_rex64"
12090   [(set (match_operand:DI 0 "register_operand" "=r")
12091         (minus:DI (const_int 63)
12092                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12093    (clobber (reg:CC FLAGS_REG))]
12094   "TARGET_64BIT"
12095   "bsr{q}\t{%1, %0|%0, %1}"
12096   [(set_attr "type" "alu1")
12097    (set_attr "prefix_0f" "1")
12098    (set_attr "mode" "DI")])
12099
12100 (define_insn "bsr"
12101   [(set (match_operand:SI 0 "register_operand" "=r")
12102         (minus:SI (const_int 31)
12103                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12104    (clobber (reg:CC FLAGS_REG))]
12105   ""
12106   "bsr{l}\t{%1, %0|%0, %1}"
12107   [(set_attr "type" "alu1")
12108    (set_attr "prefix_0f" "1")
12109    (set_attr "mode" "SI")])
12110
12111 (define_insn "*bsrhi"
12112   [(set (match_operand:HI 0 "register_operand" "=r")
12113         (minus:HI (const_int 15)
12114                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12115    (clobber (reg:CC FLAGS_REG))]
12116   ""
12117   "bsr{w}\t{%1, %0|%0, %1}"
12118   [(set_attr "type" "alu1")
12119    (set_attr "prefix_0f" "1")
12120    (set_attr "mode" "HI")])
12121
12122 (define_insn "popcount<mode>2"
12123   [(set (match_operand:SWI248 0 "register_operand" "=r")
12124         (popcount:SWI248
12125           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "TARGET_POPCNT"
12128 {
12129 #if TARGET_MACHO
12130   return "popcnt\t{%1, %0|%0, %1}";
12131 #else
12132   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12133 #endif
12134 }
12135   [(set_attr "prefix_rep" "1")
12136    (set_attr "type" "bitmanip")
12137    (set_attr "mode" "<MODE>")])
12138
12139 (define_insn "*popcount<mode>2_cmp"
12140   [(set (reg FLAGS_REG)
12141         (compare
12142           (popcount:SWI248
12143             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12144           (const_int 0)))
12145    (set (match_operand:SWI248 0 "register_operand" "=r")
12146         (popcount:SWI248 (match_dup 1)))]
12147   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12148 {
12149 #if TARGET_MACHO
12150   return "popcnt\t{%1, %0|%0, %1}";
12151 #else
12152   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12153 #endif
12154 }
12155   [(set_attr "prefix_rep" "1")
12156    (set_attr "type" "bitmanip")
12157    (set_attr "mode" "<MODE>")])
12158
12159 (define_insn "*popcountsi2_cmp_zext"
12160   [(set (reg FLAGS_REG)
12161         (compare
12162           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12163           (const_int 0)))
12164    (set (match_operand:DI 0 "register_operand" "=r")
12165         (zero_extend:DI(popcount:SI (match_dup 1))))]
12166   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12167 {
12168 #if TARGET_MACHO
12169   return "popcnt\t{%1, %0|%0, %1}";
12170 #else
12171   return "popcnt{l}\t{%1, %0|%0, %1}";
12172 #endif
12173 }
12174   [(set_attr "prefix_rep" "1")
12175    (set_attr "type" "bitmanip")
12176    (set_attr "mode" "SI")])
12177
12178 (define_expand "bswap<mode>2"
12179   [(set (match_operand:SWI48 0 "register_operand" "")
12180         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12181   ""
12182 {
12183   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12184     {
12185       rtx x = operands[0];
12186
12187       emit_move_insn (x, operands[1]);
12188       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12189       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12190       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12191       DONE;
12192     }
12193 })
12194
12195 (define_insn "*bswap<mode>2_movbe"
12196   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12197         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12198   "TARGET_MOVBE
12199    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12200   "@
12201     bswap\t%0
12202     movbe\t{%1, %0|%0, %1}
12203     movbe\t{%1, %0|%0, %1}"
12204   [(set_attr "type" "bitmanip,imov,imov")
12205    (set_attr "modrm" "0,1,1")
12206    (set_attr "prefix_0f" "*,1,1")
12207    (set_attr "prefix_extra" "*,1,1")
12208    (set_attr "mode" "<MODE>")])
12209
12210 (define_insn "*bswap<mode>2_1"
12211   [(set (match_operand:SWI48 0 "register_operand" "=r")
12212         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12213   "TARGET_BSWAP"
12214   "bswap\t%0"
12215   [(set_attr "type" "bitmanip")
12216    (set_attr "modrm" "0")
12217    (set_attr "mode" "<MODE>")])
12218
12219 (define_insn "*bswaphi_lowpart_1"
12220   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12221         (bswap:HI (match_dup 0)))
12222    (clobber (reg:CC FLAGS_REG))]
12223   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12224   "@
12225     xchg{b}\t{%h0, %b0|%b0, %h0}
12226     rol{w}\t{$8, %0|%0, 8}"
12227   [(set_attr "length" "2,4")
12228    (set_attr "mode" "QI,HI")])
12229
12230 (define_insn "bswaphi_lowpart"
12231   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12232         (bswap:HI (match_dup 0)))
12233    (clobber (reg:CC FLAGS_REG))]
12234   ""
12235   "rol{w}\t{$8, %0|%0, 8}"
12236   [(set_attr "length" "4")
12237    (set_attr "mode" "HI")])
12238
12239 (define_expand "paritydi2"
12240   [(set (match_operand:DI 0 "register_operand" "")
12241         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12242   "! TARGET_POPCNT"
12243 {
12244   rtx scratch = gen_reg_rtx (QImode);
12245   rtx cond;
12246
12247   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12248                                 NULL_RTX, operands[1]));
12249
12250   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12251                          gen_rtx_REG (CCmode, FLAGS_REG),
12252                          const0_rtx);
12253   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12254
12255   if (TARGET_64BIT)
12256     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12257   else
12258     {
12259       rtx tmp = gen_reg_rtx (SImode);
12260
12261       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12262       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12263     }
12264   DONE;
12265 })
12266
12267 (define_expand "paritysi2"
12268   [(set (match_operand:SI 0 "register_operand" "")
12269         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12270   "! TARGET_POPCNT"
12271 {
12272   rtx scratch = gen_reg_rtx (QImode);
12273   rtx cond;
12274
12275   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12276
12277   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12278                          gen_rtx_REG (CCmode, FLAGS_REG),
12279                          const0_rtx);
12280   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12281
12282   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12283   DONE;
12284 })
12285
12286 (define_insn_and_split "paritydi2_cmp"
12287   [(set (reg:CC FLAGS_REG)
12288         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12289                    UNSPEC_PARITY))
12290    (clobber (match_scratch:DI 0 "=r"))
12291    (clobber (match_scratch:SI 1 "=&r"))
12292    (clobber (match_scratch:HI 2 "=Q"))]
12293   "! TARGET_POPCNT"
12294   "#"
12295   "&& reload_completed"
12296   [(parallel
12297      [(set (match_dup 1)
12298            (xor:SI (match_dup 1) (match_dup 4)))
12299       (clobber (reg:CC FLAGS_REG))])
12300    (parallel
12301      [(set (reg:CC FLAGS_REG)
12302            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12303       (clobber (match_dup 1))
12304       (clobber (match_dup 2))])]
12305 {
12306   operands[4] = gen_lowpart (SImode, operands[3]);
12307
12308   if (TARGET_64BIT)
12309     {
12310       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12311       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12312     }
12313   else
12314     operands[1] = gen_highpart (SImode, operands[3]);
12315 })
12316
12317 (define_insn_and_split "paritysi2_cmp"
12318   [(set (reg:CC FLAGS_REG)
12319         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12320                    UNSPEC_PARITY))
12321    (clobber (match_scratch:SI 0 "=r"))
12322    (clobber (match_scratch:HI 1 "=&Q"))]
12323   "! TARGET_POPCNT"
12324   "#"
12325   "&& reload_completed"
12326   [(parallel
12327      [(set (match_dup 1)
12328            (xor:HI (match_dup 1) (match_dup 3)))
12329       (clobber (reg:CC FLAGS_REG))])
12330    (parallel
12331      [(set (reg:CC FLAGS_REG)
12332            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12333       (clobber (match_dup 1))])]
12334 {
12335   operands[3] = gen_lowpart (HImode, operands[2]);
12336
12337   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12338   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12339 })
12340
12341 (define_insn "*parityhi2_cmp"
12342   [(set (reg:CC FLAGS_REG)
12343         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12344                    UNSPEC_PARITY))
12345    (clobber (match_scratch:HI 0 "=Q"))]
12346   "! TARGET_POPCNT"
12347   "xor{b}\t{%h0, %b0|%b0, %h0}"
12348   [(set_attr "length" "2")
12349    (set_attr "mode" "HI")])
12350 \f
12351 ;; Thread-local storage patterns for ELF.
12352 ;;
12353 ;; Note that these code sequences must appear exactly as shown
12354 ;; in order to allow linker relaxation.
12355
12356 (define_insn "*tls_global_dynamic_32_gnu"
12357   [(set (match_operand:SI 0 "register_operand" "=a")
12358         (unspec:SI
12359          [(match_operand:SI 1 "register_operand" "b")
12360           (match_operand:SI 2 "tls_symbolic_operand" "")
12361           (match_operand:SI 3 "constant_call_address_operand" "z")]
12362          UNSPEC_TLS_GD))
12363    (clobber (match_scratch:SI 4 "=d"))
12364    (clobber (match_scratch:SI 5 "=c"))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "!TARGET_64BIT && TARGET_GNU_TLS"
12367 {
12368   output_asm_insn
12369     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12370   return "call\t%P3";
12371 }
12372   [(set_attr "type" "multi")
12373    (set_attr "length" "12")])
12374
12375 (define_expand "tls_global_dynamic_32"
12376   [(parallel
12377     [(set (match_operand:SI 0 "register_operand" "")
12378           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12379                       (match_operand:SI 1 "tls_symbolic_operand" "")
12380                       (match_operand:SI 3 "constant_call_address_operand" "")]
12381                      UNSPEC_TLS_GD))
12382      (clobber (match_scratch:SI 4 ""))
12383      (clobber (match_scratch:SI 5 ""))
12384      (clobber (reg:CC FLAGS_REG))])])
12385
12386 (define_insn "*tls_global_dynamic_64"
12387   [(set (match_operand:DI 0 "register_operand" "=a")
12388         (call:DI
12389          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12390          (match_operand:DI 3 "" "")))
12391    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12392               UNSPEC_TLS_GD)]
12393   "TARGET_64BIT"
12394 {
12395   fputs (ASM_BYTE "0x66\n", asm_out_file);
12396   output_asm_insn
12397     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12398   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12399   fputs ("\trex64\n", asm_out_file);
12400   return "call\t%P2";
12401 }
12402   [(set_attr "type" "multi")
12403    (set_attr "length" "16")])
12404
12405 (define_expand "tls_global_dynamic_64"
12406   [(parallel
12407     [(set (match_operand:DI 0 "register_operand" "")
12408           (call:DI
12409            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12410            (const_int 0)))
12411      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12412                 UNSPEC_TLS_GD)])])
12413
12414 (define_insn "*tls_local_dynamic_base_32_gnu"
12415   [(set (match_operand:SI 0 "register_operand" "=a")
12416         (unspec:SI
12417          [(match_operand:SI 1 "register_operand" "b")
12418           (match_operand:SI 2 "constant_call_address_operand" "z")]
12419          UNSPEC_TLS_LD_BASE))
12420    (clobber (match_scratch:SI 3 "=d"))
12421    (clobber (match_scratch:SI 4 "=c"))
12422    (clobber (reg:CC FLAGS_REG))]
12423   "!TARGET_64BIT && TARGET_GNU_TLS"
12424 {
12425   output_asm_insn
12426     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12427   return "call\t%P2";
12428 }
12429   [(set_attr "type" "multi")
12430    (set_attr "length" "11")])
12431
12432 (define_expand "tls_local_dynamic_base_32"
12433   [(parallel
12434      [(set (match_operand:SI 0 "register_operand" "")
12435            (unspec:SI
12436             [(match_operand:SI 1 "register_operand" "")
12437              (match_operand:SI 2 "constant_call_address_operand" "")]
12438             UNSPEC_TLS_LD_BASE))
12439       (clobber (match_scratch:SI 3 ""))
12440       (clobber (match_scratch:SI 4 ""))
12441       (clobber (reg:CC FLAGS_REG))])])
12442
12443 (define_insn "*tls_local_dynamic_base_64"
12444   [(set (match_operand:DI 0 "register_operand" "=a")
12445         (call:DI
12446          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12447          (match_operand:DI 2 "" "")))
12448    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12449   "TARGET_64BIT"
12450 {
12451   output_asm_insn
12452     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12453   return "call\t%P1";
12454 }
12455   [(set_attr "type" "multi")
12456    (set_attr "length" "12")])
12457
12458 (define_expand "tls_local_dynamic_base_64"
12459   [(parallel
12460      [(set (match_operand:DI 0 "register_operand" "")
12461            (call:DI
12462             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12463             (const_int 0)))
12464       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12465
12466 ;; Local dynamic of a single variable is a lose.  Show combine how
12467 ;; to convert that back to global dynamic.
12468
12469 (define_insn_and_split "*tls_local_dynamic_32_once"
12470   [(set (match_operand:SI 0 "register_operand" "=a")
12471         (plus:SI
12472          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12473                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12474                     UNSPEC_TLS_LD_BASE)
12475          (const:SI (unspec:SI
12476                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12477                     UNSPEC_DTPOFF))))
12478    (clobber (match_scratch:SI 4 "=d"))
12479    (clobber (match_scratch:SI 5 "=c"))
12480    (clobber (reg:CC FLAGS_REG))]
12481   ""
12482   "#"
12483   ""
12484   [(parallel
12485      [(set (match_dup 0)
12486            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12487                       UNSPEC_TLS_GD))
12488       (clobber (match_dup 4))
12489       (clobber (match_dup 5))
12490       (clobber (reg:CC FLAGS_REG))])])
12491
12492 ;; Segment register for the thread base ptr load
12493 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12494
12495 ;; Load and add the thread base pointer from %<tp_seg>:0.
12496 (define_insn "*load_tp_<mode>"
12497   [(set (match_operand:P 0 "register_operand" "=r")
12498         (unspec:P [(const_int 0)] UNSPEC_TP))]
12499   ""
12500   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12501   [(set_attr "type" "imov")
12502    (set_attr "modrm" "0")
12503    (set_attr "length" "7")
12504    (set_attr "memory" "load")
12505    (set_attr "imm_disp" "false")])
12506
12507 (define_insn "*add_tp_<mode>"
12508   [(set (match_operand:P 0 "register_operand" "=r")
12509         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12510                 (match_operand:P 1 "register_operand" "0")))
12511    (clobber (reg:CC FLAGS_REG))]
12512   ""
12513   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12514   [(set_attr "type" "alu")
12515    (set_attr "modrm" "0")
12516    (set_attr "length" "7")
12517    (set_attr "memory" "load")
12518    (set_attr "imm_disp" "false")])
12519
12520 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12521 ;; %rax as destination of the initial executable code sequence.
12522 (define_insn "tls_initial_exec_64_sun"
12523   [(set (match_operand:DI 0 "register_operand" "=a")
12524         (unspec:DI
12525          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12526          UNSPEC_TLS_IE_SUN))
12527    (clobber (reg:CC FLAGS_REG))]
12528   "TARGET_64BIT && TARGET_SUN_TLS"
12529 {
12530   output_asm_insn
12531     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands)
12532   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12533 }
12534   [(set_attr "type" "multi")])
12535
12536 ;; GNU2 TLS patterns can be split.
12537
12538 (define_expand "tls_dynamic_gnu2_32"
12539   [(set (match_dup 3)
12540         (plus:SI (match_operand:SI 2 "register_operand" "")
12541                  (const:SI
12542                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12543                              UNSPEC_TLSDESC))))
12544    (parallel
12545     [(set (match_operand:SI 0 "register_operand" "")
12546           (unspec:SI [(match_dup 1) (match_dup 3)
12547                       (match_dup 2) (reg:SI SP_REG)]
12548                       UNSPEC_TLSDESC))
12549      (clobber (reg:CC FLAGS_REG))])]
12550   "!TARGET_64BIT && TARGET_GNU2_TLS"
12551 {
12552   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12553   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12554 })
12555
12556 (define_insn "*tls_dynamic_lea_32"
12557   [(set (match_operand:SI 0 "register_operand" "=r")
12558         (plus:SI (match_operand:SI 1 "register_operand" "b")
12559                  (const:SI
12560                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12561                               UNSPEC_TLSDESC))))]
12562   "!TARGET_64BIT && TARGET_GNU2_TLS"
12563   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12564   [(set_attr "type" "lea")
12565    (set_attr "mode" "SI")
12566    (set_attr "length" "6")
12567    (set_attr "length_address" "4")])
12568
12569 (define_insn "*tls_dynamic_call_32"
12570   [(set (match_operand:SI 0 "register_operand" "=a")
12571         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12572                     (match_operand:SI 2 "register_operand" "0")
12573                     ;; we have to make sure %ebx still points to the GOT
12574                     (match_operand:SI 3 "register_operand" "b")
12575                     (reg:SI SP_REG)]
12576                    UNSPEC_TLSDESC))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "!TARGET_64BIT && TARGET_GNU2_TLS"
12579   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12580   [(set_attr "type" "call")
12581    (set_attr "length" "2")
12582    (set_attr "length_address" "0")])
12583
12584 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12585   [(set (match_operand:SI 0 "register_operand" "=&a")
12586         (plus:SI
12587          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12588                      (match_operand:SI 4 "" "")
12589                      (match_operand:SI 2 "register_operand" "b")
12590                      (reg:SI SP_REG)]
12591                     UNSPEC_TLSDESC)
12592          (const:SI (unspec:SI
12593                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12594                     UNSPEC_DTPOFF))))
12595    (clobber (reg:CC FLAGS_REG))]
12596   "!TARGET_64BIT && TARGET_GNU2_TLS"
12597   "#"
12598   ""
12599   [(set (match_dup 0) (match_dup 5))]
12600 {
12601   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12602   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12603 })
12604
12605 (define_expand "tls_dynamic_gnu2_64"
12606   [(set (match_dup 2)
12607         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12608                    UNSPEC_TLSDESC))
12609    (parallel
12610     [(set (match_operand:DI 0 "register_operand" "")
12611           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12612                      UNSPEC_TLSDESC))
12613      (clobber (reg:CC FLAGS_REG))])]
12614   "TARGET_64BIT && TARGET_GNU2_TLS"
12615 {
12616   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12617   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12618 })
12619
12620 (define_insn "*tls_dynamic_lea_64"
12621   [(set (match_operand:DI 0 "register_operand" "=r")
12622         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12623                    UNSPEC_TLSDESC))]
12624   "TARGET_64BIT && TARGET_GNU2_TLS"
12625   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12626   [(set_attr "type" "lea")
12627    (set_attr "mode" "DI")
12628    (set_attr "length" "7")
12629    (set_attr "length_address" "4")])
12630
12631 (define_insn "*tls_dynamic_call_64"
12632   [(set (match_operand:DI 0 "register_operand" "=a")
12633         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12634                     (match_operand:DI 2 "register_operand" "0")
12635                     (reg:DI SP_REG)]
12636                    UNSPEC_TLSDESC))
12637    (clobber (reg:CC FLAGS_REG))]
12638   "TARGET_64BIT && TARGET_GNU2_TLS"
12639   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12640   [(set_attr "type" "call")
12641    (set_attr "length" "2")
12642    (set_attr "length_address" "0")])
12643
12644 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12645   [(set (match_operand:DI 0 "register_operand" "=&a")
12646         (plus:DI
12647          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12648                      (match_operand:DI 3 "" "")
12649                      (reg:DI SP_REG)]
12650                     UNSPEC_TLSDESC)
12651          (const:DI (unspec:DI
12652                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12653                     UNSPEC_DTPOFF))))
12654    (clobber (reg:CC FLAGS_REG))]
12655   "TARGET_64BIT && TARGET_GNU2_TLS"
12656   "#"
12657   ""
12658   [(set (match_dup 0) (match_dup 4))]
12659 {
12660   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12661   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12662 })
12663 \f
12664 ;; These patterns match the binary 387 instructions for addM3, subM3,
12665 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12666 ;; SFmode.  The first is the normal insn, the second the same insn but
12667 ;; with one operand a conversion, and the third the same insn but with
12668 ;; the other operand a conversion.  The conversion may be SFmode or
12669 ;; SImode if the target mode DFmode, but only SImode if the target mode
12670 ;; is SFmode.
12671
12672 ;; Gcc is slightly more smart about handling normal two address instructions
12673 ;; so use special patterns for add and mull.
12674
12675 (define_insn "*fop_<mode>_comm_mixed"
12676   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12677         (match_operator:MODEF 3 "binary_fp_operator"
12678           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12679            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12680   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12681    && COMMUTATIVE_ARITH_P (operands[3])
12682    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12683   "* return output_387_binary_op (insn, operands);"
12684   [(set (attr "type")
12685         (if_then_else (eq_attr "alternative" "1,2")
12686            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12687               (const_string "ssemul")
12688               (const_string "sseadd"))
12689            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12690               (const_string "fmul")
12691               (const_string "fop"))))
12692    (set_attr "isa" "base,noavx,avx")
12693    (set_attr "prefix" "orig,orig,vex")
12694    (set_attr "mode" "<MODE>")])
12695
12696 (define_insn "*fop_<mode>_comm_sse"
12697   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12698         (match_operator:MODEF 3 "binary_fp_operator"
12699           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12700            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12701   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12702    && COMMUTATIVE_ARITH_P (operands[3])
12703    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12704   "* return output_387_binary_op (insn, operands);"
12705   [(set (attr "type")
12706         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12707            (const_string "ssemul")
12708            (const_string "sseadd")))
12709    (set_attr "isa" "noavx,avx")
12710    (set_attr "prefix" "orig,vex")
12711    (set_attr "mode" "<MODE>")])
12712
12713 (define_insn "*fop_<mode>_comm_i387"
12714   [(set (match_operand:MODEF 0 "register_operand" "=f")
12715         (match_operator:MODEF 3 "binary_fp_operator"
12716           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12717            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12718   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12719    && COMMUTATIVE_ARITH_P (operands[3])
12720    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12721   "* return output_387_binary_op (insn, operands);"
12722   [(set (attr "type")
12723         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12724            (const_string "fmul")
12725            (const_string "fop")))
12726    (set_attr "mode" "<MODE>")])
12727
12728 (define_insn "*fop_<mode>_1_mixed"
12729   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12730         (match_operator:MODEF 3 "binary_fp_operator"
12731           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12732            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12733   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734    && !COMMUTATIVE_ARITH_P (operands[3])
12735    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736   "* return output_387_binary_op (insn, operands);"
12737   [(set (attr "type")
12738         (cond [(and (eq_attr "alternative" "2,3")
12739                     (match_operand:MODEF 3 "mult_operator" ""))
12740                  (const_string "ssemul")
12741                (and (eq_attr "alternative" "2,3")
12742                     (match_operand:MODEF 3 "div_operator" ""))
12743                  (const_string "ssediv")
12744                (eq_attr "alternative" "2,3")
12745                  (const_string "sseadd")
12746                (match_operand:MODEF 3 "mult_operator" "")
12747                  (const_string "fmul")
12748                (match_operand:MODEF 3 "div_operator" "")
12749                  (const_string "fdiv")
12750               ]
12751               (const_string "fop")))
12752    (set_attr "isa" "base,base,noavx,avx")
12753    (set_attr "prefix" "orig,orig,orig,vex")
12754    (set_attr "mode" "<MODE>")])
12755
12756 (define_insn "*rcpsf2_sse"
12757   [(set (match_operand:SF 0 "register_operand" "=x")
12758         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12759                    UNSPEC_RCP))]
12760   "TARGET_SSE_MATH"
12761   "%vrcpss\t{%1, %d0|%d0, %1}"
12762   [(set_attr "type" "sse")
12763    (set_attr "atom_sse_attr" "rcp")
12764    (set_attr "prefix" "maybe_vex")
12765    (set_attr "mode" "SF")])
12766
12767 (define_insn "*fop_<mode>_1_sse"
12768   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12769         (match_operator:MODEF 3 "binary_fp_operator"
12770           [(match_operand:MODEF 1 "register_operand" "0,x")
12771            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12772   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12773    && !COMMUTATIVE_ARITH_P (operands[3])"
12774   "* return output_387_binary_op (insn, operands);"
12775   [(set (attr "type")
12776         (cond [(match_operand:MODEF 3 "mult_operator" "")
12777                  (const_string "ssemul")
12778                (match_operand:MODEF 3 "div_operator" "")
12779                  (const_string "ssediv")
12780               ]
12781               (const_string "sseadd")))
12782    (set_attr "isa" "noavx,avx")
12783    (set_attr "prefix" "orig,vex")
12784    (set_attr "mode" "<MODE>")])
12785
12786 ;; This pattern is not fully shadowed by the pattern above.
12787 (define_insn "*fop_<mode>_1_i387"
12788   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12789         (match_operator:MODEF 3 "binary_fp_operator"
12790           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12791            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12792   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12793    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12794    && !COMMUTATIVE_ARITH_P (operands[3])
12795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12796   "* return output_387_binary_op (insn, operands);"
12797   [(set (attr "type")
12798         (cond [(match_operand:MODEF 3 "mult_operator" "")
12799                  (const_string "fmul")
12800                (match_operand:MODEF 3 "div_operator" "")
12801                  (const_string "fdiv")
12802               ]
12803               (const_string "fop")))
12804    (set_attr "mode" "<MODE>")])
12805
12806 ;; ??? Add SSE splitters for these!
12807 (define_insn "*fop_<MODEF:mode>_2_i387"
12808   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12809         (match_operator:MODEF 3 "binary_fp_operator"
12810           [(float:MODEF
12811              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12812            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12813   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12814    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12815    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12816   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12817   [(set (attr "type")
12818         (cond [(match_operand:MODEF 3 "mult_operator" "")
12819                  (const_string "fmul")
12820                (match_operand:MODEF 3 "div_operator" "")
12821                  (const_string "fdiv")
12822               ]
12823               (const_string "fop")))
12824    (set_attr "fp_int_src" "true")
12825    (set_attr "mode" "<X87MODEI12:MODE>")])
12826
12827 (define_insn "*fop_<MODEF:mode>_3_i387"
12828   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12829         (match_operator:MODEF 3 "binary_fp_operator"
12830           [(match_operand:MODEF 1 "register_operand" "0,0")
12831            (float:MODEF
12832              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12833   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12834    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12835    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12836   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12837   [(set (attr "type")
12838         (cond [(match_operand:MODEF 3 "mult_operator" "")
12839                  (const_string "fmul")
12840                (match_operand:MODEF 3 "div_operator" "")
12841                  (const_string "fdiv")
12842               ]
12843               (const_string "fop")))
12844    (set_attr "fp_int_src" "true")
12845    (set_attr "mode" "<MODE>")])
12846
12847 (define_insn "*fop_df_4_i387"
12848   [(set (match_operand:DF 0 "register_operand" "=f,f")
12849         (match_operator:DF 3 "binary_fp_operator"
12850            [(float_extend:DF
12851              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12852             (match_operand:DF 2 "register_operand" "0,f")]))]
12853   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12854    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12855    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12856   "* return output_387_binary_op (insn, operands);"
12857   [(set (attr "type")
12858         (cond [(match_operand:DF 3 "mult_operator" "")
12859                  (const_string "fmul")
12860                (match_operand:DF 3 "div_operator" "")
12861                  (const_string "fdiv")
12862               ]
12863               (const_string "fop")))
12864    (set_attr "mode" "SF")])
12865
12866 (define_insn "*fop_df_5_i387"
12867   [(set (match_operand:DF 0 "register_operand" "=f,f")
12868         (match_operator:DF 3 "binary_fp_operator"
12869           [(match_operand:DF 1 "register_operand" "0,f")
12870            (float_extend:DF
12871             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12872   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12873    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12874   "* return output_387_binary_op (insn, operands);"
12875   [(set (attr "type")
12876         (cond [(match_operand:DF 3 "mult_operator" "")
12877                  (const_string "fmul")
12878                (match_operand:DF 3 "div_operator" "")
12879                  (const_string "fdiv")
12880               ]
12881               (const_string "fop")))
12882    (set_attr "mode" "SF")])
12883
12884 (define_insn "*fop_df_6_i387"
12885   [(set (match_operand:DF 0 "register_operand" "=f,f")
12886         (match_operator:DF 3 "binary_fp_operator"
12887           [(float_extend:DF
12888             (match_operand:SF 1 "register_operand" "0,f"))
12889            (float_extend:DF
12890             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12891   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12892    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12893   "* return output_387_binary_op (insn, operands);"
12894   [(set (attr "type")
12895         (cond [(match_operand:DF 3 "mult_operator" "")
12896                  (const_string "fmul")
12897                (match_operand:DF 3 "div_operator" "")
12898                  (const_string "fdiv")
12899               ]
12900               (const_string "fop")))
12901    (set_attr "mode" "SF")])
12902
12903 (define_insn "*fop_xf_comm_i387"
12904   [(set (match_operand:XF 0 "register_operand" "=f")
12905         (match_operator:XF 3 "binary_fp_operator"
12906                         [(match_operand:XF 1 "register_operand" "%0")
12907                          (match_operand:XF 2 "register_operand" "f")]))]
12908   "TARGET_80387
12909    && COMMUTATIVE_ARITH_P (operands[3])"
12910   "* return output_387_binary_op (insn, operands);"
12911   [(set (attr "type")
12912         (if_then_else (match_operand:XF 3 "mult_operator" "")
12913            (const_string "fmul")
12914            (const_string "fop")))
12915    (set_attr "mode" "XF")])
12916
12917 (define_insn "*fop_xf_1_i387"
12918   [(set (match_operand:XF 0 "register_operand" "=f,f")
12919         (match_operator:XF 3 "binary_fp_operator"
12920                         [(match_operand:XF 1 "register_operand" "0,f")
12921                          (match_operand:XF 2 "register_operand" "f,0")]))]
12922   "TARGET_80387
12923    && !COMMUTATIVE_ARITH_P (operands[3])"
12924   "* return output_387_binary_op (insn, operands);"
12925   [(set (attr "type")
12926         (cond [(match_operand:XF 3 "mult_operator" "")
12927                  (const_string "fmul")
12928                (match_operand:XF 3 "div_operator" "")
12929                  (const_string "fdiv")
12930               ]
12931               (const_string "fop")))
12932    (set_attr "mode" "XF")])
12933
12934 (define_insn "*fop_xf_2_i387"
12935   [(set (match_operand:XF 0 "register_operand" "=f,f")
12936         (match_operator:XF 3 "binary_fp_operator"
12937           [(float:XF
12938              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12939            (match_operand:XF 2 "register_operand" "0,0")]))]
12940   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12941   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12942   [(set (attr "type")
12943         (cond [(match_operand:XF 3 "mult_operator" "")
12944                  (const_string "fmul")
12945                (match_operand:XF 3 "div_operator" "")
12946                  (const_string "fdiv")
12947               ]
12948               (const_string "fop")))
12949    (set_attr "fp_int_src" "true")
12950    (set_attr "mode" "<MODE>")])
12951
12952 (define_insn "*fop_xf_3_i387"
12953   [(set (match_operand:XF 0 "register_operand" "=f,f")
12954         (match_operator:XF 3 "binary_fp_operator"
12955           [(match_operand:XF 1 "register_operand" "0,0")
12956            (float:XF
12957              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12958   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12959   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12960   [(set (attr "type")
12961         (cond [(match_operand:XF 3 "mult_operator" "")
12962                  (const_string "fmul")
12963                (match_operand:XF 3 "div_operator" "")
12964                  (const_string "fdiv")
12965               ]
12966               (const_string "fop")))
12967    (set_attr "fp_int_src" "true")
12968    (set_attr "mode" "<MODE>")])
12969
12970 (define_insn "*fop_xf_4_i387"
12971   [(set (match_operand:XF 0 "register_operand" "=f,f")
12972         (match_operator:XF 3 "binary_fp_operator"
12973            [(float_extend:XF
12974               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12975             (match_operand:XF 2 "register_operand" "0,f")]))]
12976   "TARGET_80387"
12977   "* return output_387_binary_op (insn, operands);"
12978   [(set (attr "type")
12979         (cond [(match_operand:XF 3 "mult_operator" "")
12980                  (const_string "fmul")
12981                (match_operand:XF 3 "div_operator" "")
12982                  (const_string "fdiv")
12983               ]
12984               (const_string "fop")))
12985    (set_attr "mode" "<MODE>")])
12986
12987 (define_insn "*fop_xf_5_i387"
12988   [(set (match_operand:XF 0 "register_operand" "=f,f")
12989         (match_operator:XF 3 "binary_fp_operator"
12990           [(match_operand:XF 1 "register_operand" "0,f")
12991            (float_extend:XF
12992              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12993   "TARGET_80387"
12994   "* return output_387_binary_op (insn, operands);"
12995   [(set (attr "type")
12996         (cond [(match_operand:XF 3 "mult_operator" "")
12997                  (const_string "fmul")
12998                (match_operand:XF 3 "div_operator" "")
12999                  (const_string "fdiv")
13000               ]
13001               (const_string "fop")))
13002    (set_attr "mode" "<MODE>")])
13003
13004 (define_insn "*fop_xf_6_i387"
13005   [(set (match_operand:XF 0 "register_operand" "=f,f")
13006         (match_operator:XF 3 "binary_fp_operator"
13007           [(float_extend:XF
13008              (match_operand:MODEF 1 "register_operand" "0,f"))
13009            (float_extend:XF
13010              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13011   "TARGET_80387"
13012   "* return output_387_binary_op (insn, operands);"
13013   [(set (attr "type")
13014         (cond [(match_operand:XF 3 "mult_operator" "")
13015                  (const_string "fmul")
13016                (match_operand:XF 3 "div_operator" "")
13017                  (const_string "fdiv")
13018               ]
13019               (const_string "fop")))
13020    (set_attr "mode" "<MODE>")])
13021
13022 (define_split
13023   [(set (match_operand 0 "register_operand" "")
13024         (match_operator 3 "binary_fp_operator"
13025            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13026             (match_operand 2 "register_operand" "")]))]
13027   "reload_completed
13028    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13029    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13030   [(const_int 0)]
13031 {
13032   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13033   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13034   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13035                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13036                                           GET_MODE (operands[3]),
13037                                           operands[4],
13038                                           operands[2])));
13039   ix86_free_from_memory (GET_MODE (operands[1]));
13040   DONE;
13041 })
13042
13043 (define_split
13044   [(set (match_operand 0 "register_operand" "")
13045         (match_operator 3 "binary_fp_operator"
13046            [(match_operand 1 "register_operand" "")
13047             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13048   "reload_completed
13049    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13050    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13051   [(const_int 0)]
13052 {
13053   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13054   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13055   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13056                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13057                                           GET_MODE (operands[3]),
13058                                           operands[1],
13059                                           operands[4])));
13060   ix86_free_from_memory (GET_MODE (operands[2]));
13061   DONE;
13062 })
13063 \f
13064 ;; FPU special functions.
13065
13066 ;; This pattern implements a no-op XFmode truncation for
13067 ;; all fancy i386 XFmode math functions.
13068
13069 (define_insn "truncxf<mode>2_i387_noop_unspec"
13070   [(set (match_operand:MODEF 0 "register_operand" "=f")
13071         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13072         UNSPEC_TRUNC_NOOP))]
13073   "TARGET_USE_FANCY_MATH_387"
13074   "* return output_387_reg_move (insn, operands);"
13075   [(set_attr "type" "fmov")
13076    (set_attr "mode" "<MODE>")])
13077
13078 (define_insn "sqrtxf2"
13079   [(set (match_operand:XF 0 "register_operand" "=f")
13080         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13081   "TARGET_USE_FANCY_MATH_387"
13082   "fsqrt"
13083   [(set_attr "type" "fpspc")
13084    (set_attr "mode" "XF")
13085    (set_attr "athlon_decode" "direct")
13086    (set_attr "amdfam10_decode" "direct")
13087    (set_attr "bdver1_decode" "direct")])
13088
13089 (define_insn "sqrt_extend<mode>xf2_i387"
13090   [(set (match_operand:XF 0 "register_operand" "=f")
13091         (sqrt:XF
13092           (float_extend:XF
13093             (match_operand:MODEF 1 "register_operand" "0"))))]
13094   "TARGET_USE_FANCY_MATH_387"
13095   "fsqrt"
13096   [(set_attr "type" "fpspc")
13097    (set_attr "mode" "XF")
13098    (set_attr "athlon_decode" "direct")
13099    (set_attr "amdfam10_decode" "direct")
13100    (set_attr "bdver1_decode" "direct")])
13101
13102 (define_insn "*rsqrtsf2_sse"
13103   [(set (match_operand:SF 0 "register_operand" "=x")
13104         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13105                    UNSPEC_RSQRT))]
13106   "TARGET_SSE_MATH"
13107   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13108   [(set_attr "type" "sse")
13109    (set_attr "atom_sse_attr" "rcp")
13110    (set_attr "prefix" "maybe_vex")
13111    (set_attr "mode" "SF")])
13112
13113 (define_expand "rsqrtsf2"
13114   [(set (match_operand:SF 0 "register_operand" "")
13115         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13116                    UNSPEC_RSQRT))]
13117   "TARGET_SSE_MATH"
13118 {
13119   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13120   DONE;
13121 })
13122
13123 (define_insn "*sqrt<mode>2_sse"
13124   [(set (match_operand:MODEF 0 "register_operand" "=x")
13125         (sqrt:MODEF
13126           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13127   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13128   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13129   [(set_attr "type" "sse")
13130    (set_attr "atom_sse_attr" "sqrt")
13131    (set_attr "prefix" "maybe_vex")
13132    (set_attr "mode" "<MODE>")
13133    (set_attr "athlon_decode" "*")
13134    (set_attr "amdfam10_decode" "*")
13135    (set_attr "bdver1_decode" "*")])
13136
13137 (define_expand "sqrt<mode>2"
13138   [(set (match_operand:MODEF 0 "register_operand" "")
13139         (sqrt:MODEF
13140           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13141   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13142    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13143 {
13144   if (<MODE>mode == SFmode
13145       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13146       && flag_finite_math_only && !flag_trapping_math
13147       && flag_unsafe_math_optimizations)
13148     {
13149       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13150       DONE;
13151     }
13152
13153   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13154     {
13155       rtx op0 = gen_reg_rtx (XFmode);
13156       rtx op1 = force_reg (<MODE>mode, operands[1]);
13157
13158       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13159       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13160       DONE;
13161    }
13162 })
13163
13164 (define_insn "fpremxf4_i387"
13165   [(set (match_operand:XF 0 "register_operand" "=f")
13166         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13167                     (match_operand:XF 3 "register_operand" "1")]
13168                    UNSPEC_FPREM_F))
13169    (set (match_operand:XF 1 "register_operand" "=u")
13170         (unspec:XF [(match_dup 2) (match_dup 3)]
13171                    UNSPEC_FPREM_U))
13172    (set (reg:CCFP FPSR_REG)
13173         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13174                      UNSPEC_C2_FLAG))]
13175   "TARGET_USE_FANCY_MATH_387"
13176   "fprem"
13177   [(set_attr "type" "fpspc")
13178    (set_attr "mode" "XF")])
13179
13180 (define_expand "fmodxf3"
13181   [(use (match_operand:XF 0 "register_operand" ""))
13182    (use (match_operand:XF 1 "general_operand" ""))
13183    (use (match_operand:XF 2 "general_operand" ""))]
13184   "TARGET_USE_FANCY_MATH_387"
13185 {
13186   rtx label = gen_label_rtx ();
13187
13188   rtx op1 = gen_reg_rtx (XFmode);
13189   rtx op2 = gen_reg_rtx (XFmode);
13190
13191   emit_move_insn (op2, operands[2]);
13192   emit_move_insn (op1, operands[1]);
13193
13194   emit_label (label);
13195   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13196   ix86_emit_fp_unordered_jump (label);
13197   LABEL_NUSES (label) = 1;
13198
13199   emit_move_insn (operands[0], op1);
13200   DONE;
13201 })
13202
13203 (define_expand "fmod<mode>3"
13204   [(use (match_operand:MODEF 0 "register_operand" ""))
13205    (use (match_operand:MODEF 1 "general_operand" ""))
13206    (use (match_operand:MODEF 2 "general_operand" ""))]
13207   "TARGET_USE_FANCY_MATH_387"
13208 {
13209   rtx (*gen_truncxf) (rtx, rtx);
13210
13211   rtx label = gen_label_rtx ();
13212
13213   rtx op1 = gen_reg_rtx (XFmode);
13214   rtx op2 = gen_reg_rtx (XFmode);
13215
13216   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13217   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13218
13219   emit_label (label);
13220   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13221   ix86_emit_fp_unordered_jump (label);
13222   LABEL_NUSES (label) = 1;
13223
13224   /* Truncate the result properly for strict SSE math.  */
13225   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13226       && !TARGET_MIX_SSE_I387)
13227     gen_truncxf = gen_truncxf<mode>2;
13228   else
13229     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13230
13231   emit_insn (gen_truncxf (operands[0], op1));
13232   DONE;
13233 })
13234
13235 (define_insn "fprem1xf4_i387"
13236   [(set (match_operand:XF 0 "register_operand" "=f")
13237         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13238                     (match_operand:XF 3 "register_operand" "1")]
13239                    UNSPEC_FPREM1_F))
13240    (set (match_operand:XF 1 "register_operand" "=u")
13241         (unspec:XF [(match_dup 2) (match_dup 3)]
13242                    UNSPEC_FPREM1_U))
13243    (set (reg:CCFP FPSR_REG)
13244         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13245                      UNSPEC_C2_FLAG))]
13246   "TARGET_USE_FANCY_MATH_387"
13247   "fprem1"
13248   [(set_attr "type" "fpspc")
13249    (set_attr "mode" "XF")])
13250
13251 (define_expand "remainderxf3"
13252   [(use (match_operand:XF 0 "register_operand" ""))
13253    (use (match_operand:XF 1 "general_operand" ""))
13254    (use (match_operand:XF 2 "general_operand" ""))]
13255   "TARGET_USE_FANCY_MATH_387"
13256 {
13257   rtx label = gen_label_rtx ();
13258
13259   rtx op1 = gen_reg_rtx (XFmode);
13260   rtx op2 = gen_reg_rtx (XFmode);
13261
13262   emit_move_insn (op2, operands[2]);
13263   emit_move_insn (op1, operands[1]);
13264
13265   emit_label (label);
13266   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13267   ix86_emit_fp_unordered_jump (label);
13268   LABEL_NUSES (label) = 1;
13269
13270   emit_move_insn (operands[0], op1);
13271   DONE;
13272 })
13273
13274 (define_expand "remainder<mode>3"
13275   [(use (match_operand:MODEF 0 "register_operand" ""))
13276    (use (match_operand:MODEF 1 "general_operand" ""))
13277    (use (match_operand:MODEF 2 "general_operand" ""))]
13278   "TARGET_USE_FANCY_MATH_387"
13279 {
13280   rtx (*gen_truncxf) (rtx, rtx);
13281
13282   rtx label = gen_label_rtx ();
13283
13284   rtx op1 = gen_reg_rtx (XFmode);
13285   rtx op2 = gen_reg_rtx (XFmode);
13286
13287   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13288   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13289
13290   emit_label (label);
13291
13292   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13293   ix86_emit_fp_unordered_jump (label);
13294   LABEL_NUSES (label) = 1;
13295
13296   /* Truncate the result properly for strict SSE math.  */
13297   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13298       && !TARGET_MIX_SSE_I387)
13299     gen_truncxf = gen_truncxf<mode>2;
13300   else
13301     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13302
13303   emit_insn (gen_truncxf (operands[0], op1));
13304   DONE;
13305 })
13306
13307 (define_insn "*sinxf2_i387"
13308   [(set (match_operand:XF 0 "register_operand" "=f")
13309         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13310   "TARGET_USE_FANCY_MATH_387
13311    && flag_unsafe_math_optimizations"
13312   "fsin"
13313   [(set_attr "type" "fpspc")
13314    (set_attr "mode" "XF")])
13315
13316 (define_insn "*sin_extend<mode>xf2_i387"
13317   [(set (match_operand:XF 0 "register_operand" "=f")
13318         (unspec:XF [(float_extend:XF
13319                       (match_operand:MODEF 1 "register_operand" "0"))]
13320                    UNSPEC_SIN))]
13321   "TARGET_USE_FANCY_MATH_387
13322    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13323        || TARGET_MIX_SSE_I387)
13324    && flag_unsafe_math_optimizations"
13325   "fsin"
13326   [(set_attr "type" "fpspc")
13327    (set_attr "mode" "XF")])
13328
13329 (define_insn "*cosxf2_i387"
13330   [(set (match_operand:XF 0 "register_operand" "=f")
13331         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13332   "TARGET_USE_FANCY_MATH_387
13333    && flag_unsafe_math_optimizations"
13334   "fcos"
13335   [(set_attr "type" "fpspc")
13336    (set_attr "mode" "XF")])
13337
13338 (define_insn "*cos_extend<mode>xf2_i387"
13339   [(set (match_operand:XF 0 "register_operand" "=f")
13340         (unspec:XF [(float_extend:XF
13341                       (match_operand:MODEF 1 "register_operand" "0"))]
13342                    UNSPEC_COS))]
13343   "TARGET_USE_FANCY_MATH_387
13344    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13345        || TARGET_MIX_SSE_I387)
13346    && flag_unsafe_math_optimizations"
13347   "fcos"
13348   [(set_attr "type" "fpspc")
13349    (set_attr "mode" "XF")])
13350
13351 ;; When sincos pattern is defined, sin and cos builtin functions will be
13352 ;; expanded to sincos pattern with one of its outputs left unused.
13353 ;; CSE pass will figure out if two sincos patterns can be combined,
13354 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13355 ;; depending on the unused output.
13356
13357 (define_insn "sincosxf3"
13358   [(set (match_operand:XF 0 "register_operand" "=f")
13359         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13360                    UNSPEC_SINCOS_COS))
13361    (set (match_operand:XF 1 "register_operand" "=u")
13362         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13363   "TARGET_USE_FANCY_MATH_387
13364    && flag_unsafe_math_optimizations"
13365   "fsincos"
13366   [(set_attr "type" "fpspc")
13367    (set_attr "mode" "XF")])
13368
13369 (define_split
13370   [(set (match_operand:XF 0 "register_operand" "")
13371         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13372                    UNSPEC_SINCOS_COS))
13373    (set (match_operand:XF 1 "register_operand" "")
13374         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13375   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13376    && can_create_pseudo_p ()"
13377   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13378
13379 (define_split
13380   [(set (match_operand:XF 0 "register_operand" "")
13381         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13382                    UNSPEC_SINCOS_COS))
13383    (set (match_operand:XF 1 "register_operand" "")
13384         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13385   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13386    && can_create_pseudo_p ()"
13387   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13388
13389 (define_insn "sincos_extend<mode>xf3_i387"
13390   [(set (match_operand:XF 0 "register_operand" "=f")
13391         (unspec:XF [(float_extend:XF
13392                       (match_operand:MODEF 2 "register_operand" "0"))]
13393                    UNSPEC_SINCOS_COS))
13394    (set (match_operand:XF 1 "register_operand" "=u")
13395         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13396   "TARGET_USE_FANCY_MATH_387
13397    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398        || TARGET_MIX_SSE_I387)
13399    && flag_unsafe_math_optimizations"
13400   "fsincos"
13401   [(set_attr "type" "fpspc")
13402    (set_attr "mode" "XF")])
13403
13404 (define_split
13405   [(set (match_operand:XF 0 "register_operand" "")
13406         (unspec:XF [(float_extend:XF
13407                       (match_operand:MODEF 2 "register_operand" ""))]
13408                    UNSPEC_SINCOS_COS))
13409    (set (match_operand:XF 1 "register_operand" "")
13410         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13411   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13412    && can_create_pseudo_p ()"
13413   [(set (match_dup 1)
13414         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13415
13416 (define_split
13417   [(set (match_operand:XF 0 "register_operand" "")
13418         (unspec:XF [(float_extend:XF
13419                       (match_operand:MODEF 2 "register_operand" ""))]
13420                    UNSPEC_SINCOS_COS))
13421    (set (match_operand:XF 1 "register_operand" "")
13422         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13423   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13424    && can_create_pseudo_p ()"
13425   [(set (match_dup 0)
13426         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13427
13428 (define_expand "sincos<mode>3"
13429   [(use (match_operand:MODEF 0 "register_operand" ""))
13430    (use (match_operand:MODEF 1 "register_operand" ""))
13431    (use (match_operand:MODEF 2 "register_operand" ""))]
13432   "TARGET_USE_FANCY_MATH_387
13433    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13434        || TARGET_MIX_SSE_I387)
13435    && flag_unsafe_math_optimizations"
13436 {
13437   rtx op0 = gen_reg_rtx (XFmode);
13438   rtx op1 = gen_reg_rtx (XFmode);
13439
13440   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13441   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13442   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13443   DONE;
13444 })
13445
13446 (define_insn "fptanxf4_i387"
13447   [(set (match_operand:XF 0 "register_operand" "=f")
13448         (match_operand:XF 3 "const_double_operand" "F"))
13449    (set (match_operand:XF 1 "register_operand" "=u")
13450         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13451                    UNSPEC_TAN))]
13452   "TARGET_USE_FANCY_MATH_387
13453    && flag_unsafe_math_optimizations
13454    && standard_80387_constant_p (operands[3]) == 2"
13455   "fptan"
13456   [(set_attr "type" "fpspc")
13457    (set_attr "mode" "XF")])
13458
13459 (define_insn "fptan_extend<mode>xf4_i387"
13460   [(set (match_operand:MODEF 0 "register_operand" "=f")
13461         (match_operand:MODEF 3 "const_double_operand" "F"))
13462    (set (match_operand:XF 1 "register_operand" "=u")
13463         (unspec:XF [(float_extend:XF
13464                       (match_operand:MODEF 2 "register_operand" "0"))]
13465                    UNSPEC_TAN))]
13466   "TARGET_USE_FANCY_MATH_387
13467    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13468        || TARGET_MIX_SSE_I387)
13469    && flag_unsafe_math_optimizations
13470    && standard_80387_constant_p (operands[3]) == 2"
13471   "fptan"
13472   [(set_attr "type" "fpspc")
13473    (set_attr "mode" "XF")])
13474
13475 (define_expand "tanxf2"
13476   [(use (match_operand:XF 0 "register_operand" ""))
13477    (use (match_operand:XF 1 "register_operand" ""))]
13478   "TARGET_USE_FANCY_MATH_387
13479    && flag_unsafe_math_optimizations"
13480 {
13481   rtx one = gen_reg_rtx (XFmode);
13482   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13483
13484   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13485   DONE;
13486 })
13487
13488 (define_expand "tan<mode>2"
13489   [(use (match_operand:MODEF 0 "register_operand" ""))
13490    (use (match_operand:MODEF 1 "register_operand" ""))]
13491   "TARGET_USE_FANCY_MATH_387
13492    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13493        || TARGET_MIX_SSE_I387)
13494    && flag_unsafe_math_optimizations"
13495 {
13496   rtx op0 = gen_reg_rtx (XFmode);
13497
13498   rtx one = gen_reg_rtx (<MODE>mode);
13499   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13500
13501   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13502                                              operands[1], op2));
13503   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13504   DONE;
13505 })
13506
13507 (define_insn "*fpatanxf3_i387"
13508   [(set (match_operand:XF 0 "register_operand" "=f")
13509         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13510                     (match_operand:XF 2 "register_operand" "u")]
13511                    UNSPEC_FPATAN))
13512    (clobber (match_scratch:XF 3 "=2"))]
13513   "TARGET_USE_FANCY_MATH_387
13514    && flag_unsafe_math_optimizations"
13515   "fpatan"
13516   [(set_attr "type" "fpspc")
13517    (set_attr "mode" "XF")])
13518
13519 (define_insn "fpatan_extend<mode>xf3_i387"
13520   [(set (match_operand:XF 0 "register_operand" "=f")
13521         (unspec:XF [(float_extend:XF
13522                       (match_operand:MODEF 1 "register_operand" "0"))
13523                     (float_extend:XF
13524                       (match_operand:MODEF 2 "register_operand" "u"))]
13525                    UNSPEC_FPATAN))
13526    (clobber (match_scratch:XF 3 "=2"))]
13527   "TARGET_USE_FANCY_MATH_387
13528    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13529        || TARGET_MIX_SSE_I387)
13530    && flag_unsafe_math_optimizations"
13531   "fpatan"
13532   [(set_attr "type" "fpspc")
13533    (set_attr "mode" "XF")])
13534
13535 (define_expand "atan2xf3"
13536   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13537                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13538                                (match_operand:XF 1 "register_operand" "")]
13539                               UNSPEC_FPATAN))
13540               (clobber (match_scratch:XF 3 ""))])]
13541   "TARGET_USE_FANCY_MATH_387
13542    && flag_unsafe_math_optimizations")
13543
13544 (define_expand "atan2<mode>3"
13545   [(use (match_operand:MODEF 0 "register_operand" ""))
13546    (use (match_operand:MODEF 1 "register_operand" ""))
13547    (use (match_operand:MODEF 2 "register_operand" ""))]
13548   "TARGET_USE_FANCY_MATH_387
13549    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13550        || TARGET_MIX_SSE_I387)
13551    && flag_unsafe_math_optimizations"
13552 {
13553   rtx op0 = gen_reg_rtx (XFmode);
13554
13555   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13556   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13557   DONE;
13558 })
13559
13560 (define_expand "atanxf2"
13561   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13562                    (unspec:XF [(match_dup 2)
13563                                (match_operand:XF 1 "register_operand" "")]
13564                               UNSPEC_FPATAN))
13565               (clobber (match_scratch:XF 3 ""))])]
13566   "TARGET_USE_FANCY_MATH_387
13567    && flag_unsafe_math_optimizations"
13568 {
13569   operands[2] = gen_reg_rtx (XFmode);
13570   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13571 })
13572
13573 (define_expand "atan<mode>2"
13574   [(use (match_operand:MODEF 0 "register_operand" ""))
13575    (use (match_operand:MODEF 1 "register_operand" ""))]
13576   "TARGET_USE_FANCY_MATH_387
13577    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578        || TARGET_MIX_SSE_I387)
13579    && flag_unsafe_math_optimizations"
13580 {
13581   rtx op0 = gen_reg_rtx (XFmode);
13582
13583   rtx op2 = gen_reg_rtx (<MODE>mode);
13584   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13585
13586   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13587   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13588   DONE;
13589 })
13590
13591 (define_expand "asinxf2"
13592   [(set (match_dup 2)
13593         (mult:XF (match_operand:XF 1 "register_operand" "")
13594                  (match_dup 1)))
13595    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13596    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13597    (parallel [(set (match_operand:XF 0 "register_operand" "")
13598                    (unspec:XF [(match_dup 5) (match_dup 1)]
13599                               UNSPEC_FPATAN))
13600               (clobber (match_scratch:XF 6 ""))])]
13601   "TARGET_USE_FANCY_MATH_387
13602    && flag_unsafe_math_optimizations"
13603 {
13604   int i;
13605
13606   if (optimize_insn_for_size_p ())
13607     FAIL;
13608
13609   for (i = 2; i < 6; i++)
13610     operands[i] = gen_reg_rtx (XFmode);
13611
13612   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13613 })
13614
13615 (define_expand "asin<mode>2"
13616   [(use (match_operand:MODEF 0 "register_operand" ""))
13617    (use (match_operand:MODEF 1 "general_operand" ""))]
13618  "TARGET_USE_FANCY_MATH_387
13619    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620        || TARGET_MIX_SSE_I387)
13621    && flag_unsafe_math_optimizations"
13622 {
13623   rtx op0 = gen_reg_rtx (XFmode);
13624   rtx op1 = gen_reg_rtx (XFmode);
13625
13626   if (optimize_insn_for_size_p ())
13627     FAIL;
13628
13629   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13630   emit_insn (gen_asinxf2 (op0, op1));
13631   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13632   DONE;
13633 })
13634
13635 (define_expand "acosxf2"
13636   [(set (match_dup 2)
13637         (mult:XF (match_operand:XF 1 "register_operand" "")
13638                  (match_dup 1)))
13639    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13640    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13641    (parallel [(set (match_operand:XF 0 "register_operand" "")
13642                    (unspec:XF [(match_dup 1) (match_dup 5)]
13643                               UNSPEC_FPATAN))
13644               (clobber (match_scratch:XF 6 ""))])]
13645   "TARGET_USE_FANCY_MATH_387
13646    && flag_unsafe_math_optimizations"
13647 {
13648   int i;
13649
13650   if (optimize_insn_for_size_p ())
13651     FAIL;
13652
13653   for (i = 2; i < 6; i++)
13654     operands[i] = gen_reg_rtx (XFmode);
13655
13656   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13657 })
13658
13659 (define_expand "acos<mode>2"
13660   [(use (match_operand:MODEF 0 "register_operand" ""))
13661    (use (match_operand:MODEF 1 "general_operand" ""))]
13662  "TARGET_USE_FANCY_MATH_387
13663    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13664        || TARGET_MIX_SSE_I387)
13665    && flag_unsafe_math_optimizations"
13666 {
13667   rtx op0 = gen_reg_rtx (XFmode);
13668   rtx op1 = gen_reg_rtx (XFmode);
13669
13670   if (optimize_insn_for_size_p ())
13671     FAIL;
13672
13673   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13674   emit_insn (gen_acosxf2 (op0, op1));
13675   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13676   DONE;
13677 })
13678
13679 (define_insn "fyl2xxf3_i387"
13680   [(set (match_operand:XF 0 "register_operand" "=f")
13681         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13682                     (match_operand:XF 2 "register_operand" "u")]
13683                    UNSPEC_FYL2X))
13684    (clobber (match_scratch:XF 3 "=2"))]
13685   "TARGET_USE_FANCY_MATH_387
13686    && flag_unsafe_math_optimizations"
13687   "fyl2x"
13688   [(set_attr "type" "fpspc")
13689    (set_attr "mode" "XF")])
13690
13691 (define_insn "fyl2x_extend<mode>xf3_i387"
13692   [(set (match_operand:XF 0 "register_operand" "=f")
13693         (unspec:XF [(float_extend:XF
13694                       (match_operand:MODEF 1 "register_operand" "0"))
13695                     (match_operand:XF 2 "register_operand" "u")]
13696                    UNSPEC_FYL2X))
13697    (clobber (match_scratch:XF 3 "=2"))]
13698   "TARGET_USE_FANCY_MATH_387
13699    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13700        || TARGET_MIX_SSE_I387)
13701    && flag_unsafe_math_optimizations"
13702   "fyl2x"
13703   [(set_attr "type" "fpspc")
13704    (set_attr "mode" "XF")])
13705
13706 (define_expand "logxf2"
13707   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13708                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13709                                (match_dup 2)] UNSPEC_FYL2X))
13710               (clobber (match_scratch:XF 3 ""))])]
13711   "TARGET_USE_FANCY_MATH_387
13712    && flag_unsafe_math_optimizations"
13713 {
13714   operands[2] = gen_reg_rtx (XFmode);
13715   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13716 })
13717
13718 (define_expand "log<mode>2"
13719   [(use (match_operand:MODEF 0 "register_operand" ""))
13720    (use (match_operand:MODEF 1 "register_operand" ""))]
13721   "TARGET_USE_FANCY_MATH_387
13722    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723        || TARGET_MIX_SSE_I387)
13724    && flag_unsafe_math_optimizations"
13725 {
13726   rtx op0 = gen_reg_rtx (XFmode);
13727
13728   rtx op2 = gen_reg_rtx (XFmode);
13729   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13730
13731   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13732   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13733   DONE;
13734 })
13735
13736 (define_expand "log10xf2"
13737   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13738                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13739                                (match_dup 2)] UNSPEC_FYL2X))
13740               (clobber (match_scratch:XF 3 ""))])]
13741   "TARGET_USE_FANCY_MATH_387
13742    && flag_unsafe_math_optimizations"
13743 {
13744   operands[2] = gen_reg_rtx (XFmode);
13745   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13746 })
13747
13748 (define_expand "log10<mode>2"
13749   [(use (match_operand:MODEF 0 "register_operand" ""))
13750    (use (match_operand:MODEF 1 "register_operand" ""))]
13751   "TARGET_USE_FANCY_MATH_387
13752    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13753        || TARGET_MIX_SSE_I387)
13754    && flag_unsafe_math_optimizations"
13755 {
13756   rtx op0 = gen_reg_rtx (XFmode);
13757
13758   rtx op2 = gen_reg_rtx (XFmode);
13759   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13760
13761   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13762   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13763   DONE;
13764 })
13765
13766 (define_expand "log2xf2"
13767   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13768                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13769                                (match_dup 2)] UNSPEC_FYL2X))
13770               (clobber (match_scratch:XF 3 ""))])]
13771   "TARGET_USE_FANCY_MATH_387
13772    && flag_unsafe_math_optimizations"
13773 {
13774   operands[2] = gen_reg_rtx (XFmode);
13775   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13776 })
13777
13778 (define_expand "log2<mode>2"
13779   [(use (match_operand:MODEF 0 "register_operand" ""))
13780    (use (match_operand:MODEF 1 "register_operand" ""))]
13781   "TARGET_USE_FANCY_MATH_387
13782    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13783        || TARGET_MIX_SSE_I387)
13784    && flag_unsafe_math_optimizations"
13785 {
13786   rtx op0 = gen_reg_rtx (XFmode);
13787
13788   rtx op2 = gen_reg_rtx (XFmode);
13789   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13790
13791   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13792   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13793   DONE;
13794 })
13795
13796 (define_insn "fyl2xp1xf3_i387"
13797   [(set (match_operand:XF 0 "register_operand" "=f")
13798         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13799                     (match_operand:XF 2 "register_operand" "u")]
13800                    UNSPEC_FYL2XP1))
13801    (clobber (match_scratch:XF 3 "=2"))]
13802   "TARGET_USE_FANCY_MATH_387
13803    && flag_unsafe_math_optimizations"
13804   "fyl2xp1"
13805   [(set_attr "type" "fpspc")
13806    (set_attr "mode" "XF")])
13807
13808 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13809   [(set (match_operand:XF 0 "register_operand" "=f")
13810         (unspec:XF [(float_extend:XF
13811                       (match_operand:MODEF 1 "register_operand" "0"))
13812                     (match_operand:XF 2 "register_operand" "u")]
13813                    UNSPEC_FYL2XP1))
13814    (clobber (match_scratch:XF 3 "=2"))]
13815   "TARGET_USE_FANCY_MATH_387
13816    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817        || TARGET_MIX_SSE_I387)
13818    && flag_unsafe_math_optimizations"
13819   "fyl2xp1"
13820   [(set_attr "type" "fpspc")
13821    (set_attr "mode" "XF")])
13822
13823 (define_expand "log1pxf2"
13824   [(use (match_operand:XF 0 "register_operand" ""))
13825    (use (match_operand:XF 1 "register_operand" ""))]
13826   "TARGET_USE_FANCY_MATH_387
13827    && flag_unsafe_math_optimizations"
13828 {
13829   if (optimize_insn_for_size_p ())
13830     FAIL;
13831
13832   ix86_emit_i387_log1p (operands[0], operands[1]);
13833   DONE;
13834 })
13835
13836 (define_expand "log1p<mode>2"
13837   [(use (match_operand:MODEF 0 "register_operand" ""))
13838    (use (match_operand:MODEF 1 "register_operand" ""))]
13839   "TARGET_USE_FANCY_MATH_387
13840    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13841        || TARGET_MIX_SSE_I387)
13842    && flag_unsafe_math_optimizations"
13843 {
13844   rtx op0;
13845
13846   if (optimize_insn_for_size_p ())
13847     FAIL;
13848
13849   op0 = gen_reg_rtx (XFmode);
13850
13851   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13852
13853   ix86_emit_i387_log1p (op0, operands[1]);
13854   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13855   DONE;
13856 })
13857
13858 (define_insn "fxtractxf3_i387"
13859   [(set (match_operand:XF 0 "register_operand" "=f")
13860         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13861                    UNSPEC_XTRACT_FRACT))
13862    (set (match_operand:XF 1 "register_operand" "=u")
13863         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13864   "TARGET_USE_FANCY_MATH_387
13865    && flag_unsafe_math_optimizations"
13866   "fxtract"
13867   [(set_attr "type" "fpspc")
13868    (set_attr "mode" "XF")])
13869
13870 (define_insn "fxtract_extend<mode>xf3_i387"
13871   [(set (match_operand:XF 0 "register_operand" "=f")
13872         (unspec:XF [(float_extend:XF
13873                       (match_operand:MODEF 2 "register_operand" "0"))]
13874                    UNSPEC_XTRACT_FRACT))
13875    (set (match_operand:XF 1 "register_operand" "=u")
13876         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13877   "TARGET_USE_FANCY_MATH_387
13878    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13879        || TARGET_MIX_SSE_I387)
13880    && flag_unsafe_math_optimizations"
13881   "fxtract"
13882   [(set_attr "type" "fpspc")
13883    (set_attr "mode" "XF")])
13884
13885 (define_expand "logbxf2"
13886   [(parallel [(set (match_dup 2)
13887                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13888                               UNSPEC_XTRACT_FRACT))
13889               (set (match_operand:XF 0 "register_operand" "")
13890                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13891   "TARGET_USE_FANCY_MATH_387
13892    && flag_unsafe_math_optimizations"
13893   "operands[2] = gen_reg_rtx (XFmode);")
13894
13895 (define_expand "logb<mode>2"
13896   [(use (match_operand:MODEF 0 "register_operand" ""))
13897    (use (match_operand:MODEF 1 "register_operand" ""))]
13898   "TARGET_USE_FANCY_MATH_387
13899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13900        || TARGET_MIX_SSE_I387)
13901    && flag_unsafe_math_optimizations"
13902 {
13903   rtx op0 = gen_reg_rtx (XFmode);
13904   rtx op1 = gen_reg_rtx (XFmode);
13905
13906   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13907   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13908   DONE;
13909 })
13910
13911 (define_expand "ilogbxf2"
13912   [(use (match_operand:SI 0 "register_operand" ""))
13913    (use (match_operand:XF 1 "register_operand" ""))]
13914   "TARGET_USE_FANCY_MATH_387
13915    && flag_unsafe_math_optimizations"
13916 {
13917   rtx op0, op1;
13918
13919   if (optimize_insn_for_size_p ())
13920     FAIL;
13921
13922   op0 = gen_reg_rtx (XFmode);
13923   op1 = gen_reg_rtx (XFmode);
13924
13925   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13926   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13927   DONE;
13928 })
13929
13930 (define_expand "ilogb<mode>2"
13931   [(use (match_operand:SI 0 "register_operand" ""))
13932    (use (match_operand:MODEF 1 "register_operand" ""))]
13933   "TARGET_USE_FANCY_MATH_387
13934    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935        || TARGET_MIX_SSE_I387)
13936    && flag_unsafe_math_optimizations"
13937 {
13938   rtx op0, op1;
13939
13940   if (optimize_insn_for_size_p ())
13941     FAIL;
13942
13943   op0 = gen_reg_rtx (XFmode);
13944   op1 = gen_reg_rtx (XFmode);
13945
13946   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13947   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13948   DONE;
13949 })
13950
13951 (define_insn "*f2xm1xf2_i387"
13952   [(set (match_operand:XF 0 "register_operand" "=f")
13953         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13954                    UNSPEC_F2XM1))]
13955   "TARGET_USE_FANCY_MATH_387
13956    && flag_unsafe_math_optimizations"
13957   "f2xm1"
13958   [(set_attr "type" "fpspc")
13959    (set_attr "mode" "XF")])
13960
13961 (define_insn "*fscalexf4_i387"
13962   [(set (match_operand:XF 0 "register_operand" "=f")
13963         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13964                     (match_operand:XF 3 "register_operand" "1")]
13965                    UNSPEC_FSCALE_FRACT))
13966    (set (match_operand:XF 1 "register_operand" "=u")
13967         (unspec:XF [(match_dup 2) (match_dup 3)]
13968                    UNSPEC_FSCALE_EXP))]
13969   "TARGET_USE_FANCY_MATH_387
13970    && flag_unsafe_math_optimizations"
13971   "fscale"
13972   [(set_attr "type" "fpspc")
13973    (set_attr "mode" "XF")])
13974
13975 (define_expand "expNcorexf3"
13976   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13977                                (match_operand:XF 2 "register_operand" "")))
13978    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13979    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13980    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13981    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13982    (parallel [(set (match_operand:XF 0 "register_operand" "")
13983                    (unspec:XF [(match_dup 8) (match_dup 4)]
13984                               UNSPEC_FSCALE_FRACT))
13985               (set (match_dup 9)
13986                    (unspec:XF [(match_dup 8) (match_dup 4)]
13987                               UNSPEC_FSCALE_EXP))])]
13988   "TARGET_USE_FANCY_MATH_387
13989    && flag_unsafe_math_optimizations"
13990 {
13991   int i;
13992
13993   if (optimize_insn_for_size_p ())
13994     FAIL;
13995
13996   for (i = 3; i < 10; i++)
13997     operands[i] = gen_reg_rtx (XFmode);
13998
13999   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14000 })
14001
14002 (define_expand "expxf2"
14003   [(use (match_operand:XF 0 "register_operand" ""))
14004    (use (match_operand:XF 1 "register_operand" ""))]
14005   "TARGET_USE_FANCY_MATH_387
14006    && flag_unsafe_math_optimizations"
14007 {
14008   rtx op2;
14009
14010   if (optimize_insn_for_size_p ())
14011     FAIL;
14012
14013   op2 = gen_reg_rtx (XFmode);
14014   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14015
14016   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14017   DONE;
14018 })
14019
14020 (define_expand "exp<mode>2"
14021   [(use (match_operand:MODEF 0 "register_operand" ""))
14022    (use (match_operand:MODEF 1 "general_operand" ""))]
14023  "TARGET_USE_FANCY_MATH_387
14024    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025        || TARGET_MIX_SSE_I387)
14026    && flag_unsafe_math_optimizations"
14027 {
14028   rtx op0, op1;
14029
14030   if (optimize_insn_for_size_p ())
14031     FAIL;
14032
14033   op0 = gen_reg_rtx (XFmode);
14034   op1 = gen_reg_rtx (XFmode);
14035
14036   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14037   emit_insn (gen_expxf2 (op0, op1));
14038   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14039   DONE;
14040 })
14041
14042 (define_expand "exp10xf2"
14043   [(use (match_operand:XF 0 "register_operand" ""))
14044    (use (match_operand:XF 1 "register_operand" ""))]
14045   "TARGET_USE_FANCY_MATH_387
14046    && flag_unsafe_math_optimizations"
14047 {
14048   rtx op2;
14049
14050   if (optimize_insn_for_size_p ())
14051     FAIL;
14052
14053   op2 = gen_reg_rtx (XFmode);
14054   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14055
14056   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14057   DONE;
14058 })
14059
14060 (define_expand "exp10<mode>2"
14061   [(use (match_operand:MODEF 0 "register_operand" ""))
14062    (use (match_operand:MODEF 1 "general_operand" ""))]
14063  "TARGET_USE_FANCY_MATH_387
14064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14065        || TARGET_MIX_SSE_I387)
14066    && flag_unsafe_math_optimizations"
14067 {
14068   rtx op0, op1;
14069
14070   if (optimize_insn_for_size_p ())
14071     FAIL;
14072
14073   op0 = gen_reg_rtx (XFmode);
14074   op1 = gen_reg_rtx (XFmode);
14075
14076   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14077   emit_insn (gen_exp10xf2 (op0, op1));
14078   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14079   DONE;
14080 })
14081
14082 (define_expand "exp2xf2"
14083   [(use (match_operand:XF 0 "register_operand" ""))
14084    (use (match_operand:XF 1 "register_operand" ""))]
14085   "TARGET_USE_FANCY_MATH_387
14086    && flag_unsafe_math_optimizations"
14087 {
14088   rtx op2;
14089
14090   if (optimize_insn_for_size_p ())
14091     FAIL;
14092
14093   op2 = gen_reg_rtx (XFmode);
14094   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14095
14096   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14097   DONE;
14098 })
14099
14100 (define_expand "exp2<mode>2"
14101   [(use (match_operand:MODEF 0 "register_operand" ""))
14102    (use (match_operand:MODEF 1 "general_operand" ""))]
14103  "TARGET_USE_FANCY_MATH_387
14104    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105        || TARGET_MIX_SSE_I387)
14106    && flag_unsafe_math_optimizations"
14107 {
14108   rtx op0, op1;
14109
14110   if (optimize_insn_for_size_p ())
14111     FAIL;
14112
14113   op0 = gen_reg_rtx (XFmode);
14114   op1 = gen_reg_rtx (XFmode);
14115
14116   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14117   emit_insn (gen_exp2xf2 (op0, op1));
14118   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14119   DONE;
14120 })
14121
14122 (define_expand "expm1xf2"
14123   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14124                                (match_dup 2)))
14125    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14126    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14127    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14128    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14129    (parallel [(set (match_dup 7)
14130                    (unspec:XF [(match_dup 6) (match_dup 4)]
14131                               UNSPEC_FSCALE_FRACT))
14132               (set (match_dup 8)
14133                    (unspec:XF [(match_dup 6) (match_dup 4)]
14134                               UNSPEC_FSCALE_EXP))])
14135    (parallel [(set (match_dup 10)
14136                    (unspec:XF [(match_dup 9) (match_dup 8)]
14137                               UNSPEC_FSCALE_FRACT))
14138               (set (match_dup 11)
14139                    (unspec:XF [(match_dup 9) (match_dup 8)]
14140                               UNSPEC_FSCALE_EXP))])
14141    (set (match_dup 12) (minus:XF (match_dup 10)
14142                                  (float_extend:XF (match_dup 13))))
14143    (set (match_operand:XF 0 "register_operand" "")
14144         (plus:XF (match_dup 12) (match_dup 7)))]
14145   "TARGET_USE_FANCY_MATH_387
14146    && flag_unsafe_math_optimizations"
14147 {
14148   int i;
14149
14150   if (optimize_insn_for_size_p ())
14151     FAIL;
14152
14153   for (i = 2; i < 13; i++)
14154     operands[i] = gen_reg_rtx (XFmode);
14155
14156   operands[13]
14157     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14158
14159   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14160 })
14161
14162 (define_expand "expm1<mode>2"
14163   [(use (match_operand:MODEF 0 "register_operand" ""))
14164    (use (match_operand:MODEF 1 "general_operand" ""))]
14165  "TARGET_USE_FANCY_MATH_387
14166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167        || TARGET_MIX_SSE_I387)
14168    && flag_unsafe_math_optimizations"
14169 {
14170   rtx op0, op1;
14171
14172   if (optimize_insn_for_size_p ())
14173     FAIL;
14174
14175   op0 = gen_reg_rtx (XFmode);
14176   op1 = gen_reg_rtx (XFmode);
14177
14178   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14179   emit_insn (gen_expm1xf2 (op0, op1));
14180   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14181   DONE;
14182 })
14183
14184 (define_expand "ldexpxf3"
14185   [(set (match_dup 3)
14186         (float:XF (match_operand:SI 2 "register_operand" "")))
14187    (parallel [(set (match_operand:XF 0 " register_operand" "")
14188                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14189                                (match_dup 3)]
14190                               UNSPEC_FSCALE_FRACT))
14191               (set (match_dup 4)
14192                    (unspec:XF [(match_dup 1) (match_dup 3)]
14193                               UNSPEC_FSCALE_EXP))])]
14194   "TARGET_USE_FANCY_MATH_387
14195    && flag_unsafe_math_optimizations"
14196 {
14197   if (optimize_insn_for_size_p ())
14198     FAIL;
14199
14200   operands[3] = gen_reg_rtx (XFmode);
14201   operands[4] = gen_reg_rtx (XFmode);
14202 })
14203
14204 (define_expand "ldexp<mode>3"
14205   [(use (match_operand:MODEF 0 "register_operand" ""))
14206    (use (match_operand:MODEF 1 "general_operand" ""))
14207    (use (match_operand:SI 2 "register_operand" ""))]
14208  "TARGET_USE_FANCY_MATH_387
14209    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14210        || TARGET_MIX_SSE_I387)
14211    && flag_unsafe_math_optimizations"
14212 {
14213   rtx op0, op1;
14214
14215   if (optimize_insn_for_size_p ())
14216     FAIL;
14217
14218   op0 = gen_reg_rtx (XFmode);
14219   op1 = gen_reg_rtx (XFmode);
14220
14221   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14222   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14223   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14224   DONE;
14225 })
14226
14227 (define_expand "scalbxf3"
14228   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14229                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14230                                (match_operand:XF 2 "register_operand" "")]
14231                               UNSPEC_FSCALE_FRACT))
14232               (set (match_dup 3)
14233                    (unspec:XF [(match_dup 1) (match_dup 2)]
14234                               UNSPEC_FSCALE_EXP))])]
14235   "TARGET_USE_FANCY_MATH_387
14236    && flag_unsafe_math_optimizations"
14237 {
14238   if (optimize_insn_for_size_p ())
14239     FAIL;
14240
14241   operands[3] = gen_reg_rtx (XFmode);
14242 })
14243
14244 (define_expand "scalb<mode>3"
14245   [(use (match_operand:MODEF 0 "register_operand" ""))
14246    (use (match_operand:MODEF 1 "general_operand" ""))
14247    (use (match_operand:MODEF 2 "general_operand" ""))]
14248  "TARGET_USE_FANCY_MATH_387
14249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250        || TARGET_MIX_SSE_I387)
14251    && flag_unsafe_math_optimizations"
14252 {
14253   rtx op0, op1, op2;
14254
14255   if (optimize_insn_for_size_p ())
14256     FAIL;
14257
14258   op0 = gen_reg_rtx (XFmode);
14259   op1 = gen_reg_rtx (XFmode);
14260   op2 = gen_reg_rtx (XFmode);
14261
14262   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14263   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14264   emit_insn (gen_scalbxf3 (op0, op1, op2));
14265   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14266   DONE;
14267 })
14268
14269 (define_expand "significandxf2"
14270   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14271                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14272                               UNSPEC_XTRACT_FRACT))
14273               (set (match_dup 2)
14274                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14275   "TARGET_USE_FANCY_MATH_387
14276    && flag_unsafe_math_optimizations"
14277   "operands[2] = gen_reg_rtx (XFmode);")
14278
14279 (define_expand "significand<mode>2"
14280   [(use (match_operand:MODEF 0 "register_operand" ""))
14281    (use (match_operand:MODEF 1 "register_operand" ""))]
14282   "TARGET_USE_FANCY_MATH_387
14283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14284        || TARGET_MIX_SSE_I387)
14285    && flag_unsafe_math_optimizations"
14286 {
14287   rtx op0 = gen_reg_rtx (XFmode);
14288   rtx op1 = gen_reg_rtx (XFmode);
14289
14290   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14291   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14292   DONE;
14293 })
14294 \f
14295
14296 (define_insn "sse4_1_round<mode>2"
14297   [(set (match_operand:MODEF 0 "register_operand" "=x")
14298         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14299                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14300                       UNSPEC_ROUND))]
14301   "TARGET_ROUND"
14302   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14303   [(set_attr "type" "ssecvt")
14304    (set_attr "prefix_extra" "1")
14305    (set_attr "prefix" "maybe_vex")
14306    (set_attr "mode" "<MODE>")])
14307
14308 (define_insn "rintxf2"
14309   [(set (match_operand:XF 0 "register_operand" "=f")
14310         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14311                    UNSPEC_FRNDINT))]
14312   "TARGET_USE_FANCY_MATH_387
14313    && flag_unsafe_math_optimizations"
14314   "frndint"
14315   [(set_attr "type" "fpspc")
14316    (set_attr "mode" "XF")])
14317
14318 (define_expand "rint<mode>2"
14319   [(use (match_operand:MODEF 0 "register_operand" ""))
14320    (use (match_operand:MODEF 1 "register_operand" ""))]
14321   "(TARGET_USE_FANCY_MATH_387
14322     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14323         || TARGET_MIX_SSE_I387)
14324     && flag_unsafe_math_optimizations)
14325    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14326        && !flag_trapping_math)"
14327 {
14328   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14329       && !flag_trapping_math)
14330     {
14331       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14332         FAIL;
14333       if (TARGET_ROUND)
14334         emit_insn (gen_sse4_1_round<mode>2
14335                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14336       else
14337         ix86_expand_rint (operand0, operand1);
14338     }
14339   else
14340     {
14341       rtx op0 = gen_reg_rtx (XFmode);
14342       rtx op1 = gen_reg_rtx (XFmode);
14343
14344       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14345       emit_insn (gen_rintxf2 (op0, op1));
14346
14347       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14348     }
14349   DONE;
14350 })
14351
14352 (define_expand "round<mode>2"
14353   [(match_operand:MODEF 0 "register_operand" "")
14354    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14355   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14356    && !flag_trapping_math && !flag_rounding_math"
14357 {
14358   if (optimize_insn_for_size_p ())
14359     FAIL;
14360   if (TARGET_64BIT || (<MODE>mode != DFmode))
14361     ix86_expand_round (operand0, operand1);
14362   else
14363     ix86_expand_rounddf_32 (operand0, operand1);
14364   DONE;
14365 })
14366
14367 (define_insn_and_split "*fistdi2_1"
14368   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14369         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14370                    UNSPEC_FIST))]
14371   "TARGET_USE_FANCY_MATH_387
14372    && can_create_pseudo_p ()"
14373   "#"
14374   "&& 1"
14375   [(const_int 0)]
14376 {
14377   if (memory_operand (operands[0], VOIDmode))
14378     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14379   else
14380     {
14381       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14382       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14383                                          operands[2]));
14384     }
14385   DONE;
14386 }
14387   [(set_attr "type" "fpspc")
14388    (set_attr "mode" "DI")])
14389
14390 (define_insn "fistdi2"
14391   [(set (match_operand:DI 0 "memory_operand" "=m")
14392         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14393                    UNSPEC_FIST))
14394    (clobber (match_scratch:XF 2 "=&1f"))]
14395   "TARGET_USE_FANCY_MATH_387"
14396   "* return output_fix_trunc (insn, operands, false);"
14397   [(set_attr "type" "fpspc")
14398    (set_attr "mode" "DI")])
14399
14400 (define_insn "fistdi2_with_temp"
14401   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14402         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14403                    UNSPEC_FIST))
14404    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14405    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14406   "TARGET_USE_FANCY_MATH_387"
14407   "#"
14408   [(set_attr "type" "fpspc")
14409    (set_attr "mode" "DI")])
14410
14411 (define_split
14412   [(set (match_operand:DI 0 "register_operand" "")
14413         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14414                    UNSPEC_FIST))
14415    (clobber (match_operand:DI 2 "memory_operand" ""))
14416    (clobber (match_scratch 3 ""))]
14417   "reload_completed"
14418   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14419               (clobber (match_dup 3))])
14420    (set (match_dup 0) (match_dup 2))])
14421
14422 (define_split
14423   [(set (match_operand:DI 0 "memory_operand" "")
14424         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14425                    UNSPEC_FIST))
14426    (clobber (match_operand:DI 2 "memory_operand" ""))
14427    (clobber (match_scratch 3 ""))]
14428   "reload_completed"
14429   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14430               (clobber (match_dup 3))])])
14431
14432 (define_insn_and_split "*fist<mode>2_1"
14433   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14434         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14435                            UNSPEC_FIST))]
14436   "TARGET_USE_FANCY_MATH_387
14437    && can_create_pseudo_p ()"
14438   "#"
14439   "&& 1"
14440   [(const_int 0)]
14441 {
14442   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14443   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14444                                         operands[2]));
14445   DONE;
14446 }
14447   [(set_attr "type" "fpspc")
14448    (set_attr "mode" "<MODE>")])
14449
14450 (define_insn "fist<mode>2"
14451   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14452         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14453                            UNSPEC_FIST))]
14454   "TARGET_USE_FANCY_MATH_387"
14455   "* return output_fix_trunc (insn, operands, false);"
14456   [(set_attr "type" "fpspc")
14457    (set_attr "mode" "<MODE>")])
14458
14459 (define_insn "fist<mode>2_with_temp"
14460   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14461         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14462                            UNSPEC_FIST))
14463    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14464   "TARGET_USE_FANCY_MATH_387"
14465   "#"
14466   [(set_attr "type" "fpspc")
14467    (set_attr "mode" "<MODE>")])
14468
14469 (define_split
14470   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14471         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14472                            UNSPEC_FIST))
14473    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14474   "reload_completed"
14475   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14476    (set (match_dup 0) (match_dup 2))])
14477
14478 (define_split
14479   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14480         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14481                            UNSPEC_FIST))
14482    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14483   "reload_completed"
14484   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14485
14486 (define_expand "lrintxf<mode>2"
14487   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14488      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14489                       UNSPEC_FIST))]
14490   "TARGET_USE_FANCY_MATH_387")
14491
14492 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14493   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14494      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14495                         UNSPEC_FIX_NOTRUNC))]
14496   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14497    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14498
14499 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14500   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14501    (match_operand:MODEF 1 "register_operand" "")]
14502   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14503    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14504    && !flag_trapping_math && !flag_rounding_math"
14505 {
14506   if (optimize_insn_for_size_p ())
14507     FAIL;
14508   ix86_expand_lround (operand0, operand1);
14509   DONE;
14510 })
14511
14512 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14513 (define_insn_and_split "frndintxf2_floor"
14514   [(set (match_operand:XF 0 "register_operand" "")
14515         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14516          UNSPEC_FRNDINT_FLOOR))
14517    (clobber (reg:CC FLAGS_REG))]
14518   "TARGET_USE_FANCY_MATH_387
14519    && flag_unsafe_math_optimizations
14520    && can_create_pseudo_p ()"
14521   "#"
14522   "&& 1"
14523   [(const_int 0)]
14524 {
14525   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14526
14527   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14528   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14529
14530   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14531                                         operands[2], operands[3]));
14532   DONE;
14533 }
14534   [(set_attr "type" "frndint")
14535    (set_attr "i387_cw" "floor")
14536    (set_attr "mode" "XF")])
14537
14538 (define_insn "frndintxf2_floor_i387"
14539   [(set (match_operand:XF 0 "register_operand" "=f")
14540         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14541          UNSPEC_FRNDINT_FLOOR))
14542    (use (match_operand:HI 2 "memory_operand" "m"))
14543    (use (match_operand:HI 3 "memory_operand" "m"))]
14544   "TARGET_USE_FANCY_MATH_387
14545    && flag_unsafe_math_optimizations"
14546   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14547   [(set_attr "type" "frndint")
14548    (set_attr "i387_cw" "floor")
14549    (set_attr "mode" "XF")])
14550
14551 (define_expand "floorxf2"
14552   [(use (match_operand:XF 0 "register_operand" ""))
14553    (use (match_operand:XF 1 "register_operand" ""))]
14554   "TARGET_USE_FANCY_MATH_387
14555    && flag_unsafe_math_optimizations"
14556 {
14557   if (optimize_insn_for_size_p ())
14558     FAIL;
14559   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14560   DONE;
14561 })
14562
14563 (define_expand "floor<mode>2"
14564   [(use (match_operand:MODEF 0 "register_operand" ""))
14565    (use (match_operand:MODEF 1 "register_operand" ""))]
14566   "(TARGET_USE_FANCY_MATH_387
14567     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568         || TARGET_MIX_SSE_I387)
14569     && flag_unsafe_math_optimizations)
14570    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14571        && !flag_trapping_math)"
14572 {
14573   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14574       && !flag_trapping_math
14575       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14576     {
14577       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14578         FAIL;
14579       if (TARGET_ROUND)
14580         emit_insn (gen_sse4_1_round<mode>2
14581                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14582       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14583         ix86_expand_floorceil (operand0, operand1, true);
14584       else
14585         ix86_expand_floorceildf_32 (operand0, operand1, true);
14586     }
14587   else
14588     {
14589       rtx op0, op1;
14590
14591       if (optimize_insn_for_size_p ())
14592         FAIL;
14593
14594       op0 = gen_reg_rtx (XFmode);
14595       op1 = gen_reg_rtx (XFmode);
14596       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14597       emit_insn (gen_frndintxf2_floor (op0, op1));
14598
14599       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14600     }
14601   DONE;
14602 })
14603
14604 (define_insn_and_split "*fist<mode>2_floor_1"
14605   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14606         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14607          UNSPEC_FIST_FLOOR))
14608    (clobber (reg:CC FLAGS_REG))]
14609   "TARGET_USE_FANCY_MATH_387
14610    && flag_unsafe_math_optimizations
14611    && can_create_pseudo_p ()"
14612   "#"
14613   "&& 1"
14614   [(const_int 0)]
14615 {
14616   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14617
14618   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14619   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14620   if (memory_operand (operands[0], VOIDmode))
14621     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14622                                       operands[2], operands[3]));
14623   else
14624     {
14625       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14626       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14627                                                   operands[2], operands[3],
14628                                                   operands[4]));
14629     }
14630   DONE;
14631 }
14632   [(set_attr "type" "fistp")
14633    (set_attr "i387_cw" "floor")
14634    (set_attr "mode" "<MODE>")])
14635
14636 (define_insn "fistdi2_floor"
14637   [(set (match_operand:DI 0 "memory_operand" "=m")
14638         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14639          UNSPEC_FIST_FLOOR))
14640    (use (match_operand:HI 2 "memory_operand" "m"))
14641    (use (match_operand:HI 3 "memory_operand" "m"))
14642    (clobber (match_scratch:XF 4 "=&1f"))]
14643   "TARGET_USE_FANCY_MATH_387
14644    && flag_unsafe_math_optimizations"
14645   "* return output_fix_trunc (insn, operands, false);"
14646   [(set_attr "type" "fistp")
14647    (set_attr "i387_cw" "floor")
14648    (set_attr "mode" "DI")])
14649
14650 (define_insn "fistdi2_floor_with_temp"
14651   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14652         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14653          UNSPEC_FIST_FLOOR))
14654    (use (match_operand:HI 2 "memory_operand" "m,m"))
14655    (use (match_operand:HI 3 "memory_operand" "m,m"))
14656    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14657    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14658   "TARGET_USE_FANCY_MATH_387
14659    && flag_unsafe_math_optimizations"
14660   "#"
14661   [(set_attr "type" "fistp")
14662    (set_attr "i387_cw" "floor")
14663    (set_attr "mode" "DI")])
14664
14665 (define_split
14666   [(set (match_operand:DI 0 "register_operand" "")
14667         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14668          UNSPEC_FIST_FLOOR))
14669    (use (match_operand:HI 2 "memory_operand" ""))
14670    (use (match_operand:HI 3 "memory_operand" ""))
14671    (clobber (match_operand:DI 4 "memory_operand" ""))
14672    (clobber (match_scratch 5 ""))]
14673   "reload_completed"
14674   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14675               (use (match_dup 2))
14676               (use (match_dup 3))
14677               (clobber (match_dup 5))])
14678    (set (match_dup 0) (match_dup 4))])
14679
14680 (define_split
14681   [(set (match_operand:DI 0 "memory_operand" "")
14682         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14683          UNSPEC_FIST_FLOOR))
14684    (use (match_operand:HI 2 "memory_operand" ""))
14685    (use (match_operand:HI 3 "memory_operand" ""))
14686    (clobber (match_operand:DI 4 "memory_operand" ""))
14687    (clobber (match_scratch 5 ""))]
14688   "reload_completed"
14689   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14690               (use (match_dup 2))
14691               (use (match_dup 3))
14692               (clobber (match_dup 5))])])
14693
14694 (define_insn "fist<mode>2_floor"
14695   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14696         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14697          UNSPEC_FIST_FLOOR))
14698    (use (match_operand:HI 2 "memory_operand" "m"))
14699    (use (match_operand:HI 3 "memory_operand" "m"))]
14700   "TARGET_USE_FANCY_MATH_387
14701    && flag_unsafe_math_optimizations"
14702   "* return output_fix_trunc (insn, operands, false);"
14703   [(set_attr "type" "fistp")
14704    (set_attr "i387_cw" "floor")
14705    (set_attr "mode" "<MODE>")])
14706
14707 (define_insn "fist<mode>2_floor_with_temp"
14708   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14709         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14710          UNSPEC_FIST_FLOOR))
14711    (use (match_operand:HI 2 "memory_operand" "m,m"))
14712    (use (match_operand:HI 3 "memory_operand" "m,m"))
14713    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14714   "TARGET_USE_FANCY_MATH_387
14715    && flag_unsafe_math_optimizations"
14716   "#"
14717   [(set_attr "type" "fistp")
14718    (set_attr "i387_cw" "floor")
14719    (set_attr "mode" "<MODE>")])
14720
14721 (define_split
14722   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14723         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14724          UNSPEC_FIST_FLOOR))
14725    (use (match_operand:HI 2 "memory_operand" ""))
14726    (use (match_operand:HI 3 "memory_operand" ""))
14727    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14728   "reload_completed"
14729   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14730                                   UNSPEC_FIST_FLOOR))
14731               (use (match_dup 2))
14732               (use (match_dup 3))])
14733    (set (match_dup 0) (match_dup 4))])
14734
14735 (define_split
14736   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14737         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14738          UNSPEC_FIST_FLOOR))
14739    (use (match_operand:HI 2 "memory_operand" ""))
14740    (use (match_operand:HI 3 "memory_operand" ""))
14741    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14742   "reload_completed"
14743   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14744                                   UNSPEC_FIST_FLOOR))
14745               (use (match_dup 2))
14746               (use (match_dup 3))])])
14747
14748 (define_expand "lfloorxf<mode>2"
14749   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14750                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14751                     UNSPEC_FIST_FLOOR))
14752               (clobber (reg:CC FLAGS_REG))])]
14753   "TARGET_USE_FANCY_MATH_387
14754    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14755    && flag_unsafe_math_optimizations")
14756
14757 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14758   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14759    (match_operand:MODEF 1 "register_operand" "")]
14760   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14761    && !flag_trapping_math"
14762 {
14763   if (TARGET_64BIT && optimize_insn_for_size_p ())
14764     FAIL;
14765   ix86_expand_lfloorceil (operand0, operand1, true);
14766   DONE;
14767 })
14768
14769 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14770 (define_insn_and_split "frndintxf2_ceil"
14771   [(set (match_operand:XF 0 "register_operand" "")
14772         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14773          UNSPEC_FRNDINT_CEIL))
14774    (clobber (reg:CC FLAGS_REG))]
14775   "TARGET_USE_FANCY_MATH_387
14776    && flag_unsafe_math_optimizations
14777    && can_create_pseudo_p ()"
14778   "#"
14779   "&& 1"
14780   [(const_int 0)]
14781 {
14782   ix86_optimize_mode_switching[I387_CEIL] = 1;
14783
14784   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14785   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14786
14787   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14788                                        operands[2], operands[3]));
14789   DONE;
14790 }
14791   [(set_attr "type" "frndint")
14792    (set_attr "i387_cw" "ceil")
14793    (set_attr "mode" "XF")])
14794
14795 (define_insn "frndintxf2_ceil_i387"
14796   [(set (match_operand:XF 0 "register_operand" "=f")
14797         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14798          UNSPEC_FRNDINT_CEIL))
14799    (use (match_operand:HI 2 "memory_operand" "m"))
14800    (use (match_operand:HI 3 "memory_operand" "m"))]
14801   "TARGET_USE_FANCY_MATH_387
14802    && flag_unsafe_math_optimizations"
14803   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14804   [(set_attr "type" "frndint")
14805    (set_attr "i387_cw" "ceil")
14806    (set_attr "mode" "XF")])
14807
14808 (define_expand "ceilxf2"
14809   [(use (match_operand:XF 0 "register_operand" ""))
14810    (use (match_operand:XF 1 "register_operand" ""))]
14811   "TARGET_USE_FANCY_MATH_387
14812    && flag_unsafe_math_optimizations"
14813 {
14814   if (optimize_insn_for_size_p ())
14815     FAIL;
14816   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14817   DONE;
14818 })
14819
14820 (define_expand "ceil<mode>2"
14821   [(use (match_operand:MODEF 0 "register_operand" ""))
14822    (use (match_operand:MODEF 1 "register_operand" ""))]
14823   "(TARGET_USE_FANCY_MATH_387
14824     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14825         || TARGET_MIX_SSE_I387)
14826     && flag_unsafe_math_optimizations)
14827    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14828        && !flag_trapping_math)"
14829 {
14830   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14831       && !flag_trapping_math
14832       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14833     {
14834       if (TARGET_ROUND)
14835         emit_insn (gen_sse4_1_round<mode>2
14836                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14837       else if (optimize_insn_for_size_p ())
14838         FAIL;
14839       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14840         ix86_expand_floorceil (operand0, operand1, false);
14841       else
14842         ix86_expand_floorceildf_32 (operand0, operand1, false);
14843     }
14844   else
14845     {
14846       rtx op0, op1;
14847
14848       if (optimize_insn_for_size_p ())
14849         FAIL;
14850
14851       op0 = gen_reg_rtx (XFmode);
14852       op1 = gen_reg_rtx (XFmode);
14853       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14854       emit_insn (gen_frndintxf2_ceil (op0, op1));
14855
14856       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14857     }
14858   DONE;
14859 })
14860
14861 (define_insn_and_split "*fist<mode>2_ceil_1"
14862   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14863         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14864          UNSPEC_FIST_CEIL))
14865    (clobber (reg:CC FLAGS_REG))]
14866   "TARGET_USE_FANCY_MATH_387
14867    && flag_unsafe_math_optimizations
14868    && can_create_pseudo_p ()"
14869   "#"
14870   "&& 1"
14871   [(const_int 0)]
14872 {
14873   ix86_optimize_mode_switching[I387_CEIL] = 1;
14874
14875   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14876   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14877   if (memory_operand (operands[0], VOIDmode))
14878     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14879                                      operands[2], operands[3]));
14880   else
14881     {
14882       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14883       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14884                                                  operands[2], operands[3],
14885                                                  operands[4]));
14886     }
14887   DONE;
14888 }
14889   [(set_attr "type" "fistp")
14890    (set_attr "i387_cw" "ceil")
14891    (set_attr "mode" "<MODE>")])
14892
14893 (define_insn "fistdi2_ceil"
14894   [(set (match_operand:DI 0 "memory_operand" "=m")
14895         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14896          UNSPEC_FIST_CEIL))
14897    (use (match_operand:HI 2 "memory_operand" "m"))
14898    (use (match_operand:HI 3 "memory_operand" "m"))
14899    (clobber (match_scratch:XF 4 "=&1f"))]
14900   "TARGET_USE_FANCY_MATH_387
14901    && flag_unsafe_math_optimizations"
14902   "* return output_fix_trunc (insn, operands, false);"
14903   [(set_attr "type" "fistp")
14904    (set_attr "i387_cw" "ceil")
14905    (set_attr "mode" "DI")])
14906
14907 (define_insn "fistdi2_ceil_with_temp"
14908   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14909         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14910          UNSPEC_FIST_CEIL))
14911    (use (match_operand:HI 2 "memory_operand" "m,m"))
14912    (use (match_operand:HI 3 "memory_operand" "m,m"))
14913    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14914    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && flag_unsafe_math_optimizations"
14917   "#"
14918   [(set_attr "type" "fistp")
14919    (set_attr "i387_cw" "ceil")
14920    (set_attr "mode" "DI")])
14921
14922 (define_split
14923   [(set (match_operand:DI 0 "register_operand" "")
14924         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14925          UNSPEC_FIST_CEIL))
14926    (use (match_operand:HI 2 "memory_operand" ""))
14927    (use (match_operand:HI 3 "memory_operand" ""))
14928    (clobber (match_operand:DI 4 "memory_operand" ""))
14929    (clobber (match_scratch 5 ""))]
14930   "reload_completed"
14931   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14932               (use (match_dup 2))
14933               (use (match_dup 3))
14934               (clobber (match_dup 5))])
14935    (set (match_dup 0) (match_dup 4))])
14936
14937 (define_split
14938   [(set (match_operand:DI 0 "memory_operand" "")
14939         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14940          UNSPEC_FIST_CEIL))
14941    (use (match_operand:HI 2 "memory_operand" ""))
14942    (use (match_operand:HI 3 "memory_operand" ""))
14943    (clobber (match_operand:DI 4 "memory_operand" ""))
14944    (clobber (match_scratch 5 ""))]
14945   "reload_completed"
14946   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14947               (use (match_dup 2))
14948               (use (match_dup 3))
14949               (clobber (match_dup 5))])])
14950
14951 (define_insn "fist<mode>2_ceil"
14952   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14953         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14954          UNSPEC_FIST_CEIL))
14955    (use (match_operand:HI 2 "memory_operand" "m"))
14956    (use (match_operand:HI 3 "memory_operand" "m"))]
14957   "TARGET_USE_FANCY_MATH_387
14958    && flag_unsafe_math_optimizations"
14959   "* return output_fix_trunc (insn, operands, false);"
14960   [(set_attr "type" "fistp")
14961    (set_attr "i387_cw" "ceil")
14962    (set_attr "mode" "<MODE>")])
14963
14964 (define_insn "fist<mode>2_ceil_with_temp"
14965   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14966         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14967          UNSPEC_FIST_CEIL))
14968    (use (match_operand:HI 2 "memory_operand" "m,m"))
14969    (use (match_operand:HI 3 "memory_operand" "m,m"))
14970    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14971   "TARGET_USE_FANCY_MATH_387
14972    && flag_unsafe_math_optimizations"
14973   "#"
14974   [(set_attr "type" "fistp")
14975    (set_attr "i387_cw" "ceil")
14976    (set_attr "mode" "<MODE>")])
14977
14978 (define_split
14979   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14980         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14981          UNSPEC_FIST_CEIL))
14982    (use (match_operand:HI 2 "memory_operand" ""))
14983    (use (match_operand:HI 3 "memory_operand" ""))
14984    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14985   "reload_completed"
14986   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14987                                   UNSPEC_FIST_CEIL))
14988               (use (match_dup 2))
14989               (use (match_dup 3))])
14990    (set (match_dup 0) (match_dup 4))])
14991
14992 (define_split
14993   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14994         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14995          UNSPEC_FIST_CEIL))
14996    (use (match_operand:HI 2 "memory_operand" ""))
14997    (use (match_operand:HI 3 "memory_operand" ""))
14998    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14999   "reload_completed"
15000   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15001                                   UNSPEC_FIST_CEIL))
15002               (use (match_dup 2))
15003               (use (match_dup 3))])])
15004
15005 (define_expand "lceilxf<mode>2"
15006   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15007                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15008                     UNSPEC_FIST_CEIL))
15009               (clobber (reg:CC FLAGS_REG))])]
15010   "TARGET_USE_FANCY_MATH_387
15011    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15012    && flag_unsafe_math_optimizations")
15013
15014 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15015   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15016    (match_operand:MODEF 1 "register_operand" "")]
15017   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15018    && !flag_trapping_math"
15019 {
15020   ix86_expand_lfloorceil (operand0, operand1, false);
15021   DONE;
15022 })
15023
15024 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15025 (define_insn_and_split "frndintxf2_trunc"
15026   [(set (match_operand:XF 0 "register_operand" "")
15027         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15028          UNSPEC_FRNDINT_TRUNC))
15029    (clobber (reg:CC FLAGS_REG))]
15030   "TARGET_USE_FANCY_MATH_387
15031    && flag_unsafe_math_optimizations
15032    && can_create_pseudo_p ()"
15033   "#"
15034   "&& 1"
15035   [(const_int 0)]
15036 {
15037   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15038
15039   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15040   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15041
15042   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15043                                         operands[2], operands[3]));
15044   DONE;
15045 }
15046   [(set_attr "type" "frndint")
15047    (set_attr "i387_cw" "trunc")
15048    (set_attr "mode" "XF")])
15049
15050 (define_insn "frndintxf2_trunc_i387"
15051   [(set (match_operand:XF 0 "register_operand" "=f")
15052         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15053          UNSPEC_FRNDINT_TRUNC))
15054    (use (match_operand:HI 2 "memory_operand" "m"))
15055    (use (match_operand:HI 3 "memory_operand" "m"))]
15056   "TARGET_USE_FANCY_MATH_387
15057    && flag_unsafe_math_optimizations"
15058   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15059   [(set_attr "type" "frndint")
15060    (set_attr "i387_cw" "trunc")
15061    (set_attr "mode" "XF")])
15062
15063 (define_expand "btruncxf2"
15064   [(use (match_operand:XF 0 "register_operand" ""))
15065    (use (match_operand:XF 1 "register_operand" ""))]
15066   "TARGET_USE_FANCY_MATH_387
15067    && flag_unsafe_math_optimizations"
15068 {
15069   if (optimize_insn_for_size_p ())
15070     FAIL;
15071   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15072   DONE;
15073 })
15074
15075 (define_expand "btrunc<mode>2"
15076   [(use (match_operand:MODEF 0 "register_operand" ""))
15077    (use (match_operand:MODEF 1 "register_operand" ""))]
15078   "(TARGET_USE_FANCY_MATH_387
15079     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15080         || TARGET_MIX_SSE_I387)
15081     && flag_unsafe_math_optimizations)
15082    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15083        && !flag_trapping_math)"
15084 {
15085   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15086       && !flag_trapping_math
15087       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15088     {
15089       if (TARGET_ROUND)
15090         emit_insn (gen_sse4_1_round<mode>2
15091                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15092       else if (optimize_insn_for_size_p ())
15093         FAIL;
15094       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15095         ix86_expand_trunc (operand0, operand1);
15096       else
15097         ix86_expand_truncdf_32 (operand0, operand1);
15098     }
15099   else
15100     {
15101       rtx op0, op1;
15102
15103       if (optimize_insn_for_size_p ())
15104         FAIL;
15105
15106       op0 = gen_reg_rtx (XFmode);
15107       op1 = gen_reg_rtx (XFmode);
15108       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15109       emit_insn (gen_frndintxf2_trunc (op0, op1));
15110
15111       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15112     }
15113   DONE;
15114 })
15115
15116 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15117 (define_insn_and_split "frndintxf2_mask_pm"
15118   [(set (match_operand:XF 0 "register_operand" "")
15119         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15120          UNSPEC_FRNDINT_MASK_PM))
15121    (clobber (reg:CC FLAGS_REG))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && flag_unsafe_math_optimizations
15124    && can_create_pseudo_p ()"
15125   "#"
15126   "&& 1"
15127   [(const_int 0)]
15128 {
15129   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15130
15131   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15132   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15133
15134   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15135                                           operands[2], operands[3]));
15136   DONE;
15137 }
15138   [(set_attr "type" "frndint")
15139    (set_attr "i387_cw" "mask_pm")
15140    (set_attr "mode" "XF")])
15141
15142 (define_insn "frndintxf2_mask_pm_i387"
15143   [(set (match_operand:XF 0 "register_operand" "=f")
15144         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15145          UNSPEC_FRNDINT_MASK_PM))
15146    (use (match_operand:HI 2 "memory_operand" "m"))
15147    (use (match_operand:HI 3 "memory_operand" "m"))]
15148   "TARGET_USE_FANCY_MATH_387
15149    && flag_unsafe_math_optimizations"
15150   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15151   [(set_attr "type" "frndint")
15152    (set_attr "i387_cw" "mask_pm")
15153    (set_attr "mode" "XF")])
15154
15155 (define_expand "nearbyintxf2"
15156   [(use (match_operand:XF 0 "register_operand" ""))
15157    (use (match_operand:XF 1 "register_operand" ""))]
15158   "TARGET_USE_FANCY_MATH_387
15159    && flag_unsafe_math_optimizations"
15160 {
15161   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15162   DONE;
15163 })
15164
15165 (define_expand "nearbyint<mode>2"
15166   [(use (match_operand:MODEF 0 "register_operand" ""))
15167    (use (match_operand:MODEF 1 "register_operand" ""))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15170        || TARGET_MIX_SSE_I387)
15171    && flag_unsafe_math_optimizations"
15172 {
15173   rtx op0 = gen_reg_rtx (XFmode);
15174   rtx op1 = gen_reg_rtx (XFmode);
15175
15176   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15177   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15178
15179   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15180   DONE;
15181 })
15182
15183 (define_insn "fxam<mode>2_i387"
15184   [(set (match_operand:HI 0 "register_operand" "=a")
15185         (unspec:HI
15186           [(match_operand:X87MODEF 1 "register_operand" "f")]
15187           UNSPEC_FXAM))]
15188   "TARGET_USE_FANCY_MATH_387"
15189   "fxam\n\tfnstsw\t%0"
15190   [(set_attr "type" "multi")
15191    (set_attr "length" "4")
15192    (set_attr "unit" "i387")
15193    (set_attr "mode" "<MODE>")])
15194
15195 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15196   [(set (match_operand:HI 0 "register_operand" "")
15197         (unspec:HI
15198           [(match_operand:MODEF 1 "memory_operand" "")]
15199           UNSPEC_FXAM_MEM))]
15200   "TARGET_USE_FANCY_MATH_387
15201    && can_create_pseudo_p ()"
15202   "#"
15203   "&& 1"
15204   [(set (match_dup 2)(match_dup 1))
15205    (set (match_dup 0)
15206         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15207 {
15208   operands[2] = gen_reg_rtx (<MODE>mode);
15209
15210   MEM_VOLATILE_P (operands[1]) = 1;
15211 }
15212   [(set_attr "type" "multi")
15213    (set_attr "unit" "i387")
15214    (set_attr "mode" "<MODE>")])
15215
15216 (define_expand "isinfxf2"
15217   [(use (match_operand:SI 0 "register_operand" ""))
15218    (use (match_operand:XF 1 "register_operand" ""))]
15219   "TARGET_USE_FANCY_MATH_387
15220    && TARGET_C99_FUNCTIONS"
15221 {
15222   rtx mask = GEN_INT (0x45);
15223   rtx val = GEN_INT (0x05);
15224
15225   rtx cond;
15226
15227   rtx scratch = gen_reg_rtx (HImode);
15228   rtx res = gen_reg_rtx (QImode);
15229
15230   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15231
15232   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15233   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15234   cond = gen_rtx_fmt_ee (EQ, QImode,
15235                          gen_rtx_REG (CCmode, FLAGS_REG),
15236                          const0_rtx);
15237   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15238   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15239   DONE;
15240 })
15241
15242 (define_expand "isinf<mode>2"
15243   [(use (match_operand:SI 0 "register_operand" ""))
15244    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15245   "TARGET_USE_FANCY_MATH_387
15246    && TARGET_C99_FUNCTIONS
15247    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15248 {
15249   rtx mask = GEN_INT (0x45);
15250   rtx val = GEN_INT (0x05);
15251
15252   rtx cond;
15253
15254   rtx scratch = gen_reg_rtx (HImode);
15255   rtx res = gen_reg_rtx (QImode);
15256
15257   /* Remove excess precision by forcing value through memory. */
15258   if (memory_operand (operands[1], VOIDmode))
15259     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15260   else
15261     {
15262       enum ix86_stack_slot slot = (virtuals_instantiated
15263                                    ? SLOT_TEMP
15264                                    : SLOT_VIRTUAL);
15265       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15266
15267       emit_move_insn (temp, operands[1]);
15268       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15269     }
15270
15271   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15272   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15273   cond = gen_rtx_fmt_ee (EQ, QImode,
15274                          gen_rtx_REG (CCmode, FLAGS_REG),
15275                          const0_rtx);
15276   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15277   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15278   DONE;
15279 })
15280
15281 (define_expand "signbitxf2"
15282   [(use (match_operand:SI 0 "register_operand" ""))
15283    (use (match_operand:XF 1 "register_operand" ""))]
15284   "TARGET_USE_FANCY_MATH_387"
15285 {
15286   rtx scratch = gen_reg_rtx (HImode);
15287
15288   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15289   emit_insn (gen_andsi3 (operands[0],
15290              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15291   DONE;
15292 })
15293
15294 (define_insn "movmsk_df"
15295   [(set (match_operand:SI 0 "register_operand" "=r")
15296         (unspec:SI
15297           [(match_operand:DF 1 "register_operand" "x")]
15298           UNSPEC_MOVMSK))]
15299   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15300   "%vmovmskpd\t{%1, %0|%0, %1}"
15301   [(set_attr "type" "ssemov")
15302    (set_attr "prefix" "maybe_vex")
15303    (set_attr "mode" "DF")])
15304
15305 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15306 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15307 (define_expand "signbitdf2"
15308   [(use (match_operand:SI 0 "register_operand" ""))
15309    (use (match_operand:DF 1 "register_operand" ""))]
15310   "TARGET_USE_FANCY_MATH_387
15311    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15312 {
15313   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15314     {
15315       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15316       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15317     }
15318   else
15319     {
15320       rtx scratch = gen_reg_rtx (HImode);
15321
15322       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15323       emit_insn (gen_andsi3 (operands[0],
15324                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15325     }
15326   DONE;
15327 })
15328
15329 (define_expand "signbitsf2"
15330   [(use (match_operand:SI 0 "register_operand" ""))
15331    (use (match_operand:SF 1 "register_operand" ""))]
15332   "TARGET_USE_FANCY_MATH_387
15333    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15334 {
15335   rtx scratch = gen_reg_rtx (HImode);
15336
15337   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15338   emit_insn (gen_andsi3 (operands[0],
15339              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15340   DONE;
15341 })
15342 \f
15343 ;; Block operation instructions
15344
15345 (define_insn "cld"
15346   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15347   ""
15348   "cld"
15349   [(set_attr "length" "1")
15350    (set_attr "length_immediate" "0")
15351    (set_attr "modrm" "0")])
15352
15353 (define_expand "movmem<mode>"
15354   [(use (match_operand:BLK 0 "memory_operand" ""))
15355    (use (match_operand:BLK 1 "memory_operand" ""))
15356    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15357    (use (match_operand:SWI48 3 "const_int_operand" ""))
15358    (use (match_operand:SI 4 "const_int_operand" ""))
15359    (use (match_operand:SI 5 "const_int_operand" ""))]
15360   ""
15361 {
15362  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15363                          operands[4], operands[5]))
15364    DONE;
15365  else
15366    FAIL;
15367 })
15368
15369 ;; Most CPUs don't like single string operations
15370 ;; Handle this case here to simplify previous expander.
15371
15372 (define_expand "strmov"
15373   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15374    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15375    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15376               (clobber (reg:CC FLAGS_REG))])
15377    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15378               (clobber (reg:CC FLAGS_REG))])]
15379   ""
15380 {
15381   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15382
15383   /* If .md ever supports :P for Pmode, these can be directly
15384      in the pattern above.  */
15385   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15386   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15387
15388   /* Can't use this if the user has appropriated esi or edi.  */
15389   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15390       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15391     {
15392       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15393                                       operands[2], operands[3],
15394                                       operands[5], operands[6]));
15395       DONE;
15396     }
15397
15398   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15399 })
15400
15401 (define_expand "strmov_singleop"
15402   [(parallel [(set (match_operand 1 "memory_operand" "")
15403                    (match_operand 3 "memory_operand" ""))
15404               (set (match_operand 0 "register_operand" "")
15405                    (match_operand 4 "" ""))
15406               (set (match_operand 2 "register_operand" "")
15407                    (match_operand 5 "" ""))])]
15408   ""
15409   "ix86_current_function_needs_cld = 1;")
15410
15411 (define_insn "*strmovdi_rex_1"
15412   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15413         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15414    (set (match_operand:DI 0 "register_operand" "=D")
15415         (plus:DI (match_dup 2)
15416                  (const_int 8)))
15417    (set (match_operand:DI 1 "register_operand" "=S")
15418         (plus:DI (match_dup 3)
15419                  (const_int 8)))]
15420   "TARGET_64BIT"
15421   "movsq"
15422   [(set_attr "type" "str")
15423    (set_attr "memory" "both")
15424    (set_attr "mode" "DI")])
15425
15426 (define_insn "*strmovsi_1"
15427   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15428         (mem:SI (match_operand:P 3 "register_operand" "1")))
15429    (set (match_operand:P 0 "register_operand" "=D")
15430         (plus:P (match_dup 2)
15431                 (const_int 4)))
15432    (set (match_operand:P 1 "register_operand" "=S")
15433         (plus:P (match_dup 3)
15434                 (const_int 4)))]
15435   ""
15436   "movs{l|d}"
15437   [(set_attr "type" "str")
15438    (set_attr "memory" "both")
15439    (set_attr "mode" "SI")])
15440
15441 (define_insn "*strmovhi_1"
15442   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15443         (mem:HI (match_operand:P 3 "register_operand" "1")))
15444    (set (match_operand:P 0 "register_operand" "=D")
15445         (plus:P (match_dup 2)
15446                 (const_int 2)))
15447    (set (match_operand:P 1 "register_operand" "=S")
15448         (plus:P (match_dup 3)
15449                 (const_int 2)))]
15450   ""
15451   "movsw"
15452   [(set_attr "type" "str")
15453    (set_attr "memory" "both")
15454    (set_attr "mode" "HI")])
15455
15456 (define_insn "*strmovqi_1"
15457   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15458         (mem:QI (match_operand:P 3 "register_operand" "1")))
15459    (set (match_operand:P 0 "register_operand" "=D")
15460         (plus:P (match_dup 2)
15461                 (const_int 1)))
15462    (set (match_operand:P 1 "register_operand" "=S")
15463         (plus:P (match_dup 3)
15464                 (const_int 1)))]
15465   ""
15466   "movsb"
15467   [(set_attr "type" "str")
15468    (set_attr "memory" "both")
15469    (set (attr "prefix_rex")
15470         (if_then_else
15471           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15472           (const_string "0")
15473           (const_string "*")))
15474    (set_attr "mode" "QI")])
15475
15476 (define_expand "rep_mov"
15477   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15478               (set (match_operand 0 "register_operand" "")
15479                    (match_operand 5 "" ""))
15480               (set (match_operand 2 "register_operand" "")
15481                    (match_operand 6 "" ""))
15482               (set (match_operand 1 "memory_operand" "")
15483                    (match_operand 3 "memory_operand" ""))
15484               (use (match_dup 4))])]
15485   ""
15486   "ix86_current_function_needs_cld = 1;")
15487
15488 (define_insn "*rep_movdi_rex64"
15489   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15490    (set (match_operand:DI 0 "register_operand" "=D")
15491         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15492                             (const_int 3))
15493                  (match_operand:DI 3 "register_operand" "0")))
15494    (set (match_operand:DI 1 "register_operand" "=S")
15495         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15496                  (match_operand:DI 4 "register_operand" "1")))
15497    (set (mem:BLK (match_dup 3))
15498         (mem:BLK (match_dup 4)))
15499    (use (match_dup 5))]
15500   "TARGET_64BIT"
15501   "rep{%;} movsq"
15502   [(set_attr "type" "str")
15503    (set_attr "prefix_rep" "1")
15504    (set_attr "memory" "both")
15505    (set_attr "mode" "DI")])
15506
15507 (define_insn "*rep_movsi"
15508   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15509    (set (match_operand:P 0 "register_operand" "=D")
15510         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15511                           (const_int 2))
15512                  (match_operand:P 3 "register_operand" "0")))
15513    (set (match_operand:P 1 "register_operand" "=S")
15514         (plus:P (ashift:P (match_dup 5) (const_int 2))
15515                 (match_operand:P 4 "register_operand" "1")))
15516    (set (mem:BLK (match_dup 3))
15517         (mem:BLK (match_dup 4)))
15518    (use (match_dup 5))]
15519   ""
15520   "rep{%;} movs{l|d}"
15521   [(set_attr "type" "str")
15522    (set_attr "prefix_rep" "1")
15523    (set_attr "memory" "both")
15524    (set_attr "mode" "SI")])
15525
15526 (define_insn "*rep_movqi"
15527   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15528    (set (match_operand:P 0 "register_operand" "=D")
15529         (plus:P (match_operand:P 3 "register_operand" "0")
15530                 (match_operand:P 5 "register_operand" "2")))
15531    (set (match_operand:P 1 "register_operand" "=S")
15532         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15533    (set (mem:BLK (match_dup 3))
15534         (mem:BLK (match_dup 4)))
15535    (use (match_dup 5))]
15536   ""
15537   "rep{%;} movsb"
15538   [(set_attr "type" "str")
15539    (set_attr "prefix_rep" "1")
15540    (set_attr "memory" "both")
15541    (set_attr "mode" "QI")])
15542
15543 (define_expand "setmem<mode>"
15544    [(use (match_operand:BLK 0 "memory_operand" ""))
15545     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15546     (use (match_operand:QI 2 "nonmemory_operand" ""))
15547     (use (match_operand 3 "const_int_operand" ""))
15548     (use (match_operand:SI 4 "const_int_operand" ""))
15549     (use (match_operand:SI 5 "const_int_operand" ""))]
15550   ""
15551 {
15552  if (ix86_expand_setmem (operands[0], operands[1],
15553                          operands[2], operands[3],
15554                          operands[4], operands[5]))
15555    DONE;
15556  else
15557    FAIL;
15558 })
15559
15560 ;; Most CPUs don't like single string operations
15561 ;; Handle this case here to simplify previous expander.
15562
15563 (define_expand "strset"
15564   [(set (match_operand 1 "memory_operand" "")
15565         (match_operand 2 "register_operand" ""))
15566    (parallel [(set (match_operand 0 "register_operand" "")
15567                    (match_dup 3))
15568               (clobber (reg:CC FLAGS_REG))])]
15569   ""
15570 {
15571   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15572     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15573
15574   /* If .md ever supports :P for Pmode, this can be directly
15575      in the pattern above.  */
15576   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15577                               GEN_INT (GET_MODE_SIZE (GET_MODE
15578                                                       (operands[2]))));
15579   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15580     {
15581       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15582                                       operands[3]));
15583       DONE;
15584     }
15585 })
15586
15587 (define_expand "strset_singleop"
15588   [(parallel [(set (match_operand 1 "memory_operand" "")
15589                    (match_operand 2 "register_operand" ""))
15590               (set (match_operand 0 "register_operand" "")
15591                    (match_operand 3 "" ""))])]
15592   ""
15593   "ix86_current_function_needs_cld = 1;")
15594
15595 (define_insn "*strsetdi_rex_1"
15596   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15597         (match_operand:DI 2 "register_operand" "a"))
15598    (set (match_operand:DI 0 "register_operand" "=D")
15599         (plus:DI (match_dup 1)
15600                  (const_int 8)))]
15601   "TARGET_64BIT"
15602   "stosq"
15603   [(set_attr "type" "str")
15604    (set_attr "memory" "store")
15605    (set_attr "mode" "DI")])
15606
15607 (define_insn "*strsetsi_1"
15608   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15609         (match_operand:SI 2 "register_operand" "a"))
15610    (set (match_operand:P 0 "register_operand" "=D")
15611         (plus:P (match_dup 1)
15612                 (const_int 4)))]
15613   ""
15614   "stos{l|d}"
15615   [(set_attr "type" "str")
15616    (set_attr "memory" "store")
15617    (set_attr "mode" "SI")])
15618
15619 (define_insn "*strsethi_1"
15620   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15621         (match_operand:HI 2 "register_operand" "a"))
15622    (set (match_operand:P 0 "register_operand" "=D")
15623         (plus:P (match_dup 1)
15624                 (const_int 2)))]
15625   ""
15626   "stosw"
15627   [(set_attr "type" "str")
15628    (set_attr "memory" "store")
15629    (set_attr "mode" "HI")])
15630
15631 (define_insn "*strsetqi_1"
15632   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15633         (match_operand:QI 2 "register_operand" "a"))
15634    (set (match_operand:P 0 "register_operand" "=D")
15635         (plus:P (match_dup 1)
15636                 (const_int 1)))]
15637   ""
15638   "stosb"
15639   [(set_attr "type" "str")
15640    (set_attr "memory" "store")
15641    (set (attr "prefix_rex")
15642         (if_then_else
15643           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15644           (const_string "0")
15645           (const_string "*")))
15646    (set_attr "mode" "QI")])
15647
15648 (define_expand "rep_stos"
15649   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15650               (set (match_operand 0 "register_operand" "")
15651                    (match_operand 4 "" ""))
15652               (set (match_operand 2 "memory_operand" "") (const_int 0))
15653               (use (match_operand 3 "register_operand" ""))
15654               (use (match_dup 1))])]
15655   ""
15656   "ix86_current_function_needs_cld = 1;")
15657
15658 (define_insn "*rep_stosdi_rex64"
15659   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15660    (set (match_operand:DI 0 "register_operand" "=D")
15661         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15662                             (const_int 3))
15663                  (match_operand:DI 3 "register_operand" "0")))
15664    (set (mem:BLK (match_dup 3))
15665         (const_int 0))
15666    (use (match_operand:DI 2 "register_operand" "a"))
15667    (use (match_dup 4))]
15668   "TARGET_64BIT"
15669   "rep{%;} stosq"
15670   [(set_attr "type" "str")
15671    (set_attr "prefix_rep" "1")
15672    (set_attr "memory" "store")
15673    (set_attr "mode" "DI")])
15674
15675 (define_insn "*rep_stossi"
15676   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15677    (set (match_operand:P 0 "register_operand" "=D")
15678         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15679                           (const_int 2))
15680                  (match_operand:P 3 "register_operand" "0")))
15681    (set (mem:BLK (match_dup 3))
15682         (const_int 0))
15683    (use (match_operand:SI 2 "register_operand" "a"))
15684    (use (match_dup 4))]
15685   ""
15686   "rep{%;} stos{l|d}"
15687   [(set_attr "type" "str")
15688    (set_attr "prefix_rep" "1")
15689    (set_attr "memory" "store")
15690    (set_attr "mode" "SI")])
15691
15692 (define_insn "*rep_stosqi"
15693   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15694    (set (match_operand:P 0 "register_operand" "=D")
15695         (plus:P (match_operand:P 3 "register_operand" "0")
15696                 (match_operand:P 4 "register_operand" "1")))
15697    (set (mem:BLK (match_dup 3))
15698         (const_int 0))
15699    (use (match_operand:QI 2 "register_operand" "a"))
15700    (use (match_dup 4))]
15701   ""
15702   "rep{%;} stosb"
15703   [(set_attr "type" "str")
15704    (set_attr "prefix_rep" "1")
15705    (set_attr "memory" "store")
15706    (set (attr "prefix_rex")
15707         (if_then_else
15708           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15709           (const_string "0")
15710           (const_string "*")))
15711    (set_attr "mode" "QI")])
15712
15713 (define_expand "cmpstrnsi"
15714   [(set (match_operand:SI 0 "register_operand" "")
15715         (compare:SI (match_operand:BLK 1 "general_operand" "")
15716                     (match_operand:BLK 2 "general_operand" "")))
15717    (use (match_operand 3 "general_operand" ""))
15718    (use (match_operand 4 "immediate_operand" ""))]
15719   ""
15720 {
15721   rtx addr1, addr2, out, outlow, count, countreg, align;
15722
15723   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15724     FAIL;
15725
15726   /* Can't use this if the user has appropriated esi or edi.  */
15727   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15728     FAIL;
15729
15730   out = operands[0];
15731   if (!REG_P (out))
15732     out = gen_reg_rtx (SImode);
15733
15734   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15735   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15736   if (addr1 != XEXP (operands[1], 0))
15737     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15738   if (addr2 != XEXP (operands[2], 0))
15739     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15740
15741   count = operands[3];
15742   countreg = ix86_zero_extend_to_Pmode (count);
15743
15744   /* %%% Iff we are testing strict equality, we can use known alignment
15745      to good advantage.  This may be possible with combine, particularly
15746      once cc0 is dead.  */
15747   align = operands[4];
15748
15749   if (CONST_INT_P (count))
15750     {
15751       if (INTVAL (count) == 0)
15752         {
15753           emit_move_insn (operands[0], const0_rtx);
15754           DONE;
15755         }
15756       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15757                                      operands[1], operands[2]));
15758     }
15759   else
15760     {
15761       rtx (*gen_cmp) (rtx, rtx);
15762
15763       gen_cmp = (TARGET_64BIT
15764                  ? gen_cmpdi_1 : gen_cmpsi_1);
15765
15766       emit_insn (gen_cmp (countreg, countreg));
15767       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15768                                   operands[1], operands[2]));
15769     }
15770
15771   outlow = gen_lowpart (QImode, out);
15772   emit_insn (gen_cmpintqi (outlow));
15773   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15774
15775   if (operands[0] != out)
15776     emit_move_insn (operands[0], out);
15777
15778   DONE;
15779 })
15780
15781 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15782
15783 (define_expand "cmpintqi"
15784   [(set (match_dup 1)
15785         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15786    (set (match_dup 2)
15787         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15788    (parallel [(set (match_operand:QI 0 "register_operand" "")
15789                    (minus:QI (match_dup 1)
15790                              (match_dup 2)))
15791               (clobber (reg:CC FLAGS_REG))])]
15792   ""
15793 {
15794   operands[1] = gen_reg_rtx (QImode);
15795   operands[2] = gen_reg_rtx (QImode);
15796 })
15797
15798 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15799 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15800
15801 (define_expand "cmpstrnqi_nz_1"
15802   [(parallel [(set (reg:CC FLAGS_REG)
15803                    (compare:CC (match_operand 4 "memory_operand" "")
15804                                (match_operand 5 "memory_operand" "")))
15805               (use (match_operand 2 "register_operand" ""))
15806               (use (match_operand:SI 3 "immediate_operand" ""))
15807               (clobber (match_operand 0 "register_operand" ""))
15808               (clobber (match_operand 1 "register_operand" ""))
15809               (clobber (match_dup 2))])]
15810   ""
15811   "ix86_current_function_needs_cld = 1;")
15812
15813 (define_insn "*cmpstrnqi_nz_1"
15814   [(set (reg:CC FLAGS_REG)
15815         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15816                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15817    (use (match_operand:P 6 "register_operand" "2"))
15818    (use (match_operand:SI 3 "immediate_operand" "i"))
15819    (clobber (match_operand:P 0 "register_operand" "=S"))
15820    (clobber (match_operand:P 1 "register_operand" "=D"))
15821    (clobber (match_operand:P 2 "register_operand" "=c"))]
15822   ""
15823   "repz{%;} cmpsb"
15824   [(set_attr "type" "str")
15825    (set_attr "mode" "QI")
15826    (set (attr "prefix_rex")
15827         (if_then_else
15828           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15829           (const_string "0")
15830           (const_string "*")))
15831    (set_attr "prefix_rep" "1")])
15832
15833 ;; The same, but the count is not known to not be zero.
15834
15835 (define_expand "cmpstrnqi_1"
15836   [(parallel [(set (reg:CC FLAGS_REG)
15837                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15838                                      (const_int 0))
15839                   (compare:CC (match_operand 4 "memory_operand" "")
15840                               (match_operand 5 "memory_operand" ""))
15841                   (const_int 0)))
15842               (use (match_operand:SI 3 "immediate_operand" ""))
15843               (use (reg:CC FLAGS_REG))
15844               (clobber (match_operand 0 "register_operand" ""))
15845               (clobber (match_operand 1 "register_operand" ""))
15846               (clobber (match_dup 2))])]
15847   ""
15848   "ix86_current_function_needs_cld = 1;")
15849
15850 (define_insn "*cmpstrnqi_1"
15851   [(set (reg:CC FLAGS_REG)
15852         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15853                              (const_int 0))
15854           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15855                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15856           (const_int 0)))
15857    (use (match_operand:SI 3 "immediate_operand" "i"))
15858    (use (reg:CC FLAGS_REG))
15859    (clobber (match_operand:P 0 "register_operand" "=S"))
15860    (clobber (match_operand:P 1 "register_operand" "=D"))
15861    (clobber (match_operand:P 2 "register_operand" "=c"))]
15862   ""
15863   "repz{%;} cmpsb"
15864   [(set_attr "type" "str")
15865    (set_attr "mode" "QI")
15866    (set (attr "prefix_rex")
15867         (if_then_else
15868           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15869           (const_string "0")
15870           (const_string "*")))
15871    (set_attr "prefix_rep" "1")])
15872
15873 (define_expand "strlen<mode>"
15874   [(set (match_operand:SWI48x 0 "register_operand" "")
15875         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15876                         (match_operand:QI 2 "immediate_operand" "")
15877                         (match_operand 3 "immediate_operand" "")]
15878                        UNSPEC_SCAS))]
15879   ""
15880 {
15881  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15882    DONE;
15883  else
15884    FAIL;
15885 })
15886
15887 (define_expand "strlenqi_1"
15888   [(parallel [(set (match_operand 0 "register_operand" "")
15889                    (match_operand 2 "" ""))
15890               (clobber (match_operand 1 "register_operand" ""))
15891               (clobber (reg:CC FLAGS_REG))])]
15892   ""
15893   "ix86_current_function_needs_cld = 1;")
15894
15895 (define_insn "*strlenqi_1"
15896   [(set (match_operand:P 0 "register_operand" "=&c")
15897         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15898                    (match_operand:QI 2 "register_operand" "a")
15899                    (match_operand:P 3 "immediate_operand" "i")
15900                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15901    (clobber (match_operand:P 1 "register_operand" "=D"))
15902    (clobber (reg:CC FLAGS_REG))]
15903   ""
15904   "repnz{%;} scasb"
15905   [(set_attr "type" "str")
15906    (set_attr "mode" "QI")
15907    (set (attr "prefix_rex")
15908         (if_then_else
15909           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15910           (const_string "0")
15911           (const_string "*")))
15912    (set_attr "prefix_rep" "1")])
15913
15914 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15915 ;; handled in combine, but it is not currently up to the task.
15916 ;; When used for their truth value, the cmpstrn* expanders generate
15917 ;; code like this:
15918 ;;
15919 ;;   repz cmpsb
15920 ;;   seta       %al
15921 ;;   setb       %dl
15922 ;;   cmpb       %al, %dl
15923 ;;   jcc        label
15924 ;;
15925 ;; The intermediate three instructions are unnecessary.
15926
15927 ;; This one handles cmpstrn*_nz_1...
15928 (define_peephole2
15929   [(parallel[
15930      (set (reg:CC FLAGS_REG)
15931           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15932                       (mem:BLK (match_operand 5 "register_operand" ""))))
15933      (use (match_operand 6 "register_operand" ""))
15934      (use (match_operand:SI 3 "immediate_operand" ""))
15935      (clobber (match_operand 0 "register_operand" ""))
15936      (clobber (match_operand 1 "register_operand" ""))
15937      (clobber (match_operand 2 "register_operand" ""))])
15938    (set (match_operand:QI 7 "register_operand" "")
15939         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15940    (set (match_operand:QI 8 "register_operand" "")
15941         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15942    (set (reg FLAGS_REG)
15943         (compare (match_dup 7) (match_dup 8)))
15944   ]
15945   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15946   [(parallel[
15947      (set (reg:CC FLAGS_REG)
15948           (compare:CC (mem:BLK (match_dup 4))
15949                       (mem:BLK (match_dup 5))))
15950      (use (match_dup 6))
15951      (use (match_dup 3))
15952      (clobber (match_dup 0))
15953      (clobber (match_dup 1))
15954      (clobber (match_dup 2))])])
15955
15956 ;; ...and this one handles cmpstrn*_1.
15957 (define_peephole2
15958   [(parallel[
15959      (set (reg:CC FLAGS_REG)
15960           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15961                                (const_int 0))
15962             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15963                         (mem:BLK (match_operand 5 "register_operand" "")))
15964             (const_int 0)))
15965      (use (match_operand:SI 3 "immediate_operand" ""))
15966      (use (reg:CC FLAGS_REG))
15967      (clobber (match_operand 0 "register_operand" ""))
15968      (clobber (match_operand 1 "register_operand" ""))
15969      (clobber (match_operand 2 "register_operand" ""))])
15970    (set (match_operand:QI 7 "register_operand" "")
15971         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15972    (set (match_operand:QI 8 "register_operand" "")
15973         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15974    (set (reg FLAGS_REG)
15975         (compare (match_dup 7) (match_dup 8)))
15976   ]
15977   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15978   [(parallel[
15979      (set (reg:CC FLAGS_REG)
15980           (if_then_else:CC (ne (match_dup 6)
15981                                (const_int 0))
15982             (compare:CC (mem:BLK (match_dup 4))
15983                         (mem:BLK (match_dup 5)))
15984             (const_int 0)))
15985      (use (match_dup 3))
15986      (use (reg:CC FLAGS_REG))
15987      (clobber (match_dup 0))
15988      (clobber (match_dup 1))
15989      (clobber (match_dup 2))])])
15990 \f
15991 ;; Conditional move instructions.
15992
15993 (define_expand "mov<mode>cc"
15994   [(set (match_operand:SWIM 0 "register_operand" "")
15995         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15996                            (match_operand:SWIM 2 "general_operand" "")
15997                            (match_operand:SWIM 3 "general_operand" "")))]
15998   ""
15999   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16000
16001 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16002 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16003 ;; So just document what we're doing explicitly.
16004
16005 (define_expand "x86_mov<mode>cc_0_m1"
16006   [(parallel
16007     [(set (match_operand:SWI48 0 "register_operand" "")
16008           (if_then_else:SWI48
16009             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16010              [(match_operand 1 "flags_reg_operand" "")
16011               (const_int 0)])
16012             (const_int -1)
16013             (const_int 0)))
16014      (clobber (reg:CC FLAGS_REG))])])
16015
16016 (define_insn "*x86_mov<mode>cc_0_m1"
16017   [(set (match_operand:SWI48 0 "register_operand" "=r")
16018         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16019                              [(reg FLAGS_REG) (const_int 0)])
16020           (const_int -1)
16021           (const_int 0)))
16022    (clobber (reg:CC FLAGS_REG))]
16023   ""
16024   "sbb{<imodesuffix>}\t%0, %0"
16025   ; Since we don't have the proper number of operands for an alu insn,
16026   ; fill in all the blanks.
16027   [(set_attr "type" "alu")
16028    (set_attr "use_carry" "1")
16029    (set_attr "pent_pair" "pu")
16030    (set_attr "memory" "none")
16031    (set_attr "imm_disp" "false")
16032    (set_attr "mode" "<MODE>")
16033    (set_attr "length_immediate" "0")])
16034
16035 (define_insn "*x86_mov<mode>cc_0_m1_se"
16036   [(set (match_operand:SWI48 0 "register_operand" "=r")
16037         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16038                              [(reg FLAGS_REG) (const_int 0)])
16039                             (const_int 1)
16040                             (const_int 0)))
16041    (clobber (reg:CC FLAGS_REG))]
16042   ""
16043   "sbb{<imodesuffix>}\t%0, %0"
16044   [(set_attr "type" "alu")
16045    (set_attr "use_carry" "1")
16046    (set_attr "pent_pair" "pu")
16047    (set_attr "memory" "none")
16048    (set_attr "imm_disp" "false")
16049    (set_attr "mode" "<MODE>")
16050    (set_attr "length_immediate" "0")])
16051
16052 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16053   [(set (match_operand:SWI48 0 "register_operand" "=r")
16054         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16055                     [(reg FLAGS_REG) (const_int 0)])))]
16056   ""
16057   "sbb{<imodesuffix>}\t%0, %0"
16058   [(set_attr "type" "alu")
16059    (set_attr "use_carry" "1")
16060    (set_attr "pent_pair" "pu")
16061    (set_attr "memory" "none")
16062    (set_attr "imm_disp" "false")
16063    (set_attr "mode" "<MODE>")
16064    (set_attr "length_immediate" "0")])
16065
16066 (define_insn "*mov<mode>cc_noc"
16067   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16068         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16069                                [(reg FLAGS_REG) (const_int 0)])
16070           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16071           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16072   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16073   "@
16074    cmov%O2%C1\t{%2, %0|%0, %2}
16075    cmov%O2%c1\t{%3, %0|%0, %3}"
16076   [(set_attr "type" "icmov")
16077    (set_attr "mode" "<MODE>")])
16078
16079 (define_insn_and_split "*movqicc_noc"
16080   [(set (match_operand:QI 0 "register_operand" "=r,r")
16081         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16082                            [(match_operand 4 "flags_reg_operand" "")
16083                             (const_int 0)])
16084                       (match_operand:QI 2 "register_operand" "r,0")
16085                       (match_operand:QI 3 "register_operand" "0,r")))]
16086   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16087   "#"
16088   "&& reload_completed"
16089   [(set (match_dup 0)
16090         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16091                       (match_dup 2)
16092                       (match_dup 3)))]
16093   "operands[0] = gen_lowpart (SImode, operands[0]);
16094    operands[2] = gen_lowpart (SImode, operands[2]);
16095    operands[3] = gen_lowpart (SImode, operands[3]);"
16096   [(set_attr "type" "icmov")
16097    (set_attr "mode" "SI")])
16098
16099 (define_expand "mov<mode>cc"
16100   [(set (match_operand:X87MODEF 0 "register_operand" "")
16101         (if_then_else:X87MODEF
16102           (match_operand 1 "ix86_fp_comparison_operator" "")
16103           (match_operand:X87MODEF 2 "register_operand" "")
16104           (match_operand:X87MODEF 3 "register_operand" "")))]
16105   "(TARGET_80387 && TARGET_CMOVE)
16106    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16107   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16108
16109 (define_insn "*movxfcc_1"
16110   [(set (match_operand:XF 0 "register_operand" "=f,f")
16111         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16112                                 [(reg FLAGS_REG) (const_int 0)])
16113                       (match_operand:XF 2 "register_operand" "f,0")
16114                       (match_operand:XF 3 "register_operand" "0,f")))]
16115   "TARGET_80387 && TARGET_CMOVE"
16116   "@
16117    fcmov%F1\t{%2, %0|%0, %2}
16118    fcmov%f1\t{%3, %0|%0, %3}"
16119   [(set_attr "type" "fcmov")
16120    (set_attr "mode" "XF")])
16121
16122 (define_insn "*movdfcc_1_rex64"
16123   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16124         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16125                                 [(reg FLAGS_REG) (const_int 0)])
16126                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16127                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16128   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16129    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16130   "@
16131    fcmov%F1\t{%2, %0|%0, %2}
16132    fcmov%f1\t{%3, %0|%0, %3}
16133    cmov%O2%C1\t{%2, %0|%0, %2}
16134    cmov%O2%c1\t{%3, %0|%0, %3}"
16135   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16136    (set_attr "mode" "DF,DF,DI,DI")])
16137
16138 (define_insn "*movdfcc_1"
16139   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16140         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16141                                 [(reg FLAGS_REG) (const_int 0)])
16142                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16143                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16144   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16145    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16146   "@
16147    fcmov%F1\t{%2, %0|%0, %2}
16148    fcmov%f1\t{%3, %0|%0, %3}
16149    #
16150    #"
16151   [(set_attr "type" "fcmov,fcmov,multi,multi")
16152    (set_attr "mode" "DF,DF,DI,DI")])
16153
16154 (define_split
16155   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16156         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16157                                 [(match_operand 4 "flags_reg_operand" "")
16158                                  (const_int 0)])
16159                       (match_operand:DF 2 "nonimmediate_operand" "")
16160                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16161   "!TARGET_64BIT && reload_completed"
16162   [(set (match_dup 2)
16163         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16164                       (match_dup 5)
16165                       (match_dup 6)))
16166    (set (match_dup 3)
16167         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16168                       (match_dup 7)
16169                       (match_dup 8)))]
16170 {
16171   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16172   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16173 })
16174
16175 (define_insn "*movsfcc_1_387"
16176   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16177         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16178                                 [(reg FLAGS_REG) (const_int 0)])
16179                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16180                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16181   "TARGET_80387 && TARGET_CMOVE
16182    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16183   "@
16184    fcmov%F1\t{%2, %0|%0, %2}
16185    fcmov%f1\t{%3, %0|%0, %3}
16186    cmov%O2%C1\t{%2, %0|%0, %2}
16187    cmov%O2%c1\t{%3, %0|%0, %3}"
16188   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16189    (set_attr "mode" "SF,SF,SI,SI")])
16190
16191 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16192 ;; the scalar versions to have only XMM registers as operands.
16193
16194 ;; XOP conditional move
16195 (define_insn "*xop_pcmov_<mode>"
16196   [(set (match_operand:MODEF 0 "register_operand" "=x")
16197         (if_then_else:MODEF
16198           (match_operand:MODEF 1 "register_operand" "x")
16199           (match_operand:MODEF 2 "register_operand" "x")
16200           (match_operand:MODEF 3 "register_operand" "x")))]
16201   "TARGET_XOP"
16202   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16203   [(set_attr "type" "sse4arg")])
16204
16205 ;; These versions of the min/max patterns are intentionally ignorant of
16206 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16207 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16208 ;; are undefined in this condition, we're certain this is correct.
16209
16210 (define_insn "<code><mode>3"
16211   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16212         (smaxmin:MODEF
16213           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16214           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16215   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16216   "@
16217    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16218    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16219   [(set_attr "isa" "noavx,avx")
16220    (set_attr "prefix" "orig,vex")
16221    (set_attr "type" "sseadd")
16222    (set_attr "mode" "<MODE>")])
16223
16224 ;; These versions of the min/max patterns implement exactly the operations
16225 ;;   min = (op1 < op2 ? op1 : op2)
16226 ;;   max = (!(op1 < op2) ? op1 : op2)
16227 ;; Their operands are not commutative, and thus they may be used in the
16228 ;; presence of -0.0 and NaN.
16229
16230 (define_insn "*ieee_smin<mode>3"
16231   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16232         (unspec:MODEF
16233           [(match_operand:MODEF 1 "register_operand" "0,x")
16234            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16235          UNSPEC_IEEE_MIN))]
16236   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16237   "@
16238    min<ssemodesuffix>\t{%2, %0|%0, %2}
16239    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16240   [(set_attr "isa" "noavx,avx")
16241    (set_attr "prefix" "orig,vex")
16242    (set_attr "type" "sseadd")
16243    (set_attr "mode" "<MODE>")])
16244
16245 (define_insn "*ieee_smax<mode>3"
16246   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16247         (unspec:MODEF
16248           [(match_operand:MODEF 1 "register_operand" "0,x")
16249            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16250          UNSPEC_IEEE_MAX))]
16251   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16252   "@
16253    max<ssemodesuffix>\t{%2, %0|%0, %2}
16254    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16255   [(set_attr "isa" "noavx,avx")
16256    (set_attr "prefix" "orig,vex")
16257    (set_attr "type" "sseadd")
16258    (set_attr "mode" "<MODE>")])
16259
16260 ;; Make two stack loads independent:
16261 ;;   fld aa              fld aa
16262 ;;   fld %st(0)     ->   fld bb
16263 ;;   fmul bb             fmul %st(1), %st
16264 ;;
16265 ;; Actually we only match the last two instructions for simplicity.
16266 (define_peephole2
16267   [(set (match_operand 0 "fp_register_operand" "")
16268         (match_operand 1 "fp_register_operand" ""))
16269    (set (match_dup 0)
16270         (match_operator 2 "binary_fp_operator"
16271            [(match_dup 0)
16272             (match_operand 3 "memory_operand" "")]))]
16273   "REGNO (operands[0]) != REGNO (operands[1])"
16274   [(set (match_dup 0) (match_dup 3))
16275    (set (match_dup 0) (match_dup 4))]
16276
16277   ;; The % modifier is not operational anymore in peephole2's, so we have to
16278   ;; swap the operands manually in the case of addition and multiplication.
16279   "if (COMMUTATIVE_ARITH_P (operands[2]))
16280      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16281                                    GET_MODE (operands[2]),
16282                                    operands[0], operands[1]);
16283    else
16284      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16285                                    GET_MODE (operands[2]),
16286                                    operands[1], operands[0]);")
16287
16288 ;; Conditional addition patterns
16289 (define_expand "add<mode>cc"
16290   [(match_operand:SWI 0 "register_operand" "")
16291    (match_operand 1 "ordered_comparison_operator" "")
16292    (match_operand:SWI 2 "register_operand" "")
16293    (match_operand:SWI 3 "const_int_operand" "")]
16294   ""
16295   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16296 \f
16297 ;; Misc patterns (?)
16298
16299 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16300 ;; Otherwise there will be nothing to keep
16301 ;;
16302 ;; [(set (reg ebp) (reg esp))]
16303 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16304 ;;  (clobber (eflags)]
16305 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16306 ;;
16307 ;; in proper program order.
16308
16309 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16310   [(set (match_operand:P 0 "register_operand" "=r,r")
16311         (plus:P (match_operand:P 1 "register_operand" "0,r")
16312                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16313    (clobber (reg:CC FLAGS_REG))
16314    (clobber (mem:BLK (scratch)))]
16315   ""
16316 {
16317   switch (get_attr_type (insn))
16318     {
16319     case TYPE_IMOV:
16320       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16321
16322     case TYPE_ALU:
16323       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16324       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16325         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16326
16327       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16328
16329     default:
16330       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16331       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16332     }
16333 }
16334   [(set (attr "type")
16335         (cond [(and (eq_attr "alternative" "0")
16336                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16337                  (const_string "alu")
16338                (match_operand:<MODE> 2 "const0_operand" "")
16339                  (const_string "imov")
16340               ]
16341               (const_string "lea")))
16342    (set (attr "length_immediate")
16343         (cond [(eq_attr "type" "imov")
16344                  (const_string "0")
16345                (and (eq_attr "type" "alu")
16346                     (match_operand 2 "const128_operand" ""))
16347                  (const_string "1")
16348               ]
16349               (const_string "*")))
16350    (set_attr "mode" "<MODE>")])
16351
16352 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16353   [(set (match_operand:P 0 "register_operand" "=r")
16354         (minus:P (match_operand:P 1 "register_operand" "0")
16355                  (match_operand:P 2 "register_operand" "r")))
16356    (clobber (reg:CC FLAGS_REG))
16357    (clobber (mem:BLK (scratch)))]
16358   ""
16359   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16360   [(set_attr "type" "alu")
16361    (set_attr "mode" "<MODE>")])
16362
16363 (define_insn "allocate_stack_worker_probe_<mode>"
16364   [(set (match_operand:P 0 "register_operand" "=a")
16365         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16366                             UNSPECV_STACK_PROBE))
16367    (clobber (reg:CC FLAGS_REG))]
16368   "ix86_target_stack_probe ()"
16369   "call\t___chkstk_ms"
16370   [(set_attr "type" "multi")
16371    (set_attr "length" "5")])
16372
16373 (define_expand "allocate_stack"
16374   [(match_operand 0 "register_operand" "")
16375    (match_operand 1 "general_operand" "")]
16376   "ix86_target_stack_probe ()"
16377 {
16378   rtx x;
16379
16380 #ifndef CHECK_STACK_LIMIT
16381 #define CHECK_STACK_LIMIT 0
16382 #endif
16383
16384   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16385       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16386     {
16387       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16388                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16389       if (x != stack_pointer_rtx)
16390         emit_move_insn (stack_pointer_rtx, x);
16391     }
16392   else
16393     {
16394       x = copy_to_mode_reg (Pmode, operands[1]);
16395       if (TARGET_64BIT)
16396         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16397       else
16398         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16399       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16400                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16401       if (x != stack_pointer_rtx)
16402         emit_move_insn (stack_pointer_rtx, x);
16403     }
16404
16405   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16406   DONE;
16407 })
16408
16409 ;; Use IOR for stack probes, this is shorter.
16410 (define_expand "probe_stack"
16411   [(match_operand 0 "memory_operand" "")]
16412   ""
16413 {
16414   rtx (*gen_ior3) (rtx, rtx, rtx);
16415
16416   gen_ior3 = (GET_MODE (operands[0]) == DImode
16417               ? gen_iordi3 : gen_iorsi3);
16418
16419   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16420   DONE;
16421 })
16422
16423 (define_insn "adjust_stack_and_probe<mode>"
16424   [(set (match_operand:P 0 "register_operand" "=r")
16425         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16426                             UNSPECV_PROBE_STACK_RANGE))
16427    (set (reg:P SP_REG)
16428         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16429    (clobber (reg:CC FLAGS_REG))
16430    (clobber (mem:BLK (scratch)))]
16431   ""
16432   "* return output_adjust_stack_and_probe (operands[0]);"
16433   [(set_attr "type" "multi")])
16434
16435 (define_insn "probe_stack_range<mode>"
16436   [(set (match_operand:P 0 "register_operand" "=r")
16437         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16438                             (match_operand:P 2 "const_int_operand" "n")]
16439                             UNSPECV_PROBE_STACK_RANGE))
16440    (clobber (reg:CC FLAGS_REG))]
16441   ""
16442   "* return output_probe_stack_range (operands[0], operands[2]);"
16443   [(set_attr "type" "multi")])
16444
16445 (define_expand "builtin_setjmp_receiver"
16446   [(label_ref (match_operand 0 "" ""))]
16447   "!TARGET_64BIT && flag_pic"
16448 {
16449 #if TARGET_MACHO
16450   if (TARGET_MACHO)
16451     {
16452       rtx xops[3];
16453       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16454       rtx label_rtx = gen_label_rtx ();
16455       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16456       xops[0] = xops[1] = picreg;
16457       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16458       ix86_expand_binary_operator (MINUS, SImode, xops);
16459     }
16460   else
16461 #endif
16462     emit_insn (gen_set_got (pic_offset_table_rtx));
16463   DONE;
16464 })
16465 \f
16466 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16467
16468 (define_split
16469   [(set (match_operand 0 "register_operand" "")
16470         (match_operator 3 "promotable_binary_operator"
16471            [(match_operand 1 "register_operand" "")
16472             (match_operand 2 "aligned_operand" "")]))
16473    (clobber (reg:CC FLAGS_REG))]
16474   "! TARGET_PARTIAL_REG_STALL && reload_completed
16475    && ((GET_MODE (operands[0]) == HImode
16476         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16477             /* ??? next two lines just !satisfies_constraint_K (...) */
16478             || !CONST_INT_P (operands[2])
16479             || satisfies_constraint_K (operands[2])))
16480        || (GET_MODE (operands[0]) == QImode
16481            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16482   [(parallel [(set (match_dup 0)
16483                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16484               (clobber (reg:CC FLAGS_REG))])]
16485   "operands[0] = gen_lowpart (SImode, operands[0]);
16486    operands[1] = gen_lowpart (SImode, operands[1]);
16487    if (GET_CODE (operands[3]) != ASHIFT)
16488      operands[2] = gen_lowpart (SImode, operands[2]);
16489    PUT_MODE (operands[3], SImode);")
16490
16491 ; Promote the QImode tests, as i386 has encoding of the AND
16492 ; instruction with 32-bit sign-extended immediate and thus the
16493 ; instruction size is unchanged, except in the %eax case for
16494 ; which it is increased by one byte, hence the ! optimize_size.
16495 (define_split
16496   [(set (match_operand 0 "flags_reg_operand" "")
16497         (match_operator 2 "compare_operator"
16498           [(and (match_operand 3 "aligned_operand" "")
16499                 (match_operand 4 "const_int_operand" ""))
16500            (const_int 0)]))
16501    (set (match_operand 1 "register_operand" "")
16502         (and (match_dup 3) (match_dup 4)))]
16503   "! TARGET_PARTIAL_REG_STALL && reload_completed
16504    && optimize_insn_for_speed_p ()
16505    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16506        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16507    /* Ensure that the operand will remain sign-extended immediate.  */
16508    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16509   [(parallel [(set (match_dup 0)
16510                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16511                                     (const_int 0)]))
16512               (set (match_dup 1)
16513                    (and:SI (match_dup 3) (match_dup 4)))])]
16514 {
16515   operands[4]
16516     = gen_int_mode (INTVAL (operands[4])
16517                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16518   operands[1] = gen_lowpart (SImode, operands[1]);
16519   operands[3] = gen_lowpart (SImode, operands[3]);
16520 })
16521
16522 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16523 ; the TEST instruction with 32-bit sign-extended immediate and thus
16524 ; the instruction size would at least double, which is not what we
16525 ; want even with ! optimize_size.
16526 (define_split
16527   [(set (match_operand 0 "flags_reg_operand" "")
16528         (match_operator 1 "compare_operator"
16529           [(and (match_operand:HI 2 "aligned_operand" "")
16530                 (match_operand:HI 3 "const_int_operand" ""))
16531            (const_int 0)]))]
16532   "! TARGET_PARTIAL_REG_STALL && reload_completed
16533    && ! TARGET_FAST_PREFIX
16534    && optimize_insn_for_speed_p ()
16535    /* Ensure that the operand will remain sign-extended immediate.  */
16536    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16537   [(set (match_dup 0)
16538         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16539                          (const_int 0)]))]
16540 {
16541   operands[3]
16542     = gen_int_mode (INTVAL (operands[3])
16543                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16544   operands[2] = gen_lowpart (SImode, operands[2]);
16545 })
16546
16547 (define_split
16548   [(set (match_operand 0 "register_operand" "")
16549         (neg (match_operand 1 "register_operand" "")))
16550    (clobber (reg:CC FLAGS_REG))]
16551   "! TARGET_PARTIAL_REG_STALL && reload_completed
16552    && (GET_MODE (operands[0]) == HImode
16553        || (GET_MODE (operands[0]) == QImode
16554            && (TARGET_PROMOTE_QImode
16555                || optimize_insn_for_size_p ())))"
16556   [(parallel [(set (match_dup 0)
16557                    (neg:SI (match_dup 1)))
16558               (clobber (reg:CC FLAGS_REG))])]
16559   "operands[0] = gen_lowpart (SImode, operands[0]);
16560    operands[1] = gen_lowpart (SImode, operands[1]);")
16561
16562 (define_split
16563   [(set (match_operand 0 "register_operand" "")
16564         (not (match_operand 1 "register_operand" "")))]
16565   "! TARGET_PARTIAL_REG_STALL && reload_completed
16566    && (GET_MODE (operands[0]) == HImode
16567        || (GET_MODE (operands[0]) == QImode
16568            && (TARGET_PROMOTE_QImode
16569                || optimize_insn_for_size_p ())))"
16570   [(set (match_dup 0)
16571         (not:SI (match_dup 1)))]
16572   "operands[0] = gen_lowpart (SImode, operands[0]);
16573    operands[1] = gen_lowpart (SImode, operands[1]);")
16574
16575 (define_split
16576   [(set (match_operand 0 "register_operand" "")
16577         (if_then_else (match_operator 1 "ordered_comparison_operator"
16578                                 [(reg FLAGS_REG) (const_int 0)])
16579                       (match_operand 2 "register_operand" "")
16580                       (match_operand 3 "register_operand" "")))]
16581   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16582    && (GET_MODE (operands[0]) == HImode
16583        || (GET_MODE (operands[0]) == QImode
16584            && (TARGET_PROMOTE_QImode
16585                || optimize_insn_for_size_p ())))"
16586   [(set (match_dup 0)
16587         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16588   "operands[0] = gen_lowpart (SImode, operands[0]);
16589    operands[2] = gen_lowpart (SImode, operands[2]);
16590    operands[3] = gen_lowpart (SImode, operands[3]);")
16591 \f
16592 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16593 ;; transform a complex memory operation into two memory to register operations.
16594
16595 ;; Don't push memory operands
16596 (define_peephole2
16597   [(set (match_operand:SWI 0 "push_operand" "")
16598         (match_operand:SWI 1 "memory_operand" ""))
16599    (match_scratch:SWI 2 "<r>")]
16600   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16601    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16602   [(set (match_dup 2) (match_dup 1))
16603    (set (match_dup 0) (match_dup 2))])
16604
16605 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16606 ;; SImode pushes.
16607 (define_peephole2
16608   [(set (match_operand:SF 0 "push_operand" "")
16609         (match_operand:SF 1 "memory_operand" ""))
16610    (match_scratch:SF 2 "r")]
16611   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16612    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16613   [(set (match_dup 2) (match_dup 1))
16614    (set (match_dup 0) (match_dup 2))])
16615
16616 ;; Don't move an immediate directly to memory when the instruction
16617 ;; gets too big.
16618 (define_peephole2
16619   [(match_scratch:SWI124 1 "<r>")
16620    (set (match_operand:SWI124 0 "memory_operand" "")
16621         (const_int 0))]
16622   "optimize_insn_for_speed_p ()
16623    && !TARGET_USE_MOV0
16624    && TARGET_SPLIT_LONG_MOVES
16625    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16626    && peep2_regno_dead_p (0, FLAGS_REG)"
16627   [(parallel [(set (match_dup 2) (const_int 0))
16628               (clobber (reg:CC FLAGS_REG))])
16629    (set (match_dup 0) (match_dup 1))]
16630   "operands[2] = gen_lowpart (SImode, operands[1]);")
16631
16632 (define_peephole2
16633   [(match_scratch:SWI124 2 "<r>")
16634    (set (match_operand:SWI124 0 "memory_operand" "")
16635         (match_operand:SWI124 1 "immediate_operand" ""))]
16636   "optimize_insn_for_speed_p ()
16637    && TARGET_SPLIT_LONG_MOVES
16638    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16639   [(set (match_dup 2) (match_dup 1))
16640    (set (match_dup 0) (match_dup 2))])
16641
16642 ;; Don't compare memory with zero, load and use a test instead.
16643 (define_peephole2
16644   [(set (match_operand 0 "flags_reg_operand" "")
16645         (match_operator 1 "compare_operator"
16646           [(match_operand:SI 2 "memory_operand" "")
16647            (const_int 0)]))
16648    (match_scratch:SI 3 "r")]
16649   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16650   [(set (match_dup 3) (match_dup 2))
16651    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16652
16653 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16654 ;; Don't split NOTs with a displacement operand, because resulting XOR
16655 ;; will not be pairable anyway.
16656 ;;
16657 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16658 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16659 ;; so this split helps here as well.
16660 ;;
16661 ;; Note: Can't do this as a regular split because we can't get proper
16662 ;; lifetime information then.
16663
16664 (define_peephole2
16665   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16666         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16667   "optimize_insn_for_speed_p ()
16668    && ((TARGET_NOT_UNPAIRABLE
16669         && (!MEM_P (operands[0])
16670             || !memory_displacement_operand (operands[0], <MODE>mode)))
16671        || (TARGET_NOT_VECTORMODE
16672            && long_memory_operand (operands[0], <MODE>mode)))
16673    && peep2_regno_dead_p (0, FLAGS_REG)"
16674   [(parallel [(set (match_dup 0)
16675                    (xor:SWI124 (match_dup 1) (const_int -1)))
16676               (clobber (reg:CC FLAGS_REG))])])
16677
16678 ;; Non pairable "test imm, reg" instructions can be translated to
16679 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16680 ;; byte opcode instead of two, have a short form for byte operands),
16681 ;; so do it for other CPUs as well.  Given that the value was dead,
16682 ;; this should not create any new dependencies.  Pass on the sub-word
16683 ;; versions if we're concerned about partial register stalls.
16684
16685 (define_peephole2
16686   [(set (match_operand 0 "flags_reg_operand" "")
16687         (match_operator 1 "compare_operator"
16688           [(and:SI (match_operand:SI 2 "register_operand" "")
16689                    (match_operand:SI 3 "immediate_operand" ""))
16690            (const_int 0)]))]
16691   "ix86_match_ccmode (insn, CCNOmode)
16692    && (true_regnum (operands[2]) != AX_REG
16693        || satisfies_constraint_K (operands[3]))
16694    && peep2_reg_dead_p (1, operands[2])"
16695   [(parallel
16696      [(set (match_dup 0)
16697            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16698                             (const_int 0)]))
16699       (set (match_dup 2)
16700            (and:SI (match_dup 2) (match_dup 3)))])])
16701
16702 ;; We don't need to handle HImode case, because it will be promoted to SImode
16703 ;; on ! TARGET_PARTIAL_REG_STALL
16704
16705 (define_peephole2
16706   [(set (match_operand 0 "flags_reg_operand" "")
16707         (match_operator 1 "compare_operator"
16708           [(and:QI (match_operand:QI 2 "register_operand" "")
16709                    (match_operand:QI 3 "immediate_operand" ""))
16710            (const_int 0)]))]
16711   "! TARGET_PARTIAL_REG_STALL
16712    && ix86_match_ccmode (insn, CCNOmode)
16713    && true_regnum (operands[2]) != AX_REG
16714    && peep2_reg_dead_p (1, operands[2])"
16715   [(parallel
16716      [(set (match_dup 0)
16717            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16718                             (const_int 0)]))
16719       (set (match_dup 2)
16720            (and:QI (match_dup 2) (match_dup 3)))])])
16721
16722 (define_peephole2
16723   [(set (match_operand 0 "flags_reg_operand" "")
16724         (match_operator 1 "compare_operator"
16725           [(and:SI
16726              (zero_extract:SI
16727                (match_operand 2 "ext_register_operand" "")
16728                (const_int 8)
16729                (const_int 8))
16730              (match_operand 3 "const_int_operand" ""))
16731            (const_int 0)]))]
16732   "! TARGET_PARTIAL_REG_STALL
16733    && ix86_match_ccmode (insn, CCNOmode)
16734    && true_regnum (operands[2]) != AX_REG
16735    && peep2_reg_dead_p (1, operands[2])"
16736   [(parallel [(set (match_dup 0)
16737                    (match_op_dup 1
16738                      [(and:SI
16739                         (zero_extract:SI
16740                           (match_dup 2)
16741                           (const_int 8)
16742                           (const_int 8))
16743                         (match_dup 3))
16744                       (const_int 0)]))
16745               (set (zero_extract:SI (match_dup 2)
16746                                     (const_int 8)
16747                                     (const_int 8))
16748                    (and:SI
16749                      (zero_extract:SI
16750                        (match_dup 2)
16751                        (const_int 8)
16752                        (const_int 8))
16753                      (match_dup 3)))])])
16754
16755 ;; Don't do logical operations with memory inputs.
16756 (define_peephole2
16757   [(match_scratch:SI 2 "r")
16758    (parallel [(set (match_operand:SI 0 "register_operand" "")
16759                    (match_operator:SI 3 "arith_or_logical_operator"
16760                      [(match_dup 0)
16761                       (match_operand:SI 1 "memory_operand" "")]))
16762               (clobber (reg:CC FLAGS_REG))])]
16763   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16764   [(set (match_dup 2) (match_dup 1))
16765    (parallel [(set (match_dup 0)
16766                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16767               (clobber (reg:CC FLAGS_REG))])])
16768
16769 (define_peephole2
16770   [(match_scratch:SI 2 "r")
16771    (parallel [(set (match_operand:SI 0 "register_operand" "")
16772                    (match_operator:SI 3 "arith_or_logical_operator"
16773                      [(match_operand:SI 1 "memory_operand" "")
16774                       (match_dup 0)]))
16775               (clobber (reg:CC FLAGS_REG))])]
16776   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16777   [(set (match_dup 2) (match_dup 1))
16778    (parallel [(set (match_dup 0)
16779                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16780               (clobber (reg:CC FLAGS_REG))])])
16781
16782 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16783 ;; refers to the destination of the load!
16784
16785 (define_peephole2
16786   [(set (match_operand:SI 0 "register_operand" "")
16787         (match_operand:SI 1 "register_operand" ""))
16788    (parallel [(set (match_dup 0)
16789                    (match_operator:SI 3 "commutative_operator"
16790                      [(match_dup 0)
16791                       (match_operand:SI 2 "memory_operand" "")]))
16792               (clobber (reg:CC FLAGS_REG))])]
16793   "REGNO (operands[0]) != REGNO (operands[1])
16794    && GENERAL_REGNO_P (REGNO (operands[0]))
16795    && GENERAL_REGNO_P (REGNO (operands[1]))"
16796   [(set (match_dup 0) (match_dup 4))
16797    (parallel [(set (match_dup 0)
16798                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16799               (clobber (reg:CC FLAGS_REG))])]
16800   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16801
16802 (define_peephole2
16803   [(set (match_operand 0 "register_operand" "")
16804         (match_operand 1 "register_operand" ""))
16805    (set (match_dup 0)
16806                    (match_operator 3 "commutative_operator"
16807                      [(match_dup 0)
16808                       (match_operand 2 "memory_operand" "")]))]
16809   "REGNO (operands[0]) != REGNO (operands[1])
16810    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16811        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16812   [(set (match_dup 0) (match_dup 2))
16813    (set (match_dup 0)
16814         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16815
16816 ; Don't do logical operations with memory outputs
16817 ;
16818 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16819 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16820 ; the same decoder scheduling characteristics as the original.
16821
16822 (define_peephole2
16823   [(match_scratch:SI 2 "r")
16824    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16825                    (match_operator:SI 3 "arith_or_logical_operator"
16826                      [(match_dup 0)
16827                       (match_operand:SI 1 "nonmemory_operand" "")]))
16828               (clobber (reg:CC FLAGS_REG))])]
16829   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16830    /* Do not split stack checking probes.  */
16831    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16832   [(set (match_dup 2) (match_dup 0))
16833    (parallel [(set (match_dup 2)
16834                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16835               (clobber (reg:CC FLAGS_REG))])
16836    (set (match_dup 0) (match_dup 2))])
16837
16838 (define_peephole2
16839   [(match_scratch:SI 2 "r")
16840    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16841                    (match_operator:SI 3 "arith_or_logical_operator"
16842                      [(match_operand:SI 1 "nonmemory_operand" "")
16843                       (match_dup 0)]))
16844               (clobber (reg:CC FLAGS_REG))])]
16845   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16846    /* Do not split stack checking probes.  */
16847    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16848   [(set (match_dup 2) (match_dup 0))
16849    (parallel [(set (match_dup 2)
16850                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16851               (clobber (reg:CC FLAGS_REG))])
16852    (set (match_dup 0) (match_dup 2))])
16853
16854 ;; Attempt to always use XOR for zeroing registers.
16855 (define_peephole2
16856   [(set (match_operand 0 "register_operand" "")
16857         (match_operand 1 "const0_operand" ""))]
16858   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16859    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16860    && GENERAL_REG_P (operands[0])
16861    && peep2_regno_dead_p (0, FLAGS_REG)"
16862   [(parallel [(set (match_dup 0) (const_int 0))
16863               (clobber (reg:CC FLAGS_REG))])]
16864   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16865
16866 (define_peephole2
16867   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16868         (const_int 0))]
16869   "(GET_MODE (operands[0]) == QImode
16870     || GET_MODE (operands[0]) == HImode)
16871    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16872    && peep2_regno_dead_p (0, FLAGS_REG)"
16873   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16874               (clobber (reg:CC FLAGS_REG))])])
16875
16876 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16877 (define_peephole2
16878   [(set (match_operand:SWI248 0 "register_operand" "")
16879         (const_int -1))]
16880   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16881    && peep2_regno_dead_p (0, FLAGS_REG)"
16882   [(parallel [(set (match_dup 0) (const_int -1))
16883               (clobber (reg:CC FLAGS_REG))])]
16884 {
16885   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16886     operands[0] = gen_lowpart (SImode, operands[0]);
16887 })
16888
16889 ;; Attempt to convert simple lea to add/shift.
16890 ;; These can be created by move expanders.
16891
16892 (define_peephole2
16893   [(set (match_operand:SWI48 0 "register_operand" "")
16894         (plus:SWI48 (match_dup 0)
16895                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16896   "peep2_regno_dead_p (0, FLAGS_REG)"
16897   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16898               (clobber (reg:CC FLAGS_REG))])])
16899
16900 (define_peephole2
16901   [(set (match_operand:SI 0 "register_operand" "")
16902         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16903                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16904   "TARGET_64BIT
16905    && peep2_regno_dead_p (0, FLAGS_REG)
16906    && REGNO (operands[0]) == REGNO (operands[1])"
16907   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16908               (clobber (reg:CC FLAGS_REG))])]
16909   "operands[2] = gen_lowpart (SImode, operands[2]);")
16910
16911 (define_peephole2
16912   [(set (match_operand:SWI48 0 "register_operand" "")
16913         (mult:SWI48 (match_dup 0)
16914                     (match_operand:SWI48 1 "const_int_operand" "")))]
16915   "exact_log2 (INTVAL (operands[1])) >= 0
16916    && peep2_regno_dead_p (0, FLAGS_REG)"
16917   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16918               (clobber (reg:CC FLAGS_REG))])]
16919   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16920
16921 (define_peephole2
16922   [(set (match_operand:SI 0 "register_operand" "")
16923         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16924                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16925   "TARGET_64BIT
16926    && exact_log2 (INTVAL (operands[2])) >= 0
16927    && REGNO (operands[0]) == REGNO (operands[1])
16928    && peep2_regno_dead_p (0, FLAGS_REG)"
16929   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16930               (clobber (reg:CC FLAGS_REG))])]
16931   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16932
16933 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16934 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16935 ;; On many CPUs it is also faster, since special hardware to avoid esp
16936 ;; dependencies is present.
16937
16938 ;; While some of these conversions may be done using splitters, we use
16939 ;; peepholes in order to allow combine_stack_adjustments pass to see
16940 ;; nonobfuscated RTL.
16941
16942 ;; Convert prologue esp subtractions to push.
16943 ;; We need register to push.  In order to keep verify_flow_info happy we have
16944 ;; two choices
16945 ;; - use scratch and clobber it in order to avoid dependencies
16946 ;; - use already live register
16947 ;; We can't use the second way right now, since there is no reliable way how to
16948 ;; verify that given register is live.  First choice will also most likely in
16949 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16950 ;; call clobbered registers are dead.  We may want to use base pointer as an
16951 ;; alternative when no register is available later.
16952
16953 (define_peephole2
16954   [(match_scratch:P 1 "r")
16955    (parallel [(set (reg:P SP_REG)
16956                    (plus:P (reg:P SP_REG)
16957                            (match_operand:P 0 "const_int_operand" "")))
16958               (clobber (reg:CC FLAGS_REG))
16959               (clobber (mem:BLK (scratch)))])]
16960   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16961    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16962   [(clobber (match_dup 1))
16963    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16964               (clobber (mem:BLK (scratch)))])])
16965
16966 (define_peephole2
16967   [(match_scratch:P 1 "r")
16968    (parallel [(set (reg:P SP_REG)
16969                    (plus:P (reg:P SP_REG)
16970                            (match_operand:P 0 "const_int_operand" "")))
16971               (clobber (reg:CC FLAGS_REG))
16972               (clobber (mem:BLK (scratch)))])]
16973   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16974    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16975   [(clobber (match_dup 1))
16976    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16977    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16978               (clobber (mem:BLK (scratch)))])])
16979
16980 ;; Convert esp subtractions to push.
16981 (define_peephole2
16982   [(match_scratch:P 1 "r")
16983    (parallel [(set (reg:P SP_REG)
16984                    (plus:P (reg:P SP_REG)
16985                            (match_operand:P 0 "const_int_operand" "")))
16986               (clobber (reg:CC FLAGS_REG))])]
16987   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16988    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16989   [(clobber (match_dup 1))
16990    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16991
16992 (define_peephole2
16993   [(match_scratch:P 1 "r")
16994    (parallel [(set (reg:P SP_REG)
16995                    (plus:P (reg:P SP_REG)
16996                            (match_operand:P 0 "const_int_operand" "")))
16997               (clobber (reg:CC FLAGS_REG))])]
16998   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16999    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17000   [(clobber (match_dup 1))
17001    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17002    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17003
17004 ;; Convert epilogue deallocator to pop.
17005 (define_peephole2
17006   [(match_scratch:P 1 "r")
17007    (parallel [(set (reg:P SP_REG)
17008                    (plus:P (reg:P SP_REG)
17009                            (match_operand:P 0 "const_int_operand" "")))
17010               (clobber (reg:CC FLAGS_REG))
17011               (clobber (mem:BLK (scratch)))])]
17012   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17013    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17014   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17015               (clobber (mem:BLK (scratch)))])])
17016
17017 ;; Two pops case is tricky, since pop causes dependency
17018 ;; on destination register.  We use two registers if available.
17019 (define_peephole2
17020   [(match_scratch:P 1 "r")
17021    (match_scratch:P 2 "r")
17022    (parallel [(set (reg:P SP_REG)
17023                    (plus:P (reg:P SP_REG)
17024                            (match_operand:P 0 "const_int_operand" "")))
17025               (clobber (reg:CC FLAGS_REG))
17026               (clobber (mem:BLK (scratch)))])]
17027   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17028    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17029   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17030               (clobber (mem:BLK (scratch)))])
17031    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17032
17033 (define_peephole2
17034   [(match_scratch:P 1 "r")
17035    (parallel [(set (reg:P SP_REG)
17036                    (plus:P (reg:P SP_REG)
17037                            (match_operand:P 0 "const_int_operand" "")))
17038               (clobber (reg:CC FLAGS_REG))
17039               (clobber (mem:BLK (scratch)))])]
17040   "optimize_insn_for_size_p ()
17041    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17042   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17043               (clobber (mem:BLK (scratch)))])
17044    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17045
17046 ;; Convert esp additions to pop.
17047 (define_peephole2
17048   [(match_scratch:P 1 "r")
17049    (parallel [(set (reg:P SP_REG)
17050                    (plus:P (reg:P SP_REG)
17051                            (match_operand:P 0 "const_int_operand" "")))
17052               (clobber (reg:CC FLAGS_REG))])]
17053   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17054   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17055
17056 ;; Two pops case is tricky, since pop causes dependency
17057 ;; on destination register.  We use two registers if available.
17058 (define_peephole2
17059   [(match_scratch:P 1 "r")
17060    (match_scratch:P 2 "r")
17061    (parallel [(set (reg:P SP_REG)
17062                    (plus:P (reg:P SP_REG)
17063                            (match_operand:P 0 "const_int_operand" "")))
17064               (clobber (reg:CC FLAGS_REG))])]
17065   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17066   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17067    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17068
17069 (define_peephole2
17070   [(match_scratch:P 1 "r")
17071    (parallel [(set (reg:P SP_REG)
17072                    (plus:P (reg:P SP_REG)
17073                            (match_operand:P 0 "const_int_operand" "")))
17074               (clobber (reg:CC FLAGS_REG))])]
17075   "optimize_insn_for_size_p ()
17076    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17077   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17078    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17079 \f
17080 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17081 ;; required and register dies.  Similarly for 128 to -128.
17082 (define_peephole2
17083   [(set (match_operand 0 "flags_reg_operand" "")
17084         (match_operator 1 "compare_operator"
17085           [(match_operand 2 "register_operand" "")
17086            (match_operand 3 "const_int_operand" "")]))]
17087   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17088      && incdec_operand (operands[3], GET_MODE (operands[3])))
17089     || (!TARGET_FUSE_CMP_AND_BRANCH
17090         && INTVAL (operands[3]) == 128))
17091    && ix86_match_ccmode (insn, CCGCmode)
17092    && peep2_reg_dead_p (1, operands[2])"
17093   [(parallel [(set (match_dup 0)
17094                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17095               (clobber (match_dup 2))])])
17096 \f
17097 ;; Convert imul by three, five and nine into lea
17098 (define_peephole2
17099   [(parallel
17100     [(set (match_operand:SWI48 0 "register_operand" "")
17101           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17102                       (match_operand:SWI48 2 "const_int_operand" "")))
17103      (clobber (reg:CC FLAGS_REG))])]
17104   "INTVAL (operands[2]) == 3
17105    || INTVAL (operands[2]) == 5
17106    || INTVAL (operands[2]) == 9"
17107   [(set (match_dup 0)
17108         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17109                     (match_dup 1)))]
17110   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17111
17112 (define_peephole2
17113   [(parallel
17114     [(set (match_operand:SWI48 0 "register_operand" "")
17115           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17116                       (match_operand:SWI48 2 "const_int_operand" "")))
17117      (clobber (reg:CC FLAGS_REG))])]
17118   "optimize_insn_for_speed_p ()
17119    && (INTVAL (operands[2]) == 3
17120        || INTVAL (operands[2]) == 5
17121        || INTVAL (operands[2]) == 9)"
17122   [(set (match_dup 0) (match_dup 1))
17123    (set (match_dup 0)
17124         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17125                     (match_dup 0)))]
17126   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17127
17128 ;; imul $32bit_imm, mem, reg is vector decoded, while
17129 ;; imul $32bit_imm, reg, reg is direct decoded.
17130 (define_peephole2
17131   [(match_scratch:SWI48 3 "r")
17132    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17133                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17134                                (match_operand:SWI48 2 "immediate_operand" "")))
17135               (clobber (reg:CC FLAGS_REG))])]
17136   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17137    && !satisfies_constraint_K (operands[2])"
17138   [(set (match_dup 3) (match_dup 1))
17139    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17140               (clobber (reg:CC FLAGS_REG))])])
17141
17142 (define_peephole2
17143   [(match_scratch:SI 3 "r")
17144    (parallel [(set (match_operand:DI 0 "register_operand" "")
17145                    (zero_extend:DI
17146                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17147                               (match_operand:SI 2 "immediate_operand" ""))))
17148               (clobber (reg:CC FLAGS_REG))])]
17149   "TARGET_64BIT
17150    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17151    && !satisfies_constraint_K (operands[2])"
17152   [(set (match_dup 3) (match_dup 1))
17153    (parallel [(set (match_dup 0)
17154                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17155               (clobber (reg:CC FLAGS_REG))])])
17156
17157 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17158 ;; Convert it into imul reg, reg
17159 ;; It would be better to force assembler to encode instruction using long
17160 ;; immediate, but there is apparently no way to do so.
17161 (define_peephole2
17162   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17163                    (mult:SWI248
17164                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17165                     (match_operand:SWI248 2 "const_int_operand" "")))
17166               (clobber (reg:CC FLAGS_REG))])
17167    (match_scratch:SWI248 3 "r")]
17168   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17169    && satisfies_constraint_K (operands[2])"
17170   [(set (match_dup 3) (match_dup 2))
17171    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17172               (clobber (reg:CC FLAGS_REG))])]
17173 {
17174   if (!rtx_equal_p (operands[0], operands[1]))
17175     emit_move_insn (operands[0], operands[1]);
17176 })
17177
17178 ;; After splitting up read-modify operations, array accesses with memory
17179 ;; operands might end up in form:
17180 ;;  sall    $2, %eax
17181 ;;  movl    4(%esp), %edx
17182 ;;  addl    %edx, %eax
17183 ;; instead of pre-splitting:
17184 ;;  sall    $2, %eax
17185 ;;  addl    4(%esp), %eax
17186 ;; Turn it into:
17187 ;;  movl    4(%esp), %edx
17188 ;;  leal    (%edx,%eax,4), %eax
17189
17190 (define_peephole2
17191   [(match_scratch:P 5 "r")
17192    (parallel [(set (match_operand 0 "register_operand" "")
17193                    (ashift (match_operand 1 "register_operand" "")
17194                            (match_operand 2 "const_int_operand" "")))
17195                (clobber (reg:CC FLAGS_REG))])
17196    (parallel [(set (match_operand 3 "register_operand" "")
17197                    (plus (match_dup 0)
17198                          (match_operand 4 "x86_64_general_operand" "")))
17199                    (clobber (reg:CC FLAGS_REG))])]
17200   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17201    /* Validate MODE for lea.  */
17202    && ((!TARGET_PARTIAL_REG_STALL
17203         && (GET_MODE (operands[0]) == QImode
17204             || GET_MODE (operands[0]) == HImode))
17205        || GET_MODE (operands[0]) == SImode
17206        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17207    && (rtx_equal_p (operands[0], operands[3])
17208        || peep2_reg_dead_p (2, operands[0]))
17209    /* We reorder load and the shift.  */
17210    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17211   [(set (match_dup 5) (match_dup 4))
17212    (set (match_dup 0) (match_dup 1))]
17213 {
17214   enum machine_mode op1mode = GET_MODE (operands[1]);
17215   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17216   int scale = 1 << INTVAL (operands[2]);
17217   rtx index = gen_lowpart (Pmode, operands[1]);
17218   rtx base = gen_lowpart (Pmode, operands[5]);
17219   rtx dest = gen_lowpart (mode, operands[3]);
17220
17221   operands[1] = gen_rtx_PLUS (Pmode, base,
17222                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17223   operands[5] = base;
17224   if (mode != Pmode)
17225     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17226   if (op1mode != Pmode)
17227     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17228   operands[0] = dest;
17229 })
17230 \f
17231 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17232 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17233 ;; caught for use by garbage collectors and the like.  Using an insn that
17234 ;; maps to SIGILL makes it more likely the program will rightfully die.
17235 ;; Keeping with tradition, "6" is in honor of #UD.
17236 (define_insn "trap"
17237   [(trap_if (const_int 1) (const_int 6))]
17238   ""
17239   { return ASM_SHORT "0x0b0f"; }
17240   [(set_attr "length" "2")])
17241
17242 (define_expand "prefetch"
17243   [(prefetch (match_operand 0 "address_operand" "")
17244              (match_operand:SI 1 "const_int_operand" "")
17245              (match_operand:SI 2 "const_int_operand" ""))]
17246   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17247 {
17248   int rw = INTVAL (operands[1]);
17249   int locality = INTVAL (operands[2]);
17250
17251   gcc_assert (rw == 0 || rw == 1);
17252   gcc_assert (locality >= 0 && locality <= 3);
17253   gcc_assert (GET_MODE (operands[0]) == Pmode
17254               || GET_MODE (operands[0]) == VOIDmode);
17255
17256   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17257      supported by SSE counterpart or the SSE prefetch is not available
17258      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17259      of locality.  */
17260   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17261     operands[2] = GEN_INT (3);
17262   else
17263     operands[1] = const0_rtx;
17264 })
17265
17266 (define_insn "*prefetch_sse_<mode>"
17267   [(prefetch (match_operand:P 0 "address_operand" "p")
17268              (const_int 0)
17269              (match_operand:SI 1 "const_int_operand" ""))]
17270   "TARGET_PREFETCH_SSE"
17271 {
17272   static const char * const patterns[4] = {
17273    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17274   };
17275
17276   int locality = INTVAL (operands[1]);
17277   gcc_assert (locality >= 0 && locality <= 3);
17278
17279   return patterns[locality];
17280 }
17281   [(set_attr "type" "sse")
17282    (set_attr "atom_sse_attr" "prefetch")
17283    (set (attr "length_address")
17284         (symbol_ref "memory_address_length (operands[0])"))
17285    (set_attr "memory" "none")])
17286
17287 (define_insn "*prefetch_3dnow_<mode>"
17288   [(prefetch (match_operand:P 0 "address_operand" "p")
17289              (match_operand:SI 1 "const_int_operand" "n")
17290              (const_int 3))]
17291   "TARGET_3DNOW"
17292 {
17293   if (INTVAL (operands[1]) == 0)
17294     return "prefetch\t%a0";
17295   else
17296     return "prefetchw\t%a0";
17297 }
17298   [(set_attr "type" "mmx")
17299    (set (attr "length_address")
17300         (symbol_ref "memory_address_length (operands[0])"))
17301    (set_attr "memory" "none")])
17302
17303 (define_expand "stack_protect_set"
17304   [(match_operand 0 "memory_operand" "")
17305    (match_operand 1 "memory_operand" "")]
17306   ""
17307 {
17308   rtx (*insn)(rtx, rtx);
17309
17310 #ifdef TARGET_THREAD_SSP_OFFSET
17311   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17312   insn = (TARGET_64BIT
17313           ? gen_stack_tls_protect_set_di
17314           : gen_stack_tls_protect_set_si);
17315 #else
17316   insn = (TARGET_64BIT
17317           ? gen_stack_protect_set_di
17318           : gen_stack_protect_set_si);
17319 #endif
17320
17321   emit_insn (insn (operands[0], operands[1]));
17322   DONE;
17323 })
17324
17325 (define_insn "stack_protect_set_<mode>"
17326   [(set (match_operand:P 0 "memory_operand" "=m")
17327         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17328    (set (match_scratch:P 2 "=&r") (const_int 0))
17329    (clobber (reg:CC FLAGS_REG))]
17330   ""
17331   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17332   [(set_attr "type" "multi")])
17333
17334 (define_insn "stack_tls_protect_set_<mode>"
17335   [(set (match_operand:P 0 "memory_operand" "=m")
17336         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17337                   UNSPEC_SP_TLS_SET))
17338    (set (match_scratch:P 2 "=&r") (const_int 0))
17339    (clobber (reg:CC FLAGS_REG))]
17340   ""
17341   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17342   [(set_attr "type" "multi")])
17343
17344 (define_expand "stack_protect_test"
17345   [(match_operand 0 "memory_operand" "")
17346    (match_operand 1 "memory_operand" "")
17347    (match_operand 2 "" "")]
17348   ""
17349 {
17350   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17351
17352   rtx (*insn)(rtx, rtx, rtx);
17353
17354 #ifdef TARGET_THREAD_SSP_OFFSET
17355   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17356   insn = (TARGET_64BIT
17357           ? gen_stack_tls_protect_test_di
17358           : gen_stack_tls_protect_test_si);
17359 #else
17360   insn = (TARGET_64BIT
17361           ? gen_stack_protect_test_di
17362           : gen_stack_protect_test_si);
17363 #endif
17364
17365   emit_insn (insn (flags, operands[0], operands[1]));
17366
17367   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17368                                   flags, const0_rtx, operands[2]));
17369   DONE;
17370 })
17371
17372 (define_insn "stack_protect_test_<mode>"
17373   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17374         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17375                      (match_operand:P 2 "memory_operand" "m")]
17376                     UNSPEC_SP_TEST))
17377    (clobber (match_scratch:P 3 "=&r"))]
17378   ""
17379   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17380   [(set_attr "type" "multi")])
17381
17382 (define_insn "stack_tls_protect_test_<mode>"
17383   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17384         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17385                      (match_operand:P 2 "const_int_operand" "i")]
17386                     UNSPEC_SP_TLS_TEST))
17387    (clobber (match_scratch:P 3 "=r"))]
17388   ""
17389   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17390   [(set_attr "type" "multi")])
17391
17392 (define_insn "sse4_2_crc32<mode>"
17393   [(set (match_operand:SI 0 "register_operand" "=r")
17394         (unspec:SI
17395           [(match_operand:SI 1 "register_operand" "0")
17396            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17397           UNSPEC_CRC32))]
17398   "TARGET_SSE4_2 || TARGET_CRC32"
17399   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17400   [(set_attr "type" "sselog1")
17401    (set_attr "prefix_rep" "1")
17402    (set_attr "prefix_extra" "1")
17403    (set (attr "prefix_data16")
17404      (if_then_else (match_operand:HI 2 "" "")
17405        (const_string "1")
17406        (const_string "*")))
17407    (set (attr "prefix_rex")
17408      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17409        (const_string "1")
17410        (const_string "*")))
17411    (set_attr "mode" "SI")])
17412
17413 (define_insn "sse4_2_crc32di"
17414   [(set (match_operand:DI 0 "register_operand" "=r")
17415         (unspec:DI
17416           [(match_operand:DI 1 "register_operand" "0")
17417            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17418           UNSPEC_CRC32))]
17419   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17420   "crc32{q}\t{%2, %0|%0, %2}"
17421   [(set_attr "type" "sselog1")
17422    (set_attr "prefix_rep" "1")
17423    (set_attr "prefix_extra" "1")
17424    (set_attr "mode" "DI")])
17425
17426 (define_expand "rdpmc"
17427   [(match_operand:DI 0 "register_operand" "")
17428    (match_operand:SI 1 "register_operand" "")]
17429   ""
17430 {
17431   rtx reg = gen_reg_rtx (DImode);
17432   rtx si;
17433
17434   /* Force operand 1 into ECX.  */
17435   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17436   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17437   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17438                                 UNSPECV_RDPMC);
17439
17440   if (TARGET_64BIT)
17441     {
17442       rtvec vec = rtvec_alloc (2);
17443       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17444       rtx upper = gen_reg_rtx (DImode);
17445       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17446                                         gen_rtvec (1, const0_rtx),
17447                                         UNSPECV_RDPMC);
17448       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17449       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17450       emit_insn (load);
17451       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17452                                    NULL, 1, OPTAB_DIRECT);
17453       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17454                                  OPTAB_DIRECT);
17455     }
17456   else
17457     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17458   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17459   DONE;
17460 })
17461
17462 (define_insn "*rdpmc"
17463   [(set (match_operand:DI 0 "register_operand" "=A")
17464         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17465                             UNSPECV_RDPMC))]
17466   "!TARGET_64BIT"
17467   "rdpmc"
17468   [(set_attr "type" "other")
17469    (set_attr "length" "2")])
17470
17471 (define_insn "*rdpmc_rex64"
17472   [(set (match_operand:DI 0 "register_operand" "=a")
17473         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17474                             UNSPECV_RDPMC))
17475   (set (match_operand:DI 1 "register_operand" "=d")
17476        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17477   "TARGET_64BIT"
17478   "rdpmc"
17479   [(set_attr "type" "other")
17480    (set_attr "length" "2")])
17481
17482 (define_expand "rdtsc"
17483   [(set (match_operand:DI 0 "register_operand" "")
17484         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17485   ""
17486 {
17487   if (TARGET_64BIT)
17488     {
17489       rtvec vec = rtvec_alloc (2);
17490       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17491       rtx upper = gen_reg_rtx (DImode);
17492       rtx lower = gen_reg_rtx (DImode);
17493       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17494                                          gen_rtvec (1, const0_rtx),
17495                                          UNSPECV_RDTSC);
17496       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17497       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17498       emit_insn (load);
17499       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17500                                    NULL, 1, OPTAB_DIRECT);
17501       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17502                                    OPTAB_DIRECT);
17503       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17504       DONE;
17505     }
17506 })
17507
17508 (define_insn "*rdtsc"
17509   [(set (match_operand:DI 0 "register_operand" "=A")
17510         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17511   "!TARGET_64BIT"
17512   "rdtsc"
17513   [(set_attr "type" "other")
17514    (set_attr "length" "2")])
17515
17516 (define_insn "*rdtsc_rex64"
17517   [(set (match_operand:DI 0 "register_operand" "=a")
17518         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17519    (set (match_operand:DI 1 "register_operand" "=d")
17520         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17521   "TARGET_64BIT"
17522   "rdtsc"
17523   [(set_attr "type" "other")
17524    (set_attr "length" "2")])
17525
17526 (define_expand "rdtscp"
17527   [(match_operand:DI 0 "register_operand" "")
17528    (match_operand:SI 1 "memory_operand" "")]
17529   ""
17530 {
17531   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17532                                     gen_rtvec (1, const0_rtx),
17533                                     UNSPECV_RDTSCP);
17534   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17535                                     gen_rtvec (1, const0_rtx),
17536                                     UNSPECV_RDTSCP);
17537   rtx reg = gen_reg_rtx (DImode);
17538   rtx tmp = gen_reg_rtx (SImode);
17539
17540   if (TARGET_64BIT)
17541     {
17542       rtvec vec = rtvec_alloc (3);
17543       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17544       rtx upper = gen_reg_rtx (DImode);
17545       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17546       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17547       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17548       emit_insn (load);
17549       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17550                                    NULL, 1, OPTAB_DIRECT);
17551       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17552                                  OPTAB_DIRECT);
17553     }
17554   else
17555     {
17556       rtvec vec = rtvec_alloc (2);
17557       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17558       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17559       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17560       emit_insn (load);
17561     }
17562   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17563   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17564   DONE;
17565 })
17566
17567 (define_insn "*rdtscp"
17568   [(set (match_operand:DI 0 "register_operand" "=A")
17569         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17570    (set (match_operand:SI 1 "register_operand" "=c")
17571         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17572   "!TARGET_64BIT"
17573   "rdtscp"
17574   [(set_attr "type" "other")
17575    (set_attr "length" "3")])
17576
17577 (define_insn "*rdtscp_rex64"
17578   [(set (match_operand:DI 0 "register_operand" "=a")
17579         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17580    (set (match_operand:DI 1 "register_operand" "=d")
17581         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17582    (set (match_operand:SI 2 "register_operand" "=c")
17583         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17584   "TARGET_64BIT"
17585   "rdtscp"
17586   [(set_attr "type" "other")
17587    (set_attr "length" "3")])
17588
17589 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17590 ;;
17591 ;; LWP instructions
17592 ;;
17593 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17594
17595 (define_expand "lwp_llwpcb"
17596   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17597                     UNSPECV_LLWP_INTRINSIC)]
17598   "TARGET_LWP")
17599
17600 (define_insn "*lwp_llwpcb<mode>1"
17601   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17602                     UNSPECV_LLWP_INTRINSIC)]
17603   "TARGET_LWP"
17604   "llwpcb\t%0"
17605   [(set_attr "type" "lwp")
17606    (set_attr "mode" "<MODE>")
17607    (set_attr "length" "5")])
17608
17609 (define_expand "lwp_slwpcb"
17610   [(set (match_operand 0 "register_operand" "=r")
17611         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17612   "TARGET_LWP"
17613 {
17614   rtx (*insn)(rtx);
17615
17616   insn = (TARGET_64BIT
17617           ? gen_lwp_slwpcbdi
17618           : gen_lwp_slwpcbsi);
17619
17620   emit_insn (insn (operands[0]));
17621   DONE;
17622 })
17623
17624 (define_insn "lwp_slwpcb<mode>"
17625   [(set (match_operand:P 0 "register_operand" "=r")
17626         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17627   "TARGET_LWP"
17628   "slwpcb\t%0"
17629   [(set_attr "type" "lwp")
17630    (set_attr "mode" "<MODE>")
17631    (set_attr "length" "5")])
17632
17633 (define_expand "lwp_lwpval<mode>3"
17634   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17635                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17636                      (match_operand:SI 3 "const_int_operand" "i")]
17637                     UNSPECV_LWPVAL_INTRINSIC)]
17638   "TARGET_LWP"
17639   "/* Avoid unused variable warning.  */
17640    (void) operand0;")
17641
17642 (define_insn "*lwp_lwpval<mode>3_1"
17643   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17644                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17645                      (match_operand:SI 2 "const_int_operand" "i")]
17646                     UNSPECV_LWPVAL_INTRINSIC)]
17647   "TARGET_LWP"
17648   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17649   [(set_attr "type" "lwp")
17650    (set_attr "mode" "<MODE>")
17651    (set (attr "length")
17652         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17653
17654 (define_expand "lwp_lwpins<mode>3"
17655   [(set (reg:CCC FLAGS_REG)
17656         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17657                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17658                               (match_operand:SI 3 "const_int_operand" "i")]
17659                              UNSPECV_LWPINS_INTRINSIC))
17660    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17661         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17662   "TARGET_LWP")
17663
17664 (define_insn "*lwp_lwpins<mode>3_1"
17665   [(set (reg:CCC FLAGS_REG)
17666         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17667                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17668                               (match_operand:SI 2 "const_int_operand" "i")]
17669                              UNSPECV_LWPINS_INTRINSIC))]
17670   "TARGET_LWP"
17671   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17672   [(set_attr "type" "lwp")
17673    (set_attr "mode" "<MODE>")
17674    (set (attr "length")
17675         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17676
17677 (define_insn "rdfsbase<mode>"
17678   [(set (match_operand:SWI48 0 "register_operand" "=r")
17679         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17680   "TARGET_64BIT && TARGET_FSGSBASE"
17681   "rdfsbase %0"
17682   [(set_attr "type" "other")
17683    (set_attr "prefix_extra" "2")])
17684
17685 (define_insn "rdgsbase<mode>"
17686   [(set (match_operand:SWI48 0 "register_operand" "=r")
17687         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17688   "TARGET_64BIT && TARGET_FSGSBASE"
17689   "rdgsbase %0"
17690   [(set_attr "type" "other")
17691    (set_attr "prefix_extra" "2")])
17692
17693 (define_insn "wrfsbase<mode>"
17694   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17695                     UNSPECV_WRFSBASE)]
17696   "TARGET_64BIT && TARGET_FSGSBASE"
17697   "wrfsbase %0"
17698   [(set_attr "type" "other")
17699    (set_attr "prefix_extra" "2")])
17700
17701 (define_insn "wrgsbase<mode>"
17702   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17703                     UNSPECV_WRGSBASE)]
17704   "TARGET_64BIT && TARGET_FSGSBASE"
17705   "wrgsbase %0"
17706   [(set_attr "type" "other")
17707    (set_attr "prefix_extra" "2")])
17708
17709 (define_insn "rdrand<mode>_1"
17710   [(set (match_operand:SWI248 0 "register_operand" "=r")
17711         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17712    (set (reg:CCC FLAGS_REG)
17713         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17714   "TARGET_RDRND"
17715   "rdrand\t%0"
17716   [(set_attr "type" "other")
17717    (set_attr "prefix_extra" "1")])
17718
17719 (include "mmx.md")
17720 (include "sse.md")
17721 (include "sync.md")