OSDN Git Service

gcc/
[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,1)")
418          (eq_attr "type" "imov,test")
419            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
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, 1, 1)")
528       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
529     (if_then_else (eq_attr "prefix_vex_w" "1")
530       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
531       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
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 asm suffix for floating point modes
938 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
939
940 ;; SSE vector mode corresponding to a scalar mode
941 (define_mode_attr ssevecmode
942   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
943
944 ;; Instruction suffix for REX 64bit operators.
945 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
946
947 ;; This mode iterator allows :P to be used for patterns that operate on
948 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
949 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
950 \f
951 ;; Scheduling descriptions
952
953 (include "pentium.md")
954 (include "ppro.md")
955 (include "k6.md")
956 (include "athlon.md")
957 (include "bdver1.md")
958 (include "geode.md")
959 (include "atom.md")
960 (include "core2.md")
961
962 \f
963 ;; Operand and operator predicates and constraints
964
965 (include "predicates.md")
966 (include "constraints.md")
967
968 \f
969 ;; Compare and branch/compare and store instructions.
970
971 (define_expand "cbranch<mode>4"
972   [(set (reg:CC FLAGS_REG)
973         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
974                     (match_operand:SDWIM 2 "<general_operand>" "")))
975    (set (pc) (if_then_else
976                (match_operator 0 "ordered_comparison_operator"
977                 [(reg:CC FLAGS_REG) (const_int 0)])
978                (label_ref (match_operand 3 "" ""))
979                (pc)))]
980   ""
981 {
982   if (MEM_P (operands[1]) && MEM_P (operands[2]))
983     operands[1] = force_reg (<MODE>mode, operands[1]);
984   ix86_expand_branch (GET_CODE (operands[0]),
985                       operands[1], operands[2], operands[3]);
986   DONE;
987 })
988
989 (define_expand "cstore<mode>4"
990   [(set (reg:CC FLAGS_REG)
991         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
992                     (match_operand:SWIM 3 "<general_operand>" "")))
993    (set (match_operand:QI 0 "register_operand" "")
994         (match_operator 1 "ordered_comparison_operator"
995           [(reg:CC FLAGS_REG) (const_int 0)]))]
996   ""
997 {
998   if (MEM_P (operands[2]) && MEM_P (operands[3]))
999     operands[2] = force_reg (<MODE>mode, operands[2]);
1000   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1001                      operands[2], operands[3]);
1002   DONE;
1003 })
1004
1005 (define_expand "cmp<mode>_1"
1006   [(set (reg:CC FLAGS_REG)
1007         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1008                     (match_operand:SWI48 1 "<general_operand>" "")))])
1009
1010 (define_insn "*cmp<mode>_ccno_1"
1011   [(set (reg FLAGS_REG)
1012         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1013                  (match_operand:SWI 1 "const0_operand" "")))]
1014   "ix86_match_ccmode (insn, CCNOmode)"
1015   "@
1016    test{<imodesuffix>}\t%0, %0
1017    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1018   [(set_attr "type" "test,icmp")
1019    (set_attr "length_immediate" "0,1")
1020    (set_attr "mode" "<MODE>")])
1021
1022 (define_insn "*cmp<mode>_1"
1023   [(set (reg FLAGS_REG)
1024         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1025                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1026   "ix86_match_ccmode (insn, CCmode)"
1027   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1028   [(set_attr "type" "icmp")
1029    (set_attr "mode" "<MODE>")])
1030
1031 (define_insn "*cmp<mode>_minus_1"
1032   [(set (reg FLAGS_REG)
1033         (compare
1034           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1035                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1036           (const_int 0)))]
1037   "ix86_match_ccmode (insn, CCGOCmode)"
1038   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1039   [(set_attr "type" "icmp")
1040    (set_attr "mode" "<MODE>")])
1041
1042 (define_insn "*cmpqi_ext_1"
1043   [(set (reg FLAGS_REG)
1044         (compare
1045           (match_operand:QI 0 "general_operand" "Qm")
1046           (subreg:QI
1047             (zero_extract:SI
1048               (match_operand 1 "ext_register_operand" "Q")
1049               (const_int 8)
1050               (const_int 8)) 0)))]
1051   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1052   "cmp{b}\t{%h1, %0|%0, %h1}"
1053   [(set_attr "type" "icmp")
1054    (set_attr "mode" "QI")])
1055
1056 (define_insn "*cmpqi_ext_1_rex64"
1057   [(set (reg FLAGS_REG)
1058         (compare
1059           (match_operand:QI 0 "register_operand" "Q")
1060           (subreg:QI
1061             (zero_extract:SI
1062               (match_operand 1 "ext_register_operand" "Q")
1063               (const_int 8)
1064               (const_int 8)) 0)))]
1065   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1066   "cmp{b}\t{%h1, %0|%0, %h1}"
1067   [(set_attr "type" "icmp")
1068    (set_attr "mode" "QI")])
1069
1070 (define_insn "*cmpqi_ext_2"
1071   [(set (reg FLAGS_REG)
1072         (compare
1073           (subreg:QI
1074             (zero_extract:SI
1075               (match_operand 0 "ext_register_operand" "Q")
1076               (const_int 8)
1077               (const_int 8)) 0)
1078           (match_operand:QI 1 "const0_operand" "")))]
1079   "ix86_match_ccmode (insn, CCNOmode)"
1080   "test{b}\t%h0, %h0"
1081   [(set_attr "type" "test")
1082    (set_attr "length_immediate" "0")
1083    (set_attr "mode" "QI")])
1084
1085 (define_expand "cmpqi_ext_3"
1086   [(set (reg:CC FLAGS_REG)
1087         (compare:CC
1088           (subreg:QI
1089             (zero_extract:SI
1090               (match_operand 0 "ext_register_operand" "")
1091               (const_int 8)
1092               (const_int 8)) 0)
1093           (match_operand:QI 1 "immediate_operand" "")))])
1094
1095 (define_insn "*cmpqi_ext_3_insn"
1096   [(set (reg FLAGS_REG)
1097         (compare
1098           (subreg:QI
1099             (zero_extract:SI
1100               (match_operand 0 "ext_register_operand" "Q")
1101               (const_int 8)
1102               (const_int 8)) 0)
1103           (match_operand:QI 1 "general_operand" "Qmn")))]
1104   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1105   "cmp{b}\t{%1, %h0|%h0, %1}"
1106   [(set_attr "type" "icmp")
1107    (set_attr "modrm" "1")
1108    (set_attr "mode" "QI")])
1109
1110 (define_insn "*cmpqi_ext_3_insn_rex64"
1111   [(set (reg FLAGS_REG)
1112         (compare
1113           (subreg:QI
1114             (zero_extract:SI
1115               (match_operand 0 "ext_register_operand" "Q")
1116               (const_int 8)
1117               (const_int 8)) 0)
1118           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1119   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1120   "cmp{b}\t{%1, %h0|%h0, %1}"
1121   [(set_attr "type" "icmp")
1122    (set_attr "modrm" "1")
1123    (set_attr "mode" "QI")])
1124
1125 (define_insn "*cmpqi_ext_4"
1126   [(set (reg FLAGS_REG)
1127         (compare
1128           (subreg:QI
1129             (zero_extract:SI
1130               (match_operand 0 "ext_register_operand" "Q")
1131               (const_int 8)
1132               (const_int 8)) 0)
1133           (subreg:QI
1134             (zero_extract:SI
1135               (match_operand 1 "ext_register_operand" "Q")
1136               (const_int 8)
1137               (const_int 8)) 0)))]
1138   "ix86_match_ccmode (insn, CCmode)"
1139   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1140   [(set_attr "type" "icmp")
1141    (set_attr "mode" "QI")])
1142
1143 ;; These implement float point compares.
1144 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1145 ;; which would allow mix and match FP modes on the compares.  Which is what
1146 ;; the old patterns did, but with many more of them.
1147
1148 (define_expand "cbranchxf4"
1149   [(set (reg:CC FLAGS_REG)
1150         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1151                     (match_operand:XF 2 "nonmemory_operand" "")))
1152    (set (pc) (if_then_else
1153               (match_operator 0 "ix86_fp_comparison_operator"
1154                [(reg:CC FLAGS_REG)
1155                 (const_int 0)])
1156               (label_ref (match_operand 3 "" ""))
1157               (pc)))]
1158   "TARGET_80387"
1159 {
1160   ix86_expand_branch (GET_CODE (operands[0]),
1161                       operands[1], operands[2], operands[3]);
1162   DONE;
1163 })
1164
1165 (define_expand "cstorexf4"
1166   [(set (reg:CC FLAGS_REG)
1167         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1168                     (match_operand:XF 3 "nonmemory_operand" "")))
1169    (set (match_operand:QI 0 "register_operand" "")
1170               (match_operator 1 "ix86_fp_comparison_operator"
1171                [(reg:CC FLAGS_REG)
1172                 (const_int 0)]))]
1173   "TARGET_80387"
1174 {
1175   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1176                      operands[2], operands[3]);
1177   DONE;
1178 })
1179
1180 (define_expand "cbranch<mode>4"
1181   [(set (reg:CC FLAGS_REG)
1182         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1183                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1184    (set (pc) (if_then_else
1185               (match_operator 0 "ix86_fp_comparison_operator"
1186                [(reg:CC FLAGS_REG)
1187                 (const_int 0)])
1188               (label_ref (match_operand 3 "" ""))
1189               (pc)))]
1190   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1191 {
1192   ix86_expand_branch (GET_CODE (operands[0]),
1193                       operands[1], operands[2], operands[3]);
1194   DONE;
1195 })
1196
1197 (define_expand "cstore<mode>4"
1198   [(set (reg:CC FLAGS_REG)
1199         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1200                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1201    (set (match_operand:QI 0 "register_operand" "")
1202               (match_operator 1 "ix86_fp_comparison_operator"
1203                [(reg:CC FLAGS_REG)
1204                 (const_int 0)]))]
1205   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1206 {
1207   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208                      operands[2], operands[3]);
1209   DONE;
1210 })
1211
1212 (define_expand "cbranchcc4"
1213   [(set (pc) (if_then_else
1214               (match_operator 0 "comparison_operator"
1215                [(match_operand 1 "flags_reg_operand" "")
1216                 (match_operand 2 "const0_operand" "")])
1217               (label_ref (match_operand 3 "" ""))
1218               (pc)))]
1219   ""
1220 {
1221   ix86_expand_branch (GET_CODE (operands[0]),
1222                       operands[1], operands[2], operands[3]);
1223   DONE;
1224 })
1225
1226 (define_expand "cstorecc4"
1227   [(set (match_operand:QI 0 "register_operand" "")
1228               (match_operator 1 "comparison_operator"
1229                [(match_operand 2 "flags_reg_operand" "")
1230                 (match_operand 3 "const0_operand" "")]))]
1231   ""
1232 {
1233   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1234                      operands[2], operands[3]);
1235   DONE;
1236 })
1237
1238
1239 ;; FP compares, step 1:
1240 ;; Set the FP condition codes.
1241 ;;
1242 ;; CCFPmode     compare with exceptions
1243 ;; CCFPUmode    compare with no exceptions
1244
1245 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1246 ;; used to manage the reg stack popping would not be preserved.
1247
1248 (define_insn "*cmpfp_0"
1249   [(set (match_operand:HI 0 "register_operand" "=a")
1250         (unspec:HI
1251           [(compare:CCFP
1252              (match_operand 1 "register_operand" "f")
1253              (match_operand 2 "const0_operand" ""))]
1254         UNSPEC_FNSTSW))]
1255   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1256    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1257   "* return output_fp_compare (insn, operands, 0, 0);"
1258   [(set_attr "type" "multi")
1259    (set_attr "unit" "i387")
1260    (set (attr "mode")
1261      (cond [(match_operand:SF 1 "" "")
1262               (const_string "SF")
1263             (match_operand:DF 1 "" "")
1264               (const_string "DF")
1265            ]
1266            (const_string "XF")))])
1267
1268 (define_insn_and_split "*cmpfp_0_cc"
1269   [(set (reg:CCFP FLAGS_REG)
1270         (compare:CCFP
1271           (match_operand 1 "register_operand" "f")
1272           (match_operand 2 "const0_operand" "")))
1273    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1274   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1275    && TARGET_SAHF && !TARGET_CMOVE
1276    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1277   "#"
1278   "&& reload_completed"
1279   [(set (match_dup 0)
1280         (unspec:HI
1281           [(compare:CCFP (match_dup 1)(match_dup 2))]
1282         UNSPEC_FNSTSW))
1283    (set (reg:CC FLAGS_REG)
1284         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1285   ""
1286   [(set_attr "type" "multi")
1287    (set_attr "unit" "i387")
1288    (set (attr "mode")
1289      (cond [(match_operand:SF 1 "" "")
1290               (const_string "SF")
1291             (match_operand:DF 1 "" "")
1292               (const_string "DF")
1293            ]
1294            (const_string "XF")))])
1295
1296 (define_insn "*cmpfp_xf"
1297   [(set (match_operand:HI 0 "register_operand" "=a")
1298         (unspec:HI
1299           [(compare:CCFP
1300              (match_operand:XF 1 "register_operand" "f")
1301              (match_operand:XF 2 "register_operand" "f"))]
1302           UNSPEC_FNSTSW))]
1303   "TARGET_80387"
1304   "* return output_fp_compare (insn, operands, 0, 0);"
1305   [(set_attr "type" "multi")
1306    (set_attr "unit" "i387")
1307    (set_attr "mode" "XF")])
1308
1309 (define_insn_and_split "*cmpfp_xf_cc"
1310   [(set (reg:CCFP FLAGS_REG)
1311         (compare:CCFP
1312           (match_operand:XF 1 "register_operand" "f")
1313           (match_operand:XF 2 "register_operand" "f")))
1314    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1315   "TARGET_80387
1316    && TARGET_SAHF && !TARGET_CMOVE"
1317   "#"
1318   "&& reload_completed"
1319   [(set (match_dup 0)
1320         (unspec:HI
1321           [(compare:CCFP (match_dup 1)(match_dup 2))]
1322         UNSPEC_FNSTSW))
1323    (set (reg:CC FLAGS_REG)
1324         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1325   ""
1326   [(set_attr "type" "multi")
1327    (set_attr "unit" "i387")
1328    (set_attr "mode" "XF")])
1329
1330 (define_insn "*cmpfp_<mode>"
1331   [(set (match_operand:HI 0 "register_operand" "=a")
1332         (unspec:HI
1333           [(compare:CCFP
1334              (match_operand:MODEF 1 "register_operand" "f")
1335              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1336           UNSPEC_FNSTSW))]
1337   "TARGET_80387"
1338   "* return output_fp_compare (insn, operands, 0, 0);"
1339   [(set_attr "type" "multi")
1340    (set_attr "unit" "i387")
1341    (set_attr "mode" "<MODE>")])
1342
1343 (define_insn_and_split "*cmpfp_<mode>_cc"
1344   [(set (reg:CCFP FLAGS_REG)
1345         (compare:CCFP
1346           (match_operand:MODEF 1 "register_operand" "f")
1347           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1348    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1349   "TARGET_80387
1350    && TARGET_SAHF && !TARGET_CMOVE"
1351   "#"
1352   "&& reload_completed"
1353   [(set (match_dup 0)
1354         (unspec:HI
1355           [(compare:CCFP (match_dup 1)(match_dup 2))]
1356         UNSPEC_FNSTSW))
1357    (set (reg:CC FLAGS_REG)
1358         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1359   ""
1360   [(set_attr "type" "multi")
1361    (set_attr "unit" "i387")
1362    (set_attr "mode" "<MODE>")])
1363
1364 (define_insn "*cmpfp_u"
1365   [(set (match_operand:HI 0 "register_operand" "=a")
1366         (unspec:HI
1367           [(compare:CCFPU
1368              (match_operand 1 "register_operand" "f")
1369              (match_operand 2 "register_operand" "f"))]
1370           UNSPEC_FNSTSW))]
1371   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1372    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1373   "* return output_fp_compare (insn, operands, 0, 1);"
1374   [(set_attr "type" "multi")
1375    (set_attr "unit" "i387")
1376    (set (attr "mode")
1377      (cond [(match_operand:SF 1 "" "")
1378               (const_string "SF")
1379             (match_operand:DF 1 "" "")
1380               (const_string "DF")
1381            ]
1382            (const_string "XF")))])
1383
1384 (define_insn_and_split "*cmpfp_u_cc"
1385   [(set (reg:CCFPU FLAGS_REG)
1386         (compare:CCFPU
1387           (match_operand 1 "register_operand" "f")
1388           (match_operand 2 "register_operand" "f")))
1389    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1390   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391    && TARGET_SAHF && !TARGET_CMOVE
1392    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1393   "#"
1394   "&& reload_completed"
1395   [(set (match_dup 0)
1396         (unspec:HI
1397           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1398         UNSPEC_FNSTSW))
1399    (set (reg:CC FLAGS_REG)
1400         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1401   ""
1402   [(set_attr "type" "multi")
1403    (set_attr "unit" "i387")
1404    (set (attr "mode")
1405      (cond [(match_operand:SF 1 "" "")
1406               (const_string "SF")
1407             (match_operand:DF 1 "" "")
1408               (const_string "DF")
1409            ]
1410            (const_string "XF")))])
1411
1412 (define_insn "*cmpfp_<mode>"
1413   [(set (match_operand:HI 0 "register_operand" "=a")
1414         (unspec:HI
1415           [(compare:CCFP
1416              (match_operand 1 "register_operand" "f")
1417              (match_operator 3 "float_operator"
1418                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1419           UNSPEC_FNSTSW))]
1420   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1421    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1422    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1423   "* return output_fp_compare (insn, operands, 0, 0);"
1424   [(set_attr "type" "multi")
1425    (set_attr "unit" "i387")
1426    (set_attr "fp_int_src" "true")
1427    (set_attr "mode" "<MODE>")])
1428
1429 (define_insn_and_split "*cmpfp_<mode>_cc"
1430   [(set (reg:CCFP FLAGS_REG)
1431         (compare:CCFP
1432           (match_operand 1 "register_operand" "f")
1433           (match_operator 3 "float_operator"
1434             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1435    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1436   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1437    && TARGET_SAHF && !TARGET_CMOVE
1438    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1439    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1440   "#"
1441   "&& reload_completed"
1442   [(set (match_dup 0)
1443         (unspec:HI
1444           [(compare:CCFP
1445              (match_dup 1)
1446              (match_op_dup 3 [(match_dup 2)]))]
1447         UNSPEC_FNSTSW))
1448    (set (reg:CC FLAGS_REG)
1449         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1450   ""
1451   [(set_attr "type" "multi")
1452    (set_attr "unit" "i387")
1453    (set_attr "fp_int_src" "true")
1454    (set_attr "mode" "<MODE>")])
1455
1456 ;; FP compares, step 2
1457 ;; Move the fpsw to ax.
1458
1459 (define_insn "x86_fnstsw_1"
1460   [(set (match_operand:HI 0 "register_operand" "=a")
1461         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1462   "TARGET_80387"
1463   "fnstsw\t%0"
1464   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1465    (set_attr "mode" "SI")
1466    (set_attr "unit" "i387")])
1467
1468 ;; FP compares, step 3
1469 ;; Get ax into flags, general case.
1470
1471 (define_insn "x86_sahf_1"
1472   [(set (reg:CC FLAGS_REG)
1473         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1474                    UNSPEC_SAHF))]
1475   "TARGET_SAHF"
1476 {
1477 #ifndef HAVE_AS_IX86_SAHF
1478   if (TARGET_64BIT)
1479     return ASM_BYTE "0x9e";
1480   else
1481 #endif
1482   return "sahf";
1483 }
1484   [(set_attr "length" "1")
1485    (set_attr "athlon_decode" "vector")
1486    (set_attr "amdfam10_decode" "direct")
1487    (set_attr "bdver1_decode" "direct")
1488    (set_attr "mode" "SI")])
1489
1490 ;; Pentium Pro can do steps 1 through 3 in one go.
1491 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1492 (define_insn "*cmpfp_i_mixed"
1493   [(set (reg:CCFP FLAGS_REG)
1494         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1495                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1496   "TARGET_MIX_SSE_I387
1497    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1498    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1499   "* return output_fp_compare (insn, operands, 1, 0);"
1500   [(set_attr "type" "fcmp,ssecomi")
1501    (set_attr "prefix" "orig,maybe_vex")
1502    (set (attr "mode")
1503      (if_then_else (match_operand:SF 1 "" "")
1504         (const_string "SF")
1505         (const_string "DF")))
1506    (set (attr "prefix_rep")
1507         (if_then_else (eq_attr "type" "ssecomi")
1508                       (const_string "0")
1509                       (const_string "*")))
1510    (set (attr "prefix_data16")
1511         (cond [(eq_attr "type" "fcmp")
1512                  (const_string "*")
1513                (eq_attr "mode" "DF")
1514                  (const_string "1")
1515               ]
1516               (const_string "0")))
1517    (set_attr "athlon_decode" "vector")
1518    (set_attr "amdfam10_decode" "direct")
1519    (set_attr "bdver1_decode" "double")])
1520
1521 (define_insn "*cmpfp_i_sse"
1522   [(set (reg:CCFP FLAGS_REG)
1523         (compare:CCFP (match_operand 0 "register_operand" "x")
1524                       (match_operand 1 "nonimmediate_operand" "xm")))]
1525   "TARGET_SSE_MATH
1526    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1527    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1528   "* return output_fp_compare (insn, operands, 1, 0);"
1529   [(set_attr "type" "ssecomi")
1530    (set_attr "prefix" "maybe_vex")
1531    (set (attr "mode")
1532      (if_then_else (match_operand:SF 1 "" "")
1533         (const_string "SF")
1534         (const_string "DF")))
1535    (set_attr "prefix_rep" "0")
1536    (set (attr "prefix_data16")
1537         (if_then_else (eq_attr "mode" "DF")
1538                       (const_string "1")
1539                       (const_string "0")))
1540    (set_attr "athlon_decode" "vector")
1541    (set_attr "amdfam10_decode" "direct")
1542    (set_attr "bdver1_decode" "double")])
1543
1544 (define_insn "*cmpfp_i_i387"
1545   [(set (reg:CCFP FLAGS_REG)
1546         (compare:CCFP (match_operand 0 "register_operand" "f")
1547                       (match_operand 1 "register_operand" "f")))]
1548   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1549    && TARGET_CMOVE
1550    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1551    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1552   "* return output_fp_compare (insn, operands, 1, 0);"
1553   [(set_attr "type" "fcmp")
1554    (set (attr "mode")
1555      (cond [(match_operand:SF 1 "" "")
1556               (const_string "SF")
1557             (match_operand:DF 1 "" "")
1558               (const_string "DF")
1559            ]
1560            (const_string "XF")))
1561    (set_attr "athlon_decode" "vector")
1562    (set_attr "amdfam10_decode" "direct")
1563    (set_attr "bdver1_decode" "double")])
1564
1565 (define_insn "*cmpfp_iu_mixed"
1566   [(set (reg:CCFPU FLAGS_REG)
1567         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1568                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1569   "TARGET_MIX_SSE_I387
1570    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1571    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1572   "* return output_fp_compare (insn, operands, 1, 1);"
1573   [(set_attr "type" "fcmp,ssecomi")
1574    (set_attr "prefix" "orig,maybe_vex")
1575    (set (attr "mode")
1576      (if_then_else (match_operand:SF 1 "" "")
1577         (const_string "SF")
1578         (const_string "DF")))
1579    (set (attr "prefix_rep")
1580         (if_then_else (eq_attr "type" "ssecomi")
1581                       (const_string "0")
1582                       (const_string "*")))
1583    (set (attr "prefix_data16")
1584         (cond [(eq_attr "type" "fcmp")
1585                  (const_string "*")
1586                (eq_attr "mode" "DF")
1587                  (const_string "1")
1588               ]
1589               (const_string "0")))
1590    (set_attr "athlon_decode" "vector")
1591    (set_attr "amdfam10_decode" "direct")
1592    (set_attr "bdver1_decode" "double")])
1593
1594 (define_insn "*cmpfp_iu_sse"
1595   [(set (reg:CCFPU FLAGS_REG)
1596         (compare:CCFPU (match_operand 0 "register_operand" "x")
1597                        (match_operand 1 "nonimmediate_operand" "xm")))]
1598   "TARGET_SSE_MATH
1599    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1600    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1601   "* return output_fp_compare (insn, operands, 1, 1);"
1602   [(set_attr "type" "ssecomi")
1603    (set_attr "prefix" "maybe_vex")
1604    (set (attr "mode")
1605      (if_then_else (match_operand:SF 1 "" "")
1606         (const_string "SF")
1607         (const_string "DF")))
1608    (set_attr "prefix_rep" "0")
1609    (set (attr "prefix_data16")
1610         (if_then_else (eq_attr "mode" "DF")
1611                       (const_string "1")
1612                       (const_string "0")))
1613    (set_attr "athlon_decode" "vector")
1614    (set_attr "amdfam10_decode" "direct")
1615    (set_attr "bdver1_decode" "double")])
1616
1617 (define_insn "*cmpfp_iu_387"
1618   [(set (reg:CCFPU FLAGS_REG)
1619         (compare:CCFPU (match_operand 0 "register_operand" "f")
1620                        (match_operand 1 "register_operand" "f")))]
1621   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1622    && TARGET_CMOVE
1623    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1624    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1625   "* return output_fp_compare (insn, operands, 1, 1);"
1626   [(set_attr "type" "fcmp")
1627    (set (attr "mode")
1628      (cond [(match_operand:SF 1 "" "")
1629               (const_string "SF")
1630             (match_operand:DF 1 "" "")
1631               (const_string "DF")
1632            ]
1633            (const_string "XF")))
1634    (set_attr "athlon_decode" "vector")
1635    (set_attr "amdfam10_decode" "direct")
1636    (set_attr "bdver1_decode" "direct")])
1637 \f
1638 ;; Push/pop instructions.
1639
1640 (define_insn "*push<mode>2"
1641   [(set (match_operand:DWI 0 "push_operand" "=<")
1642         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1643   ""
1644   "#")
1645
1646 (define_split
1647   [(set (match_operand:TI 0 "push_operand" "")
1648         (match_operand:TI 1 "general_operand" ""))]
1649   "TARGET_64BIT && reload_completed
1650    && !SSE_REG_P (operands[1])"
1651   [(const_int 0)]
1652   "ix86_split_long_move (operands); DONE;")
1653
1654 (define_insn "*pushdi2_rex64"
1655   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1656         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1657   "TARGET_64BIT"
1658   "@
1659    push{q}\t%1
1660    #"
1661   [(set_attr "type" "push,multi")
1662    (set_attr "mode" "DI")])
1663
1664 ;; Convert impossible pushes of immediate to existing instructions.
1665 ;; First try to get scratch register and go through it.  In case this
1666 ;; fails, push sign extended lower part first and then overwrite
1667 ;; upper part by 32bit move.
1668 (define_peephole2
1669   [(match_scratch:DI 2 "r")
1670    (set (match_operand:DI 0 "push_operand" "")
1671         (match_operand:DI 1 "immediate_operand" ""))]
1672   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1673    && !x86_64_immediate_operand (operands[1], DImode)"
1674   [(set (match_dup 2) (match_dup 1))
1675    (set (match_dup 0) (match_dup 2))])
1676
1677 ;; We need to define this as both peepholer and splitter for case
1678 ;; peephole2 pass is not run.
1679 ;; "&& 1" is needed to keep it from matching the previous pattern.
1680 (define_peephole2
1681   [(set (match_operand:DI 0 "push_operand" "")
1682         (match_operand:DI 1 "immediate_operand" ""))]
1683   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1684    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1685   [(set (match_dup 0) (match_dup 1))
1686    (set (match_dup 2) (match_dup 3))]
1687 {
1688   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1689
1690   operands[1] = gen_lowpart (DImode, operands[2]);
1691   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1692                                                    GEN_INT (4)));
1693 })
1694
1695 (define_split
1696   [(set (match_operand:DI 0 "push_operand" "")
1697         (match_operand:DI 1 "immediate_operand" ""))]
1698   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1699                     ? epilogue_completed : reload_completed)
1700    && !symbolic_operand (operands[1], DImode)
1701    && !x86_64_immediate_operand (operands[1], DImode)"
1702   [(set (match_dup 0) (match_dup 1))
1703    (set (match_dup 2) (match_dup 3))]
1704 {
1705   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1706
1707   operands[1] = gen_lowpart (DImode, operands[2]);
1708   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1709                                                    GEN_INT (4)));
1710 })
1711
1712 (define_split
1713   [(set (match_operand:DI 0 "push_operand" "")
1714         (match_operand:DI 1 "general_operand" ""))]
1715   "!TARGET_64BIT && reload_completed
1716    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1717   [(const_int 0)]
1718   "ix86_split_long_move (operands); DONE;")
1719
1720 (define_insn "*pushsi2"
1721   [(set (match_operand:SI 0 "push_operand" "=<")
1722         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1723   "!TARGET_64BIT"
1724   "push{l}\t%1"
1725   [(set_attr "type" "push")
1726    (set_attr "mode" "SI")])
1727
1728 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1729 ;; "push a byte/word".  But actually we use pushl, which has the effect
1730 ;; of rounding the amount pushed up to a word.
1731
1732 ;; For TARGET_64BIT we always round up to 8 bytes.
1733 (define_insn "*push<mode>2_rex64"
1734   [(set (match_operand:SWI124 0 "push_operand" "=X")
1735         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1736   "TARGET_64BIT"
1737   "push{q}\t%q1"
1738   [(set_attr "type" "push")
1739    (set_attr "mode" "DI")])
1740
1741 (define_insn "*push<mode>2"
1742   [(set (match_operand:SWI12 0 "push_operand" "=X")
1743         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1744   "!TARGET_64BIT"
1745   "push{l}\t%k1"
1746   [(set_attr "type" "push")
1747    (set_attr "mode" "SI")])
1748
1749 (define_insn "*push<mode>2_prologue"
1750   [(set (match_operand:P 0 "push_operand" "=<")
1751         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1752    (clobber (mem:BLK (scratch)))]
1753   ""
1754   "push{<imodesuffix>}\t%1"
1755   [(set_attr "type" "push")
1756    (set_attr "mode" "<MODE>")])
1757
1758 (define_insn "*pop<mode>1"
1759   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1760         (match_operand:P 1 "pop_operand" ">"))]
1761   ""
1762   "pop{<imodesuffix>}\t%0"
1763   [(set_attr "type" "pop")
1764    (set_attr "mode" "<MODE>")])
1765
1766 (define_insn "*pop<mode>1_epilogue"
1767   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768         (match_operand:P 1 "pop_operand" ">"))
1769    (clobber (mem:BLK (scratch)))]
1770   ""
1771   "pop{<imodesuffix>}\t%0"
1772   [(set_attr "type" "pop")
1773    (set_attr "mode" "<MODE>")])
1774 \f
1775 ;; Move instructions.
1776
1777 (define_expand "movoi"
1778   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1779         (match_operand:OI 1 "general_operand" ""))]
1780   "TARGET_AVX"
1781   "ix86_expand_move (OImode, operands); DONE;")
1782
1783 (define_expand "movti"
1784   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1785         (match_operand:TI 1 "nonimmediate_operand" ""))]
1786   "TARGET_64BIT || TARGET_SSE"
1787 {
1788   if (TARGET_64BIT)
1789     ix86_expand_move (TImode, operands);
1790   else if (push_operand (operands[0], TImode))
1791     ix86_expand_push (TImode, operands[1]);
1792   else
1793     ix86_expand_vector_move (TImode, operands);
1794   DONE;
1795 })
1796
1797 ;; This expands to what emit_move_complex would generate if we didn't
1798 ;; have a movti pattern.  Having this avoids problems with reload on
1799 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1800 ;; to have around all the time.
1801 (define_expand "movcdi"
1802   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1803         (match_operand:CDI 1 "general_operand" ""))]
1804   ""
1805 {
1806   if (push_operand (operands[0], CDImode))
1807     emit_move_complex_push (CDImode, operands[0], operands[1]);
1808   else
1809     emit_move_complex_parts (operands[0], operands[1]);
1810   DONE;
1811 })
1812
1813 (define_expand "mov<mode>"
1814   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1815         (match_operand:SWI1248x 1 "general_operand" ""))]
1816   ""
1817   "ix86_expand_move (<MODE>mode, operands); DONE;")
1818
1819 (define_insn "*mov<mode>_xor"
1820   [(set (match_operand:SWI48 0 "register_operand" "=r")
1821         (match_operand:SWI48 1 "const0_operand" ""))
1822    (clobber (reg:CC FLAGS_REG))]
1823   "reload_completed"
1824   "xor{l}\t%k0, %k0"
1825   [(set_attr "type" "alu1")
1826    (set_attr "mode" "SI")
1827    (set_attr "length_immediate" "0")])
1828
1829 (define_insn "*mov<mode>_or"
1830   [(set (match_operand:SWI48 0 "register_operand" "=r")
1831         (match_operand:SWI48 1 "const_int_operand" ""))
1832    (clobber (reg:CC FLAGS_REG))]
1833   "reload_completed
1834    && operands[1] == constm1_rtx"
1835   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1836   [(set_attr "type" "alu1")
1837    (set_attr "mode" "<MODE>")
1838    (set_attr "length_immediate" "1")])
1839
1840 (define_insn "*movoi_internal_avx"
1841   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1842         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1843   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1844 {
1845   switch (which_alternative)
1846     {
1847     case 0:
1848       return "vxorps\t%0, %0, %0";
1849     case 1:
1850     case 2:
1851       if (misaligned_operand (operands[0], OImode)
1852           || misaligned_operand (operands[1], OImode))
1853         return "vmovdqu\t{%1, %0|%0, %1}";
1854       else
1855         return "vmovdqa\t{%1, %0|%0, %1}";
1856     default:
1857       gcc_unreachable ();
1858     }
1859 }
1860   [(set_attr "type" "sselog1,ssemov,ssemov")
1861    (set_attr "prefix" "vex")
1862    (set_attr "mode" "OI")])
1863
1864 (define_insn "*movti_internal_rex64"
1865   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1866         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1867   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1868 {
1869   switch (which_alternative)
1870     {
1871     case 0:
1872     case 1:
1873       return "#";
1874     case 2:
1875       if (get_attr_mode (insn) == MODE_V4SF)
1876         return "%vxorps\t%0, %d0";
1877       else
1878         return "%vpxor\t%0, %d0";
1879     case 3:
1880     case 4:
1881       /* TDmode values are passed as TImode on the stack.  Moving them
1882          to stack may result in unaligned memory access.  */
1883       if (misaligned_operand (operands[0], TImode)
1884           || misaligned_operand (operands[1], TImode))
1885         {
1886           if (get_attr_mode (insn) == MODE_V4SF)
1887             return "%vmovups\t{%1, %0|%0, %1}";
1888          else
1889            return "%vmovdqu\t{%1, %0|%0, %1}";
1890         }
1891       else
1892         {
1893           if (get_attr_mode (insn) == MODE_V4SF)
1894             return "%vmovaps\t{%1, %0|%0, %1}";
1895          else
1896            return "%vmovdqa\t{%1, %0|%0, %1}";
1897         }
1898     default:
1899       gcc_unreachable ();
1900     }
1901 }
1902   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1903    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1904    (set (attr "mode")
1905         (cond [(eq_attr "alternative" "2,3")
1906                  (if_then_else
1907                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1908                        (const_int 0))
1909                    (const_string "V4SF")
1910                    (const_string "TI"))
1911                (eq_attr "alternative" "4")
1912                  (if_then_else
1913                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1914                             (const_int 0))
1915                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1916                             (const_int 0)))
1917                    (const_string "V4SF")
1918                    (const_string "TI"))]
1919                (const_string "DI")))])
1920
1921 (define_split
1922   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1923         (match_operand:TI 1 "general_operand" ""))]
1924   "reload_completed
1925    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1926   [(const_int 0)]
1927   "ix86_split_long_move (operands); DONE;")
1928
1929 (define_insn "*movti_internal_sse"
1930   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1931         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1932   "TARGET_SSE && !TARGET_64BIT
1933    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1934 {
1935   switch (which_alternative)
1936     {
1937     case 0:
1938       if (get_attr_mode (insn) == MODE_V4SF)
1939         return "%vxorps\t%0, %d0";
1940       else
1941         return "%vpxor\t%0, %d0";
1942     case 1:
1943     case 2:
1944       /* TDmode values are passed as TImode on the stack.  Moving them
1945          to stack may result in unaligned memory access.  */
1946       if (misaligned_operand (operands[0], TImode)
1947           || misaligned_operand (operands[1], TImode))
1948         {
1949           if (get_attr_mode (insn) == MODE_V4SF)
1950             return "%vmovups\t{%1, %0|%0, %1}";
1951          else
1952            return "%vmovdqu\t{%1, %0|%0, %1}";
1953         }
1954       else
1955         {
1956           if (get_attr_mode (insn) == MODE_V4SF)
1957             return "%vmovaps\t{%1, %0|%0, %1}";
1958          else
1959            return "%vmovdqa\t{%1, %0|%0, %1}";
1960         }
1961     default:
1962       gcc_unreachable ();
1963     }
1964 }
1965   [(set_attr "type" "sselog1,ssemov,ssemov")
1966    (set_attr "prefix" "maybe_vex")
1967    (set (attr "mode")
1968         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1969                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1970                         (const_int 0)))
1971                  (const_string "V4SF")
1972                (and (eq_attr "alternative" "2")
1973                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1974                         (const_int 0)))
1975                  (const_string "V4SF")]
1976               (const_string "TI")))])
1977
1978 (define_insn "*movdi_internal_rex64"
1979   [(set (match_operand:DI 0 "nonimmediate_operand"
1980           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1981         (match_operand:DI 1 "general_operand"
1982           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1983   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984 {
1985   switch (get_attr_type (insn))
1986     {
1987     case TYPE_SSECVT:
1988       if (SSE_REG_P (operands[0]))
1989         return "movq2dq\t{%1, %0|%0, %1}";
1990       else
1991         return "movdq2q\t{%1, %0|%0, %1}";
1992
1993     case TYPE_SSEMOV:
1994       if (TARGET_AVX)
1995         {
1996           if (get_attr_mode (insn) == MODE_TI)
1997             return "vmovdqa\t{%1, %0|%0, %1}";
1998           else
1999             return "vmovq\t{%1, %0|%0, %1}";
2000         }
2001
2002       if (get_attr_mode (insn) == MODE_TI)
2003         return "movdqa\t{%1, %0|%0, %1}";
2004       /* FALLTHRU */
2005
2006     case TYPE_MMXMOV:
2007       /* Moves from and into integer register is done using movd
2008          opcode with REX prefix.  */
2009       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2010         return "movd\t{%1, %0|%0, %1}";
2011       return "movq\t{%1, %0|%0, %1}";
2012
2013     case TYPE_SSELOG1:
2014       return "%vpxor\t%0, %d0";
2015
2016     case TYPE_MMX:
2017       return "pxor\t%0, %0";
2018
2019     case TYPE_MULTI:
2020       return "#";
2021
2022     case TYPE_LEA:
2023       return "lea{q}\t{%a1, %0|%0, %a1}";
2024
2025     default:
2026       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2027       if (get_attr_mode (insn) == MODE_SI)
2028         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2029       else if (which_alternative == 2)
2030         return "movabs{q}\t{%1, %0|%0, %1}";
2031       else
2032         return "mov{q}\t{%1, %0|%0, %1}";
2033     }
2034 }
2035   [(set (attr "type")
2036      (cond [(eq_attr "alternative" "5")
2037               (const_string "mmx")
2038             (eq_attr "alternative" "6,7,8,9,10")
2039               (const_string "mmxmov")
2040             (eq_attr "alternative" "11")
2041               (const_string "sselog1")
2042             (eq_attr "alternative" "12,13,14,15,16")
2043               (const_string "ssemov")
2044             (eq_attr "alternative" "17,18")
2045               (const_string "ssecvt")
2046             (eq_attr "alternative" "4")
2047               (const_string "multi")
2048             (match_operand:DI 1 "pic_32bit_operand" "")
2049               (const_string "lea")
2050            ]
2051            (const_string "imov")))
2052    (set (attr "modrm")
2053      (if_then_else
2054        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2055          (const_string "0")
2056          (const_string "*")))
2057    (set (attr "length_immediate")
2058      (if_then_else
2059        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2060          (const_string "8")
2061          (const_string "*")))
2062    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2063    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2064    (set (attr "prefix")
2065      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2066        (const_string "maybe_vex")
2067        (const_string "orig")))
2068    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it.  In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))])
2081
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 (define_peephole2
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090   [(set (match_dup 2) (match_dup 3))
2091    (set (match_dup 4) (match_dup 5))]
2092   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2093
2094 (define_split
2095   [(set (match_operand:DI 0 "memory_operand" "")
2096         (match_operand:DI 1 "immediate_operand" ""))]
2097   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098                     ? epilogue_completed : reload_completed)
2099    && !symbolic_operand (operands[1], DImode)
2100    && !x86_64_immediate_operand (operands[1], DImode)"
2101   [(set (match_dup 2) (match_dup 3))
2102    (set (match_dup 4) (match_dup 5))]
2103   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2104
2105 (define_insn "*movdi_internal"
2106   [(set (match_operand:DI 0 "nonimmediate_operand"
2107                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2108         (match_operand:DI 1 "general_operand"
2109                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2110   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2111   "@
2112    #
2113    #
2114    pxor\t%0, %0
2115    movq\t{%1, %0|%0, %1}
2116    movq\t{%1, %0|%0, %1}
2117    %vpxor\t%0, %d0
2118    %vmovq\t{%1, %0|%0, %1}
2119    %vmovdqa\t{%1, %0|%0, %1}
2120    %vmovq\t{%1, %0|%0, %1}
2121    xorps\t%0, %0
2122    movlps\t{%1, %0|%0, %1}
2123    movaps\t{%1, %0|%0, %1}
2124    movlps\t{%1, %0|%0, %1}"
2125   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2126    (set (attr "prefix")
2127      (if_then_else (eq_attr "alternative" "5,6,7,8")
2128        (const_string "vex")
2129        (const_string "orig")))
2130    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2131
2132 (define_split
2133   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2134         (match_operand:DI 1 "general_operand" ""))]
2135   "!TARGET_64BIT && reload_completed
2136    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2137    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2138   [(const_int 0)]
2139   "ix86_split_long_move (operands); DONE;")
2140
2141 (define_insn "*movsi_internal"
2142   [(set (match_operand:SI 0 "nonimmediate_operand"
2143                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2144         (match_operand:SI 1 "general_operand"
2145                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2146   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2147 {
2148   switch (get_attr_type (insn))
2149     {
2150     case TYPE_SSELOG1:
2151       if (get_attr_mode (insn) == MODE_TI)
2152         return "%vpxor\t%0, %d0";
2153       return "%vxorps\t%0, %d0";
2154
2155     case TYPE_SSEMOV:
2156       switch (get_attr_mode (insn))
2157         {
2158         case MODE_TI:
2159           return "%vmovdqa\t{%1, %0|%0, %1}";
2160         case MODE_V4SF:
2161           return "%vmovaps\t{%1, %0|%0, %1}";
2162         case MODE_SI:
2163           return "%vmovd\t{%1, %0|%0, %1}";
2164         case MODE_SF:
2165           return "%vmovss\t{%1, %0|%0, %1}";
2166         default:
2167           gcc_unreachable ();
2168         }
2169
2170     case TYPE_MMX:
2171       return "pxor\t%0, %0";
2172
2173     case TYPE_MMXMOV:
2174       if (get_attr_mode (insn) == MODE_DI)
2175         return "movq\t{%1, %0|%0, %1}";
2176       return "movd\t{%1, %0|%0, %1}";
2177
2178     case TYPE_LEA:
2179       return "lea{l}\t{%a1, %0|%0, %a1}";
2180
2181     default:
2182       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2183       return "mov{l}\t{%1, %0|%0, %1}";
2184     }
2185 }
2186   [(set (attr "type")
2187      (cond [(eq_attr "alternative" "2")
2188               (const_string "mmx")
2189             (eq_attr "alternative" "3,4,5")
2190               (const_string "mmxmov")
2191             (eq_attr "alternative" "6")
2192               (const_string "sselog1")
2193             (eq_attr "alternative" "7,8,9,10,11")
2194               (const_string "ssemov")
2195             (match_operand:DI 1 "pic_32bit_operand" "")
2196               (const_string "lea")
2197            ]
2198            (const_string "imov")))
2199    (set (attr "prefix")
2200      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2201        (const_string "orig")
2202        (const_string "maybe_vex")))
2203    (set (attr "prefix_data16")
2204      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2205        (const_string "1")
2206        (const_string "*")))
2207    (set (attr "mode")
2208      (cond [(eq_attr "alternative" "2,3")
2209               (const_string "DI")
2210             (eq_attr "alternative" "6,7")
2211               (if_then_else
2212                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2213                 (const_string "V4SF")
2214                 (const_string "TI"))
2215             (and (eq_attr "alternative" "8,9,10,11")
2216                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2217               (const_string "SF")
2218            ]
2219            (const_string "SI")))])
2220
2221 (define_insn "*movhi_internal"
2222   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2223         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2224   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2225 {
2226   switch (get_attr_type (insn))
2227     {
2228     case TYPE_IMOVX:
2229       /* movzwl is faster than movw on p2 due to partial word stalls,
2230          though not as fast as an aligned movl.  */
2231       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2232     default:
2233       if (get_attr_mode (insn) == MODE_SI)
2234         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2235       else
2236         return "mov{w}\t{%1, %0|%0, %1}";
2237     }
2238 }
2239   [(set (attr "type")
2240      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2241                 (const_int 0))
2242               (const_string "imov")
2243             (and (eq_attr "alternative" "0")
2244                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2245                           (const_int 0))
2246                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2247                           (const_int 0))))
2248               (const_string "imov")
2249             (and (eq_attr "alternative" "1,2")
2250                  (match_operand:HI 1 "aligned_operand" ""))
2251               (const_string "imov")
2252             (and (ne (symbol_ref "TARGET_MOVX")
2253                      (const_int 0))
2254                  (eq_attr "alternative" "0,2"))
2255               (const_string "imovx")
2256            ]
2257            (const_string "imov")))
2258     (set (attr "mode")
2259       (cond [(eq_attr "type" "imovx")
2260                (const_string "SI")
2261              (and (eq_attr "alternative" "1,2")
2262                   (match_operand:HI 1 "aligned_operand" ""))
2263                (const_string "SI")
2264              (and (eq_attr "alternative" "0")
2265                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2266                            (const_int 0))
2267                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2268                            (const_int 0))))
2269                (const_string "SI")
2270             ]
2271             (const_string "HI")))])
2272
2273 ;; Situation is quite tricky about when to choose full sized (SImode) move
2274 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2275 ;; partial register dependency machines (such as AMD Athlon), where QImode
2276 ;; moves issue extra dependency and for partial register stalls machines
2277 ;; that don't use QImode patterns (and QImode move cause stall on the next
2278 ;; instruction).
2279 ;;
2280 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2281 ;; register stall machines with, where we use QImode instructions, since
2282 ;; partial register stall can be caused there.  Then we use movzx.
2283 (define_insn "*movqi_internal"
2284   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2285         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2286   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2287 {
2288   switch (get_attr_type (insn))
2289     {
2290     case TYPE_IMOVX:
2291       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2292       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2293     default:
2294       if (get_attr_mode (insn) == MODE_SI)
2295         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2296       else
2297         return "mov{b}\t{%1, %0|%0, %1}";
2298     }
2299 }
2300   [(set (attr "type")
2301      (cond [(and (eq_attr "alternative" "5")
2302                  (not (match_operand:QI 1 "aligned_operand" "")))
2303               (const_string "imovx")
2304             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2305                 (const_int 0))
2306               (const_string "imov")
2307             (and (eq_attr "alternative" "3")
2308                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2309                           (const_int 0))
2310                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2311                           (const_int 0))))
2312               (const_string "imov")
2313             (eq_attr "alternative" "3,5")
2314               (const_string "imovx")
2315             (and (ne (symbol_ref "TARGET_MOVX")
2316                      (const_int 0))
2317                  (eq_attr "alternative" "2"))
2318               (const_string "imovx")
2319            ]
2320            (const_string "imov")))
2321    (set (attr "mode")
2322       (cond [(eq_attr "alternative" "3,4,5")
2323                (const_string "SI")
2324              (eq_attr "alternative" "6")
2325                (const_string "QI")
2326              (eq_attr "type" "imovx")
2327                (const_string "SI")
2328              (and (eq_attr "type" "imov")
2329                   (and (eq_attr "alternative" "0,1")
2330                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2331                                 (const_int 0))
2332                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2333                                      (const_int 0))
2334                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2335                                      (const_int 0))))))
2336                (const_string "SI")
2337              ;; Avoid partial register stalls when not using QImode arithmetic
2338              (and (eq_attr "type" "imov")
2339                   (and (eq_attr "alternative" "0,1")
2340                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2341                                 (const_int 0))
2342                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2343                                 (const_int 0)))))
2344                (const_string "SI")
2345            ]
2346            (const_string "QI")))])
2347
2348 ;; Stores and loads of ax to arbitrary constant address.
2349 ;; We fake an second form of instruction to force reload to load address
2350 ;; into register when rax is not available
2351 (define_insn "*movabs<mode>_1"
2352   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2353         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2354   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2355   "@
2356    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2357    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2358   [(set_attr "type" "imov")
2359    (set_attr "modrm" "0,*")
2360    (set_attr "length_address" "8,0")
2361    (set_attr "length_immediate" "0,*")
2362    (set_attr "memory" "store")
2363    (set_attr "mode" "<MODE>")])
2364
2365 (define_insn "*movabs<mode>_2"
2366   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2367         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2368   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2369   "@
2370    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2371    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2372   [(set_attr "type" "imov")
2373    (set_attr "modrm" "0,*")
2374    (set_attr "length_address" "8,0")
2375    (set_attr "length_immediate" "0")
2376    (set_attr "memory" "load")
2377    (set_attr "mode" "<MODE>")])
2378
2379 (define_insn "*swap<mode>"
2380   [(set (match_operand:SWI48 0 "register_operand" "+r")
2381         (match_operand:SWI48 1 "register_operand" "+r"))
2382    (set (match_dup 1)
2383         (match_dup 0))]
2384   ""
2385   "xchg{<imodesuffix>}\t%1, %0"
2386   [(set_attr "type" "imov")
2387    (set_attr "mode" "<MODE>")
2388    (set_attr "pent_pair" "np")
2389    (set_attr "athlon_decode" "vector")
2390    (set_attr "amdfam10_decode" "double")
2391    (set_attr "bdver1_decode" "double")])
2392
2393 (define_insn "*swap<mode>_1"
2394   [(set (match_operand:SWI12 0 "register_operand" "+r")
2395         (match_operand:SWI12 1 "register_operand" "+r"))
2396    (set (match_dup 1)
2397         (match_dup 0))]
2398   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2399   "xchg{l}\t%k1, %k0"
2400   [(set_attr "type" "imov")
2401    (set_attr "mode" "SI")
2402    (set_attr "pent_pair" "np")
2403    (set_attr "athlon_decode" "vector")
2404    (set_attr "amdfam10_decode" "double")
2405    (set_attr "bdver1_decode" "double")])
2406
2407 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2408 ;; is disabled for AMDFAM10
2409 (define_insn "*swap<mode>_2"
2410   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2411         (match_operand:SWI12 1 "register_operand" "+<r>"))
2412    (set (match_dup 1)
2413         (match_dup 0))]
2414   "TARGET_PARTIAL_REG_STALL"
2415   "xchg{<imodesuffix>}\t%1, %0"
2416   [(set_attr "type" "imov")
2417    (set_attr "mode" "<MODE>")
2418    (set_attr "pent_pair" "np")
2419    (set_attr "athlon_decode" "vector")])
2420
2421 (define_expand "movstrict<mode>"
2422   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2423         (match_operand:SWI12 1 "general_operand" ""))]
2424   ""
2425 {
2426   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2427     FAIL;
2428   if (GET_CODE (operands[0]) == SUBREG
2429       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2430     FAIL;
2431   /* Don't generate memory->memory moves, go through a register */
2432   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2433     operands[1] = force_reg (<MODE>mode, operands[1]);
2434 })
2435
2436 (define_insn "*movstrict<mode>_1"
2437   [(set (strict_low_part
2438           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2439         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2440   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2441    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2442   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2443   [(set_attr "type" "imov")
2444    (set_attr "mode" "<MODE>")])
2445
2446 (define_insn "*movstrict<mode>_xor"
2447   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2448         (match_operand:SWI12 1 "const0_operand" ""))
2449    (clobber (reg:CC FLAGS_REG))]
2450   "reload_completed"
2451   "xor{<imodesuffix>}\t%0, %0"
2452   [(set_attr "type" "alu1")
2453    (set_attr "mode" "<MODE>")
2454    (set_attr "length_immediate" "0")])
2455
2456 (define_insn "*mov<mode>_extv_1"
2457   [(set (match_operand:SWI24 0 "register_operand" "=R")
2458         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2459                             (const_int 8)
2460                             (const_int 8)))]
2461   ""
2462   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2463   [(set_attr "type" "imovx")
2464    (set_attr "mode" "SI")])
2465
2466 (define_insn "*movqi_extv_1_rex64"
2467   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2468         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2469                          (const_int 8)
2470                          (const_int 8)))]
2471   "TARGET_64BIT"
2472 {
2473   switch (get_attr_type (insn))
2474     {
2475     case TYPE_IMOVX:
2476       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2477     default:
2478       return "mov{b}\t{%h1, %0|%0, %h1}";
2479     }
2480 }
2481   [(set (attr "type")
2482      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2483                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2484                              (ne (symbol_ref "TARGET_MOVX")
2485                                  (const_int 0))))
2486         (const_string "imovx")
2487         (const_string "imov")))
2488    (set (attr "mode")
2489      (if_then_else (eq_attr "type" "imovx")
2490         (const_string "SI")
2491         (const_string "QI")))])
2492
2493 (define_insn "*movqi_extv_1"
2494   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2495         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2496                          (const_int 8)
2497                          (const_int 8)))]
2498   "!TARGET_64BIT"
2499 {
2500   switch (get_attr_type (insn))
2501     {
2502     case TYPE_IMOVX:
2503       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2504     default:
2505       return "mov{b}\t{%h1, %0|%0, %h1}";
2506     }
2507 }
2508   [(set (attr "type")
2509      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2510                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2511                              (ne (symbol_ref "TARGET_MOVX")
2512                                  (const_int 0))))
2513         (const_string "imovx")
2514         (const_string "imov")))
2515    (set (attr "mode")
2516      (if_then_else (eq_attr "type" "imovx")
2517         (const_string "SI")
2518         (const_string "QI")))])
2519
2520 (define_insn "*mov<mode>_extzv_1"
2521   [(set (match_operand:SWI48 0 "register_operand" "=R")
2522         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2523                             (const_int 8)
2524                             (const_int 8)))]
2525   ""
2526   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2527   [(set_attr "type" "imovx")
2528    (set_attr "mode" "SI")])
2529
2530 (define_insn "*movqi_extzv_2_rex64"
2531   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2532         (subreg:QI
2533           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2534                            (const_int 8)
2535                            (const_int 8)) 0))]
2536   "TARGET_64BIT"
2537 {
2538   switch (get_attr_type (insn))
2539     {
2540     case TYPE_IMOVX:
2541       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2542     default:
2543       return "mov{b}\t{%h1, %0|%0, %h1}";
2544     }
2545 }
2546   [(set (attr "type")
2547      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2548                         (ne (symbol_ref "TARGET_MOVX")
2549                             (const_int 0)))
2550         (const_string "imovx")
2551         (const_string "imov")))
2552    (set (attr "mode")
2553      (if_then_else (eq_attr "type" "imovx")
2554         (const_string "SI")
2555         (const_string "QI")))])
2556
2557 (define_insn "*movqi_extzv_2"
2558   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2559         (subreg:QI
2560           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2561                            (const_int 8)
2562                            (const_int 8)) 0))]
2563   "!TARGET_64BIT"
2564 {
2565   switch (get_attr_type (insn))
2566     {
2567     case TYPE_IMOVX:
2568       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2569     default:
2570       return "mov{b}\t{%h1, %0|%0, %h1}";
2571     }
2572 }
2573   [(set (attr "type")
2574      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2575                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2576                              (ne (symbol_ref "TARGET_MOVX")
2577                                  (const_int 0))))
2578         (const_string "imovx")
2579         (const_string "imov")))
2580    (set (attr "mode")
2581      (if_then_else (eq_attr "type" "imovx")
2582         (const_string "SI")
2583         (const_string "QI")))])
2584
2585 (define_expand "mov<mode>_insv_1"
2586   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2587                             (const_int 8)
2588                             (const_int 8))
2589         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2590
2591 (define_insn "*mov<mode>_insv_1_rex64"
2592   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2593                              (const_int 8)
2594                              (const_int 8))
2595         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2596   "TARGET_64BIT"
2597   "mov{b}\t{%b1, %h0|%h0, %b1}"
2598   [(set_attr "type" "imov")
2599    (set_attr "mode" "QI")])
2600
2601 (define_insn "*movsi_insv_1"
2602   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2603                          (const_int 8)
2604                          (const_int 8))
2605         (match_operand:SI 1 "general_operand" "Qmn"))]
2606   "!TARGET_64BIT"
2607   "mov{b}\t{%b1, %h0|%h0, %b1}"
2608   [(set_attr "type" "imov")
2609    (set_attr "mode" "QI")])
2610
2611 (define_insn "*movqi_insv_2"
2612   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2613                          (const_int 8)
2614                          (const_int 8))
2615         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2616                      (const_int 8)))]
2617   ""
2618   "mov{b}\t{%h1, %h0|%h0, %h1}"
2619   [(set_attr "type" "imov")
2620    (set_attr "mode" "QI")])
2621 \f
2622 ;; Floating point push instructions.
2623
2624 (define_insn "*pushtf"
2625   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2626         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2627   "TARGET_SSE2"
2628 {
2629   /* This insn should be already split before reg-stack.  */
2630   gcc_unreachable ();
2631 }
2632   [(set_attr "type" "multi")
2633    (set_attr "unit" "sse,*,*")
2634    (set_attr "mode" "TF,SI,SI")])
2635
2636 (define_split
2637   [(set (match_operand:TF 0 "push_operand" "")
2638         (match_operand:TF 1 "sse_reg_operand" ""))]
2639   "TARGET_SSE2 && reload_completed"
2640   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2641    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2642
2643 (define_split
2644   [(set (match_operand:TF 0 "push_operand" "")
2645         (match_operand:TF 1 "general_operand" ""))]
2646   "TARGET_SSE2 && reload_completed
2647    && !SSE_REG_P (operands[1])"
2648   [(const_int 0)]
2649   "ix86_split_long_move (operands); DONE;")
2650
2651 (define_insn "*pushxf"
2652   [(set (match_operand:XF 0 "push_operand" "=<,<")
2653         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2654   "optimize_function_for_speed_p (cfun)"
2655 {
2656   /* This insn should be already split before reg-stack.  */
2657   gcc_unreachable ();
2658 }
2659   [(set_attr "type" "multi")
2660    (set_attr "unit" "i387,*")
2661    (set_attr "mode" "XF,SI")])
2662
2663 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2664 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2665 ;; Pushing using integer instructions is longer except for constants
2666 ;; and direct memory references (assuming that any given constant is pushed
2667 ;; only once, but this ought to be handled elsewhere).
2668
2669 (define_insn "*pushxf_nointeger"
2670   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2671         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2672   "optimize_function_for_size_p (cfun)"
2673 {
2674   /* This insn should be already split before reg-stack.  */
2675   gcc_unreachable ();
2676 }
2677   [(set_attr "type" "multi")
2678    (set_attr "unit" "i387,*,*")
2679    (set_attr "mode" "XF,SI,SI")])
2680
2681 (define_split
2682   [(set (match_operand:XF 0 "push_operand" "")
2683         (match_operand:XF 1 "fp_register_operand" ""))]
2684   "reload_completed"
2685   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2688
2689 (define_split
2690   [(set (match_operand:XF 0 "push_operand" "")
2691         (match_operand:XF 1 "general_operand" ""))]
2692   "reload_completed
2693    && !FP_REG_P (operands[1])"
2694   [(const_int 0)]
2695   "ix86_split_long_move (operands); DONE;")
2696
2697 (define_insn "*pushdf"
2698   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2699         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2700   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2701 {
2702   /* This insn should be already split before reg-stack.  */
2703   gcc_unreachable ();
2704 }
2705   [(set_attr "type" "multi")
2706    (set_attr "unit" "i387,*,*")
2707    (set_attr "mode" "DF,SI,DF")])
2708
2709 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2710 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2711 ;; On the average, pushdf using integers can be still shorter.  Allow this
2712 ;; pattern for optimize_size too.
2713
2714 (define_insn "*pushdf_nointeger"
2715   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2716         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2717   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2718 {
2719   /* This insn should be already split before reg-stack.  */
2720   gcc_unreachable ();
2721 }
2722   [(set_attr "type" "multi")
2723    (set_attr "unit" "i387,*,*,*")
2724    (set_attr "mode" "DF,SI,SI,DF")])
2725
2726 ;; %%% Kill this when call knows how to work this out.
2727 (define_split
2728   [(set (match_operand:DF 0 "push_operand" "")
2729         (match_operand:DF 1 "any_fp_register_operand" ""))]
2730   "reload_completed"
2731   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2732    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2733
2734 (define_split
2735   [(set (match_operand:DF 0 "push_operand" "")
2736         (match_operand:DF 1 "general_operand" ""))]
2737   "reload_completed
2738    && !ANY_FP_REG_P (operands[1])"
2739   [(const_int 0)]
2740   "ix86_split_long_move (operands); DONE;")
2741
2742 (define_insn "*pushsf_rex64"
2743   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2744         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2745   "TARGET_64BIT"
2746 {
2747   /* Anything else should be already split before reg-stack.  */
2748   gcc_assert (which_alternative == 1);
2749   return "push{q}\t%q1";
2750 }
2751   [(set_attr "type" "multi,push,multi")
2752    (set_attr "unit" "i387,*,*")
2753    (set_attr "mode" "SF,DI,SF")])
2754
2755 (define_insn "*pushsf"
2756   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2757         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2758   "!TARGET_64BIT"
2759 {
2760   /* Anything else should be already split before reg-stack.  */
2761   gcc_assert (which_alternative == 1);
2762   return "push{l}\t%1";
2763 }
2764   [(set_attr "type" "multi,push,multi")
2765    (set_attr "unit" "i387,*,*")
2766    (set_attr "mode" "SF,SI,SF")])
2767
2768 (define_split
2769   [(set (match_operand:SF 0 "push_operand" "")
2770         (match_operand:SF 1 "memory_operand" ""))]
2771   "reload_completed
2772    && MEM_P (operands[1])
2773    && (operands[2] = find_constant_src (insn))"
2774   [(set (match_dup 0)
2775         (match_dup 2))])
2776
2777 ;; %%% Kill this when call knows how to work this out.
2778 (define_split
2779   [(set (match_operand:SF 0 "push_operand" "")
2780         (match_operand:SF 1 "any_fp_register_operand" ""))]
2781   "reload_completed"
2782   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2783    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2784   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2785 \f
2786 ;; Floating point move instructions.
2787
2788 (define_expand "movtf"
2789   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2790         (match_operand:TF 1 "nonimmediate_operand" ""))]
2791   "TARGET_SSE2"
2792 {
2793   ix86_expand_move (TFmode, operands);
2794   DONE;
2795 })
2796
2797 (define_expand "mov<mode>"
2798   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2799         (match_operand:X87MODEF 1 "general_operand" ""))]
2800   ""
2801   "ix86_expand_move (<MODE>mode, operands); DONE;")
2802
2803 (define_insn "*movtf_internal"
2804   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2805         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2806   "TARGET_SSE2
2807    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2808 {
2809   switch (which_alternative)
2810     {
2811     case 0:
2812     case 1:
2813       if (get_attr_mode (insn) == MODE_V4SF)
2814         return "%vmovaps\t{%1, %0|%0, %1}";
2815       else
2816         return "%vmovdqa\t{%1, %0|%0, %1}";
2817     case 2:
2818       if (get_attr_mode (insn) == MODE_V4SF)
2819         return "%vxorps\t%0, %d0";
2820       else
2821         return "%vpxor\t%0, %d0";
2822     case 3:
2823     case 4:
2824         return "#";
2825     default:
2826       gcc_unreachable ();
2827     }
2828 }
2829   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2830    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2831    (set (attr "mode")
2832         (cond [(eq_attr "alternative" "0,2")
2833                  (if_then_else
2834                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2835                        (const_int 0))
2836                    (const_string "V4SF")
2837                    (const_string "TI"))
2838                (eq_attr "alternative" "1")
2839                  (if_then_else
2840                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2841                             (const_int 0))
2842                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2843                             (const_int 0)))
2844                    (const_string "V4SF")
2845                    (const_string "TI"))]
2846                (const_string "DI")))])
2847
2848 (define_split
2849   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2850         (match_operand:TF 1 "general_operand" ""))]
2851   "reload_completed
2852    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2855
2856 (define_insn "*movxf_internal"
2857   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2858         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2859   "optimize_function_for_speed_p (cfun)
2860    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2861    && (reload_in_progress || reload_completed
2862        || GET_CODE (operands[1]) != CONST_DOUBLE
2863        || memory_operand (operands[0], XFmode))"
2864 {
2865   switch (which_alternative)
2866     {
2867     case 0:
2868     case 1:
2869       return output_387_reg_move (insn, operands);
2870
2871     case 2:
2872       return standard_80387_constant_opcode (operands[1]);
2873
2874     case 3: case 4:
2875       return "#";
2876
2877     default:
2878       gcc_unreachable ();
2879     }
2880 }
2881   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2882    (set_attr "mode" "XF,XF,XF,SI,SI")])
2883
2884 ;; Do not use integer registers when optimizing for size
2885 (define_insn "*movxf_internal_nointeger"
2886   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2887         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2888   "optimize_function_for_size_p (cfun)
2889    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2890    && (reload_in_progress || reload_completed
2891        || standard_80387_constant_p (operands[1])
2892        || GET_CODE (operands[1]) != CONST_DOUBLE
2893        || memory_operand (operands[0], XFmode))"
2894 {
2895   switch (which_alternative)
2896     {
2897     case 0:
2898     case 1:
2899       return output_387_reg_move (insn, operands);
2900
2901     case 2:
2902       return standard_80387_constant_opcode (operands[1]);
2903
2904     case 3: case 4:
2905       return "#";
2906     default:
2907       gcc_unreachable ();
2908     }
2909 }
2910   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2911    (set_attr "mode" "XF,XF,XF,SI,SI")])
2912
2913 (define_split
2914   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2915         (match_operand:XF 1 "general_operand" ""))]
2916   "reload_completed
2917    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2918    && ! (FP_REG_P (operands[0]) ||
2919          (GET_CODE (operands[0]) == SUBREG
2920           && FP_REG_P (SUBREG_REG (operands[0]))))
2921    && ! (FP_REG_P (operands[1]) ||
2922          (GET_CODE (operands[1]) == SUBREG
2923           && FP_REG_P (SUBREG_REG (operands[1]))))"
2924   [(const_int 0)]
2925   "ix86_split_long_move (operands); DONE;")
2926
2927 (define_insn "*movdf_internal_rex64"
2928   [(set (match_operand:DF 0 "nonimmediate_operand"
2929                 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2930         (match_operand:DF 1 "general_operand"
2931                 "fm,f,G,rm,r,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2932   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2933    && (reload_in_progress || reload_completed
2934        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2935        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2936            && optimize_function_for_size_p (cfun)
2937            && standard_80387_constant_p (operands[1]))
2938        || GET_CODE (operands[1]) != CONST_DOUBLE
2939        || memory_operand (operands[0], DFmode))"
2940 {
2941   switch (which_alternative)
2942     {
2943     case 0:
2944     case 1:
2945       return output_387_reg_move (insn, operands);
2946
2947     case 2:
2948       return standard_80387_constant_opcode (operands[1]);
2949
2950     case 3:
2951     case 4:
2952       return "mov{q}\t{%1, %0|%0, %1}";
2953
2954     case 5:
2955       return "movabs{q}\t{%1, %0|%0, %1}";
2956
2957     case 6:
2958       return "#";
2959
2960     case 7:
2961       switch (get_attr_mode (insn))
2962         {
2963         case MODE_V4SF:
2964           return "%vxorps\t%0, %d0";
2965         case MODE_V2DF:
2966           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2967             return "%vxorps\t%0, %d0";
2968           else
2969             return "%vxorpd\t%0, %d0";
2970         case MODE_TI:
2971           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2972             return "%vxorps\t%0, %d0";
2973           else
2974             return "%vpxor\t%0, %d0";
2975         default:
2976           gcc_unreachable ();
2977         }
2978     case 8:
2979     case 9:
2980     case 10:
2981       switch (get_attr_mode (insn))
2982         {
2983         case MODE_V4SF:
2984           return "%vmovaps\t{%1, %0|%0, %1}";
2985         case MODE_V2DF:
2986           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2987             return "%vmovaps\t{%1, %0|%0, %1}";
2988           else
2989             return "%vmovapd\t{%1, %0|%0, %1}";
2990         case MODE_TI:
2991           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2992             return "%vmovaps\t{%1, %0|%0, %1}";
2993           else
2994             return "%vmovdqa\t{%1, %0|%0, %1}";
2995         case MODE_DI:
2996           return "%vmovq\t{%1, %0|%0, %1}";
2997         case MODE_DF:
2998           if (TARGET_AVX)
2999             {
3000               if (REG_P (operands[0]) && REG_P (operands[1]))
3001                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3002               else
3003                 return "vmovsd\t{%1, %0|%0, %1}";
3004             }
3005           else
3006             return "movsd\t{%1, %0|%0, %1}";
3007         case MODE_V1DF:
3008           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3009         case MODE_V2SF:
3010           return "%vmovlps\t{%1, %d0|%d0, %1}";
3011         default:
3012           gcc_unreachable ();
3013         }
3014
3015     case 11:
3016     case 12:
3017     return "%vmovd\t{%1, %0|%0, %1}";
3018
3019     default:
3020       gcc_unreachable();
3021     }
3022 }
3023   [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3024    (set (attr "modrm")
3025      (if_then_else
3026        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3027          (const_string "0")
3028          (const_string "*")))
3029    (set (attr "length_immediate")
3030      (if_then_else
3031        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3032          (const_string "8")
3033          (const_string "*")))
3034    (set (attr "prefix")
3035      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3036        (const_string "orig")
3037        (const_string "maybe_vex")))
3038    (set (attr "prefix_data16")
3039      (if_then_else (eq_attr "mode" "V1DF")
3040        (const_string "1")
3041        (const_string "*")))
3042    (set (attr "mode")
3043         (cond [(eq_attr "alternative" "0,1,2")
3044                  (const_string "DF")
3045                (eq_attr "alternative" "3,4,5,6,11,12")
3046                  (const_string "DI")
3047
3048                /* For SSE1, we have many fewer alternatives.  */
3049                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3050                  (cond [(eq_attr "alternative" "7,8")
3051                           (const_string "V4SF")
3052                        ]
3053                    (const_string "V2SF"))
3054
3055                /* xorps is one byte shorter.  */
3056                (eq_attr "alternative" "7")
3057                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3058                             (const_int 0))
3059                           (const_string "V4SF")
3060                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3061                             (const_int 0))
3062                           (const_string "TI")
3063                        ]
3064                        (const_string "V2DF"))
3065
3066                /* For architectures resolving dependencies on
3067                   whole SSE registers use APD move to break dependency
3068                   chains, otherwise use short move to avoid extra work.
3069
3070                   movaps encodes one byte shorter.  */
3071                (eq_attr "alternative" "8")
3072                  (cond
3073                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3074                         (const_int 0))
3075                       (const_string "V4SF")
3076                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3077                         (const_int 0))
3078                       (const_string "V2DF")
3079                    ]
3080                    (const_string "DF"))
3081                /* For architectures resolving dependencies on register
3082                   parts we may avoid extra work to zero out upper part
3083                   of register.  */
3084                (eq_attr "alternative" "9")
3085                  (if_then_else
3086                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3087                        (const_int 0))
3088                    (const_string "V1DF")
3089                    (const_string "DF"))
3090               ]
3091               (const_string "DF")))])
3092
3093 (define_insn "*movdf_internal"
3094   [(set (match_operand:DF 0 "nonimmediate_operand"
3095                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3096         (match_operand:DF 1 "general_operand"
3097                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3098   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3099    && optimize_function_for_speed_p (cfun)
3100    && TARGET_INTEGER_DFMODE_MOVES
3101    && (reload_in_progress || reload_completed
3102        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3103        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3104            && optimize_function_for_size_p (cfun)
3105            && standard_80387_constant_p (operands[1]))
3106        || GET_CODE (operands[1]) != CONST_DOUBLE
3107        || memory_operand (operands[0], DFmode))"
3108 {
3109   switch (which_alternative)
3110     {
3111     case 0:
3112     case 1:
3113       return output_387_reg_move (insn, operands);
3114
3115     case 2:
3116       return standard_80387_constant_opcode (operands[1]);
3117
3118     case 3:
3119     case 4:
3120       return "#";
3121
3122     case 5:
3123       switch (get_attr_mode (insn))
3124         {
3125         case MODE_V4SF:
3126           return "xorps\t%0, %0";
3127         case MODE_V2DF:
3128           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3129             return "xorps\t%0, %0";
3130           else
3131             return "xorpd\t%0, %0";
3132         case MODE_TI:
3133           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3134             return "xorps\t%0, %0";
3135           else
3136             return "pxor\t%0, %0";
3137         default:
3138           gcc_unreachable ();
3139         }
3140     case 6:
3141     case 7:
3142     case 8:
3143       switch (get_attr_mode (insn))
3144         {
3145         case MODE_V4SF:
3146           return "movaps\t{%1, %0|%0, %1}";
3147         case MODE_V2DF:
3148           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3149             return "movaps\t{%1, %0|%0, %1}";
3150           else
3151             return "movapd\t{%1, %0|%0, %1}";
3152         case MODE_TI:
3153           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3154             return "movaps\t{%1, %0|%0, %1}";
3155           else
3156             return "movdqa\t{%1, %0|%0, %1}";
3157         case MODE_DI:
3158           return "movq\t{%1, %0|%0, %1}";
3159         case MODE_DF:
3160           return "movsd\t{%1, %0|%0, %1}";
3161         case MODE_V1DF:
3162           return "movlpd\t{%1, %0|%0, %1}";
3163         case MODE_V2SF:
3164           return "movlps\t{%1, %0|%0, %1}";
3165         default:
3166           gcc_unreachable ();
3167         }
3168
3169     default:
3170       gcc_unreachable();
3171     }
3172 }
3173   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3174    (set (attr "prefix_data16")
3175      (if_then_else (eq_attr "mode" "V1DF")
3176        (const_string "1")
3177        (const_string "*")))
3178    (set (attr "mode")
3179         (cond [(eq_attr "alternative" "0,1,2")
3180                  (const_string "DF")
3181                (eq_attr "alternative" "3,4")
3182                  (const_string "SI")
3183
3184                /* For SSE1, we have many fewer alternatives.  */
3185                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3186                  (cond [(eq_attr "alternative" "5,6")
3187                           (const_string "V4SF")
3188                        ]
3189                    (const_string "V2SF"))
3190
3191                /* xorps is one byte shorter.  */
3192                (eq_attr "alternative" "5")
3193                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3194                             (const_int 0))
3195                           (const_string "V4SF")
3196                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3197                             (const_int 0))
3198                           (const_string "TI")
3199                        ]
3200                        (const_string "V2DF"))
3201
3202                /* For architectures resolving dependencies on
3203                   whole SSE registers use APD move to break dependency
3204                   chains, otherwise use short move to avoid extra work.
3205
3206                   movaps encodes one byte shorter.  */
3207                (eq_attr "alternative" "6")
3208                  (cond
3209                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3210                         (const_int 0))
3211                       (const_string "V4SF")
3212                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3213                         (const_int 0))
3214                       (const_string "V2DF")
3215                    ]
3216                    (const_string "DF"))
3217                /* For architectures resolving dependencies on register
3218                   parts we may avoid extra work to zero out upper part
3219                   of register.  */
3220                (eq_attr "alternative" "7")
3221                  (if_then_else
3222                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3223                        (const_int 0))
3224                    (const_string "V1DF")
3225                    (const_string "DF"))
3226               ]
3227               (const_string "DF")))])
3228
3229 ;; Moving is usually shorter when only FP registers are used. This separate
3230 ;; movdf pattern avoids the use of integer registers for FP operations
3231 ;; when optimizing for size.
3232
3233 (define_insn "*movdf_internal_nointeger"
3234   [(set (match_operand:DF 0 "nonimmediate_operand"
3235                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3236         (match_operand:DF 1 "general_operand"
3237                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3238   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3239    && (optimize_function_for_size_p (cfun)
3240        || !TARGET_INTEGER_DFMODE_MOVES)
3241    && (reload_in_progress || reload_completed
3242        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3243        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3244            && optimize_function_for_size_p (cfun)
3245            && !memory_operand (operands[0], DFmode)
3246            && standard_80387_constant_p (operands[1]))
3247        || GET_CODE (operands[1]) != CONST_DOUBLE
3248        || ((optimize_function_for_size_p (cfun)
3249             || !TARGET_MEMORY_MISMATCH_STALL
3250             || reload_in_progress || reload_completed)
3251            && memory_operand (operands[0], DFmode)))"
3252 {
3253   switch (which_alternative)
3254     {
3255     case 0:
3256     case 1:
3257       return output_387_reg_move (insn, operands);
3258
3259     case 2:
3260       return standard_80387_constant_opcode (operands[1]);
3261
3262     case 3:
3263     case 4:
3264       return "#";
3265
3266     case 5:
3267       switch (get_attr_mode (insn))
3268         {
3269         case MODE_V4SF:
3270           return "%vxorps\t%0, %d0";
3271         case MODE_V2DF:
3272           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3273             return "%vxorps\t%0, %d0";
3274           else
3275             return "%vxorpd\t%0, %d0";
3276         case MODE_TI:
3277           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3278             return "%vxorps\t%0, %d0";
3279           else
3280             return "%vpxor\t%0, %d0";
3281         default:
3282           gcc_unreachable ();
3283         }
3284     case 6:
3285     case 7:
3286     case 8:
3287       switch (get_attr_mode (insn))
3288         {
3289         case MODE_V4SF:
3290           return "%vmovaps\t{%1, %0|%0, %1}";
3291         case MODE_V2DF:
3292           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3293             return "%vmovaps\t{%1, %0|%0, %1}";
3294           else
3295             return "%vmovapd\t{%1, %0|%0, %1}";
3296         case MODE_TI:
3297           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3298             return "%vmovaps\t{%1, %0|%0, %1}";
3299           else
3300             return "%vmovdqa\t{%1, %0|%0, %1}";
3301         case MODE_DI:
3302           return "%vmovq\t{%1, %0|%0, %1}";
3303         case MODE_DF:
3304           if (TARGET_AVX)
3305             {
3306               if (REG_P (operands[0]) && REG_P (operands[1]))
3307                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3308               else
3309                 return "vmovsd\t{%1, %0|%0, %1}";
3310             }
3311           else
3312             return "movsd\t{%1, %0|%0, %1}";
3313         case MODE_V1DF:
3314           if (TARGET_AVX)
3315             {
3316               if (REG_P (operands[0]))
3317                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3318               else
3319                 return "vmovlpd\t{%1, %0|%0, %1}";
3320             }
3321           else
3322             return "movlpd\t{%1, %0|%0, %1}";
3323         case MODE_V2SF:
3324           if (TARGET_AVX)
3325             {
3326               if (REG_P (operands[0]))
3327                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3328               else
3329                 return "vmovlps\t{%1, %0|%0, %1}";
3330             }
3331           else
3332             return "movlps\t{%1, %0|%0, %1}";
3333         default:
3334           gcc_unreachable ();
3335         }
3336
3337     default:
3338       gcc_unreachable ();
3339     }
3340 }
3341   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3342    (set (attr "prefix")
3343      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3344        (const_string "orig")
3345        (const_string "maybe_vex")))
3346    (set (attr "prefix_data16")
3347      (if_then_else (eq_attr "mode" "V1DF")
3348        (const_string "1")
3349        (const_string "*")))
3350    (set (attr "mode")
3351         (cond [(eq_attr "alternative" "0,1,2")
3352                  (const_string "DF")
3353                (eq_attr "alternative" "3,4")
3354                  (const_string "SI")
3355
3356                /* For SSE1, we have many fewer alternatives.  */
3357                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3358                  (cond [(eq_attr "alternative" "5,6")
3359                           (const_string "V4SF")
3360                        ]
3361                    (const_string "V2SF"))
3362
3363                /* xorps is one byte shorter.  */
3364                (eq_attr "alternative" "5")
3365                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3366                             (const_int 0))
3367                           (const_string "V4SF")
3368                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3369                             (const_int 0))
3370                           (const_string "TI")
3371                        ]
3372                        (const_string "V2DF"))
3373
3374                /* For architectures resolving dependencies on
3375                   whole SSE registers use APD move to break dependency
3376                   chains, otherwise use short move to avoid extra work.
3377
3378                   movaps encodes one byte shorter.  */
3379                (eq_attr "alternative" "6")
3380                  (cond
3381                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3382                         (const_int 0))
3383                       (const_string "V4SF")
3384                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3385                         (const_int 0))
3386                       (const_string "V2DF")
3387                    ]
3388                    (const_string "DF"))
3389                /* For architectures resolving dependencies on register
3390                   parts we may avoid extra work to zero out upper part
3391                   of register.  */
3392                (eq_attr "alternative" "7")
3393                  (if_then_else
3394                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3395                        (const_int 0))
3396                    (const_string "V1DF")
3397                    (const_string "DF"))
3398               ]
3399               (const_string "DF")))])
3400
3401 (define_split
3402   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3403         (match_operand:DF 1 "general_operand" ""))]
3404   "reload_completed
3405    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3406    && ! (ANY_FP_REG_P (operands[0]) ||
3407          (GET_CODE (operands[0]) == SUBREG
3408           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3409    && ! (ANY_FP_REG_P (operands[1]) ||
3410          (GET_CODE (operands[1]) == SUBREG
3411           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3412   [(const_int 0)]
3413   "ix86_split_long_move (operands); DONE;")
3414
3415 (define_insn "*movsf_internal"
3416   [(set (match_operand:SF 0 "nonimmediate_operand"
3417           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3418         (match_operand:SF 1 "general_operand"
3419           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3420   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3421    && (reload_in_progress || reload_completed
3422        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3423        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3424            && standard_80387_constant_p (operands[1]))
3425        || GET_CODE (operands[1]) != CONST_DOUBLE
3426        || memory_operand (operands[0], SFmode))"
3427 {
3428   switch (which_alternative)
3429     {
3430     case 0:
3431     case 1:
3432       return output_387_reg_move (insn, operands);
3433
3434     case 2:
3435       return standard_80387_constant_opcode (operands[1]);
3436
3437     case 3:
3438     case 4:
3439       return "mov{l}\t{%1, %0|%0, %1}";
3440     case 5:
3441       if (get_attr_mode (insn) == MODE_TI)
3442         return "%vpxor\t%0, %d0";
3443       else
3444         return "%vxorps\t%0, %d0";
3445     case 6:
3446       if (get_attr_mode (insn) == MODE_V4SF)
3447         return "%vmovaps\t{%1, %0|%0, %1}";
3448       else
3449         return "%vmovss\t{%1, %d0|%d0, %1}";
3450     case 7:
3451       if (TARGET_AVX)
3452         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3453                                    : "vmovss\t{%1, %0|%0, %1}";
3454       else
3455         return "movss\t{%1, %0|%0, %1}";
3456     case 8:
3457       return "%vmovss\t{%1, %0|%0, %1}";
3458
3459     case 9: case 10: case 14: case 15:
3460       return "movd\t{%1, %0|%0, %1}";
3461     case 12: case 13:
3462       return "%vmovd\t{%1, %0|%0, %1}";
3463
3464     case 11:
3465       return "movq\t{%1, %0|%0, %1}";
3466
3467     default:
3468       gcc_unreachable ();
3469     }
3470 }
3471   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3472    (set (attr "prefix")
3473      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3474        (const_string "maybe_vex")
3475        (const_string "orig")))
3476    (set (attr "mode")
3477         (cond [(eq_attr "alternative" "3,4,9,10")
3478                  (const_string "SI")
3479                (eq_attr "alternative" "5")
3480                  (if_then_else
3481                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3482                                  (const_int 0))
3483                              (ne (symbol_ref "TARGET_SSE2")
3484                                  (const_int 0)))
3485                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3486                             (const_int 0)))
3487                    (const_string "TI")
3488                    (const_string "V4SF"))
3489                /* For architectures resolving dependencies on
3490                   whole SSE registers use APS move to break dependency
3491                   chains, otherwise use short move to avoid extra work.
3492
3493                   Do the same for architectures resolving dependencies on
3494                   the parts.  While in DF mode it is better to always handle
3495                   just register parts, the SF mode is different due to lack
3496                   of instructions to load just part of the register.  It is
3497                   better to maintain the whole registers in single format
3498                   to avoid problems on using packed logical operations.  */
3499                (eq_attr "alternative" "6")
3500                  (if_then_else
3501                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3502                             (const_int 0))
3503                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3504                             (const_int 0)))
3505                    (const_string "V4SF")
3506                    (const_string "SF"))
3507                (eq_attr "alternative" "11")
3508                  (const_string "DI")]
3509                (const_string "SF")))])
3510
3511 (define_split
3512   [(set (match_operand 0 "register_operand" "")
3513         (match_operand 1 "memory_operand" ""))]
3514   "reload_completed
3515    && MEM_P (operands[1])
3516    && (GET_MODE (operands[0]) == TFmode
3517        || GET_MODE (operands[0]) == XFmode
3518        || GET_MODE (operands[0]) == DFmode
3519        || GET_MODE (operands[0]) == SFmode)
3520    && (operands[2] = find_constant_src (insn))"
3521   [(set (match_dup 0) (match_dup 2))]
3522 {
3523   rtx c = operands[2];
3524   rtx r = operands[0];
3525
3526   if (GET_CODE (r) == SUBREG)
3527     r = SUBREG_REG (r);
3528
3529   if (SSE_REG_P (r))
3530     {
3531       if (!standard_sse_constant_p (c))
3532         FAIL;
3533     }
3534   else if (FP_REG_P (r))
3535     {
3536       if (!standard_80387_constant_p (c))
3537         FAIL;
3538     }
3539   else if (MMX_REG_P (r))
3540     FAIL;
3541 })
3542
3543 (define_split
3544   [(set (match_operand 0 "register_operand" "")
3545         (float_extend (match_operand 1 "memory_operand" "")))]
3546   "reload_completed
3547    && MEM_P (operands[1])
3548    && (GET_MODE (operands[0]) == TFmode
3549        || GET_MODE (operands[0]) == XFmode
3550        || GET_MODE (operands[0]) == DFmode
3551        || GET_MODE (operands[0]) == SFmode)
3552    && (operands[2] = find_constant_src (insn))"
3553   [(set (match_dup 0) (match_dup 2))]
3554 {
3555   rtx c = operands[2];
3556   rtx r = operands[0];
3557
3558   if (GET_CODE (r) == SUBREG)
3559     r = SUBREG_REG (r);
3560
3561   if (SSE_REG_P (r))
3562     {
3563       if (!standard_sse_constant_p (c))
3564         FAIL;
3565     }
3566   else if (FP_REG_P (r))
3567     {
3568       if (!standard_80387_constant_p (c))
3569         FAIL;
3570     }
3571   else if (MMX_REG_P (r))
3572     FAIL;
3573 })
3574
3575 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3576 (define_split
3577   [(set (match_operand:X87MODEF 0 "register_operand" "")
3578         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3579   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3580    && (standard_80387_constant_p (operands[1]) == 8
3581        || standard_80387_constant_p (operands[1]) == 9)"
3582   [(set (match_dup 0)(match_dup 1))
3583    (set (match_dup 0)
3584         (neg:X87MODEF (match_dup 0)))]
3585 {
3586   REAL_VALUE_TYPE r;
3587
3588   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3589   if (real_isnegzero (&r))
3590     operands[1] = CONST0_RTX (<MODE>mode);
3591   else
3592     operands[1] = CONST1_RTX (<MODE>mode);
3593 })
3594
3595 (define_insn "swapxf"
3596   [(set (match_operand:XF 0 "register_operand" "+f")
3597         (match_operand:XF 1 "register_operand" "+f"))
3598    (set (match_dup 1)
3599         (match_dup 0))]
3600   "TARGET_80387"
3601 {
3602   if (STACK_TOP_P (operands[0]))
3603     return "fxch\t%1";
3604   else
3605     return "fxch\t%0";
3606 }
3607   [(set_attr "type" "fxch")
3608    (set_attr "mode" "XF")])
3609
3610 (define_insn "*swap<mode>"
3611   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3612         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3613    (set (match_dup 1)
3614         (match_dup 0))]
3615   "TARGET_80387 || reload_completed"
3616 {
3617   if (STACK_TOP_P (operands[0]))
3618     return "fxch\t%1";
3619   else
3620     return "fxch\t%0";
3621 }
3622   [(set_attr "type" "fxch")
3623    (set_attr "mode" "<MODE>")])
3624 \f
3625 ;; Zero extension instructions
3626
3627 (define_expand "zero_extendsidi2"
3628   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3629         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3630   ""
3631 {
3632   if (!TARGET_64BIT)
3633     {
3634       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3635       DONE;
3636     }
3637 })
3638
3639 (define_insn "*zero_extendsidi2_rex64"
3640   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3641         (zero_extend:DI
3642          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3643   "TARGET_64BIT"
3644   "@
3645    mov\t{%k1, %k0|%k0, %k1}
3646    #
3647    movd\t{%1, %0|%0, %1}
3648    movd\t{%1, %0|%0, %1}
3649    %vmovd\t{%1, %0|%0, %1}
3650    %vmovd\t{%1, %0|%0, %1}"
3651   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3652    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3653    (set_attr "prefix_0f" "0,*,*,*,*,*")
3654    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3655
3656 (define_split
3657   [(set (match_operand:DI 0 "memory_operand" "")
3658         (zero_extend:DI (match_dup 0)))]
3659   "TARGET_64BIT"
3660   [(set (match_dup 4) (const_int 0))]
3661   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3662
3663 ;; %%% Kill me once multi-word ops are sane.
3664 (define_insn "zero_extendsidi2_1"
3665   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3666         (zero_extend:DI
3667          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3668    (clobber (reg:CC FLAGS_REG))]
3669   "!TARGET_64BIT"
3670   "@
3671    #
3672    #
3673    #
3674    movd\t{%1, %0|%0, %1}
3675    movd\t{%1, %0|%0, %1}
3676    %vmovd\t{%1, %0|%0, %1}
3677    %vmovd\t{%1, %0|%0, %1}"
3678   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3679    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3680    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3681
3682 (define_split
3683   [(set (match_operand:DI 0 "register_operand" "")
3684         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3685    (clobber (reg:CC FLAGS_REG))]
3686   "!TARGET_64BIT && reload_completed
3687    && true_regnum (operands[0]) == true_regnum (operands[1])"
3688   [(set (match_dup 4) (const_int 0))]
3689   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3690
3691 (define_split
3692   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3693         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3694    (clobber (reg:CC FLAGS_REG))]
3695   "!TARGET_64BIT && reload_completed
3696    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3697   [(set (match_dup 3) (match_dup 1))
3698    (set (match_dup 4) (const_int 0))]
3699   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3700
3701 (define_insn "zero_extend<mode>di2"
3702   [(set (match_operand:DI 0 "register_operand" "=r")
3703         (zero_extend:DI
3704          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3705   "TARGET_64BIT"
3706   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3707   [(set_attr "type" "imovx")
3708    (set_attr "mode" "SI")])
3709
3710 (define_expand "zero_extendhisi2"
3711   [(set (match_operand:SI 0 "register_operand" "")
3712         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3713   ""
3714 {
3715   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3716     {
3717       operands[1] = force_reg (HImode, operands[1]);
3718       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3719       DONE;
3720     }
3721 })
3722
3723 (define_insn_and_split "zero_extendhisi2_and"
3724   [(set (match_operand:SI 0 "register_operand" "=r")
3725         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3726    (clobber (reg:CC FLAGS_REG))]
3727   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3728   "#"
3729   "&& reload_completed"
3730   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3731               (clobber (reg:CC FLAGS_REG))])]
3732   ""
3733   [(set_attr "type" "alu1")
3734    (set_attr "mode" "SI")])
3735
3736 (define_insn "*zero_extendhisi2_movzwl"
3737   [(set (match_operand:SI 0 "register_operand" "=r")
3738         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3739   "!TARGET_ZERO_EXTEND_WITH_AND
3740    || optimize_function_for_size_p (cfun)"
3741   "movz{wl|x}\t{%1, %0|%0, %1}"
3742   [(set_attr "type" "imovx")
3743    (set_attr "mode" "SI")])
3744
3745 (define_expand "zero_extendqi<mode>2"
3746   [(parallel
3747     [(set (match_operand:SWI24 0 "register_operand" "")
3748           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3749      (clobber (reg:CC FLAGS_REG))])])
3750
3751 (define_insn "*zero_extendqi<mode>2_and"
3752   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3753         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3754    (clobber (reg:CC FLAGS_REG))]
3755   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3756   "#"
3757   [(set_attr "type" "alu1")
3758    (set_attr "mode" "<MODE>")])
3759
3760 ;; When source and destination does not overlap, clear destination
3761 ;; first and then do the movb
3762 (define_split
3763   [(set (match_operand:SWI24 0 "register_operand" "")
3764         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3765    (clobber (reg:CC FLAGS_REG))]
3766   "reload_completed
3767    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3768    && ANY_QI_REG_P (operands[0])
3769    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3770    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3771   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3772 {
3773   operands[2] = gen_lowpart (QImode, operands[0]);
3774   ix86_expand_clear (operands[0]);
3775 })
3776
3777 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3778   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3779         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3780    (clobber (reg:CC FLAGS_REG))]
3781   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3782   "#"
3783   [(set_attr "type" "imovx,alu1")
3784    (set_attr "mode" "<MODE>")])
3785
3786 ;; For the movzbl case strip only the clobber
3787 (define_split
3788   [(set (match_operand:SWI24 0 "register_operand" "")
3789         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3790    (clobber (reg:CC FLAGS_REG))]
3791   "reload_completed
3792    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3793    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3794   [(set (match_dup 0)
3795         (zero_extend:SWI24 (match_dup 1)))])
3796
3797 ; zero extend to SImode to avoid partial register stalls
3798 (define_insn "*zero_extendqi<mode>2_movzbl"
3799   [(set (match_operand:SWI24 0 "register_operand" "=r")
3800         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3801   "reload_completed
3802    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3803   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3804   [(set_attr "type" "imovx")
3805    (set_attr "mode" "SI")])
3806
3807 ;; Rest is handled by single and.
3808 (define_split
3809   [(set (match_operand:SWI24 0 "register_operand" "")
3810         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3811    (clobber (reg:CC FLAGS_REG))]
3812   "reload_completed
3813    && true_regnum (operands[0]) == true_regnum (operands[1])"
3814   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3815               (clobber (reg:CC FLAGS_REG))])])
3816 \f
3817 ;; Sign extension instructions
3818
3819 (define_expand "extendsidi2"
3820   [(set (match_operand:DI 0 "register_operand" "")
3821         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3822   ""
3823 {
3824   if (!TARGET_64BIT)
3825     {
3826       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3827       DONE;
3828     }
3829 })
3830
3831 (define_insn "*extendsidi2_rex64"
3832   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3833         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3834   "TARGET_64BIT"
3835   "@
3836    {cltq|cdqe}
3837    movs{lq|x}\t{%1, %0|%0, %1}"
3838   [(set_attr "type" "imovx")
3839    (set_attr "mode" "DI")
3840    (set_attr "prefix_0f" "0")
3841    (set_attr "modrm" "0,1")])
3842
3843 (define_insn "extendsidi2_1"
3844   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3845         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3846    (clobber (reg:CC FLAGS_REG))
3847    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3848   "!TARGET_64BIT"
3849   "#")
3850
3851 ;; Extend to memory case when source register does die.
3852 (define_split
3853   [(set (match_operand:DI 0 "memory_operand" "")
3854         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3855    (clobber (reg:CC FLAGS_REG))
3856    (clobber (match_operand:SI 2 "register_operand" ""))]
3857   "(reload_completed
3858     && dead_or_set_p (insn, operands[1])
3859     && !reg_mentioned_p (operands[1], operands[0]))"
3860   [(set (match_dup 3) (match_dup 1))
3861    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3862               (clobber (reg:CC FLAGS_REG))])
3863    (set (match_dup 4) (match_dup 1))]
3864   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3865
3866 ;; Extend to memory case when source register does not die.
3867 (define_split
3868   [(set (match_operand:DI 0 "memory_operand" "")
3869         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3870    (clobber (reg:CC FLAGS_REG))
3871    (clobber (match_operand:SI 2 "register_operand" ""))]
3872   "reload_completed"
3873   [(const_int 0)]
3874 {
3875   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3876
3877   emit_move_insn (operands[3], operands[1]);
3878
3879   /* Generate a cltd if possible and doing so it profitable.  */
3880   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3881       && true_regnum (operands[1]) == AX_REG
3882       && true_regnum (operands[2]) == DX_REG)
3883     {
3884       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3885     }
3886   else
3887     {
3888       emit_move_insn (operands[2], operands[1]);
3889       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3890     }
3891   emit_move_insn (operands[4], operands[2]);
3892   DONE;
3893 })
3894
3895 ;; Extend to register case.  Optimize case where source and destination
3896 ;; registers match and cases where we can use cltd.
3897 (define_split
3898   [(set (match_operand:DI 0 "register_operand" "")
3899         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3900    (clobber (reg:CC FLAGS_REG))
3901    (clobber (match_scratch:SI 2 ""))]
3902   "reload_completed"
3903   [(const_int 0)]
3904 {
3905   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3906
3907   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3908     emit_move_insn (operands[3], operands[1]);
3909
3910   /* Generate a cltd if possible and doing so it profitable.  */
3911   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3912       && true_regnum (operands[3]) == AX_REG
3913       && true_regnum (operands[4]) == DX_REG)
3914     {
3915       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3916       DONE;
3917     }
3918
3919   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3920     emit_move_insn (operands[4], operands[1]);
3921
3922   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3923   DONE;
3924 })
3925
3926 (define_insn "extend<mode>di2"
3927   [(set (match_operand:DI 0 "register_operand" "=r")
3928         (sign_extend:DI
3929          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3930   "TARGET_64BIT"
3931   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3932   [(set_attr "type" "imovx")
3933    (set_attr "mode" "DI")])
3934
3935 (define_insn "extendhisi2"
3936   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3937         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3938   ""
3939 {
3940   switch (get_attr_prefix_0f (insn))
3941     {
3942     case 0:
3943       return "{cwtl|cwde}";
3944     default:
3945       return "movs{wl|x}\t{%1, %0|%0, %1}";
3946     }
3947 }
3948   [(set_attr "type" "imovx")
3949    (set_attr "mode" "SI")
3950    (set (attr "prefix_0f")
3951      ;; movsx is short decodable while cwtl is vector decoded.
3952      (if_then_else (and (eq_attr "cpu" "!k6")
3953                         (eq_attr "alternative" "0"))
3954         (const_string "0")
3955         (const_string "1")))
3956    (set (attr "modrm")
3957      (if_then_else (eq_attr "prefix_0f" "0")
3958         (const_string "0")
3959         (const_string "1")))])
3960
3961 (define_insn "*extendhisi2_zext"
3962   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3963         (zero_extend:DI
3964          (sign_extend:SI
3965           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3966   "TARGET_64BIT"
3967 {
3968   switch (get_attr_prefix_0f (insn))
3969     {
3970     case 0:
3971       return "{cwtl|cwde}";
3972     default:
3973       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3974     }
3975 }
3976   [(set_attr "type" "imovx")
3977    (set_attr "mode" "SI")
3978    (set (attr "prefix_0f")
3979      ;; movsx is short decodable while cwtl is vector decoded.
3980      (if_then_else (and (eq_attr "cpu" "!k6")
3981                         (eq_attr "alternative" "0"))
3982         (const_string "0")
3983         (const_string "1")))
3984    (set (attr "modrm")
3985      (if_then_else (eq_attr "prefix_0f" "0")
3986         (const_string "0")
3987         (const_string "1")))])
3988
3989 (define_insn "extendqisi2"
3990   [(set (match_operand:SI 0 "register_operand" "=r")
3991         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3992   ""
3993   "movs{bl|x}\t{%1, %0|%0, %1}"
3994    [(set_attr "type" "imovx")
3995     (set_attr "mode" "SI")])
3996
3997 (define_insn "*extendqisi2_zext"
3998   [(set (match_operand:DI 0 "register_operand" "=r")
3999         (zero_extend:DI
4000           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4001   "TARGET_64BIT"
4002   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4003    [(set_attr "type" "imovx")
4004     (set_attr "mode" "SI")])
4005
4006 (define_insn "extendqihi2"
4007   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4008         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4009   ""
4010 {
4011   switch (get_attr_prefix_0f (insn))
4012     {
4013     case 0:
4014       return "{cbtw|cbw}";
4015     default:
4016       return "movs{bw|x}\t{%1, %0|%0, %1}";
4017     }
4018 }
4019   [(set_attr "type" "imovx")
4020    (set_attr "mode" "HI")
4021    (set (attr "prefix_0f")
4022      ;; movsx is short decodable while cwtl is vector decoded.
4023      (if_then_else (and (eq_attr "cpu" "!k6")
4024                         (eq_attr "alternative" "0"))
4025         (const_string "0")
4026         (const_string "1")))
4027    (set (attr "modrm")
4028      (if_then_else (eq_attr "prefix_0f" "0")
4029         (const_string "0")
4030         (const_string "1")))])
4031 \f
4032 ;; Conversions between float and double.
4033
4034 ;; These are all no-ops in the model used for the 80387.
4035 ;; So just emit moves.
4036
4037 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4038 (define_split
4039   [(set (match_operand:DF 0 "push_operand" "")
4040         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4041   "reload_completed"
4042   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4043    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4044
4045 (define_split
4046   [(set (match_operand:XF 0 "push_operand" "")
4047         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4048   "reload_completed"
4049   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4050    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4051   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4052
4053 (define_expand "extendsfdf2"
4054   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4055         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4056   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4057 {
4058   /* ??? Needed for compress_float_constant since all fp constants
4059      are TARGET_LEGITIMATE_CONSTANT_P.  */
4060   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4061     {
4062       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4063           && standard_80387_constant_p (operands[1]) > 0)
4064         {
4065           operands[1] = simplify_const_unary_operation
4066             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4067           emit_move_insn_1 (operands[0], operands[1]);
4068           DONE;
4069         }
4070       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4071     }
4072 })
4073
4074 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4075    cvtss2sd:
4076       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4077       cvtps2pd xmm2,xmm1
4078    We do the conversion post reload to avoid producing of 128bit spills
4079    that might lead to ICE on 32bit target.  The sequence unlikely combine
4080    anyway.  */
4081 (define_split
4082   [(set (match_operand:DF 0 "register_operand" "")
4083         (float_extend:DF
4084           (match_operand:SF 1 "nonimmediate_operand" "")))]
4085   "TARGET_USE_VECTOR_FP_CONVERTS
4086    && optimize_insn_for_speed_p ()
4087    && reload_completed && SSE_REG_P (operands[0])"
4088    [(set (match_dup 2)
4089          (float_extend:V2DF
4090            (vec_select:V2SF
4091              (match_dup 3)
4092              (parallel [(const_int 0) (const_int 1)]))))]
4093 {
4094   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4095   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4096   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4097      Try to avoid move when unpacking can be done in source.  */
4098   if (REG_P (operands[1]))
4099     {
4100       /* If it is unsafe to overwrite upper half of source, we need
4101          to move to destination and unpack there.  */
4102       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4103            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4104           && true_regnum (operands[0]) != true_regnum (operands[1]))
4105         {
4106           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4107           emit_move_insn (tmp, operands[1]);
4108         }
4109       else
4110         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4111       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4112                                              operands[3]));
4113     }
4114   else
4115     emit_insn (gen_vec_setv4sf_0 (operands[3],
4116                                   CONST0_RTX (V4SFmode), operands[1]));
4117 })
4118
4119 (define_insn "*extendsfdf2_mixed"
4120   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4121         (float_extend:DF
4122           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4123   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4124 {
4125   switch (which_alternative)
4126     {
4127     case 0:
4128     case 1:
4129       return output_387_reg_move (insn, operands);
4130
4131     case 2:
4132       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4133
4134     default:
4135       gcc_unreachable ();
4136     }
4137 }
4138   [(set_attr "type" "fmov,fmov,ssecvt")
4139    (set_attr "prefix" "orig,orig,maybe_vex")
4140    (set_attr "mode" "SF,XF,DF")])
4141
4142 (define_insn "*extendsfdf2_sse"
4143   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4144         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4145   "TARGET_SSE2 && TARGET_SSE_MATH"
4146   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4147   [(set_attr "type" "ssecvt")
4148    (set_attr "prefix" "maybe_vex")
4149    (set_attr "mode" "DF")])
4150
4151 (define_insn "*extendsfdf2_i387"
4152   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4153         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4154   "TARGET_80387"
4155   "* return output_387_reg_move (insn, operands);"
4156   [(set_attr "type" "fmov")
4157    (set_attr "mode" "SF,XF")])
4158
4159 (define_expand "extend<mode>xf2"
4160   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4161         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4162   "TARGET_80387"
4163 {
4164   /* ??? Needed for compress_float_constant since all fp constants
4165      are TARGET_LEGITIMATE_CONSTANT_P.  */
4166   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4167     {
4168       if (standard_80387_constant_p (operands[1]) > 0)
4169         {
4170           operands[1] = simplify_const_unary_operation
4171             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4172           emit_move_insn_1 (operands[0], operands[1]);
4173           DONE;
4174         }
4175       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4176     }
4177 })
4178
4179 (define_insn "*extend<mode>xf2_i387"
4180   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4181         (float_extend:XF
4182           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4183   "TARGET_80387"
4184   "* return output_387_reg_move (insn, operands);"
4185   [(set_attr "type" "fmov")
4186    (set_attr "mode" "<MODE>,XF")])
4187
4188 ;; %%% This seems bad bad news.
4189 ;; This cannot output into an f-reg because there is no way to be sure
4190 ;; of truncating in that case.  Otherwise this is just like a simple move
4191 ;; insn.  So we pretend we can output to a reg in order to get better
4192 ;; register preferencing, but we really use a stack slot.
4193
4194 ;; Conversion from DFmode to SFmode.
4195
4196 (define_expand "truncdfsf2"
4197   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4198         (float_truncate:SF
4199           (match_operand:DF 1 "nonimmediate_operand" "")))]
4200   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4201 {
4202   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4203     ;
4204   else if (flag_unsafe_math_optimizations)
4205     ;
4206   else
4207     {
4208       enum ix86_stack_slot slot = (virtuals_instantiated
4209                                    ? SLOT_TEMP
4210                                    : SLOT_VIRTUAL);
4211       rtx temp = assign_386_stack_local (SFmode, slot);
4212       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4213       DONE;
4214     }
4215 })
4216
4217 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4218    cvtsd2ss:
4219       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4220       cvtpd2ps xmm2,xmm1
4221    We do the conversion post reload to avoid producing of 128bit spills
4222    that might lead to ICE on 32bit target.  The sequence unlikely combine
4223    anyway.  */
4224 (define_split
4225   [(set (match_operand:SF 0 "register_operand" "")
4226         (float_truncate:SF
4227           (match_operand:DF 1 "nonimmediate_operand" "")))]
4228   "TARGET_USE_VECTOR_FP_CONVERTS
4229    && optimize_insn_for_speed_p ()
4230    && reload_completed && SSE_REG_P (operands[0])"
4231    [(set (match_dup 2)
4232          (vec_concat:V4SF
4233            (float_truncate:V2SF
4234              (match_dup 4))
4235            (match_dup 3)))]
4236 {
4237   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4238   operands[3] = CONST0_RTX (V2SFmode);
4239   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4240   /* Use movsd for loading from memory, unpcklpd for registers.
4241      Try to avoid move when unpacking can be done in source, or SSE3
4242      movddup is available.  */
4243   if (REG_P (operands[1]))
4244     {
4245       if (!TARGET_SSE3
4246           && true_regnum (operands[0]) != true_regnum (operands[1])
4247           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4248               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4249         {
4250           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4251           emit_move_insn (tmp, operands[1]);
4252           operands[1] = tmp;
4253         }
4254       else if (!TARGET_SSE3)
4255         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4256       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4257     }
4258   else
4259     emit_insn (gen_sse2_loadlpd (operands[4],
4260                                  CONST0_RTX (V2DFmode), operands[1]));
4261 })
4262
4263 (define_expand "truncdfsf2_with_temp"
4264   [(parallel [(set (match_operand:SF 0 "" "")
4265                    (float_truncate:SF (match_operand:DF 1 "" "")))
4266               (clobber (match_operand:SF 2 "" ""))])])
4267
4268 (define_insn "*truncdfsf_fast_mixed"
4269   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4270         (float_truncate:SF
4271           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4272   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4273 {
4274   switch (which_alternative)
4275     {
4276     case 0:
4277       return output_387_reg_move (insn, operands);
4278     case 1:
4279       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4280     default:
4281       gcc_unreachable ();
4282     }
4283 }
4284   [(set_attr "type" "fmov,ssecvt")
4285    (set_attr "prefix" "orig,maybe_vex")
4286    (set_attr "mode" "SF")])
4287
4288 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4289 ;; because nothing we do here is unsafe.
4290 (define_insn "*truncdfsf_fast_sse"
4291   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4292         (float_truncate:SF
4293           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4294   "TARGET_SSE2 && TARGET_SSE_MATH"
4295   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4296   [(set_attr "type" "ssecvt")
4297    (set_attr "prefix" "maybe_vex")
4298    (set_attr "mode" "SF")])
4299
4300 (define_insn "*truncdfsf_fast_i387"
4301   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4302         (float_truncate:SF
4303           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4304   "TARGET_80387 && flag_unsafe_math_optimizations"
4305   "* return output_387_reg_move (insn, operands);"
4306   [(set_attr "type" "fmov")
4307    (set_attr "mode" "SF")])
4308
4309 (define_insn "*truncdfsf_mixed"
4310   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4311         (float_truncate:SF
4312           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4313    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4314   "TARGET_MIX_SSE_I387"
4315 {
4316   switch (which_alternative)
4317     {
4318     case 0:
4319       return output_387_reg_move (insn, operands);
4320     case 1:
4321       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4322
4323     default:
4324       return "#";
4325     }
4326 }
4327   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4328    (set_attr "unit" "*,*,i387,i387,i387")
4329    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4330    (set_attr "mode" "SF")])
4331
4332 (define_insn "*truncdfsf_i387"
4333   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4334         (float_truncate:SF
4335           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4336    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4337   "TARGET_80387"
4338 {
4339   switch (which_alternative)
4340     {
4341     case 0:
4342       return output_387_reg_move (insn, operands);
4343
4344     default:
4345       return "#";
4346     }
4347 }
4348   [(set_attr "type" "fmov,multi,multi,multi")
4349    (set_attr "unit" "*,i387,i387,i387")
4350    (set_attr "mode" "SF")])
4351
4352 (define_insn "*truncdfsf2_i387_1"
4353   [(set (match_operand:SF 0 "memory_operand" "=m")
4354         (float_truncate:SF
4355           (match_operand:DF 1 "register_operand" "f")))]
4356   "TARGET_80387
4357    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4358    && !TARGET_MIX_SSE_I387"
4359   "* return output_387_reg_move (insn, operands);"
4360   [(set_attr "type" "fmov")
4361    (set_attr "mode" "SF")])
4362
4363 (define_split
4364   [(set (match_operand:SF 0 "register_operand" "")
4365         (float_truncate:SF
4366          (match_operand:DF 1 "fp_register_operand" "")))
4367    (clobber (match_operand 2 "" ""))]
4368   "reload_completed"
4369   [(set (match_dup 2) (match_dup 1))
4370    (set (match_dup 0) (match_dup 2))]
4371   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4372
4373 ;; Conversion from XFmode to {SF,DF}mode
4374
4375 (define_expand "truncxf<mode>2"
4376   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4377                    (float_truncate:MODEF
4378                      (match_operand:XF 1 "register_operand" "")))
4379               (clobber (match_dup 2))])]
4380   "TARGET_80387"
4381 {
4382   if (flag_unsafe_math_optimizations)
4383     {
4384       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4385       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4386       if (reg != operands[0])
4387         emit_move_insn (operands[0], reg);
4388       DONE;
4389     }
4390   else
4391     {
4392       enum ix86_stack_slot slot = (virtuals_instantiated
4393                                    ? SLOT_TEMP
4394                                    : SLOT_VIRTUAL);
4395       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4396     }
4397 })
4398
4399 (define_insn "*truncxfsf2_mixed"
4400   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4401         (float_truncate:SF
4402           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4403    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4404   "TARGET_80387"
4405 {
4406   gcc_assert (!which_alternative);
4407   return output_387_reg_move (insn, operands);
4408 }
4409   [(set_attr "type" "fmov,multi,multi,multi")
4410    (set_attr "unit" "*,i387,i387,i387")
4411    (set_attr "mode" "SF")])
4412
4413 (define_insn "*truncxfdf2_mixed"
4414   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4415         (float_truncate:DF
4416           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4417    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4418   "TARGET_80387"
4419 {
4420   gcc_assert (!which_alternative);
4421   return output_387_reg_move (insn, operands);
4422 }
4423   [(set_attr "type" "fmov,multi,multi,multi")
4424    (set_attr "unit" "*,i387,i387,i387")
4425    (set_attr "mode" "DF")])
4426
4427 (define_insn "truncxf<mode>2_i387_noop"
4428   [(set (match_operand:MODEF 0 "register_operand" "=f")
4429         (float_truncate:MODEF
4430           (match_operand:XF 1 "register_operand" "f")))]
4431   "TARGET_80387 && flag_unsafe_math_optimizations"
4432   "* return output_387_reg_move (insn, operands);"
4433   [(set_attr "type" "fmov")
4434    (set_attr "mode" "<MODE>")])
4435
4436 (define_insn "*truncxf<mode>2_i387"
4437   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4438         (float_truncate:MODEF
4439           (match_operand:XF 1 "register_operand" "f")))]
4440   "TARGET_80387"
4441   "* return output_387_reg_move (insn, operands);"
4442   [(set_attr "type" "fmov")
4443    (set_attr "mode" "<MODE>")])
4444
4445 (define_split
4446   [(set (match_operand:MODEF 0 "register_operand" "")
4447         (float_truncate:MODEF
4448           (match_operand:XF 1 "register_operand" "")))
4449    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4450   "TARGET_80387 && reload_completed"
4451   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4452    (set (match_dup 0) (match_dup 2))])
4453
4454 (define_split
4455   [(set (match_operand:MODEF 0 "memory_operand" "")
4456         (float_truncate:MODEF
4457           (match_operand:XF 1 "register_operand" "")))
4458    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4459   "TARGET_80387"
4460   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4461 \f
4462 ;; Signed conversion to DImode.
4463
4464 (define_expand "fix_truncxfdi2"
4465   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4466                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4467               (clobber (reg:CC FLAGS_REG))])]
4468   "TARGET_80387"
4469 {
4470   if (TARGET_FISTTP)
4471    {
4472      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4473      DONE;
4474    }
4475 })
4476
4477 (define_expand "fix_trunc<mode>di2"
4478   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4479                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4480               (clobber (reg:CC FLAGS_REG))])]
4481   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4482 {
4483   if (TARGET_FISTTP
4484       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4485    {
4486      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4487      DONE;
4488    }
4489   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4490    {
4491      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4492      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4493      if (out != operands[0])
4494         emit_move_insn (operands[0], out);
4495      DONE;
4496    }
4497 })
4498
4499 ;; Signed conversion to SImode.
4500
4501 (define_expand "fix_truncxfsi2"
4502   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4503                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4504               (clobber (reg:CC FLAGS_REG))])]
4505   "TARGET_80387"
4506 {
4507   if (TARGET_FISTTP)
4508    {
4509      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4510      DONE;
4511    }
4512 })
4513
4514 (define_expand "fix_trunc<mode>si2"
4515   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4516                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4517               (clobber (reg:CC FLAGS_REG))])]
4518   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4519 {
4520   if (TARGET_FISTTP
4521       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4522    {
4523      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4524      DONE;
4525    }
4526   if (SSE_FLOAT_MODE_P (<MODE>mode))
4527    {
4528      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4529      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4530      if (out != operands[0])
4531         emit_move_insn (operands[0], out);
4532      DONE;
4533    }
4534 })
4535
4536 ;; Signed conversion to HImode.
4537
4538 (define_expand "fix_trunc<mode>hi2"
4539   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4540                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4541               (clobber (reg:CC FLAGS_REG))])]
4542   "TARGET_80387
4543    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4544 {
4545   if (TARGET_FISTTP)
4546    {
4547      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4548      DONE;
4549    }
4550 })
4551
4552 ;; Unsigned conversion to SImode.
4553
4554 (define_expand "fixuns_trunc<mode>si2"
4555   [(parallel
4556     [(set (match_operand:SI 0 "register_operand" "")
4557           (unsigned_fix:SI
4558             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4559      (use (match_dup 2))
4560      (clobber (match_scratch:<ssevecmode> 3 ""))
4561      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4562   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4563 {
4564   enum machine_mode mode = <MODE>mode;
4565   enum machine_mode vecmode = <ssevecmode>mode;
4566   REAL_VALUE_TYPE TWO31r;
4567   rtx two31;
4568
4569   if (optimize_insn_for_size_p ())
4570     FAIL;
4571
4572   real_ldexp (&TWO31r, &dconst1, 31);
4573   two31 = const_double_from_real_value (TWO31r, mode);
4574   two31 = ix86_build_const_vector (vecmode, true, two31);
4575   operands[2] = force_reg (vecmode, two31);
4576 })
4577
4578 (define_insn_and_split "*fixuns_trunc<mode>_1"
4579   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4580         (unsigned_fix:SI
4581           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4582    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4583    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4584    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4585   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4586    && optimize_function_for_speed_p (cfun)"
4587   "#"
4588   "&& reload_completed"
4589   [(const_int 0)]
4590 {
4591   ix86_split_convert_uns_si_sse (operands);
4592   DONE;
4593 })
4594
4595 ;; Unsigned conversion to HImode.
4596 ;; Without these patterns, we'll try the unsigned SI conversion which
4597 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4598
4599 (define_expand "fixuns_trunc<mode>hi2"
4600   [(set (match_dup 2)
4601         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4602    (set (match_operand:HI 0 "nonimmediate_operand" "")
4603         (subreg:HI (match_dup 2) 0))]
4604   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4605   "operands[2] = gen_reg_rtx (SImode);")
4606
4607 ;; When SSE is available, it is always faster to use it!
4608 (define_insn "fix_trunc<mode>di_sse"
4609   [(set (match_operand:DI 0 "register_operand" "=r,r")
4610         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4611   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4612    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4613   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4614   [(set_attr "type" "sseicvt")
4615    (set_attr "prefix" "maybe_vex")
4616    (set_attr "prefix_rex" "1")
4617    (set_attr "mode" "<MODE>")
4618    (set_attr "athlon_decode" "double,vector")
4619    (set_attr "amdfam10_decode" "double,double")
4620    (set_attr "bdver1_decode" "double,double")])
4621
4622 (define_insn "fix_trunc<mode>si_sse"
4623   [(set (match_operand:SI 0 "register_operand" "=r,r")
4624         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4625   "SSE_FLOAT_MODE_P (<MODE>mode)
4626    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4627   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4628   [(set_attr "type" "sseicvt")
4629    (set_attr "prefix" "maybe_vex")
4630    (set_attr "mode" "<MODE>")
4631    (set_attr "athlon_decode" "double,vector")
4632    (set_attr "amdfam10_decode" "double,double")
4633    (set_attr "bdver1_decode" "double,double")])
4634
4635 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4636 (define_peephole2
4637   [(set (match_operand:MODEF 0 "register_operand" "")
4638         (match_operand:MODEF 1 "memory_operand" ""))
4639    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4640         (fix:SSEMODEI24 (match_dup 0)))]
4641   "TARGET_SHORTEN_X87_SSE
4642    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4643    && peep2_reg_dead_p (2, operands[0])"
4644   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4645
4646 ;; Avoid vector decoded forms of the instruction.
4647 (define_peephole2
4648   [(match_scratch:DF 2 "Y2")
4649    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4650         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4651   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4652   [(set (match_dup 2) (match_dup 1))
4653    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4654
4655 (define_peephole2
4656   [(match_scratch:SF 2 "x")
4657    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4658         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4659   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4660   [(set (match_dup 2) (match_dup 1))
4661    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4662
4663 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4664   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4665         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4666   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4667    && TARGET_FISTTP
4668    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4669          && (TARGET_64BIT || <MODE>mode != DImode))
4670         && TARGET_SSE_MATH)
4671    && can_create_pseudo_p ()"
4672   "#"
4673   "&& 1"
4674   [(const_int 0)]
4675 {
4676   if (memory_operand (operands[0], VOIDmode))
4677     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4678   else
4679     {
4680       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4681       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4682                                                             operands[1],
4683                                                             operands[2]));
4684     }
4685   DONE;
4686 }
4687   [(set_attr "type" "fisttp")
4688    (set_attr "mode" "<MODE>")])
4689
4690 (define_insn "fix_trunc<mode>_i387_fisttp"
4691   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4692         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4693    (clobber (match_scratch:XF 2 "=&1f"))]
4694   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4695    && TARGET_FISTTP
4696    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4697          && (TARGET_64BIT || <MODE>mode != DImode))
4698         && TARGET_SSE_MATH)"
4699   "* return output_fix_trunc (insn, operands, 1);"
4700   [(set_attr "type" "fisttp")
4701    (set_attr "mode" "<MODE>")])
4702
4703 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4704   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4705         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4706    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4707    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4708   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4709    && TARGET_FISTTP
4710    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4711         && (TARGET_64BIT || <MODE>mode != DImode))
4712         && TARGET_SSE_MATH)"
4713   "#"
4714   [(set_attr "type" "fisttp")
4715    (set_attr "mode" "<MODE>")])
4716
4717 (define_split
4718   [(set (match_operand:X87MODEI 0 "register_operand" "")
4719         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4720    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4721    (clobber (match_scratch 3 ""))]
4722   "reload_completed"
4723   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4724               (clobber (match_dup 3))])
4725    (set (match_dup 0) (match_dup 2))])
4726
4727 (define_split
4728   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4729         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4730    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4731    (clobber (match_scratch 3 ""))]
4732   "reload_completed"
4733   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4734               (clobber (match_dup 3))])])
4735
4736 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4737 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4738 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4739 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4740 ;; function in i386.c.
4741 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4742   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4743         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4744    (clobber (reg:CC FLAGS_REG))]
4745   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4746    && !TARGET_FISTTP
4747    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4748          && (TARGET_64BIT || <MODE>mode != DImode))
4749    && can_create_pseudo_p ()"
4750   "#"
4751   "&& 1"
4752   [(const_int 0)]
4753 {
4754   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4755
4756   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4757   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4758   if (memory_operand (operands[0], VOIDmode))
4759     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4760                                          operands[2], operands[3]));
4761   else
4762     {
4763       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4764       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4765                                                      operands[2], operands[3],
4766                                                      operands[4]));
4767     }
4768   DONE;
4769 }
4770   [(set_attr "type" "fistp")
4771    (set_attr "i387_cw" "trunc")
4772    (set_attr "mode" "<MODE>")])
4773
4774 (define_insn "fix_truncdi_i387"
4775   [(set (match_operand:DI 0 "memory_operand" "=m")
4776         (fix:DI (match_operand 1 "register_operand" "f")))
4777    (use (match_operand:HI 2 "memory_operand" "m"))
4778    (use (match_operand:HI 3 "memory_operand" "m"))
4779    (clobber (match_scratch:XF 4 "=&1f"))]
4780   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4781    && !TARGET_FISTTP
4782    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4783   "* return output_fix_trunc (insn, operands, 0);"
4784   [(set_attr "type" "fistp")
4785    (set_attr "i387_cw" "trunc")
4786    (set_attr "mode" "DI")])
4787
4788 (define_insn "fix_truncdi_i387_with_temp"
4789   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4790         (fix:DI (match_operand 1 "register_operand" "f,f")))
4791    (use (match_operand:HI 2 "memory_operand" "m,m"))
4792    (use (match_operand:HI 3 "memory_operand" "m,m"))
4793    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4794    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4795   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4796    && !TARGET_FISTTP
4797    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4798   "#"
4799   [(set_attr "type" "fistp")
4800    (set_attr "i387_cw" "trunc")
4801    (set_attr "mode" "DI")])
4802
4803 (define_split
4804   [(set (match_operand:DI 0 "register_operand" "")
4805         (fix:DI (match_operand 1 "register_operand" "")))
4806    (use (match_operand:HI 2 "memory_operand" ""))
4807    (use (match_operand:HI 3 "memory_operand" ""))
4808    (clobber (match_operand:DI 4 "memory_operand" ""))
4809    (clobber (match_scratch 5 ""))]
4810   "reload_completed"
4811   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4812               (use (match_dup 2))
4813               (use (match_dup 3))
4814               (clobber (match_dup 5))])
4815    (set (match_dup 0) (match_dup 4))])
4816
4817 (define_split
4818   [(set (match_operand:DI 0 "memory_operand" "")
4819         (fix:DI (match_operand 1 "register_operand" "")))
4820    (use (match_operand:HI 2 "memory_operand" ""))
4821    (use (match_operand:HI 3 "memory_operand" ""))
4822    (clobber (match_operand:DI 4 "memory_operand" ""))
4823    (clobber (match_scratch 5 ""))]
4824   "reload_completed"
4825   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4826               (use (match_dup 2))
4827               (use (match_dup 3))
4828               (clobber (match_dup 5))])])
4829
4830 (define_insn "fix_trunc<mode>_i387"
4831   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4832         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4833    (use (match_operand:HI 2 "memory_operand" "m"))
4834    (use (match_operand:HI 3 "memory_operand" "m"))]
4835   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4836    && !TARGET_FISTTP
4837    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4838   "* return output_fix_trunc (insn, operands, 0);"
4839   [(set_attr "type" "fistp")
4840    (set_attr "i387_cw" "trunc")
4841    (set_attr "mode" "<MODE>")])
4842
4843 (define_insn "fix_trunc<mode>_i387_with_temp"
4844   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4845         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4846    (use (match_operand:HI 2 "memory_operand" "m,m"))
4847    (use (match_operand:HI 3 "memory_operand" "m,m"))
4848    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4849   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4850    && !TARGET_FISTTP
4851    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4852   "#"
4853   [(set_attr "type" "fistp")
4854    (set_attr "i387_cw" "trunc")
4855    (set_attr "mode" "<MODE>")])
4856
4857 (define_split
4858   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4859         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4860    (use (match_operand:HI 2 "memory_operand" ""))
4861    (use (match_operand:HI 3 "memory_operand" ""))
4862    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4863   "reload_completed"
4864   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4865               (use (match_dup 2))
4866               (use (match_dup 3))])
4867    (set (match_dup 0) (match_dup 4))])
4868
4869 (define_split
4870   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4871         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4872    (use (match_operand:HI 2 "memory_operand" ""))
4873    (use (match_operand:HI 3 "memory_operand" ""))
4874    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4875   "reload_completed"
4876   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4877               (use (match_dup 2))
4878               (use (match_dup 3))])])
4879
4880 (define_insn "x86_fnstcw_1"
4881   [(set (match_operand:HI 0 "memory_operand" "=m")
4882         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4883   "TARGET_80387"
4884   "fnstcw\t%0"
4885   [(set (attr "length")
4886         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4887    (set_attr "mode" "HI")
4888    (set_attr "unit" "i387")
4889    (set_attr "bdver1_decode" "vector")])
4890
4891 (define_insn "x86_fldcw_1"
4892   [(set (reg:HI FPCR_REG)
4893         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4894   "TARGET_80387"
4895   "fldcw\t%0"
4896   [(set (attr "length")
4897         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4898    (set_attr "mode" "HI")
4899    (set_attr "unit" "i387")
4900    (set_attr "athlon_decode" "vector")
4901    (set_attr "amdfam10_decode" "vector")
4902    (set_attr "bdver1_decode" "vector")])
4903 \f
4904 ;; Conversion between fixed point and floating point.
4905
4906 ;; Even though we only accept memory inputs, the backend _really_
4907 ;; wants to be able to do this between registers.
4908
4909 (define_expand "floathi<mode>2"
4910   [(set (match_operand:X87MODEF 0 "register_operand" "")
4911         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4912   "TARGET_80387
4913    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4914        || TARGET_MIX_SSE_I387)")
4915
4916 ;; Pre-reload splitter to add memory clobber to the pattern.
4917 (define_insn_and_split "*floathi<mode>2_1"
4918   [(set (match_operand:X87MODEF 0 "register_operand" "")
4919         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4920   "TARGET_80387
4921    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4922        || TARGET_MIX_SSE_I387)
4923    && can_create_pseudo_p ()"
4924   "#"
4925   "&& 1"
4926   [(parallel [(set (match_dup 0)
4927               (float:X87MODEF (match_dup 1)))
4928    (clobber (match_dup 2))])]
4929   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4930
4931 (define_insn "*floathi<mode>2_i387_with_temp"
4932   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4933         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4934   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4935   "TARGET_80387
4936    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4937        || TARGET_MIX_SSE_I387)"
4938   "#"
4939   [(set_attr "type" "fmov,multi")
4940    (set_attr "mode" "<MODE>")
4941    (set_attr "unit" "*,i387")
4942    (set_attr "fp_int_src" "true")])
4943
4944 (define_insn "*floathi<mode>2_i387"
4945   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4946         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4947   "TARGET_80387
4948    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4949        || TARGET_MIX_SSE_I387)"
4950   "fild%Z1\t%1"
4951   [(set_attr "type" "fmov")
4952    (set_attr "mode" "<MODE>")
4953    (set_attr "fp_int_src" "true")])
4954
4955 (define_split
4956   [(set (match_operand:X87MODEF 0 "register_operand" "")
4957         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4958    (clobber (match_operand:HI 2 "memory_operand" ""))]
4959   "TARGET_80387
4960    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4961        || TARGET_MIX_SSE_I387)
4962    && reload_completed"
4963   [(set (match_dup 2) (match_dup 1))
4964    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4965
4966 (define_split
4967   [(set (match_operand:X87MODEF 0 "register_operand" "")
4968         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4969    (clobber (match_operand:HI 2 "memory_operand" ""))]
4970    "TARGET_80387
4971     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4972         || TARGET_MIX_SSE_I387)
4973     && reload_completed"
4974   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4975
4976 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4977   [(set (match_operand:X87MODEF 0 "register_operand" "")
4978         (float:X87MODEF
4979           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4980   "TARGET_80387
4981    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4982        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4983 {
4984   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4985         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4986       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4987     {
4988       rtx reg = gen_reg_rtx (XFmode);
4989       rtx (*insn)(rtx, rtx);
4990
4991       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4992
4993       if (<X87MODEF:MODE>mode == SFmode)
4994         insn = gen_truncxfsf2;
4995       else if (<X87MODEF:MODE>mode == DFmode)
4996         insn = gen_truncxfdf2;
4997       else
4998         gcc_unreachable ();
4999
5000       emit_insn (insn (operands[0], reg));
5001       DONE;
5002     }
5003 })
5004
5005 ;; Pre-reload splitter to add memory clobber to the pattern.
5006 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5007   [(set (match_operand:X87MODEF 0 "register_operand" "")
5008         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5009   "((TARGET_80387
5010      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5011      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5012            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5013          || TARGET_MIX_SSE_I387))
5014     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5015         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5016         && ((<SSEMODEI24:MODE>mode == SImode
5017              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5018              && optimize_function_for_speed_p (cfun)
5019              && flag_trapping_math)
5020             || !(TARGET_INTER_UNIT_CONVERSIONS
5021                  || optimize_function_for_size_p (cfun)))))
5022    && can_create_pseudo_p ()"
5023   "#"
5024   "&& 1"
5025   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5026               (clobber (match_dup 2))])]
5027 {
5028   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5029
5030   /* Avoid store forwarding (partial memory) stall penalty
5031      by passing DImode value through XMM registers.  */
5032   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5033       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5034       && optimize_function_for_speed_p (cfun))
5035     {
5036       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5037                                                             operands[1],
5038                                                             operands[2]));
5039       DONE;
5040     }
5041 })
5042
5043 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5044   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5045         (float:MODEF
5046           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5047    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5048   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5049    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5050   "#"
5051   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5052    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5053    (set_attr "unit" "*,i387,*,*,*")
5054    (set_attr "athlon_decode" "*,*,double,direct,double")
5055    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5056    (set_attr "bdver1_decode" "*,*,double,direct,double")
5057    (set_attr "fp_int_src" "true")])
5058
5059 (define_insn "*floatsi<mode>2_vector_mixed"
5060   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5061         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5062   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5063    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5064   "@
5065    fild%Z1\t%1
5066    #"
5067   [(set_attr "type" "fmov,sseicvt")
5068    (set_attr "mode" "<MODE>,<ssevecmode>")
5069    (set_attr "unit" "i387,*")
5070    (set_attr "athlon_decode" "*,direct")
5071    (set_attr "amdfam10_decode" "*,double")
5072    (set_attr "bdver1_decode" "*,direct")
5073    (set_attr "fp_int_src" "true")])
5074
5075 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5076   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5077         (float:MODEF
5078           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5079   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5080   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5081    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5082   "#"
5083   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5084    (set_attr "mode" "<MODEF:MODE>")
5085    (set_attr "unit" "*,i387,*,*")
5086    (set_attr "athlon_decode" "*,*,double,direct")
5087    (set_attr "amdfam10_decode" "*,*,vector,double")
5088    (set_attr "bdver1_decode" "*,*,double,direct")
5089    (set_attr "fp_int_src" "true")])
5090
5091 (define_split
5092   [(set (match_operand:MODEF 0 "register_operand" "")
5093         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5094    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5095   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5096    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5097    && TARGET_INTER_UNIT_CONVERSIONS
5098    && reload_completed
5099    && (SSE_REG_P (operands[0])
5100        || (GET_CODE (operands[0]) == SUBREG
5101            && SSE_REG_P (operands[0])))"
5102   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5103
5104 (define_split
5105   [(set (match_operand:MODEF 0 "register_operand" "")
5106         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5107    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5108   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5109    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5110    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5111    && reload_completed
5112    && (SSE_REG_P (operands[0])
5113        || (GET_CODE (operands[0]) == SUBREG
5114            && SSE_REG_P (operands[0])))"
5115   [(set (match_dup 2) (match_dup 1))
5116    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5117
5118 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5119   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5120         (float:MODEF
5121           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5122   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5123    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5124    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5125   "@
5126    fild%Z1\t%1
5127    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5128    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5129   [(set_attr "type" "fmov,sseicvt,sseicvt")
5130    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5131    (set_attr "mode" "<MODEF:MODE>")
5132    (set (attr "prefix_rex")
5133      (if_then_else
5134        (and (eq_attr "prefix" "maybe_vex")
5135             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5136        (const_string "1")
5137        (const_string "*")))
5138    (set_attr "unit" "i387,*,*")
5139    (set_attr "athlon_decode" "*,double,direct")
5140    (set_attr "amdfam10_decode" "*,vector,double")
5141    (set_attr "bdver1_decode" "*,double,direct")
5142    (set_attr "fp_int_src" "true")])
5143
5144 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5145   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5146         (float:MODEF
5147           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5148   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5149    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5150    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5151   "@
5152    fild%Z1\t%1
5153    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5154   [(set_attr "type" "fmov,sseicvt")
5155    (set_attr "prefix" "orig,maybe_vex")
5156    (set_attr "mode" "<MODEF:MODE>")
5157    (set (attr "prefix_rex")
5158      (if_then_else
5159        (and (eq_attr "prefix" "maybe_vex")
5160             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5161        (const_string "1")
5162        (const_string "*")))
5163    (set_attr "athlon_decode" "*,direct")
5164    (set_attr "amdfam10_decode" "*,double")
5165    (set_attr "bdver1_decode" "*,direct")
5166    (set_attr "fp_int_src" "true")])
5167
5168 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5169   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5170         (float:MODEF
5171           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5172    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5173   "TARGET_SSE2 && TARGET_SSE_MATH
5174    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5175   "#"
5176   [(set_attr "type" "sseicvt")
5177    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5178    (set_attr "athlon_decode" "double,direct,double")
5179    (set_attr "amdfam10_decode" "vector,double,double")
5180    (set_attr "bdver1_decode" "double,direct,double")
5181    (set_attr "fp_int_src" "true")])
5182
5183 (define_insn "*floatsi<mode>2_vector_sse"
5184   [(set (match_operand:MODEF 0 "register_operand" "=x")
5185         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5186   "TARGET_SSE2 && TARGET_SSE_MATH
5187    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5188   "#"
5189   [(set_attr "type" "sseicvt")
5190    (set_attr "mode" "<MODE>")
5191    (set_attr "athlon_decode" "direct")
5192    (set_attr "amdfam10_decode" "double")
5193    (set_attr "bdver1_decode" "direct")
5194    (set_attr "fp_int_src" "true")])
5195
5196 (define_split
5197   [(set (match_operand:MODEF 0 "register_operand" "")
5198         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5199    (clobber (match_operand:SI 2 "memory_operand" ""))]
5200   "TARGET_SSE2 && TARGET_SSE_MATH
5201    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5202    && reload_completed
5203    && (SSE_REG_P (operands[0])
5204        || (GET_CODE (operands[0]) == SUBREG
5205            && SSE_REG_P (operands[0])))"
5206   [(const_int 0)]
5207 {
5208   rtx op1 = operands[1];
5209
5210   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5211                                      <MODE>mode, 0);
5212   if (GET_CODE (op1) == SUBREG)
5213     op1 = SUBREG_REG (op1);
5214
5215   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5216     {
5217       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5218       emit_insn (gen_sse2_loadld (operands[4],
5219                                   CONST0_RTX (V4SImode), operands[1]));
5220     }
5221   /* We can ignore possible trapping value in the
5222      high part of SSE register for non-trapping math. */
5223   else if (SSE_REG_P (op1) && !flag_trapping_math)
5224     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5225   else
5226     {
5227       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5228       emit_move_insn (operands[2], operands[1]);
5229       emit_insn (gen_sse2_loadld (operands[4],
5230                                   CONST0_RTX (V4SImode), operands[2]));
5231     }
5232   emit_insn
5233     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5234   DONE;
5235 })
5236
5237 (define_split
5238   [(set (match_operand:MODEF 0 "register_operand" "")
5239         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5240    (clobber (match_operand:SI 2 "memory_operand" ""))]
5241   "TARGET_SSE2 && TARGET_SSE_MATH
5242    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5243    && reload_completed
5244    && (SSE_REG_P (operands[0])
5245        || (GET_CODE (operands[0]) == SUBREG
5246            && SSE_REG_P (operands[0])))"
5247   [(const_int 0)]
5248 {
5249   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5250                                      <MODE>mode, 0);
5251   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5252
5253   emit_insn (gen_sse2_loadld (operands[4],
5254                               CONST0_RTX (V4SImode), operands[1]));
5255   emit_insn
5256     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5257   DONE;
5258 })
5259
5260 (define_split
5261   [(set (match_operand:MODEF 0 "register_operand" "")
5262         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5263   "TARGET_SSE2 && TARGET_SSE_MATH
5264    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5265    && reload_completed
5266    && (SSE_REG_P (operands[0])
5267        || (GET_CODE (operands[0]) == SUBREG
5268            && SSE_REG_P (operands[0])))"
5269   [(const_int 0)]
5270 {
5271   rtx op1 = operands[1];
5272
5273   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5274                                      <MODE>mode, 0);
5275   if (GET_CODE (op1) == SUBREG)
5276     op1 = SUBREG_REG (op1);
5277
5278   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5279     {
5280       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5281       emit_insn (gen_sse2_loadld (operands[4],
5282                                   CONST0_RTX (V4SImode), operands[1]));
5283     }
5284   /* We can ignore possible trapping value in the
5285      high part of SSE register for non-trapping math. */
5286   else if (SSE_REG_P (op1) && !flag_trapping_math)
5287     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5288   else
5289     gcc_unreachable ();
5290   emit_insn
5291     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5292   DONE;
5293 })
5294
5295 (define_split
5296   [(set (match_operand:MODEF 0 "register_operand" "")
5297         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5298   "TARGET_SSE2 && TARGET_SSE_MATH
5299    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5300    && reload_completed
5301    && (SSE_REG_P (operands[0])
5302        || (GET_CODE (operands[0]) == SUBREG
5303            && SSE_REG_P (operands[0])))"
5304   [(const_int 0)]
5305 {
5306   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5307                                      <MODE>mode, 0);
5308   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5309
5310   emit_insn (gen_sse2_loadld (operands[4],
5311                               CONST0_RTX (V4SImode), operands[1]));
5312   emit_insn
5313     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5314   DONE;
5315 })
5316
5317 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5318   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5319         (float:MODEF
5320           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5321   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5322   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5323    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5324   "#"
5325   [(set_attr "type" "sseicvt")
5326    (set_attr "mode" "<MODEF:MODE>")
5327    (set_attr "athlon_decode" "double,direct")
5328    (set_attr "amdfam10_decode" "vector,double")
5329    (set_attr "bdver1_decode" "double,direct")
5330    (set_attr "fp_int_src" "true")])
5331
5332 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5333   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5334         (float:MODEF
5335           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5336   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5337    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5338    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5339   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5340   [(set_attr "type" "sseicvt")
5341    (set_attr "prefix" "maybe_vex")
5342    (set_attr "mode" "<MODEF:MODE>")
5343    (set (attr "prefix_rex")
5344      (if_then_else
5345        (and (eq_attr "prefix" "maybe_vex")
5346             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5347        (const_string "1")
5348        (const_string "*")))
5349    (set_attr "athlon_decode" "double,direct")
5350    (set_attr "amdfam10_decode" "vector,double")
5351    (set_attr "bdver1_decode" "double,direct")
5352    (set_attr "fp_int_src" "true")])
5353
5354 (define_split
5355   [(set (match_operand:MODEF 0 "register_operand" "")
5356         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5357    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5358   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5359    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5360    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5361    && reload_completed
5362    && (SSE_REG_P (operands[0])
5363        || (GET_CODE (operands[0]) == SUBREG
5364            && SSE_REG_P (operands[0])))"
5365   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5366
5367 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5368   [(set (match_operand:MODEF 0 "register_operand" "=x")
5369         (float:MODEF
5370           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5371   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5372    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5373    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5374   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5375   [(set_attr "type" "sseicvt")
5376    (set_attr "prefix" "maybe_vex")
5377    (set_attr "mode" "<MODEF:MODE>")
5378    (set (attr "prefix_rex")
5379      (if_then_else
5380        (and (eq_attr "prefix" "maybe_vex")
5381             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5382        (const_string "1")
5383        (const_string "*")))
5384    (set_attr "athlon_decode" "direct")
5385    (set_attr "amdfam10_decode" "double")
5386    (set_attr "bdver1_decode" "direct")
5387    (set_attr "fp_int_src" "true")])
5388
5389 (define_split
5390   [(set (match_operand:MODEF 0 "register_operand" "")
5391         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5392    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5393   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5394    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5395    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5396    && reload_completed
5397    && (SSE_REG_P (operands[0])
5398        || (GET_CODE (operands[0]) == SUBREG
5399            && SSE_REG_P (operands[0])))"
5400   [(set (match_dup 2) (match_dup 1))
5401    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5402
5403 (define_split
5404   [(set (match_operand:MODEF 0 "register_operand" "")
5405         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5406    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5407   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5408    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5409    && reload_completed
5410    && (SSE_REG_P (operands[0])
5411        || (GET_CODE (operands[0]) == SUBREG
5412            && SSE_REG_P (operands[0])))"
5413   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5414
5415 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5416   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5417         (float:X87MODEF
5418           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5419   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5420   "TARGET_80387
5421    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5422   "@
5423    fild%Z1\t%1
5424    #"
5425   [(set_attr "type" "fmov,multi")
5426    (set_attr "mode" "<X87MODEF:MODE>")
5427    (set_attr "unit" "*,i387")
5428    (set_attr "fp_int_src" "true")])
5429
5430 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5431   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5432         (float:X87MODEF
5433           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5434   "TARGET_80387
5435    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5436   "fild%Z1\t%1"
5437   [(set_attr "type" "fmov")
5438    (set_attr "mode" "<X87MODEF:MODE>")
5439    (set_attr "fp_int_src" "true")])
5440
5441 (define_split
5442   [(set (match_operand:X87MODEF 0 "register_operand" "")
5443         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5444    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5445   "TARGET_80387
5446    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5447    && reload_completed
5448    && FP_REG_P (operands[0])"
5449   [(set (match_dup 2) (match_dup 1))
5450    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5451
5452 (define_split
5453   [(set (match_operand:X87MODEF 0 "register_operand" "")
5454         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5455    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5456   "TARGET_80387
5457    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5458    && reload_completed
5459    && FP_REG_P (operands[0])"
5460   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5461
5462 ;; Avoid store forwarding (partial memory) stall penalty
5463 ;; by passing DImode value through XMM registers.  */
5464
5465 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5466   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5467         (float:X87MODEF
5468           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5469    (clobber (match_scratch:V4SI 3 "=X,x"))
5470    (clobber (match_scratch:V4SI 4 "=X,x"))
5471    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5472   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5473    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5474    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5475   "#"
5476   [(set_attr "type" "multi")
5477    (set_attr "mode" "<X87MODEF:MODE>")
5478    (set_attr "unit" "i387")
5479    (set_attr "fp_int_src" "true")])
5480
5481 (define_split
5482   [(set (match_operand:X87MODEF 0 "register_operand" "")
5483         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5484    (clobber (match_scratch:V4SI 3 ""))
5485    (clobber (match_scratch:V4SI 4 ""))
5486    (clobber (match_operand:DI 2 "memory_operand" ""))]
5487   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5488    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5489    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5490    && reload_completed
5491    && FP_REG_P (operands[0])"
5492   [(set (match_dup 2) (match_dup 3))
5493    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5494 {
5495   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5496      Assemble the 64-bit DImode value in an xmm register.  */
5497   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5498                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5499   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5500                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5501   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5502                                          operands[4]));
5503
5504   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5505 })
5506
5507 (define_split
5508   [(set (match_operand:X87MODEF 0 "register_operand" "")
5509         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5510    (clobber (match_scratch:V4SI 3 ""))
5511    (clobber (match_scratch:V4SI 4 ""))
5512    (clobber (match_operand:DI 2 "memory_operand" ""))]
5513   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5514    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5515    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5516    && reload_completed
5517    && FP_REG_P (operands[0])"
5518   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5519
5520 ;; Avoid store forwarding (partial memory) stall penalty by extending
5521 ;; SImode value to DImode through XMM register instead of pushing two
5522 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5523 ;; targets benefit from this optimization. Also note that fild
5524 ;; loads from memory only.
5525
5526 (define_insn "*floatunssi<mode>2_1"
5527   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5528         (unsigned_float:X87MODEF
5529           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5530    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5531    (clobber (match_scratch:SI 3 "=X,x"))]
5532   "!TARGET_64BIT
5533    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5534    && TARGET_SSE"
5535   "#"
5536   [(set_attr "type" "multi")
5537    (set_attr "mode" "<MODE>")])
5538
5539 (define_split
5540   [(set (match_operand:X87MODEF 0 "register_operand" "")
5541         (unsigned_float:X87MODEF
5542           (match_operand:SI 1 "register_operand" "")))
5543    (clobber (match_operand:DI 2 "memory_operand" ""))
5544    (clobber (match_scratch:SI 3 ""))]
5545   "!TARGET_64BIT
5546    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5547    && TARGET_SSE
5548    && reload_completed"
5549   [(set (match_dup 2) (match_dup 1))
5550    (set (match_dup 0)
5551         (float:X87MODEF (match_dup 2)))]
5552   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5553
5554 (define_split
5555   [(set (match_operand:X87MODEF 0 "register_operand" "")
5556         (unsigned_float:X87MODEF
5557           (match_operand:SI 1 "memory_operand" "")))
5558    (clobber (match_operand:DI 2 "memory_operand" ""))
5559    (clobber (match_scratch:SI 3 ""))]
5560   "!TARGET_64BIT
5561    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5562    && TARGET_SSE
5563    && reload_completed"
5564   [(set (match_dup 2) (match_dup 3))
5565    (set (match_dup 0)
5566         (float:X87MODEF (match_dup 2)))]
5567 {
5568   emit_move_insn (operands[3], operands[1]);
5569   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5570 })
5571
5572 (define_expand "floatunssi<mode>2"
5573   [(parallel
5574      [(set (match_operand:X87MODEF 0 "register_operand" "")
5575            (unsigned_float:X87MODEF
5576              (match_operand:SI 1 "nonimmediate_operand" "")))
5577       (clobber (match_dup 2))
5578       (clobber (match_scratch:SI 3 ""))])]
5579   "!TARGET_64BIT
5580    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5581         && TARGET_SSE)
5582        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5583 {
5584   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5585     {
5586       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5587       DONE;
5588     }
5589   else
5590     {
5591       enum ix86_stack_slot slot = (virtuals_instantiated
5592                                    ? SLOT_TEMP
5593                                    : SLOT_VIRTUAL);
5594       operands[2] = assign_386_stack_local (DImode, slot);
5595     }
5596 })
5597
5598 (define_expand "floatunsdisf2"
5599   [(use (match_operand:SF 0 "register_operand" ""))
5600    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5601   "TARGET_64BIT && TARGET_SSE_MATH"
5602   "x86_emit_floatuns (operands); DONE;")
5603
5604 (define_expand "floatunsdidf2"
5605   [(use (match_operand:DF 0 "register_operand" ""))
5606    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5607   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5608    && TARGET_SSE2 && TARGET_SSE_MATH"
5609 {
5610   if (TARGET_64BIT)
5611     x86_emit_floatuns (operands);
5612   else
5613     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5614   DONE;
5615 })
5616 \f
5617 ;; Add instructions
5618
5619 (define_expand "add<mode>3"
5620   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5621         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5622                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5623   ""
5624   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5625
5626 (define_insn_and_split "*add<dwi>3_doubleword"
5627   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5628         (plus:<DWI>
5629           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5630           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5631    (clobber (reg:CC FLAGS_REG))]
5632   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5633   "#"
5634   "reload_completed"
5635   [(parallel [(set (reg:CC FLAGS_REG)
5636                    (unspec:CC [(match_dup 1) (match_dup 2)]
5637                               UNSPEC_ADD_CARRY))
5638               (set (match_dup 0)
5639                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5640    (parallel [(set (match_dup 3)
5641                    (plus:DWIH
5642                      (match_dup 4)
5643                      (plus:DWIH
5644                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5645                        (match_dup 5))))
5646               (clobber (reg:CC FLAGS_REG))])]
5647   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5648
5649 (define_insn "*add<mode>3_cc"
5650   [(set (reg:CC FLAGS_REG)
5651         (unspec:CC
5652           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5653            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5654           UNSPEC_ADD_CARRY))
5655    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5656         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5657   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5658   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5659   [(set_attr "type" "alu")
5660    (set_attr "mode" "<MODE>")])
5661
5662 (define_insn "addqi3_cc"
5663   [(set (reg:CC FLAGS_REG)
5664         (unspec:CC
5665           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5666            (match_operand:QI 2 "general_operand" "qn,qm")]
5667           UNSPEC_ADD_CARRY))
5668    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5669         (plus:QI (match_dup 1) (match_dup 2)))]
5670   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5671   "add{b}\t{%2, %0|%0, %2}"
5672   [(set_attr "type" "alu")
5673    (set_attr "mode" "QI")])
5674
5675 (define_insn "*lea_1"
5676   [(set (match_operand:P 0 "register_operand" "=r")
5677         (match_operand:P 1 "no_seg_address_operand" "p"))]
5678   ""
5679   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5680   [(set_attr "type" "lea")
5681    (set_attr "mode" "<MODE>")])
5682
5683 (define_insn "*lea_2"
5684   [(set (match_operand:SI 0 "register_operand" "=r")
5685         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5686   "TARGET_64BIT"
5687   "lea{l}\t{%a1, %0|%0, %a1}"
5688   [(set_attr "type" "lea")
5689    (set_attr "mode" "SI")])
5690
5691 (define_insn "*lea_2_zext"
5692   [(set (match_operand:DI 0 "register_operand" "=r")
5693         (zero_extend:DI
5694           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5695   "TARGET_64BIT"
5696   "lea{l}\t{%a1, %k0|%k0, %a1}"
5697   [(set_attr "type" "lea")
5698    (set_attr "mode" "SI")])
5699
5700 (define_insn "*add<mode>_1"
5701   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5702         (plus:SWI48
5703           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5704           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5705    (clobber (reg:CC FLAGS_REG))]
5706   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5707 {
5708   switch (get_attr_type (insn))
5709     {
5710     case TYPE_LEA:
5711       return "#";
5712
5713     case TYPE_INCDEC:
5714       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5715       if (operands[2] == const1_rtx)
5716         return "inc{<imodesuffix>}\t%0";
5717       else
5718         {
5719           gcc_assert (operands[2] == constm1_rtx);
5720           return "dec{<imodesuffix>}\t%0";
5721         }
5722
5723     default:
5724       /* For most processors, ADD is faster than LEA.  This alternative
5725          was added to use ADD as much as possible.  */
5726       if (which_alternative == 2)
5727         {
5728           rtx tmp;
5729           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5730         }
5731         
5732       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5733       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5734         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5735
5736       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5737     }
5738 }
5739   [(set (attr "type")
5740      (cond [(eq_attr "alternative" "3")
5741               (const_string "lea")
5742             (match_operand:SWI48 2 "incdec_operand" "")
5743               (const_string "incdec")
5744            ]
5745            (const_string "alu")))
5746    (set (attr "length_immediate")
5747       (if_then_else
5748         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5749         (const_string "1")
5750         (const_string "*")))
5751    (set_attr "mode" "<MODE>")])
5752
5753 ;; It may seem that nonimmediate operand is proper one for operand 1.
5754 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5755 ;; we take care in ix86_binary_operator_ok to not allow two memory
5756 ;; operands so proper swapping will be done in reload.  This allow
5757 ;; patterns constructed from addsi_1 to match.
5758
5759 (define_insn "*addsi_1_zext"
5760   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5761         (zero_extend:DI
5762           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5763                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5764    (clobber (reg:CC FLAGS_REG))]
5765   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5766 {
5767   switch (get_attr_type (insn))
5768     {
5769     case TYPE_LEA:
5770       return "#";
5771
5772     case TYPE_INCDEC:
5773       if (operands[2] == const1_rtx)
5774         return "inc{l}\t%k0";
5775       else
5776         {
5777           gcc_assert (operands[2] == constm1_rtx);
5778           return "dec{l}\t%k0";
5779         }
5780
5781     default:
5782       /* For most processors, ADD is faster than LEA.  This alternative
5783          was added to use ADD as much as possible.  */
5784       if (which_alternative == 1)
5785         {
5786           rtx tmp;
5787           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5788         }
5789
5790       if (x86_maybe_negate_const_int (&operands[2], SImode))
5791         return "sub{l}\t{%2, %k0|%k0, %2}";
5792
5793       return "add{l}\t{%2, %k0|%k0, %2}";
5794     }
5795 }
5796   [(set (attr "type")
5797      (cond [(eq_attr "alternative" "2")
5798               (const_string "lea")
5799             (match_operand:SI 2 "incdec_operand" "")
5800               (const_string "incdec")
5801            ]
5802            (const_string "alu")))
5803    (set (attr "length_immediate")
5804       (if_then_else
5805         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5806         (const_string "1")
5807         (const_string "*")))
5808    (set_attr "mode" "SI")])
5809
5810 (define_insn "*addhi_1"
5811   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5812         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5813                  (match_operand:HI 2 "general_operand" "rn,rm")))
5814    (clobber (reg:CC FLAGS_REG))]
5815   "TARGET_PARTIAL_REG_STALL
5816    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5817 {
5818   switch (get_attr_type (insn))
5819     {
5820     case TYPE_INCDEC:
5821       if (operands[2] == const1_rtx)
5822         return "inc{w}\t%0";
5823       else
5824         {
5825           gcc_assert (operands[2] == constm1_rtx);
5826           return "dec{w}\t%0";
5827         }
5828
5829     default:
5830       if (x86_maybe_negate_const_int (&operands[2], HImode))
5831         return "sub{w}\t{%2, %0|%0, %2}";
5832
5833       return "add{w}\t{%2, %0|%0, %2}";
5834     }
5835 }
5836   [(set (attr "type")
5837      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5838         (const_string "incdec")
5839         (const_string "alu")))
5840    (set (attr "length_immediate")
5841       (if_then_else
5842         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5843         (const_string "1")
5844         (const_string "*")))
5845    (set_attr "mode" "HI")])
5846
5847 (define_insn "*addhi_1_lea"
5848   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5849         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5850                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5851    (clobber (reg:CC FLAGS_REG))]
5852   "!TARGET_PARTIAL_REG_STALL
5853    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5854 {
5855   switch (get_attr_type (insn))
5856     {
5857     case TYPE_LEA:
5858       return "#";
5859
5860     case TYPE_INCDEC:
5861       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5862       if (operands[2] == const1_rtx)
5863         return "inc{w}\t%0";
5864       else
5865         {
5866           gcc_assert (operands[2] == constm1_rtx);
5867           return "dec{w}\t%0";
5868         }
5869
5870     default:
5871       /* For most processors, ADD is faster than LEA.  This alternative
5872          was added to use ADD as much as possible.  */
5873       if (which_alternative == 2)
5874         {
5875           rtx tmp;
5876           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5877         }
5878
5879       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5880       if (x86_maybe_negate_const_int (&operands[2], HImode))
5881         return "sub{w}\t{%2, %0|%0, %2}";
5882
5883       return "add{w}\t{%2, %0|%0, %2}";
5884     }
5885 }
5886   [(set (attr "type")
5887      (cond [(eq_attr "alternative" "3")
5888               (const_string "lea")
5889             (match_operand:HI 2 "incdec_operand" "")
5890               (const_string "incdec")
5891            ]
5892            (const_string "alu")))
5893    (set (attr "length_immediate")
5894       (if_then_else
5895         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5896         (const_string "1")
5897         (const_string "*")))
5898    (set_attr "mode" "HI,HI,HI,SI")])
5899
5900 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5901 (define_insn "*addqi_1"
5902   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5903         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5904                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5905    (clobber (reg:CC FLAGS_REG))]
5906   "TARGET_PARTIAL_REG_STALL
5907    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5908 {
5909   int widen = (which_alternative == 2);
5910   switch (get_attr_type (insn))
5911     {
5912     case TYPE_INCDEC:
5913       if (operands[2] == const1_rtx)
5914         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5915       else
5916         {
5917           gcc_assert (operands[2] == constm1_rtx);
5918           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5919         }
5920
5921     default:
5922       if (x86_maybe_negate_const_int (&operands[2], QImode))
5923         {
5924           if (widen)
5925             return "sub{l}\t{%2, %k0|%k0, %2}";
5926           else
5927             return "sub{b}\t{%2, %0|%0, %2}";
5928         }
5929       if (widen)
5930         return "add{l}\t{%k2, %k0|%k0, %k2}";
5931       else
5932         return "add{b}\t{%2, %0|%0, %2}";
5933     }
5934 }
5935   [(set (attr "type")
5936      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5937         (const_string "incdec")
5938         (const_string "alu")))
5939    (set (attr "length_immediate")
5940       (if_then_else
5941         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5942         (const_string "1")
5943         (const_string "*")))
5944    (set_attr "mode" "QI,QI,SI")])
5945
5946 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5947 (define_insn "*addqi_1_lea"
5948   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5949         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5950                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5951    (clobber (reg:CC FLAGS_REG))]
5952   "!TARGET_PARTIAL_REG_STALL
5953    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5954 {
5955   int widen = (which_alternative == 3 || which_alternative == 4);
5956
5957   switch (get_attr_type (insn))
5958     {
5959     case TYPE_LEA:
5960       return "#";
5961
5962     case TYPE_INCDEC:
5963       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5964       if (operands[2] == const1_rtx)
5965         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5966       else
5967         {
5968           gcc_assert (operands[2] == constm1_rtx);
5969           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5970         }
5971
5972     default:
5973       /* For most processors, ADD is faster than LEA.  These alternatives
5974          were added to use ADD as much as possible.  */
5975       if (which_alternative == 2 || which_alternative == 4)
5976         {
5977           rtx tmp;
5978           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5979         }
5980
5981       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5982       if (x86_maybe_negate_const_int (&operands[2], QImode))
5983         {
5984           if (widen)
5985             return "sub{l}\t{%2, %k0|%k0, %2}";
5986           else
5987             return "sub{b}\t{%2, %0|%0, %2}";
5988         }
5989       if (widen)
5990         return "add{l}\t{%k2, %k0|%k0, %k2}";
5991       else
5992         return "add{b}\t{%2, %0|%0, %2}";
5993     }
5994 }
5995   [(set (attr "type")
5996      (cond [(eq_attr "alternative" "5")
5997               (const_string "lea")
5998             (match_operand:QI 2 "incdec_operand" "")
5999               (const_string "incdec")
6000            ]
6001            (const_string "alu")))
6002    (set (attr "length_immediate")
6003       (if_then_else
6004         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6005         (const_string "1")
6006         (const_string "*")))
6007    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6008
6009 (define_insn "*addqi_1_slp"
6010   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6011         (plus:QI (match_dup 0)
6012                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6013    (clobber (reg:CC FLAGS_REG))]
6014   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6015    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6016 {
6017   switch (get_attr_type (insn))
6018     {
6019     case TYPE_INCDEC:
6020       if (operands[1] == const1_rtx)
6021         return "inc{b}\t%0";
6022       else
6023         {
6024           gcc_assert (operands[1] == constm1_rtx);
6025           return "dec{b}\t%0";
6026         }
6027
6028     default:
6029       if (x86_maybe_negate_const_int (&operands[1], QImode))
6030         return "sub{b}\t{%1, %0|%0, %1}";
6031
6032       return "add{b}\t{%1, %0|%0, %1}";
6033     }
6034 }
6035   [(set (attr "type")
6036      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6037         (const_string "incdec")
6038         (const_string "alu1")))
6039    (set (attr "memory")
6040      (if_then_else (match_operand 1 "memory_operand" "")
6041         (const_string "load")
6042         (const_string "none")))
6043    (set_attr "mode" "QI")])
6044
6045 ;; Convert lea to the lea pattern to avoid flags dependency.
6046 (define_split
6047   [(set (match_operand 0 "register_operand" "")
6048         (plus (match_operand 1 "register_operand" "")
6049               (match_operand 2 "nonmemory_operand" "")))
6050    (clobber (reg:CC FLAGS_REG))]
6051   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6052   [(const_int 0)]
6053 {
6054   rtx pat;
6055   enum machine_mode mode = GET_MODE (operands[0]);
6056
6057   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6058      may confuse gen_lowpart.  */
6059   if (mode != Pmode)
6060     {
6061       operands[1] = gen_lowpart (Pmode, operands[1]);
6062       operands[2] = gen_lowpart (Pmode, operands[2]);
6063     }
6064
6065   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6066
6067   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6068     operands[0] = gen_lowpart (SImode, operands[0]);
6069
6070   if (TARGET_64BIT && mode != Pmode)
6071     pat = gen_rtx_SUBREG (SImode, pat, 0);
6072
6073   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6074   DONE;
6075 })
6076
6077 ;; Convert lea to the lea pattern to avoid flags dependency.
6078 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6079 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
6080 (define_split
6081   [(set (match_operand:DI 0 "register_operand" "")
6082         (plus:DI (match_operand:DI 1 "register_operand" "")
6083                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6084    (clobber (reg:CC FLAGS_REG))]
6085   "TARGET_64BIT && reload_completed 
6086    && true_regnum (operands[0]) != true_regnum (operands[1])"
6087   [(set (match_dup 0)
6088         (plus:DI (match_dup 1) (match_dup 2)))])
6089
6090 ;; Convert lea to the lea pattern to avoid flags dependency.
6091 (define_split
6092   [(set (match_operand:DI 0 "register_operand" "")
6093         (zero_extend:DI
6094           (plus:SI (match_operand:SI 1 "register_operand" "")
6095                    (match_operand:SI 2 "nonmemory_operand" ""))))
6096    (clobber (reg:CC FLAGS_REG))]
6097   "TARGET_64BIT && reload_completed
6098    && ix86_lea_for_add_ok (insn, operands)"
6099   [(set (match_dup 0)
6100         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6101 {
6102   operands[1] = gen_lowpart (DImode, operands[1]);
6103   operands[2] = gen_lowpart (DImode, operands[2]);
6104 })
6105
6106 (define_insn "*add<mode>_2"
6107   [(set (reg FLAGS_REG)
6108         (compare
6109           (plus:SWI
6110             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6111             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6112           (const_int 0)))
6113    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6114         (plus:SWI (match_dup 1) (match_dup 2)))]
6115   "ix86_match_ccmode (insn, CCGOCmode)
6116    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6117 {
6118   switch (get_attr_type (insn))
6119     {
6120     case TYPE_INCDEC:
6121       if (operands[2] == const1_rtx)
6122         return "inc{<imodesuffix>}\t%0";
6123       else
6124         {
6125           gcc_assert (operands[2] == constm1_rtx);
6126           return "dec{<imodesuffix>}\t%0";
6127         }
6128
6129     default:
6130       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6131         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6132
6133       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6134     }
6135 }
6136   [(set (attr "type")
6137      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6138         (const_string "incdec")
6139         (const_string "alu")))
6140    (set (attr "length_immediate")
6141       (if_then_else
6142         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6143         (const_string "1")
6144         (const_string "*")))
6145    (set_attr "mode" "<MODE>")])
6146
6147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6148 (define_insn "*addsi_2_zext"
6149   [(set (reg FLAGS_REG)
6150         (compare
6151           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6152                    (match_operand:SI 2 "general_operand" "g"))
6153           (const_int 0)))
6154    (set (match_operand:DI 0 "register_operand" "=r")
6155         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6156   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6157    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6158 {
6159   switch (get_attr_type (insn))
6160     {
6161     case TYPE_INCDEC:
6162       if (operands[2] == const1_rtx)
6163         return "inc{l}\t%k0";
6164       else
6165         {
6166           gcc_assert (operands[2] == constm1_rtx);
6167           return "dec{l}\t%k0";
6168         }
6169
6170     default:
6171       if (x86_maybe_negate_const_int (&operands[2], SImode))
6172         return "sub{l}\t{%2, %k0|%k0, %2}";
6173
6174       return "add{l}\t{%2, %k0|%k0, %2}";
6175     }
6176 }
6177   [(set (attr "type")
6178      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6179         (const_string "incdec")
6180         (const_string "alu")))
6181    (set (attr "length_immediate")
6182       (if_then_else
6183         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6184         (const_string "1")
6185         (const_string "*")))
6186    (set_attr "mode" "SI")])
6187
6188 (define_insn "*add<mode>_3"
6189   [(set (reg FLAGS_REG)
6190         (compare
6191           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6192           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6193    (clobber (match_scratch:SWI 0 "=<r>"))]
6194   "ix86_match_ccmode (insn, CCZmode)
6195    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6196 {
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_INCDEC:
6200       if (operands[2] == const1_rtx)
6201         return "inc{<imodesuffix>}\t%0";
6202       else
6203         {
6204           gcc_assert (operands[2] == constm1_rtx);
6205           return "dec{<imodesuffix>}\t%0";
6206         }
6207
6208     default:
6209       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6210         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6211
6212       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6213     }
6214 }
6215   [(set (attr "type")
6216      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6217         (const_string "incdec")
6218         (const_string "alu")))
6219    (set (attr "length_immediate")
6220       (if_then_else
6221         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6222         (const_string "1")
6223         (const_string "*")))
6224    (set_attr "mode" "<MODE>")])
6225
6226 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6227 (define_insn "*addsi_3_zext"
6228   [(set (reg FLAGS_REG)
6229         (compare
6230           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6231           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6232    (set (match_operand:DI 0 "register_operand" "=r")
6233         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6234   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6235    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6236 {
6237   switch (get_attr_type (insn))
6238     {
6239     case TYPE_INCDEC:
6240       if (operands[2] == const1_rtx)
6241         return "inc{l}\t%k0";
6242       else
6243         {
6244           gcc_assert (operands[2] == constm1_rtx);
6245           return "dec{l}\t%k0";
6246         }
6247
6248     default:
6249       if (x86_maybe_negate_const_int (&operands[2], SImode))
6250         return "sub{l}\t{%2, %k0|%k0, %2}";
6251
6252       return "add{l}\t{%2, %k0|%k0, %2}";
6253     }
6254 }
6255   [(set (attr "type")
6256      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6257         (const_string "incdec")
6258         (const_string "alu")))
6259    (set (attr "length_immediate")
6260       (if_then_else
6261         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6262         (const_string "1")
6263         (const_string "*")))
6264    (set_attr "mode" "SI")])
6265
6266 ; For comparisons against 1, -1 and 128, we may generate better code
6267 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6268 ; is matched then.  We can't accept general immediate, because for
6269 ; case of overflows,  the result is messed up.
6270 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6271 ; only for comparisons not depending on it.
6272
6273 (define_insn "*adddi_4"
6274   [(set (reg FLAGS_REG)
6275         (compare
6276           (match_operand:DI 1 "nonimmediate_operand" "0")
6277           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6278    (clobber (match_scratch:DI 0 "=rm"))]
6279   "TARGET_64BIT
6280    && ix86_match_ccmode (insn, CCGCmode)"
6281 {
6282   switch (get_attr_type (insn))
6283     {
6284     case TYPE_INCDEC:
6285       if (operands[2] == constm1_rtx)
6286         return "inc{q}\t%0";
6287       else
6288         {
6289           gcc_assert (operands[2] == const1_rtx);
6290           return "dec{q}\t%0";
6291         }
6292
6293     default:
6294       if (x86_maybe_negate_const_int (&operands[2], DImode))
6295         return "add{q}\t{%2, %0|%0, %2}";
6296
6297       return "sub{q}\t{%2, %0|%0, %2}";
6298     }
6299 }
6300   [(set (attr "type")
6301      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6302         (const_string "incdec")
6303         (const_string "alu")))
6304    (set (attr "length_immediate")
6305       (if_then_else
6306         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6307         (const_string "1")
6308         (const_string "*")))
6309    (set_attr "mode" "DI")])
6310
6311 ; For comparisons against 1, -1 and 128, we may generate better code
6312 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6313 ; is matched then.  We can't accept general immediate, because for
6314 ; case of overflows,  the result is messed up.
6315 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6316 ; only for comparisons not depending on it.
6317
6318 (define_insn "*add<mode>_4"
6319   [(set (reg FLAGS_REG)
6320         (compare
6321           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6322           (match_operand:SWI124 2 "const_int_operand" "n")))
6323    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6324   "ix86_match_ccmode (insn, CCGCmode)"
6325 {
6326   switch (get_attr_type (insn))
6327     {
6328     case TYPE_INCDEC:
6329       if (operands[2] == constm1_rtx)
6330         return "inc{<imodesuffix>}\t%0";
6331       else
6332         {
6333           gcc_assert (operands[2] == const1_rtx);
6334           return "dec{<imodesuffix>}\t%0";
6335         }
6336
6337     default:
6338       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6339         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6340
6341       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6342     }
6343 }
6344   [(set (attr "type")
6345      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6346         (const_string "incdec")
6347         (const_string "alu")))
6348    (set (attr "length_immediate")
6349       (if_then_else
6350         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6351         (const_string "1")
6352         (const_string "*")))
6353    (set_attr "mode" "<MODE>")])
6354
6355 (define_insn "*add<mode>_5"
6356   [(set (reg FLAGS_REG)
6357         (compare
6358           (plus:SWI
6359             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6360             (match_operand:SWI 2 "<general_operand>" "<g>"))
6361           (const_int 0)))
6362    (clobber (match_scratch:SWI 0 "=<r>"))]
6363   "ix86_match_ccmode (insn, CCGOCmode)
6364    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6365 {
6366   switch (get_attr_type (insn))
6367     {
6368     case TYPE_INCDEC:
6369       if (operands[2] == const1_rtx)
6370         return "inc{<imodesuffix>}\t%0";
6371       else
6372         {
6373           gcc_assert (operands[2] == constm1_rtx);
6374           return "dec{<imodesuffix>}\t%0";
6375         }
6376
6377     default:
6378       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6379         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6380
6381       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6382     }
6383 }
6384   [(set (attr "type")
6385      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6386         (const_string "incdec")
6387         (const_string "alu")))
6388    (set (attr "length_immediate")
6389       (if_then_else
6390         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6391         (const_string "1")
6392         (const_string "*")))
6393    (set_attr "mode" "<MODE>")])
6394
6395 (define_insn "*addqi_ext_1_rex64"
6396   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6397                          (const_int 8)
6398                          (const_int 8))
6399         (plus:SI
6400           (zero_extract:SI
6401             (match_operand 1 "ext_register_operand" "0")
6402             (const_int 8)
6403             (const_int 8))
6404           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6405    (clobber (reg:CC FLAGS_REG))]
6406   "TARGET_64BIT"
6407 {
6408   switch (get_attr_type (insn))
6409     {
6410     case TYPE_INCDEC:
6411       if (operands[2] == const1_rtx)
6412         return "inc{b}\t%h0";
6413       else
6414         {
6415           gcc_assert (operands[2] == constm1_rtx);
6416           return "dec{b}\t%h0";
6417         }
6418
6419     default:
6420       return "add{b}\t{%2, %h0|%h0, %2}";
6421     }
6422 }
6423   [(set (attr "type")
6424      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425         (const_string "incdec")
6426         (const_string "alu")))
6427    (set_attr "modrm" "1")
6428    (set_attr "mode" "QI")])
6429
6430 (define_insn "addqi_ext_1"
6431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6432                          (const_int 8)
6433                          (const_int 8))
6434         (plus:SI
6435           (zero_extract:SI
6436             (match_operand 1 "ext_register_operand" "0")
6437             (const_int 8)
6438             (const_int 8))
6439           (match_operand:QI 2 "general_operand" "Qmn")))
6440    (clobber (reg:CC FLAGS_REG))]
6441   "!TARGET_64BIT"
6442 {
6443   switch (get_attr_type (insn))
6444     {
6445     case TYPE_INCDEC:
6446       if (operands[2] == const1_rtx)
6447         return "inc{b}\t%h0";
6448       else
6449         {
6450           gcc_assert (operands[2] == constm1_rtx);
6451           return "dec{b}\t%h0";
6452         }
6453
6454     default:
6455       return "add{b}\t{%2, %h0|%h0, %2}";
6456     }
6457 }
6458   [(set (attr "type")
6459      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6460         (const_string "incdec")
6461         (const_string "alu")))
6462    (set_attr "modrm" "1")
6463    (set_attr "mode" "QI")])
6464
6465 (define_insn "*addqi_ext_2"
6466   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6467                          (const_int 8)
6468                          (const_int 8))
6469         (plus:SI
6470           (zero_extract:SI
6471             (match_operand 1 "ext_register_operand" "%0")
6472             (const_int 8)
6473             (const_int 8))
6474           (zero_extract:SI
6475             (match_operand 2 "ext_register_operand" "Q")
6476             (const_int 8)
6477             (const_int 8))))
6478    (clobber (reg:CC FLAGS_REG))]
6479   ""
6480   "add{b}\t{%h2, %h0|%h0, %h2}"
6481   [(set_attr "type" "alu")
6482    (set_attr "mode" "QI")])
6483
6484 ;; The lea patterns for non-Pmodes needs to be matched by
6485 ;; several insns converted to real lea by splitters.
6486
6487 (define_insn_and_split "*lea_general_1"
6488   [(set (match_operand 0 "register_operand" "=r")
6489         (plus (plus (match_operand 1 "index_register_operand" "l")
6490                     (match_operand 2 "register_operand" "r"))
6491               (match_operand 3 "immediate_operand" "i")))]
6492   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6493     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6494    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6495    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6496    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6497    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6498        || GET_MODE (operands[3]) == VOIDmode)"
6499   "#"
6500   "&& reload_completed"
6501   [(const_int 0)]
6502 {
6503   rtx pat;
6504   operands[0] = gen_lowpart (SImode, operands[0]);
6505   operands[1] = gen_lowpart (Pmode, operands[1]);
6506   operands[2] = gen_lowpart (Pmode, operands[2]);
6507   operands[3] = gen_lowpart (Pmode, operands[3]);
6508   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6509                       operands[3]);
6510   if (Pmode != SImode)
6511     pat = gen_rtx_SUBREG (SImode, pat, 0);
6512   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6513   DONE;
6514 }
6515   [(set_attr "type" "lea")
6516    (set_attr "mode" "SI")])
6517
6518 (define_insn_and_split "*lea_general_1_zext"
6519   [(set (match_operand:DI 0 "register_operand" "=r")
6520         (zero_extend:DI
6521           (plus:SI (plus:SI
6522                      (match_operand:SI 1 "index_register_operand" "l")
6523                      (match_operand:SI 2 "register_operand" "r"))
6524                    (match_operand:SI 3 "immediate_operand" "i"))))]
6525   "TARGET_64BIT"
6526   "#"
6527   "&& reload_completed"
6528   [(set (match_dup 0)
6529         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6530                                                      (match_dup 2))
6531                                             (match_dup 3)) 0)))]
6532 {
6533   operands[1] = gen_lowpart (Pmode, operands[1]);
6534   operands[2] = gen_lowpart (Pmode, operands[2]);
6535   operands[3] = gen_lowpart (Pmode, operands[3]);
6536 }
6537   [(set_attr "type" "lea")
6538    (set_attr "mode" "SI")])
6539
6540 (define_insn_and_split "*lea_general_2"
6541   [(set (match_operand 0 "register_operand" "=r")
6542         (plus (mult (match_operand 1 "index_register_operand" "l")
6543                     (match_operand 2 "const248_operand" "i"))
6544               (match_operand 3 "nonmemory_operand" "ri")))]
6545   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6546     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6547    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6548    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6549    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6550        || GET_MODE (operands[3]) == VOIDmode)"
6551   "#"
6552   "&& reload_completed"
6553   [(const_int 0)]
6554 {
6555   rtx pat;
6556   operands[0] = gen_lowpart (SImode, operands[0]);
6557   operands[1] = gen_lowpart (Pmode, operands[1]);
6558   operands[3] = gen_lowpart (Pmode, operands[3]);
6559   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6560                       operands[3]);
6561   if (Pmode != SImode)
6562     pat = gen_rtx_SUBREG (SImode, pat, 0);
6563   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6564   DONE;
6565 }
6566   [(set_attr "type" "lea")
6567    (set_attr "mode" "SI")])
6568
6569 (define_insn_and_split "*lea_general_2_zext"
6570   [(set (match_operand:DI 0 "register_operand" "=r")
6571         (zero_extend:DI
6572           (plus:SI (mult:SI
6573                      (match_operand:SI 1 "index_register_operand" "l")
6574                      (match_operand:SI 2 "const248_operand" "n"))
6575                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6576   "TARGET_64BIT"
6577   "#"
6578   "&& reload_completed"
6579   [(set (match_dup 0)
6580         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6581                                                      (match_dup 2))
6582                                             (match_dup 3)) 0)))]
6583 {
6584   operands[1] = gen_lowpart (Pmode, operands[1]);
6585   operands[3] = gen_lowpart (Pmode, operands[3]);
6586 }
6587   [(set_attr "type" "lea")
6588    (set_attr "mode" "SI")])
6589
6590 (define_insn_and_split "*lea_general_3"
6591   [(set (match_operand 0 "register_operand" "=r")
6592         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6593                           (match_operand 2 "const248_operand" "i"))
6594                     (match_operand 3 "register_operand" "r"))
6595               (match_operand 4 "immediate_operand" "i")))]
6596   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6597     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6598    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6599    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6600    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6601   "#"
6602   "&& reload_completed"
6603   [(const_int 0)]
6604 {
6605   rtx pat;
6606   operands[0] = gen_lowpart (SImode, operands[0]);
6607   operands[1] = gen_lowpart (Pmode, operands[1]);
6608   operands[3] = gen_lowpart (Pmode, operands[3]);
6609   operands[4] = gen_lowpart (Pmode, operands[4]);
6610   pat = gen_rtx_PLUS (Pmode,
6611                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6612                                                          operands[2]),
6613                                     operands[3]),
6614                       operands[4]);
6615   if (Pmode != SImode)
6616     pat = gen_rtx_SUBREG (SImode, pat, 0);
6617   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6618   DONE;
6619 }
6620   [(set_attr "type" "lea")
6621    (set_attr "mode" "SI")])
6622
6623 (define_insn_and_split "*lea_general_3_zext"
6624   [(set (match_operand:DI 0 "register_operand" "=r")
6625         (zero_extend:DI
6626           (plus:SI (plus:SI
6627                      (mult:SI
6628                        (match_operand:SI 1 "index_register_operand" "l")
6629                        (match_operand:SI 2 "const248_operand" "n"))
6630                      (match_operand:SI 3 "register_operand" "r"))
6631                    (match_operand:SI 4 "immediate_operand" "i"))))]
6632   "TARGET_64BIT"
6633   "#"
6634   "&& reload_completed"
6635   [(set (match_dup 0)
6636         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6637                                                               (match_dup 2))
6638                                                      (match_dup 3))
6639                                             (match_dup 4)) 0)))]
6640 {
6641   operands[1] = gen_lowpart (Pmode, operands[1]);
6642   operands[3] = gen_lowpart (Pmode, operands[3]);
6643   operands[4] = gen_lowpart (Pmode, operands[4]);
6644 }
6645   [(set_attr "type" "lea")
6646    (set_attr "mode" "SI")])
6647 \f
6648 ;; Subtract instructions
6649
6650 (define_expand "sub<mode>3"
6651   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6652         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6653                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6654   ""
6655   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6656
6657 (define_insn_and_split "*sub<dwi>3_doubleword"
6658   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6659         (minus:<DWI>
6660           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6661           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6662    (clobber (reg:CC FLAGS_REG))]
6663   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6664   "#"
6665   "reload_completed"
6666   [(parallel [(set (reg:CC FLAGS_REG)
6667                    (compare:CC (match_dup 1) (match_dup 2)))
6668               (set (match_dup 0)
6669                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6670    (parallel [(set (match_dup 3)
6671                    (minus:DWIH
6672                      (match_dup 4)
6673                      (plus:DWIH
6674                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6675                        (match_dup 5))))
6676               (clobber (reg:CC FLAGS_REG))])]
6677   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6678
6679 (define_insn "*sub<mode>_1"
6680   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6681         (minus:SWI
6682           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6683           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6684    (clobber (reg:CC FLAGS_REG))]
6685   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6686   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "<MODE>")])
6689
6690 (define_insn "*subsi_1_zext"
6691   [(set (match_operand:DI 0 "register_operand" "=r")
6692         (zero_extend:DI
6693           (minus:SI (match_operand:SI 1 "register_operand" "0")
6694                     (match_operand:SI 2 "general_operand" "g"))))
6695    (clobber (reg:CC FLAGS_REG))]
6696   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6697   "sub{l}\t{%2, %k0|%k0, %2}"
6698   [(set_attr "type" "alu")
6699    (set_attr "mode" "SI")])
6700
6701 (define_insn "*subqi_1_slp"
6702   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6703         (minus:QI (match_dup 0)
6704                   (match_operand:QI 1 "general_operand" "qn,qm")))
6705    (clobber (reg:CC FLAGS_REG))]
6706   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6707    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6708   "sub{b}\t{%1, %0|%0, %1}"
6709   [(set_attr "type" "alu1")
6710    (set_attr "mode" "QI")])
6711
6712 (define_insn "*sub<mode>_2"
6713   [(set (reg FLAGS_REG)
6714         (compare
6715           (minus:SWI
6716             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6717             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6718           (const_int 0)))
6719    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6720         (minus:SWI (match_dup 1) (match_dup 2)))]
6721   "ix86_match_ccmode (insn, CCGOCmode)
6722    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6723   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6724   [(set_attr "type" "alu")
6725    (set_attr "mode" "<MODE>")])
6726
6727 (define_insn "*subsi_2_zext"
6728   [(set (reg FLAGS_REG)
6729         (compare
6730           (minus:SI (match_operand:SI 1 "register_operand" "0")
6731                     (match_operand:SI 2 "general_operand" "g"))
6732           (const_int 0)))
6733    (set (match_operand:DI 0 "register_operand" "=r")
6734         (zero_extend:DI
6735           (minus:SI (match_dup 1)
6736                     (match_dup 2))))]
6737   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6738    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6739   "sub{l}\t{%2, %k0|%k0, %2}"
6740   [(set_attr "type" "alu")
6741    (set_attr "mode" "SI")])
6742
6743 (define_insn "*sub<mode>_3"
6744   [(set (reg FLAGS_REG)
6745         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6746                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6747    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6748         (minus:SWI (match_dup 1) (match_dup 2)))]
6749   "ix86_match_ccmode (insn, CCmode)
6750    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6751   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6752   [(set_attr "type" "alu")
6753    (set_attr "mode" "<MODE>")])
6754
6755 (define_insn "*subsi_3_zext"
6756   [(set (reg FLAGS_REG)
6757         (compare (match_operand:SI 1 "register_operand" "0")
6758                  (match_operand:SI 2 "general_operand" "g")))
6759    (set (match_operand:DI 0 "register_operand" "=r")
6760         (zero_extend:DI
6761           (minus:SI (match_dup 1)
6762                     (match_dup 2))))]
6763   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6764    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6765   "sub{l}\t{%2, %1|%1, %2}"
6766   [(set_attr "type" "alu")
6767    (set_attr "mode" "SI")])
6768 \f
6769 ;; Add with carry and subtract with borrow
6770
6771 (define_expand "<plusminus_insn><mode>3_carry"
6772   [(parallel
6773     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6774           (plusminus:SWI
6775             (match_operand:SWI 1 "nonimmediate_operand" "")
6776             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6777                        [(match_operand 3 "flags_reg_operand" "")
6778                         (const_int 0)])
6779                       (match_operand:SWI 2 "<general_operand>" ""))))
6780      (clobber (reg:CC FLAGS_REG))])]
6781   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6782
6783 (define_insn "*<plusminus_insn><mode>3_carry"
6784   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6785         (plusminus:SWI
6786           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6787           (plus:SWI
6788             (match_operator 3 "ix86_carry_flag_operator"
6789              [(reg FLAGS_REG) (const_int 0)])
6790             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6791    (clobber (reg:CC FLAGS_REG))]
6792   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6793   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "use_carry" "1")
6796    (set_attr "pent_pair" "pu")
6797    (set_attr "mode" "<MODE>")])
6798
6799 (define_insn "*addsi3_carry_zext"
6800   [(set (match_operand:DI 0 "register_operand" "=r")
6801         (zero_extend:DI
6802           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6803                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6804                              [(reg FLAGS_REG) (const_int 0)])
6805                             (match_operand:SI 2 "general_operand" "g")))))
6806    (clobber (reg:CC FLAGS_REG))]
6807   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6808   "adc{l}\t{%2, %k0|%k0, %2}"
6809   [(set_attr "type" "alu")
6810    (set_attr "use_carry" "1")
6811    (set_attr "pent_pair" "pu")
6812    (set_attr "mode" "SI")])
6813
6814 (define_insn "*subsi3_carry_zext"
6815   [(set (match_operand:DI 0 "register_operand" "=r")
6816         (zero_extend:DI
6817           (minus:SI (match_operand:SI 1 "register_operand" "0")
6818                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6819                               [(reg FLAGS_REG) (const_int 0)])
6820                              (match_operand:SI 2 "general_operand" "g")))))
6821    (clobber (reg:CC FLAGS_REG))]
6822   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6823   "sbb{l}\t{%2, %k0|%k0, %2}"
6824   [(set_attr "type" "alu")
6825    (set_attr "pent_pair" "pu")
6826    (set_attr "mode" "SI")])
6827 \f
6828 ;; Overflow setting add and subtract instructions
6829
6830 (define_insn "*add<mode>3_cconly_overflow"
6831   [(set (reg:CCC FLAGS_REG)
6832         (compare:CCC
6833           (plus:SWI
6834             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6835             (match_operand:SWI 2 "<general_operand>" "<g>"))
6836           (match_dup 1)))
6837    (clobber (match_scratch:SWI 0 "=<r>"))]
6838   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6839   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6840   [(set_attr "type" "alu")
6841    (set_attr "mode" "<MODE>")])
6842
6843 (define_insn "*sub<mode>3_cconly_overflow"
6844   [(set (reg:CCC FLAGS_REG)
6845         (compare:CCC
6846           (minus:SWI
6847             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6848             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6849           (match_dup 0)))]
6850   ""
6851   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6852   [(set_attr "type" "icmp")
6853    (set_attr "mode" "<MODE>")])
6854
6855 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6856   [(set (reg:CCC FLAGS_REG)
6857         (compare:CCC
6858             (plusminus:SWI
6859                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6860                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6861             (match_dup 1)))
6862    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6863         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6864   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6865   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6866   [(set_attr "type" "alu")
6867    (set_attr "mode" "<MODE>")])
6868
6869 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6870   [(set (reg:CCC FLAGS_REG)
6871         (compare:CCC
6872           (plusminus:SI
6873             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6874             (match_operand:SI 2 "general_operand" "g"))
6875           (match_dup 1)))
6876    (set (match_operand:DI 0 "register_operand" "=r")
6877         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6878   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6879   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6880   [(set_attr "type" "alu")
6881    (set_attr "mode" "SI")])
6882
6883 ;; The patterns that match these are at the end of this file.
6884
6885 (define_expand "<plusminus_insn>xf3"
6886   [(set (match_operand:XF 0 "register_operand" "")
6887         (plusminus:XF
6888           (match_operand:XF 1 "register_operand" "")
6889           (match_operand:XF 2 "register_operand" "")))]
6890   "TARGET_80387")
6891
6892 (define_expand "<plusminus_insn><mode>3"
6893   [(set (match_operand:MODEF 0 "register_operand" "")
6894         (plusminus:MODEF
6895           (match_operand:MODEF 1 "register_operand" "")
6896           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6897   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6898     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6899 \f
6900 ;; Multiply instructions
6901
6902 (define_expand "mul<mode>3"
6903   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6904                    (mult:SWIM248
6905                      (match_operand:SWIM248 1 "register_operand" "")
6906                      (match_operand:SWIM248 2 "<general_operand>" "")))
6907               (clobber (reg:CC FLAGS_REG))])])
6908
6909 (define_expand "mulqi3"
6910   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6911                    (mult:QI
6912                      (match_operand:QI 1 "register_operand" "")
6913                      (match_operand:QI 2 "nonimmediate_operand" "")))
6914               (clobber (reg:CC FLAGS_REG))])]
6915   "TARGET_QIMODE_MATH")
6916
6917 ;; On AMDFAM10
6918 ;; IMUL reg32/64, reg32/64, imm8        Direct
6919 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6920 ;; IMUL reg32/64, reg32/64, imm32       Direct
6921 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6922 ;; IMUL reg32/64, reg32/64              Direct
6923 ;; IMUL reg32/64, mem32/64              Direct
6924 ;;
6925 ;; On BDVER1, all above IMULs use DirectPath
6926
6927 (define_insn "*mul<mode>3_1"
6928   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6929         (mult:SWI48
6930           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6931           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6932    (clobber (reg:CC FLAGS_REG))]
6933   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6934   "@
6935    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6936    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6937    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6938   [(set_attr "type" "imul")
6939    (set_attr "prefix_0f" "0,0,1")
6940    (set (attr "athlon_decode")
6941         (cond [(eq_attr "cpu" "athlon")
6942                   (const_string "vector")
6943                (eq_attr "alternative" "1")
6944                   (const_string "vector")
6945                (and (eq_attr "alternative" "2")
6946                     (match_operand 1 "memory_operand" ""))
6947                   (const_string "vector")]
6948               (const_string "direct")))
6949    (set (attr "amdfam10_decode")
6950         (cond [(and (eq_attr "alternative" "0,1")
6951                     (match_operand 1 "memory_operand" ""))
6952                   (const_string "vector")]
6953               (const_string "direct")))
6954    (set_attr "bdver1_decode" "direct")
6955    (set_attr "mode" "<MODE>")])
6956
6957 (define_insn "*mulsi3_1_zext"
6958   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6959         (zero_extend:DI
6960           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6961                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6962    (clobber (reg:CC FLAGS_REG))]
6963   "TARGET_64BIT
6964    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965   "@
6966    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6967    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6968    imul{l}\t{%2, %k0|%k0, %2}"
6969   [(set_attr "type" "imul")
6970    (set_attr "prefix_0f" "0,0,1")
6971    (set (attr "athlon_decode")
6972         (cond [(eq_attr "cpu" "athlon")
6973                   (const_string "vector")
6974                (eq_attr "alternative" "1")
6975                   (const_string "vector")
6976                (and (eq_attr "alternative" "2")
6977                     (match_operand 1 "memory_operand" ""))
6978                   (const_string "vector")]
6979               (const_string "direct")))
6980    (set (attr "amdfam10_decode")
6981         (cond [(and (eq_attr "alternative" "0,1")
6982                     (match_operand 1 "memory_operand" ""))
6983                   (const_string "vector")]
6984               (const_string "direct")))
6985    (set_attr "bdver1_decode" "direct")
6986    (set_attr "mode" "SI")])
6987
6988 ;; On AMDFAM10
6989 ;; IMUL reg16, reg16, imm8      VectorPath
6990 ;; IMUL reg16, mem16, imm8      VectorPath
6991 ;; IMUL reg16, reg16, imm16     VectorPath
6992 ;; IMUL reg16, mem16, imm16     VectorPath
6993 ;; IMUL reg16, reg16            Direct
6994 ;; IMUL reg16, mem16            Direct
6995 ;;
6996 ;; On BDVER1, all HI MULs use DoublePath
6997
6998 (define_insn "*mulhi3_1"
6999   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7000         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7001                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7002    (clobber (reg:CC FLAGS_REG))]
7003   "TARGET_HIMODE_MATH
7004    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7005   "@
7006    imul{w}\t{%2, %1, %0|%0, %1, %2}
7007    imul{w}\t{%2, %1, %0|%0, %1, %2}
7008    imul{w}\t{%2, %0|%0, %2}"
7009   [(set_attr "type" "imul")
7010    (set_attr "prefix_0f" "0,0,1")
7011    (set (attr "athlon_decode")
7012         (cond [(eq_attr "cpu" "athlon")
7013                   (const_string "vector")
7014                (eq_attr "alternative" "1,2")
7015                   (const_string "vector")]
7016               (const_string "direct")))
7017    (set (attr "amdfam10_decode")
7018         (cond [(eq_attr "alternative" "0,1")
7019                   (const_string "vector")]
7020               (const_string "direct")))
7021    (set_attr "bdver1_decode" "double")
7022    (set_attr "mode" "HI")])
7023
7024 ;;On AMDFAM10 and BDVER1
7025 ;; MUL reg8     Direct
7026 ;; MUL mem8     Direct
7027
7028 (define_insn "*mulqi3_1"
7029   [(set (match_operand:QI 0 "register_operand" "=a")
7030         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7032    (clobber (reg:CC FLAGS_REG))]
7033   "TARGET_QIMODE_MATH
7034    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7035   "mul{b}\t%2"
7036   [(set_attr "type" "imul")
7037    (set_attr "length_immediate" "0")
7038    (set (attr "athlon_decode")
7039      (if_then_else (eq_attr "cpu" "athlon")
7040         (const_string "vector")
7041         (const_string "direct")))
7042    (set_attr "amdfam10_decode" "direct")
7043    (set_attr "bdver1_decode" "direct")
7044    (set_attr "mode" "QI")])
7045
7046 (define_expand "<u>mul<mode><dwi>3"
7047   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7048                    (mult:<DWI>
7049                      (any_extend:<DWI>
7050                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7051                      (any_extend:<DWI>
7052                        (match_operand:DWIH 2 "register_operand" ""))))
7053               (clobber (reg:CC FLAGS_REG))])])
7054
7055 (define_expand "<u>mulqihi3"
7056   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7057                    (mult:HI
7058                      (any_extend:HI
7059                        (match_operand:QI 1 "nonimmediate_operand" ""))
7060                      (any_extend:HI
7061                        (match_operand:QI 2 "register_operand" ""))))
7062               (clobber (reg:CC FLAGS_REG))])]
7063   "TARGET_QIMODE_MATH")
7064
7065 (define_insn "*<u>mul<mode><dwi>3_1"
7066   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7067         (mult:<DWI>
7068           (any_extend:<DWI>
7069             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7070           (any_extend:<DWI>
7071             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7072    (clobber (reg:CC FLAGS_REG))]
7073   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7074   "<sgnprefix>mul{<imodesuffix>}\t%2"
7075   [(set_attr "type" "imul")
7076    (set_attr "length_immediate" "0")
7077    (set (attr "athlon_decode")
7078      (if_then_else (eq_attr "cpu" "athlon")
7079         (const_string "vector")
7080         (const_string "double")))
7081    (set_attr "amdfam10_decode" "double")
7082    (set_attr "bdver1_decode" "direct")
7083    (set_attr "mode" "<MODE>")])
7084
7085 (define_insn "*<u>mulqihi3_1"
7086   [(set (match_operand:HI 0 "register_operand" "=a")
7087         (mult:HI
7088           (any_extend:HI
7089             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7090           (any_extend:HI
7091             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7092    (clobber (reg:CC FLAGS_REG))]
7093   "TARGET_QIMODE_MATH
7094    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7095   "<sgnprefix>mul{b}\t%2"
7096   [(set_attr "type" "imul")
7097    (set_attr "length_immediate" "0")
7098    (set (attr "athlon_decode")
7099      (if_then_else (eq_attr "cpu" "athlon")
7100         (const_string "vector")
7101         (const_string "direct")))
7102    (set_attr "amdfam10_decode" "direct")
7103    (set_attr "bdver1_decode" "direct")
7104    (set_attr "mode" "QI")])
7105
7106 (define_expand "<s>mul<mode>3_highpart"
7107   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7108                    (truncate:SWI48
7109                      (lshiftrt:<DWI>
7110                        (mult:<DWI>
7111                          (any_extend:<DWI>
7112                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7113                          (any_extend:<DWI>
7114                            (match_operand:SWI48 2 "register_operand" "")))
7115                        (match_dup 4))))
7116               (clobber (match_scratch:SWI48 3 ""))
7117               (clobber (reg:CC FLAGS_REG))])]
7118   ""
7119   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7120
7121 (define_insn "*<s>muldi3_highpart_1"
7122   [(set (match_operand:DI 0 "register_operand" "=d")
7123         (truncate:DI
7124           (lshiftrt:TI
7125             (mult:TI
7126               (any_extend:TI
7127                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7128               (any_extend:TI
7129                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7130             (const_int 64))))
7131    (clobber (match_scratch:DI 3 "=1"))
7132    (clobber (reg:CC FLAGS_REG))]
7133   "TARGET_64BIT
7134    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7135   "<sgnprefix>mul{q}\t%2"
7136   [(set_attr "type" "imul")
7137    (set_attr "length_immediate" "0")
7138    (set (attr "athlon_decode")
7139      (if_then_else (eq_attr "cpu" "athlon")
7140         (const_string "vector")
7141         (const_string "double")))
7142    (set_attr "amdfam10_decode" "double")
7143    (set_attr "bdver1_decode" "direct")
7144    (set_attr "mode" "DI")])
7145
7146 (define_insn "*<s>mulsi3_highpart_1"
7147   [(set (match_operand:SI 0 "register_operand" "=d")
7148         (truncate:SI
7149           (lshiftrt:DI
7150             (mult:DI
7151               (any_extend:DI
7152                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7153               (any_extend:DI
7154                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7155             (const_int 32))))
7156    (clobber (match_scratch:SI 3 "=1"))
7157    (clobber (reg:CC FLAGS_REG))]
7158   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7159   "<sgnprefix>mul{l}\t%2"
7160   [(set_attr "type" "imul")
7161    (set_attr "length_immediate" "0")
7162    (set (attr "athlon_decode")
7163      (if_then_else (eq_attr "cpu" "athlon")
7164         (const_string "vector")
7165         (const_string "double")))
7166    (set_attr "amdfam10_decode" "double")
7167    (set_attr "bdver1_decode" "direct")
7168    (set_attr "mode" "SI")])
7169
7170 (define_insn "*<s>mulsi3_highpart_zext"
7171   [(set (match_operand:DI 0 "register_operand" "=d")
7172         (zero_extend:DI (truncate:SI
7173           (lshiftrt:DI
7174             (mult:DI (any_extend:DI
7175                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7176                      (any_extend:DI
7177                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7178             (const_int 32)))))
7179    (clobber (match_scratch:SI 3 "=1"))
7180    (clobber (reg:CC FLAGS_REG))]
7181   "TARGET_64BIT
7182    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7183   "<sgnprefix>mul{l}\t%2"
7184   [(set_attr "type" "imul")
7185    (set_attr "length_immediate" "0")
7186    (set (attr "athlon_decode")
7187      (if_then_else (eq_attr "cpu" "athlon")
7188         (const_string "vector")
7189         (const_string "double")))
7190    (set_attr "amdfam10_decode" "double")
7191    (set_attr "bdver1_decode" "direct")
7192    (set_attr "mode" "SI")])
7193
7194 ;; The patterns that match these are at the end of this file.
7195
7196 (define_expand "mulxf3"
7197   [(set (match_operand:XF 0 "register_operand" "")
7198         (mult:XF (match_operand:XF 1 "register_operand" "")
7199                  (match_operand:XF 2 "register_operand" "")))]
7200   "TARGET_80387")
7201
7202 (define_expand "mul<mode>3"
7203   [(set (match_operand:MODEF 0 "register_operand" "")
7204         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7205                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7206   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7207     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7208 \f
7209 ;; Divide instructions
7210
7211 ;; The patterns that match these are at the end of this file.
7212
7213 (define_expand "divxf3"
7214   [(set (match_operand:XF 0 "register_operand" "")
7215         (div:XF (match_operand:XF 1 "register_operand" "")
7216                 (match_operand:XF 2 "register_operand" "")))]
7217   "TARGET_80387")
7218
7219 (define_expand "divdf3"
7220   [(set (match_operand:DF 0 "register_operand" "")
7221         (div:DF (match_operand:DF 1 "register_operand" "")
7222                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7223    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7224     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7225
7226 (define_expand "divsf3"
7227   [(set (match_operand:SF 0 "register_operand" "")
7228         (div:SF (match_operand:SF 1 "register_operand" "")
7229                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7230   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7231     || TARGET_SSE_MATH"
7232 {
7233   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7234       && flag_finite_math_only && !flag_trapping_math
7235       && flag_unsafe_math_optimizations)
7236     {
7237       ix86_emit_swdivsf (operands[0], operands[1],
7238                          operands[2], SFmode);
7239       DONE;
7240     }
7241 })
7242 \f
7243 ;; Divmod instructions.
7244
7245 (define_expand "divmod<mode>4"
7246   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7247                    (div:SWIM248
7248                      (match_operand:SWIM248 1 "register_operand" "")
7249                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7250               (set (match_operand:SWIM248 3 "register_operand" "")
7251                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7252               (clobber (reg:CC FLAGS_REG))])])
7253
7254 ;; Split with 8bit unsigned divide:
7255 ;;      if (dividend an divisor are in [0-255])
7256 ;;         use 8bit unsigned integer divide
7257 ;;       else
7258 ;;         use original integer divide
7259 (define_split
7260   [(set (match_operand:SWI48 0 "register_operand" "")
7261         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7262                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7263    (set (match_operand:SWI48 1 "register_operand" "")
7264         (mod:SWI48 (match_dup 2) (match_dup 3)))
7265    (clobber (reg:CC FLAGS_REG))]
7266   "TARGET_USE_8BIT_IDIV
7267    && TARGET_QIMODE_MATH
7268    && can_create_pseudo_p ()
7269    && !optimize_insn_for_size_p ()"
7270   [(const_int 0)]
7271   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7272
7273 (define_insn_and_split "divmod<mode>4_1"
7274   [(set (match_operand:SWI48 0 "register_operand" "=a")
7275         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7276                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7277    (set (match_operand:SWI48 1 "register_operand" "=&d")
7278         (mod:SWI48 (match_dup 2) (match_dup 3)))
7279    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7280    (clobber (reg:CC FLAGS_REG))]
7281   ""
7282   "#"
7283   "reload_completed"
7284   [(parallel [(set (match_dup 1)
7285                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7286               (clobber (reg:CC FLAGS_REG))])
7287    (parallel [(set (match_dup 0)
7288                    (div:SWI48 (match_dup 2) (match_dup 3)))
7289               (set (match_dup 1)
7290                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7291               (use (match_dup 1))
7292               (clobber (reg:CC FLAGS_REG))])]
7293 {
7294   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7295
7296   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7297     operands[4] = operands[2];
7298   else
7299     {
7300       /* Avoid use of cltd in favor of a mov+shift.  */
7301       emit_move_insn (operands[1], operands[2]);
7302       operands[4] = operands[1];
7303     }
7304 }
7305   [(set_attr "type" "multi")
7306    (set_attr "mode" "<MODE>")])
7307
7308 (define_insn_and_split "*divmod<mode>4"
7309   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7310         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7311                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7312    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7313         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7314    (clobber (reg:CC FLAGS_REG))]
7315   ""
7316   "#"
7317   "reload_completed"
7318   [(parallel [(set (match_dup 1)
7319                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7320               (clobber (reg:CC FLAGS_REG))])
7321    (parallel [(set (match_dup 0)
7322                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7323               (set (match_dup 1)
7324                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7325               (use (match_dup 1))
7326               (clobber (reg:CC FLAGS_REG))])]
7327 {
7328   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7329
7330   if (<MODE>mode != HImode
7331       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7332     operands[4] = operands[2];
7333   else
7334     {
7335       /* Avoid use of cltd in favor of a mov+shift.  */
7336       emit_move_insn (operands[1], operands[2]);
7337       operands[4] = operands[1];
7338     }
7339 }
7340   [(set_attr "type" "multi")
7341    (set_attr "mode" "<MODE>")])
7342
7343 (define_insn "*divmod<mode>4_noext"
7344   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7345         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7346                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7347    (set (match_operand:SWIM248 1 "register_operand" "=d")
7348         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7349    (use (match_operand:SWIM248 4 "register_operand" "1"))
7350    (clobber (reg:CC FLAGS_REG))]
7351   ""
7352   "idiv{<imodesuffix>}\t%3"
7353   [(set_attr "type" "idiv")
7354    (set_attr "mode" "<MODE>")])
7355
7356 (define_expand "divmodqi4"
7357   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7358                    (div:QI
7359                      (match_operand:QI 1 "register_operand" "")
7360                      (match_operand:QI 2 "nonimmediate_operand" "")))
7361               (set (match_operand:QI 3 "register_operand" "")
7362                    (mod:QI (match_dup 1) (match_dup 2)))
7363               (clobber (reg:CC FLAGS_REG))])]
7364   "TARGET_QIMODE_MATH"
7365 {
7366   rtx div, mod, insn;
7367   rtx tmp0, tmp1;
7368   
7369   tmp0 = gen_reg_rtx (HImode);
7370   tmp1 = gen_reg_rtx (HImode);
7371
7372   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7373      in AX.  */
7374   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7375   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7376
7377   /* Extract remainder from AH.  */
7378   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7379   insn = emit_move_insn (operands[3], tmp1);
7380
7381   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7382   set_unique_reg_note (insn, REG_EQUAL, mod);
7383
7384   /* Extract quotient from AL.  */
7385   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7386
7387   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7388   set_unique_reg_note (insn, REG_EQUAL, div);
7389
7390   DONE;
7391 })
7392
7393 ;; Divide AX by r/m8, with result stored in
7394 ;; AL <- Quotient
7395 ;; AH <- Remainder
7396 ;; Change div/mod to HImode and extend the second argument to HImode
7397 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7398 ;; combine may fail.
7399 (define_insn "divmodhiqi3"
7400   [(set (match_operand:HI 0 "register_operand" "=a")
7401         (ior:HI
7402           (ashift:HI
7403             (zero_extend:HI
7404               (truncate:QI
7405                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7406                         (sign_extend:HI
7407                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7408             (const_int 8))
7409           (zero_extend:HI
7410             (truncate:QI
7411               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7412    (clobber (reg:CC FLAGS_REG))]
7413   "TARGET_QIMODE_MATH"
7414   "idiv{b}\t%2"
7415   [(set_attr "type" "idiv")
7416    (set_attr "mode" "QI")])
7417
7418 (define_expand "udivmod<mode>4"
7419   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7420                    (udiv:SWIM248
7421                      (match_operand:SWIM248 1 "register_operand" "")
7422                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7423               (set (match_operand:SWIM248 3 "register_operand" "")
7424                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7425               (clobber (reg:CC FLAGS_REG))])])
7426
7427 ;; Split with 8bit unsigned divide:
7428 ;;      if (dividend an divisor are in [0-255])
7429 ;;         use 8bit unsigned integer divide
7430 ;;       else
7431 ;;         use original integer divide
7432 (define_split
7433   [(set (match_operand:SWI48 0 "register_operand" "")
7434         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7435                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7436    (set (match_operand:SWI48 1 "register_operand" "")
7437         (umod:SWI48 (match_dup 2) (match_dup 3)))
7438    (clobber (reg:CC FLAGS_REG))]
7439   "TARGET_USE_8BIT_IDIV
7440    && TARGET_QIMODE_MATH
7441    && can_create_pseudo_p ()
7442    && !optimize_insn_for_size_p ()"
7443   [(const_int 0)]
7444   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7445
7446 (define_insn_and_split "udivmod<mode>4_1"
7447   [(set (match_operand:SWI48 0 "register_operand" "=a")
7448         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7449                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7450    (set (match_operand:SWI48 1 "register_operand" "=&d")
7451         (umod:SWI48 (match_dup 2) (match_dup 3)))
7452    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7453    (clobber (reg:CC FLAGS_REG))]
7454   ""
7455   "#"
7456   "reload_completed"
7457   [(set (match_dup 1) (const_int 0))
7458    (parallel [(set (match_dup 0)
7459                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7460               (set (match_dup 1)
7461                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7462               (use (match_dup 1))
7463               (clobber (reg:CC FLAGS_REG))])]
7464   ""
7465   [(set_attr "type" "multi")
7466    (set_attr "mode" "<MODE>")])
7467
7468 (define_insn_and_split "*udivmod<mode>4"
7469   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7470         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7471                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7472    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7473         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7474    (clobber (reg:CC FLAGS_REG))]
7475   ""
7476   "#"
7477   "reload_completed"
7478   [(set (match_dup 1) (const_int 0))
7479    (parallel [(set (match_dup 0)
7480                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7481               (set (match_dup 1)
7482                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7483               (use (match_dup 1))
7484               (clobber (reg:CC FLAGS_REG))])]
7485   ""
7486   [(set_attr "type" "multi")
7487    (set_attr "mode" "<MODE>")])
7488
7489 (define_insn "*udivmod<mode>4_noext"
7490   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7491         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7492                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7493    (set (match_operand:SWIM248 1 "register_operand" "=d")
7494         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7495    (use (match_operand:SWIM248 4 "register_operand" "1"))
7496    (clobber (reg:CC FLAGS_REG))]
7497   ""
7498   "div{<imodesuffix>}\t%3"
7499   [(set_attr "type" "idiv")
7500    (set_attr "mode" "<MODE>")])
7501
7502 (define_expand "udivmodqi4"
7503   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7504                    (udiv:QI
7505                      (match_operand:QI 1 "register_operand" "")
7506                      (match_operand:QI 2 "nonimmediate_operand" "")))
7507               (set (match_operand:QI 3 "register_operand" "")
7508                    (umod:QI (match_dup 1) (match_dup 2)))
7509               (clobber (reg:CC FLAGS_REG))])]
7510   "TARGET_QIMODE_MATH"
7511 {
7512   rtx div, mod, insn;
7513   rtx tmp0, tmp1;
7514   
7515   tmp0 = gen_reg_rtx (HImode);
7516   tmp1 = gen_reg_rtx (HImode);
7517
7518   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7519      in AX.  */
7520   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7521   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7522
7523   /* Extract remainder from AH.  */
7524   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7525   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7526   insn = emit_move_insn (operands[3], tmp1);
7527
7528   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7529   set_unique_reg_note (insn, REG_EQUAL, mod);
7530
7531   /* Extract quotient from AL.  */
7532   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7533
7534   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7535   set_unique_reg_note (insn, REG_EQUAL, div);
7536
7537   DONE;
7538 })
7539
7540 (define_insn "udivmodhiqi3"
7541   [(set (match_operand:HI 0 "register_operand" "=a")
7542         (ior:HI
7543           (ashift:HI
7544             (zero_extend:HI
7545               (truncate:QI
7546                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7547                         (zero_extend:HI
7548                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7549             (const_int 8))
7550           (zero_extend:HI
7551             (truncate:QI
7552               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7553    (clobber (reg:CC FLAGS_REG))]
7554   "TARGET_QIMODE_MATH"
7555   "div{b}\t%2"
7556   [(set_attr "type" "idiv")
7557    (set_attr "mode" "QI")])
7558
7559 ;; We cannot use div/idiv for double division, because it causes
7560 ;; "division by zero" on the overflow and that's not what we expect
7561 ;; from truncate.  Because true (non truncating) double division is
7562 ;; never generated, we can't create this insn anyway.
7563 ;
7564 ;(define_insn ""
7565 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7566 ;       (truncate:SI
7567 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7568 ;                  (zero_extend:DI
7569 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7570 ;   (set (match_operand:SI 3 "register_operand" "=d")
7571 ;       (truncate:SI
7572 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7573 ;   (clobber (reg:CC FLAGS_REG))]
7574 ;  ""
7575 ;  "div{l}\t{%2, %0|%0, %2}"
7576 ;  [(set_attr "type" "idiv")])
7577 \f
7578 ;;- Logical AND instructions
7579
7580 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7581 ;; Note that this excludes ah.
7582
7583 (define_expand "testsi_ccno_1"
7584   [(set (reg:CCNO FLAGS_REG)
7585         (compare:CCNO
7586           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7587                   (match_operand:SI 1 "nonmemory_operand" ""))
7588           (const_int 0)))])
7589
7590 (define_expand "testqi_ccz_1"
7591   [(set (reg:CCZ FLAGS_REG)
7592         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7593                              (match_operand:QI 1 "nonmemory_operand" ""))
7594                  (const_int 0)))])
7595
7596 (define_expand "testdi_ccno_1"
7597   [(set (reg:CCNO FLAGS_REG)
7598         (compare:CCNO
7599           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7600                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7601           (const_int 0)))]
7602   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7603
7604 (define_insn "*testdi_1"
7605   [(set (reg FLAGS_REG)
7606         (compare
7607          (and:DI
7608           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7609           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7610          (const_int 0)))]
7611   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7612    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7613   "@
7614    test{l}\t{%k1, %k0|%k0, %k1}
7615    test{l}\t{%k1, %k0|%k0, %k1}
7616    test{q}\t{%1, %0|%0, %1}
7617    test{q}\t{%1, %0|%0, %1}
7618    test{q}\t{%1, %0|%0, %1}"
7619   [(set_attr "type" "test")
7620    (set_attr "modrm" "0,1,0,1,1")
7621    (set_attr "mode" "SI,SI,DI,DI,DI")])
7622
7623 (define_insn "*testqi_1_maybe_si"
7624   [(set (reg FLAGS_REG)
7625         (compare
7626           (and:QI
7627             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7628             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7629           (const_int 0)))]
7630    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7631     && ix86_match_ccmode (insn,
7632                          CONST_INT_P (operands[1])
7633                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7634 {
7635   if (which_alternative == 3)
7636     {
7637       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7638         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7639       return "test{l}\t{%1, %k0|%k0, %1}";
7640     }
7641   return "test{b}\t{%1, %0|%0, %1}";
7642 }
7643   [(set_attr "type" "test")
7644    (set_attr "modrm" "0,1,1,1")
7645    (set_attr "mode" "QI,QI,QI,SI")
7646    (set_attr "pent_pair" "uv,np,uv,np")])
7647
7648 (define_insn "*test<mode>_1"
7649   [(set (reg FLAGS_REG)
7650         (compare
7651          (and:SWI124
7652           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7653           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7654          (const_int 0)))]
7655   "ix86_match_ccmode (insn, CCNOmode)
7656    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7657   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7658   [(set_attr "type" "test")
7659    (set_attr "modrm" "0,1,1")
7660    (set_attr "mode" "<MODE>")
7661    (set_attr "pent_pair" "uv,np,uv")])
7662
7663 (define_expand "testqi_ext_ccno_0"
7664   [(set (reg:CCNO FLAGS_REG)
7665         (compare:CCNO
7666           (and:SI
7667             (zero_extract:SI
7668               (match_operand 0 "ext_register_operand" "")
7669               (const_int 8)
7670               (const_int 8))
7671             (match_operand 1 "const_int_operand" ""))
7672           (const_int 0)))])
7673
7674 (define_insn "*testqi_ext_0"
7675   [(set (reg FLAGS_REG)
7676         (compare
7677           (and:SI
7678             (zero_extract:SI
7679               (match_operand 0 "ext_register_operand" "Q")
7680               (const_int 8)
7681               (const_int 8))
7682             (match_operand 1 "const_int_operand" "n"))
7683           (const_int 0)))]
7684   "ix86_match_ccmode (insn, CCNOmode)"
7685   "test{b}\t{%1, %h0|%h0, %1}"
7686   [(set_attr "type" "test")
7687    (set_attr "mode" "QI")
7688    (set_attr "length_immediate" "1")
7689    (set_attr "modrm" "1")
7690    (set_attr "pent_pair" "np")])
7691
7692 (define_insn "*testqi_ext_1_rex64"
7693   [(set (reg FLAGS_REG)
7694         (compare
7695           (and:SI
7696             (zero_extract:SI
7697               (match_operand 0 "ext_register_operand" "Q")
7698               (const_int 8)
7699               (const_int 8))
7700             (zero_extend:SI
7701               (match_operand:QI 1 "register_operand" "Q")))
7702           (const_int 0)))]
7703   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7704   "test{b}\t{%1, %h0|%h0, %1}"
7705   [(set_attr "type" "test")
7706    (set_attr "mode" "QI")])
7707
7708 (define_insn "*testqi_ext_1"
7709   [(set (reg FLAGS_REG)
7710         (compare
7711           (and:SI
7712             (zero_extract:SI
7713               (match_operand 0 "ext_register_operand" "Q")
7714               (const_int 8)
7715               (const_int 8))
7716             (zero_extend:SI
7717               (match_operand:QI 1 "general_operand" "Qm")))
7718           (const_int 0)))]
7719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7720   "test{b}\t{%1, %h0|%h0, %1}"
7721   [(set_attr "type" "test")
7722    (set_attr "mode" "QI")])
7723
7724 (define_insn "*testqi_ext_2"
7725   [(set (reg FLAGS_REG)
7726         (compare
7727           (and:SI
7728             (zero_extract:SI
7729               (match_operand 0 "ext_register_operand" "Q")
7730               (const_int 8)
7731               (const_int 8))
7732             (zero_extract:SI
7733               (match_operand 1 "ext_register_operand" "Q")
7734               (const_int 8)
7735               (const_int 8)))
7736           (const_int 0)))]
7737   "ix86_match_ccmode (insn, CCNOmode)"
7738   "test{b}\t{%h1, %h0|%h0, %h1}"
7739   [(set_attr "type" "test")
7740    (set_attr "mode" "QI")])
7741
7742 (define_insn "*testqi_ext_3_rex64"
7743   [(set (reg FLAGS_REG)
7744         (compare (zero_extract:DI
7745                    (match_operand 0 "nonimmediate_operand" "rm")
7746                    (match_operand:DI 1 "const_int_operand" "")
7747                    (match_operand:DI 2 "const_int_operand" ""))
7748                  (const_int 0)))]
7749   "TARGET_64BIT
7750    && ix86_match_ccmode (insn, CCNOmode)
7751    && INTVAL (operands[1]) > 0
7752    && INTVAL (operands[2]) >= 0
7753    /* Ensure that resulting mask is zero or sign extended operand.  */
7754    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7755        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7756            && INTVAL (operands[1]) > 32))
7757    && (GET_MODE (operands[0]) == SImode
7758        || GET_MODE (operands[0]) == DImode
7759        || GET_MODE (operands[0]) == HImode
7760        || GET_MODE (operands[0]) == QImode)"
7761   "#")
7762
7763 ;; Combine likes to form bit extractions for some tests.  Humor it.
7764 (define_insn "*testqi_ext_3"
7765   [(set (reg FLAGS_REG)
7766         (compare (zero_extract:SI
7767                    (match_operand 0 "nonimmediate_operand" "rm")
7768                    (match_operand:SI 1 "const_int_operand" "")
7769                    (match_operand:SI 2 "const_int_operand" ""))
7770                  (const_int 0)))]
7771   "ix86_match_ccmode (insn, CCNOmode)
7772    && INTVAL (operands[1]) > 0
7773    && INTVAL (operands[2]) >= 0
7774    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7775    && (GET_MODE (operands[0]) == SImode
7776        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7777        || GET_MODE (operands[0]) == HImode
7778        || GET_MODE (operands[0]) == QImode)"
7779   "#")
7780
7781 (define_split
7782   [(set (match_operand 0 "flags_reg_operand" "")
7783         (match_operator 1 "compare_operator"
7784           [(zero_extract
7785              (match_operand 2 "nonimmediate_operand" "")
7786              (match_operand 3 "const_int_operand" "")
7787              (match_operand 4 "const_int_operand" ""))
7788            (const_int 0)]))]
7789   "ix86_match_ccmode (insn, CCNOmode)"
7790   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7791 {
7792   rtx val = operands[2];
7793   HOST_WIDE_INT len = INTVAL (operands[3]);
7794   HOST_WIDE_INT pos = INTVAL (operands[4]);
7795   HOST_WIDE_INT mask;
7796   enum machine_mode mode, submode;
7797
7798   mode = GET_MODE (val);
7799   if (MEM_P (val))
7800     {
7801       /* ??? Combine likes to put non-volatile mem extractions in QImode
7802          no matter the size of the test.  So find a mode that works.  */
7803       if (! MEM_VOLATILE_P (val))
7804         {
7805           mode = smallest_mode_for_size (pos + len, MODE_INT);
7806           val = adjust_address (val, mode, 0);
7807         }
7808     }
7809   else if (GET_CODE (val) == SUBREG
7810            && (submode = GET_MODE (SUBREG_REG (val)),
7811                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7812            && pos + len <= GET_MODE_BITSIZE (submode)
7813            && GET_MODE_CLASS (submode) == MODE_INT)
7814     {
7815       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7816       mode = submode;
7817       val = SUBREG_REG (val);
7818     }
7819   else if (mode == HImode && pos + len <= 8)
7820     {
7821       /* Small HImode tests can be converted to QImode.  */
7822       mode = QImode;
7823       val = gen_lowpart (QImode, val);
7824     }
7825
7826   if (len == HOST_BITS_PER_WIDE_INT)
7827     mask = -1;
7828   else
7829     mask = ((HOST_WIDE_INT)1 << len) - 1;
7830   mask <<= pos;
7831
7832   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7833 })
7834
7835 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7836 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7837 ;; this is relatively important trick.
7838 ;; Do the conversion only post-reload to avoid limiting of the register class
7839 ;; to QI regs.
7840 (define_split
7841   [(set (match_operand 0 "flags_reg_operand" "")
7842         (match_operator 1 "compare_operator"
7843           [(and (match_operand 2 "register_operand" "")
7844                 (match_operand 3 "const_int_operand" ""))
7845            (const_int 0)]))]
7846    "reload_completed
7847     && QI_REG_P (operands[2])
7848     && GET_MODE (operands[2]) != QImode
7849     && ((ix86_match_ccmode (insn, CCZmode)
7850          && !(INTVAL (operands[3]) & ~(255 << 8)))
7851         || (ix86_match_ccmode (insn, CCNOmode)
7852             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7853   [(set (match_dup 0)
7854         (match_op_dup 1
7855           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7856                    (match_dup 3))
7857            (const_int 0)]))]
7858   "operands[2] = gen_lowpart (SImode, operands[2]);
7859    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7860
7861 (define_split
7862   [(set (match_operand 0 "flags_reg_operand" "")
7863         (match_operator 1 "compare_operator"
7864           [(and (match_operand 2 "nonimmediate_operand" "")
7865                 (match_operand 3 "const_int_operand" ""))
7866            (const_int 0)]))]
7867    "reload_completed
7868     && GET_MODE (operands[2]) != QImode
7869     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7870     && ((ix86_match_ccmode (insn, CCZmode)
7871          && !(INTVAL (operands[3]) & ~255))
7872         || (ix86_match_ccmode (insn, CCNOmode)
7873             && !(INTVAL (operands[3]) & ~127)))"
7874   [(set (match_dup 0)
7875         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7876                          (const_int 0)]))]
7877   "operands[2] = gen_lowpart (QImode, operands[2]);
7878    operands[3] = gen_lowpart (QImode, operands[3]);")
7879
7880 ;; %%% This used to optimize known byte-wide and operations to memory,
7881 ;; and sometimes to QImode registers.  If this is considered useful,
7882 ;; it should be done with splitters.
7883
7884 (define_expand "and<mode>3"
7885   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7886         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7887                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7888   ""
7889   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7890
7891 (define_insn "*anddi_1"
7892   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7893         (and:DI
7894          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7895          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7896    (clobber (reg:CC FLAGS_REG))]
7897   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7898 {
7899   switch (get_attr_type (insn))
7900     {
7901     case TYPE_IMOVX:
7902       {
7903         enum machine_mode mode;
7904
7905         gcc_assert (CONST_INT_P (operands[2]));
7906         if (INTVAL (operands[2]) == 0xff)
7907           mode = QImode;
7908         else
7909           {
7910             gcc_assert (INTVAL (operands[2]) == 0xffff);
7911             mode = HImode;
7912           }
7913
7914         operands[1] = gen_lowpart (mode, operands[1]);
7915         if (mode == QImode)
7916           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7917         else
7918           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7919       }
7920
7921     default:
7922       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7923       if (get_attr_mode (insn) == MODE_SI)
7924         return "and{l}\t{%k2, %k0|%k0, %k2}";
7925       else
7926         return "and{q}\t{%2, %0|%0, %2}";
7927     }
7928 }
7929   [(set_attr "type" "alu,alu,alu,imovx")
7930    (set_attr "length_immediate" "*,*,*,0")
7931    (set (attr "prefix_rex")
7932      (if_then_else
7933        (and (eq_attr "type" "imovx")
7934             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7935                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7936        (const_string "1")
7937        (const_string "*")))
7938    (set_attr "mode" "SI,DI,DI,SI")])
7939
7940 (define_insn "*andsi_1"
7941   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7942         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7943                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7944    (clobber (reg:CC FLAGS_REG))]
7945   "ix86_binary_operator_ok (AND, SImode, operands)"
7946 {
7947   switch (get_attr_type (insn))
7948     {
7949     case TYPE_IMOVX:
7950       {
7951         enum machine_mode mode;
7952
7953         gcc_assert (CONST_INT_P (operands[2]));
7954         if (INTVAL (operands[2]) == 0xff)
7955           mode = QImode;
7956         else
7957           {
7958             gcc_assert (INTVAL (operands[2]) == 0xffff);
7959             mode = HImode;
7960           }
7961
7962         operands[1] = gen_lowpart (mode, operands[1]);
7963         if (mode == QImode)
7964           return "movz{bl|x}\t{%1, %0|%0, %1}";
7965         else
7966           return "movz{wl|x}\t{%1, %0|%0, %1}";
7967       }
7968
7969     default:
7970       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7971       return "and{l}\t{%2, %0|%0, %2}";
7972     }
7973 }
7974   [(set_attr "type" "alu,alu,imovx")
7975    (set (attr "prefix_rex")
7976      (if_then_else
7977        (and (eq_attr "type" "imovx")
7978             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7979                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7980        (const_string "1")
7981        (const_string "*")))
7982    (set_attr "length_immediate" "*,*,0")
7983    (set_attr "mode" "SI")])
7984
7985 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7986 (define_insn "*andsi_1_zext"
7987   [(set (match_operand:DI 0 "register_operand" "=r")
7988         (zero_extend:DI
7989           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7990                   (match_operand:SI 2 "general_operand" "g"))))
7991    (clobber (reg:CC FLAGS_REG))]
7992   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7993   "and{l}\t{%2, %k0|%k0, %2}"
7994   [(set_attr "type" "alu")
7995    (set_attr "mode" "SI")])
7996
7997 (define_insn "*andhi_1"
7998   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7999         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8000                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8001    (clobber (reg:CC FLAGS_REG))]
8002   "ix86_binary_operator_ok (AND, HImode, operands)"
8003 {
8004   switch (get_attr_type (insn))
8005     {
8006     case TYPE_IMOVX:
8007       gcc_assert (CONST_INT_P (operands[2]));
8008       gcc_assert (INTVAL (operands[2]) == 0xff);
8009       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8010
8011     default:
8012       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8013
8014       return "and{w}\t{%2, %0|%0, %2}";
8015     }
8016 }
8017   [(set_attr "type" "alu,alu,imovx")
8018    (set_attr "length_immediate" "*,*,0")
8019    (set (attr "prefix_rex")
8020      (if_then_else
8021        (and (eq_attr "type" "imovx")
8022             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8023        (const_string "1")
8024        (const_string "*")))
8025    (set_attr "mode" "HI,HI,SI")])
8026
8027 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8028 (define_insn "*andqi_1"
8029   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8030         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8031                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8032    (clobber (reg:CC FLAGS_REG))]
8033   "ix86_binary_operator_ok (AND, QImode, operands)"
8034   "@
8035    and{b}\t{%2, %0|%0, %2}
8036    and{b}\t{%2, %0|%0, %2}
8037    and{l}\t{%k2, %k0|%k0, %k2}"
8038   [(set_attr "type" "alu")
8039    (set_attr "mode" "QI,QI,SI")])
8040
8041 (define_insn "*andqi_1_slp"
8042   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8043         (and:QI (match_dup 0)
8044                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8045    (clobber (reg:CC FLAGS_REG))]
8046   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8047    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8048   "and{b}\t{%1, %0|%0, %1}"
8049   [(set_attr "type" "alu1")
8050    (set_attr "mode" "QI")])
8051
8052 (define_split
8053   [(set (match_operand 0 "register_operand" "")
8054         (and (match_dup 0)
8055              (const_int -65536)))
8056    (clobber (reg:CC FLAGS_REG))]
8057   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8058     || optimize_function_for_size_p (cfun)"
8059   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8060   "operands[1] = gen_lowpart (HImode, operands[0]);")
8061
8062 (define_split
8063   [(set (match_operand 0 "ext_register_operand" "")
8064         (and (match_dup 0)
8065              (const_int -256)))
8066    (clobber (reg:CC FLAGS_REG))]
8067   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8068    && reload_completed"
8069   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8070   "operands[1] = gen_lowpart (QImode, operands[0]);")
8071
8072 (define_split
8073   [(set (match_operand 0 "ext_register_operand" "")
8074         (and (match_dup 0)
8075              (const_int -65281)))
8076    (clobber (reg:CC FLAGS_REG))]
8077   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078    && reload_completed"
8079   [(parallel [(set (zero_extract:SI (match_dup 0)
8080                                     (const_int 8)
8081                                     (const_int 8))
8082                    (xor:SI
8083                      (zero_extract:SI (match_dup 0)
8084                                       (const_int 8)
8085                                       (const_int 8))
8086                      (zero_extract:SI (match_dup 0)
8087                                       (const_int 8)
8088                                       (const_int 8))))
8089               (clobber (reg:CC FLAGS_REG))])]
8090   "operands[0] = gen_lowpart (SImode, operands[0]);")
8091
8092 (define_insn "*anddi_2"
8093   [(set (reg FLAGS_REG)
8094         (compare
8095          (and:DI
8096           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8097           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8098          (const_int 0)))
8099    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8100         (and:DI (match_dup 1) (match_dup 2)))]
8101   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8102    && ix86_binary_operator_ok (AND, DImode, operands)"
8103   "@
8104    and{l}\t{%k2, %k0|%k0, %k2}
8105    and{q}\t{%2, %0|%0, %2}
8106    and{q}\t{%2, %0|%0, %2}"
8107   [(set_attr "type" "alu")
8108    (set_attr "mode" "SI,DI,DI")])
8109
8110 (define_insn "*andqi_2_maybe_si"
8111   [(set (reg FLAGS_REG)
8112         (compare (and:QI
8113                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8114                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8115                  (const_int 0)))
8116    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8117         (and:QI (match_dup 1) (match_dup 2)))]
8118   "ix86_binary_operator_ok (AND, QImode, operands)
8119    && ix86_match_ccmode (insn,
8120                          CONST_INT_P (operands[2])
8121                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8122 {
8123   if (which_alternative == 2)
8124     {
8125       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8126         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8127       return "and{l}\t{%2, %k0|%k0, %2}";
8128     }
8129   return "and{b}\t{%2, %0|%0, %2}";
8130 }
8131   [(set_attr "type" "alu")
8132    (set_attr "mode" "QI,QI,SI")])
8133
8134 (define_insn "*and<mode>_2"
8135   [(set (reg FLAGS_REG)
8136         (compare (and:SWI124
8137                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8138                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8139                  (const_int 0)))
8140    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8141         (and:SWI124 (match_dup 1) (match_dup 2)))]
8142   "ix86_match_ccmode (insn, CCNOmode)
8143    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8144   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8145   [(set_attr "type" "alu")
8146    (set_attr "mode" "<MODE>")])
8147
8148 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8149 (define_insn "*andsi_2_zext"
8150   [(set (reg FLAGS_REG)
8151         (compare (and:SI
8152                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8153                   (match_operand:SI 2 "general_operand" "g"))
8154                  (const_int 0)))
8155    (set (match_operand:DI 0 "register_operand" "=r")
8156         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8157   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8158    && ix86_binary_operator_ok (AND, SImode, operands)"
8159   "and{l}\t{%2, %k0|%k0, %2}"
8160   [(set_attr "type" "alu")
8161    (set_attr "mode" "SI")])
8162
8163 (define_insn "*andqi_2_slp"
8164   [(set (reg FLAGS_REG)
8165         (compare (and:QI
8166                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8167                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8168                  (const_int 0)))
8169    (set (strict_low_part (match_dup 0))
8170         (and:QI (match_dup 0) (match_dup 1)))]
8171   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8172    && ix86_match_ccmode (insn, CCNOmode)
8173    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8174   "and{b}\t{%1, %0|%0, %1}"
8175   [(set_attr "type" "alu1")
8176    (set_attr "mode" "QI")])
8177
8178 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8179 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8180 ;; for a QImode operand, which of course failed.
8181 (define_insn "andqi_ext_0"
8182   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8183                          (const_int 8)
8184                          (const_int 8))
8185         (and:SI
8186           (zero_extract:SI
8187             (match_operand 1 "ext_register_operand" "0")
8188             (const_int 8)
8189             (const_int 8))
8190           (match_operand 2 "const_int_operand" "n")))
8191    (clobber (reg:CC FLAGS_REG))]
8192   ""
8193   "and{b}\t{%2, %h0|%h0, %2}"
8194   [(set_attr "type" "alu")
8195    (set_attr "length_immediate" "1")
8196    (set_attr "modrm" "1")
8197    (set_attr "mode" "QI")])
8198
8199 ;; Generated by peephole translating test to and.  This shows up
8200 ;; often in fp comparisons.
8201 (define_insn "*andqi_ext_0_cc"
8202   [(set (reg FLAGS_REG)
8203         (compare
8204           (and:SI
8205             (zero_extract:SI
8206               (match_operand 1 "ext_register_operand" "0")
8207               (const_int 8)
8208               (const_int 8))
8209             (match_operand 2 "const_int_operand" "n"))
8210           (const_int 0)))
8211    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8212                          (const_int 8)
8213                          (const_int 8))
8214         (and:SI
8215           (zero_extract:SI
8216             (match_dup 1)
8217             (const_int 8)
8218             (const_int 8))
8219           (match_dup 2)))]
8220   "ix86_match_ccmode (insn, CCNOmode)"
8221   "and{b}\t{%2, %h0|%h0, %2}"
8222   [(set_attr "type" "alu")
8223    (set_attr "length_immediate" "1")
8224    (set_attr "modrm" "1")
8225    (set_attr "mode" "QI")])
8226
8227 (define_insn "*andqi_ext_1_rex64"
8228   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8229                          (const_int 8)
8230                          (const_int 8))
8231         (and:SI
8232           (zero_extract:SI
8233             (match_operand 1 "ext_register_operand" "0")
8234             (const_int 8)
8235             (const_int 8))
8236           (zero_extend:SI
8237             (match_operand 2 "ext_register_operand" "Q"))))
8238    (clobber (reg:CC FLAGS_REG))]
8239   "TARGET_64BIT"
8240   "and{b}\t{%2, %h0|%h0, %2}"
8241   [(set_attr "type" "alu")
8242    (set_attr "length_immediate" "0")
8243    (set_attr "mode" "QI")])
8244
8245 (define_insn "*andqi_ext_1"
8246   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8247                          (const_int 8)
8248                          (const_int 8))
8249         (and:SI
8250           (zero_extract:SI
8251             (match_operand 1 "ext_register_operand" "0")
8252             (const_int 8)
8253             (const_int 8))
8254           (zero_extend:SI
8255             (match_operand:QI 2 "general_operand" "Qm"))))
8256    (clobber (reg:CC FLAGS_REG))]
8257   "!TARGET_64BIT"
8258   "and{b}\t{%2, %h0|%h0, %2}"
8259   [(set_attr "type" "alu")
8260    (set_attr "length_immediate" "0")
8261    (set_attr "mode" "QI")])
8262
8263 (define_insn "*andqi_ext_2"
8264   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8265                          (const_int 8)
8266                          (const_int 8))
8267         (and:SI
8268           (zero_extract:SI
8269             (match_operand 1 "ext_register_operand" "%0")
8270             (const_int 8)
8271             (const_int 8))
8272           (zero_extract:SI
8273             (match_operand 2 "ext_register_operand" "Q")
8274             (const_int 8)
8275             (const_int 8))))
8276    (clobber (reg:CC FLAGS_REG))]
8277   ""
8278   "and{b}\t{%h2, %h0|%h0, %h2}"
8279   [(set_attr "type" "alu")
8280    (set_attr "length_immediate" "0")
8281    (set_attr "mode" "QI")])
8282
8283 ;; Convert wide AND instructions with immediate operand to shorter QImode
8284 ;; equivalents when possible.
8285 ;; Don't do the splitting with memory operands, since it introduces risk
8286 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8287 ;; for size, but that can (should?) be handled by generic code instead.
8288 (define_split
8289   [(set (match_operand 0 "register_operand" "")
8290         (and (match_operand 1 "register_operand" "")
8291              (match_operand 2 "const_int_operand" "")))
8292    (clobber (reg:CC FLAGS_REG))]
8293    "reload_completed
8294     && QI_REG_P (operands[0])
8295     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8296     && !(~INTVAL (operands[2]) & ~(255 << 8))
8297     && GET_MODE (operands[0]) != QImode"
8298   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8299                    (and:SI (zero_extract:SI (match_dup 1)
8300                                             (const_int 8) (const_int 8))
8301                            (match_dup 2)))
8302               (clobber (reg:CC FLAGS_REG))])]
8303   "operands[0] = gen_lowpart (SImode, operands[0]);
8304    operands[1] = gen_lowpart (SImode, operands[1]);
8305    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8306
8307 ;; Since AND can be encoded with sign extended immediate, this is only
8308 ;; profitable when 7th bit is not set.
8309 (define_split
8310   [(set (match_operand 0 "register_operand" "")
8311         (and (match_operand 1 "general_operand" "")
8312              (match_operand 2 "const_int_operand" "")))
8313    (clobber (reg:CC FLAGS_REG))]
8314    "reload_completed
8315     && ANY_QI_REG_P (operands[0])
8316     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8317     && !(~INTVAL (operands[2]) & ~255)
8318     && !(INTVAL (operands[2]) & 128)
8319     && GET_MODE (operands[0]) != QImode"
8320   [(parallel [(set (strict_low_part (match_dup 0))
8321                    (and:QI (match_dup 1)
8322                            (match_dup 2)))
8323               (clobber (reg:CC FLAGS_REG))])]
8324   "operands[0] = gen_lowpart (QImode, operands[0]);
8325    operands[1] = gen_lowpart (QImode, operands[1]);
8326    operands[2] = gen_lowpart (QImode, operands[2]);")
8327 \f
8328 ;; Logical inclusive and exclusive OR instructions
8329
8330 ;; %%% This used to optimize known byte-wide and operations to memory.
8331 ;; If this is considered useful, it should be done with splitters.
8332
8333 (define_expand "<code><mode>3"
8334   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8335         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8336                      (match_operand:SWIM 2 "<general_operand>" "")))]
8337   ""
8338   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8339
8340 (define_insn "*<code><mode>_1"
8341   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8342         (any_or:SWI248
8343          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8344          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8347   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8348   [(set_attr "type" "alu")
8349    (set_attr "mode" "<MODE>")])
8350
8351 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8352 (define_insn "*<code>qi_1"
8353   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8354         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8355                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8358   "@
8359    <logic>{b}\t{%2, %0|%0, %2}
8360    <logic>{b}\t{%2, %0|%0, %2}
8361    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8362   [(set_attr "type" "alu")
8363    (set_attr "mode" "QI,QI,SI")])
8364
8365 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8366 (define_insn "*<code>si_1_zext"
8367   [(set (match_operand:DI 0 "register_operand" "=r")
8368         (zero_extend:DI
8369          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8370                     (match_operand:SI 2 "general_operand" "g"))))
8371    (clobber (reg:CC FLAGS_REG))]
8372   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8373   "<logic>{l}\t{%2, %k0|%k0, %2}"
8374   [(set_attr "type" "alu")
8375    (set_attr "mode" "SI")])
8376
8377 (define_insn "*<code>si_1_zext_imm"
8378   [(set (match_operand:DI 0 "register_operand" "=r")
8379         (any_or:DI
8380          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8381          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8382    (clobber (reg:CC FLAGS_REG))]
8383   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8384   "<logic>{l}\t{%2, %k0|%k0, %2}"
8385   [(set_attr "type" "alu")
8386    (set_attr "mode" "SI")])
8387
8388 (define_insn "*<code>qi_1_slp"
8389   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8390         (any_or:QI (match_dup 0)
8391                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8392    (clobber (reg:CC FLAGS_REG))]
8393   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8394    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8395   "<logic>{b}\t{%1, %0|%0, %1}"
8396   [(set_attr "type" "alu1")
8397    (set_attr "mode" "QI")])
8398
8399 (define_insn "*<code><mode>_2"
8400   [(set (reg FLAGS_REG)
8401         (compare (any_or:SWI
8402                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8403                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8404                  (const_int 0)))
8405    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8406         (any_or:SWI (match_dup 1) (match_dup 2)))]
8407   "ix86_match_ccmode (insn, CCNOmode)
8408    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8409   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8410   [(set_attr "type" "alu")
8411    (set_attr "mode" "<MODE>")])
8412
8413 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8414 ;; ??? Special case for immediate operand is missing - it is tricky.
8415 (define_insn "*<code>si_2_zext"
8416   [(set (reg FLAGS_REG)
8417         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8418                             (match_operand:SI 2 "general_operand" "g"))
8419                  (const_int 0)))
8420    (set (match_operand:DI 0 "register_operand" "=r")
8421         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8422   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8423    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8424   "<logic>{l}\t{%2, %k0|%k0, %2}"
8425   [(set_attr "type" "alu")
8426    (set_attr "mode" "SI")])
8427
8428 (define_insn "*<code>si_2_zext_imm"
8429   [(set (reg FLAGS_REG)
8430         (compare (any_or:SI
8431                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8432                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8433                  (const_int 0)))
8434    (set (match_operand:DI 0 "register_operand" "=r")
8435         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8436   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8437    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8438   "<logic>{l}\t{%2, %k0|%k0, %2}"
8439   [(set_attr "type" "alu")
8440    (set_attr "mode" "SI")])
8441
8442 (define_insn "*<code>qi_2_slp"
8443   [(set (reg FLAGS_REG)
8444         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8445                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8446                  (const_int 0)))
8447    (set (strict_low_part (match_dup 0))
8448         (any_or:QI (match_dup 0) (match_dup 1)))]
8449   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8450    && ix86_match_ccmode (insn, CCNOmode)
8451    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8452   "<logic>{b}\t{%1, %0|%0, %1}"
8453   [(set_attr "type" "alu1")
8454    (set_attr "mode" "QI")])
8455
8456 (define_insn "*<code><mode>_3"
8457   [(set (reg FLAGS_REG)
8458         (compare (any_or:SWI
8459                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8460                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8461                  (const_int 0)))
8462    (clobber (match_scratch:SWI 0 "=<r>"))]
8463   "ix86_match_ccmode (insn, CCNOmode)
8464    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8465   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8466   [(set_attr "type" "alu")
8467    (set_attr "mode" "<MODE>")])
8468
8469 (define_insn "*<code>qi_ext_0"
8470   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8471                          (const_int 8)
8472                          (const_int 8))
8473         (any_or:SI
8474           (zero_extract:SI
8475             (match_operand 1 "ext_register_operand" "0")
8476             (const_int 8)
8477             (const_int 8))
8478           (match_operand 2 "const_int_operand" "n")))
8479    (clobber (reg:CC FLAGS_REG))]
8480   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8481   "<logic>{b}\t{%2, %h0|%h0, %2}"
8482   [(set_attr "type" "alu")
8483    (set_attr "length_immediate" "1")
8484    (set_attr "modrm" "1")
8485    (set_attr "mode" "QI")])
8486
8487 (define_insn "*<code>qi_ext_1_rex64"
8488   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8489                          (const_int 8)
8490                          (const_int 8))
8491         (any_or:SI
8492           (zero_extract:SI
8493             (match_operand 1 "ext_register_operand" "0")
8494             (const_int 8)
8495             (const_int 8))
8496           (zero_extend:SI
8497             (match_operand 2 "ext_register_operand" "Q"))))
8498    (clobber (reg:CC FLAGS_REG))]
8499   "TARGET_64BIT
8500    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8501   "<logic>{b}\t{%2, %h0|%h0, %2}"
8502   [(set_attr "type" "alu")
8503    (set_attr "length_immediate" "0")
8504    (set_attr "mode" "QI")])
8505
8506 (define_insn "*<code>qi_ext_1"
8507   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8508                          (const_int 8)
8509                          (const_int 8))
8510         (any_or:SI
8511           (zero_extract:SI
8512             (match_operand 1 "ext_register_operand" "0")
8513             (const_int 8)
8514             (const_int 8))
8515           (zero_extend:SI
8516             (match_operand:QI 2 "general_operand" "Qm"))))
8517    (clobber (reg:CC FLAGS_REG))]
8518   "!TARGET_64BIT
8519    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8520   "<logic>{b}\t{%2, %h0|%h0, %2}"
8521   [(set_attr "type" "alu")
8522    (set_attr "length_immediate" "0")
8523    (set_attr "mode" "QI")])
8524
8525 (define_insn "*<code>qi_ext_2"
8526   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8527                          (const_int 8)
8528                          (const_int 8))
8529         (any_or:SI
8530           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8531                            (const_int 8)
8532                            (const_int 8))
8533           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8534                            (const_int 8)
8535                            (const_int 8))))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8538   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "length_immediate" "0")
8541    (set_attr "mode" "QI")])
8542
8543 (define_split
8544   [(set (match_operand 0 "register_operand" "")
8545         (any_or (match_operand 1 "register_operand" "")
8546                 (match_operand 2 "const_int_operand" "")))
8547    (clobber (reg:CC FLAGS_REG))]
8548    "reload_completed
8549     && QI_REG_P (operands[0])
8550     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8551     && !(INTVAL (operands[2]) & ~(255 << 8))
8552     && GET_MODE (operands[0]) != QImode"
8553   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8554                    (any_or:SI (zero_extract:SI (match_dup 1)
8555                                                (const_int 8) (const_int 8))
8556                               (match_dup 2)))
8557               (clobber (reg:CC FLAGS_REG))])]
8558   "operands[0] = gen_lowpart (SImode, operands[0]);
8559    operands[1] = gen_lowpart (SImode, operands[1]);
8560    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8561
8562 ;; Since OR can be encoded with sign extended immediate, this is only
8563 ;; profitable when 7th bit is set.
8564 (define_split
8565   [(set (match_operand 0 "register_operand" "")
8566         (any_or (match_operand 1 "general_operand" "")
8567                 (match_operand 2 "const_int_operand" "")))
8568    (clobber (reg:CC FLAGS_REG))]
8569    "reload_completed
8570     && ANY_QI_REG_P (operands[0])
8571     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8572     && !(INTVAL (operands[2]) & ~255)
8573     && (INTVAL (operands[2]) & 128)
8574     && GET_MODE (operands[0]) != QImode"
8575   [(parallel [(set (strict_low_part (match_dup 0))
8576                    (any_or:QI (match_dup 1)
8577                               (match_dup 2)))
8578               (clobber (reg:CC FLAGS_REG))])]
8579   "operands[0] = gen_lowpart (QImode, operands[0]);
8580    operands[1] = gen_lowpart (QImode, operands[1]);
8581    operands[2] = gen_lowpart (QImode, operands[2]);")
8582
8583 (define_expand "xorqi_cc_ext_1"
8584   [(parallel [
8585      (set (reg:CCNO FLAGS_REG)
8586           (compare:CCNO
8587             (xor:SI
8588               (zero_extract:SI
8589                 (match_operand 1 "ext_register_operand" "")
8590                 (const_int 8)
8591                 (const_int 8))
8592               (match_operand:QI 2 "general_operand" ""))
8593             (const_int 0)))
8594      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8595                            (const_int 8)
8596                            (const_int 8))
8597           (xor:SI
8598             (zero_extract:SI
8599              (match_dup 1)
8600              (const_int 8)
8601              (const_int 8))
8602             (match_dup 2)))])])
8603
8604 (define_insn "*xorqi_cc_ext_1_rex64"
8605   [(set (reg FLAGS_REG)
8606         (compare
8607           (xor:SI
8608             (zero_extract:SI
8609               (match_operand 1 "ext_register_operand" "0")
8610               (const_int 8)
8611               (const_int 8))
8612             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8613           (const_int 0)))
8614    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8615                          (const_int 8)
8616                          (const_int 8))
8617         (xor:SI
8618           (zero_extract:SI
8619            (match_dup 1)
8620            (const_int 8)
8621            (const_int 8))
8622           (match_dup 2)))]
8623   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8624   "xor{b}\t{%2, %h0|%h0, %2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "modrm" "1")
8627    (set_attr "mode" "QI")])
8628
8629 (define_insn "*xorqi_cc_ext_1"
8630   [(set (reg FLAGS_REG)
8631         (compare
8632           (xor:SI
8633             (zero_extract:SI
8634               (match_operand 1 "ext_register_operand" "0")
8635               (const_int 8)
8636               (const_int 8))
8637             (match_operand:QI 2 "general_operand" "qmn"))
8638           (const_int 0)))
8639    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8640                          (const_int 8)
8641                          (const_int 8))
8642         (xor:SI
8643           (zero_extract:SI
8644            (match_dup 1)
8645            (const_int 8)
8646            (const_int 8))
8647           (match_dup 2)))]
8648   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8649   "xor{b}\t{%2, %h0|%h0, %2}"
8650   [(set_attr "type" "alu")
8651    (set_attr "modrm" "1")
8652    (set_attr "mode" "QI")])
8653 \f
8654 ;; Negation instructions
8655
8656 (define_expand "neg<mode>2"
8657   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8658         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8659   ""
8660   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8661
8662 (define_insn_and_split "*neg<dwi>2_doubleword"
8663   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8664         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8665    (clobber (reg:CC FLAGS_REG))]
8666   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8667   "#"
8668   "reload_completed"
8669   [(parallel
8670     [(set (reg:CCZ FLAGS_REG)
8671           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8672      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8673    (parallel
8674     [(set (match_dup 2)
8675           (plus:DWIH (match_dup 3)
8676                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8677                                 (const_int 0))))
8678      (clobber (reg:CC FLAGS_REG))])
8679    (parallel
8680     [(set (match_dup 2)
8681           (neg:DWIH (match_dup 2)))
8682      (clobber (reg:CC FLAGS_REG))])]
8683   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8684
8685 (define_insn "*neg<mode>2_1"
8686   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8687         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8688    (clobber (reg:CC FLAGS_REG))]
8689   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8690   "neg{<imodesuffix>}\t%0"
8691   [(set_attr "type" "negnot")
8692    (set_attr "mode" "<MODE>")])
8693
8694 ;; Combine is quite creative about this pattern.
8695 (define_insn "*negsi2_1_zext"
8696   [(set (match_operand:DI 0 "register_operand" "=r")
8697         (lshiftrt:DI
8698           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8699                              (const_int 32)))
8700         (const_int 32)))
8701    (clobber (reg:CC FLAGS_REG))]
8702   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8703   "neg{l}\t%k0"
8704   [(set_attr "type" "negnot")
8705    (set_attr "mode" "SI")])
8706
8707 ;; The problem with neg is that it does not perform (compare x 0),
8708 ;; it really performs (compare 0 x), which leaves us with the zero
8709 ;; flag being the only useful item.
8710
8711 (define_insn "*neg<mode>2_cmpz"
8712   [(set (reg:CCZ FLAGS_REG)
8713         (compare:CCZ
8714           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8715                    (const_int 0)))
8716    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8717         (neg:SWI (match_dup 1)))]
8718   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8719   "neg{<imodesuffix>}\t%0"
8720   [(set_attr "type" "negnot")
8721    (set_attr "mode" "<MODE>")])
8722
8723 (define_insn "*negsi2_cmpz_zext"
8724   [(set (reg:CCZ FLAGS_REG)
8725         (compare:CCZ
8726           (lshiftrt:DI
8727             (neg:DI (ashift:DI
8728                       (match_operand:DI 1 "register_operand" "0")
8729                       (const_int 32)))
8730             (const_int 32))
8731           (const_int 0)))
8732    (set (match_operand:DI 0 "register_operand" "=r")
8733         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8734                                         (const_int 32)))
8735                      (const_int 32)))]
8736   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8737   "neg{l}\t%k0"
8738   [(set_attr "type" "negnot")
8739    (set_attr "mode" "SI")])
8740
8741 ;; Changing of sign for FP values is doable using integer unit too.
8742
8743 (define_expand "<code><mode>2"
8744   [(set (match_operand:X87MODEF 0 "register_operand" "")
8745         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8746   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8747   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8748
8749 (define_insn "*absneg<mode>2_mixed"
8750   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8751         (match_operator:MODEF 3 "absneg_operator"
8752           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8753    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8754    (clobber (reg:CC FLAGS_REG))]
8755   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8756   "#")
8757
8758 (define_insn "*absneg<mode>2_sse"
8759   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8760         (match_operator:MODEF 3 "absneg_operator"
8761           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8762    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8763    (clobber (reg:CC FLAGS_REG))]
8764   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8765   "#")
8766
8767 (define_insn "*absneg<mode>2_i387"
8768   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8769         (match_operator:X87MODEF 3 "absneg_operator"
8770           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8771    (use (match_operand 2 "" ""))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8774   "#")
8775
8776 (define_expand "<code>tf2"
8777   [(set (match_operand:TF 0 "register_operand" "")
8778         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8779   "TARGET_SSE2"
8780   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8781
8782 (define_insn "*absnegtf2_sse"
8783   [(set (match_operand:TF 0 "register_operand" "=x,x")
8784         (match_operator:TF 3 "absneg_operator"
8785           [(match_operand:TF 1 "register_operand" "0,x")]))
8786    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8787    (clobber (reg:CC FLAGS_REG))]
8788   "TARGET_SSE2"
8789   "#")
8790
8791 ;; Splitters for fp abs and neg.
8792
8793 (define_split
8794   [(set (match_operand 0 "fp_register_operand" "")
8795         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8796    (use (match_operand 2 "" ""))
8797    (clobber (reg:CC FLAGS_REG))]
8798   "reload_completed"
8799   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8800
8801 (define_split
8802   [(set (match_operand 0 "register_operand" "")
8803         (match_operator 3 "absneg_operator"
8804           [(match_operand 1 "register_operand" "")]))
8805    (use (match_operand 2 "nonimmediate_operand" ""))
8806    (clobber (reg:CC FLAGS_REG))]
8807   "reload_completed && SSE_REG_P (operands[0])"
8808   [(set (match_dup 0) (match_dup 3))]
8809 {
8810   enum machine_mode mode = GET_MODE (operands[0]);
8811   enum machine_mode vmode = GET_MODE (operands[2]);
8812   rtx tmp;
8813
8814   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8815   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8816   if (operands_match_p (operands[0], operands[2]))
8817     {
8818       tmp = operands[1];
8819       operands[1] = operands[2];
8820       operands[2] = tmp;
8821     }
8822   if (GET_CODE (operands[3]) == ABS)
8823     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8824   else
8825     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8826   operands[3] = tmp;
8827 })
8828
8829 (define_split
8830   [(set (match_operand:SF 0 "register_operand" "")
8831         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8832    (use (match_operand:V4SF 2 "" ""))
8833    (clobber (reg:CC FLAGS_REG))]
8834   "reload_completed"
8835   [(parallel [(set (match_dup 0) (match_dup 1))
8836               (clobber (reg:CC FLAGS_REG))])]
8837 {
8838   rtx tmp;
8839   operands[0] = gen_lowpart (SImode, operands[0]);
8840   if (GET_CODE (operands[1]) == ABS)
8841     {
8842       tmp = gen_int_mode (0x7fffffff, SImode);
8843       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8844     }
8845   else
8846     {
8847       tmp = gen_int_mode (0x80000000, SImode);
8848       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8849     }
8850   operands[1] = tmp;
8851 })
8852
8853 (define_split
8854   [(set (match_operand:DF 0 "register_operand" "")
8855         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8856    (use (match_operand 2 "" ""))
8857    (clobber (reg:CC FLAGS_REG))]
8858   "reload_completed"
8859   [(parallel [(set (match_dup 0) (match_dup 1))
8860               (clobber (reg:CC FLAGS_REG))])]
8861 {
8862   rtx tmp;
8863   if (TARGET_64BIT)
8864     {
8865       tmp = gen_lowpart (DImode, operands[0]);
8866       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8867       operands[0] = tmp;
8868
8869       if (GET_CODE (operands[1]) == ABS)
8870         tmp = const0_rtx;
8871       else
8872         tmp = gen_rtx_NOT (DImode, tmp);
8873     }
8874   else
8875     {
8876       operands[0] = gen_highpart (SImode, operands[0]);
8877       if (GET_CODE (operands[1]) == ABS)
8878         {
8879           tmp = gen_int_mode (0x7fffffff, SImode);
8880           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8881         }
8882       else
8883         {
8884           tmp = gen_int_mode (0x80000000, SImode);
8885           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8886         }
8887     }
8888   operands[1] = tmp;
8889 })
8890
8891 (define_split
8892   [(set (match_operand:XF 0 "register_operand" "")
8893         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8894    (use (match_operand 2 "" ""))
8895    (clobber (reg:CC FLAGS_REG))]
8896   "reload_completed"
8897   [(parallel [(set (match_dup 0) (match_dup 1))
8898               (clobber (reg:CC FLAGS_REG))])]
8899 {
8900   rtx tmp;
8901   operands[0] = gen_rtx_REG (SImode,
8902                              true_regnum (operands[0])
8903                              + (TARGET_64BIT ? 1 : 2));
8904   if (GET_CODE (operands[1]) == ABS)
8905     {
8906       tmp = GEN_INT (0x7fff);
8907       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8908     }
8909   else
8910     {
8911       tmp = GEN_INT (0x8000);
8912       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8913     }
8914   operands[1] = tmp;
8915 })
8916
8917 ;; Conditionalize these after reload. If they match before reload, we
8918 ;; lose the clobber and ability to use integer instructions.
8919
8920 (define_insn "*<code><mode>2_1"
8921   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8922         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8923   "TARGET_80387
8924    && (reload_completed
8925        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8926   "f<absneg_mnemonic>"
8927   [(set_attr "type" "fsgn")
8928    (set_attr "mode" "<MODE>")])
8929
8930 (define_insn "*<code>extendsfdf2"
8931   [(set (match_operand:DF 0 "register_operand" "=f")
8932         (absneg:DF (float_extend:DF
8933                      (match_operand:SF 1 "register_operand" "0"))))]
8934   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8935   "f<absneg_mnemonic>"
8936   [(set_attr "type" "fsgn")
8937    (set_attr "mode" "DF")])
8938
8939 (define_insn "*<code>extendsfxf2"
8940   [(set (match_operand:XF 0 "register_operand" "=f")
8941         (absneg:XF (float_extend:XF
8942                      (match_operand:SF 1 "register_operand" "0"))))]
8943   "TARGET_80387"
8944   "f<absneg_mnemonic>"
8945   [(set_attr "type" "fsgn")
8946    (set_attr "mode" "XF")])
8947
8948 (define_insn "*<code>extenddfxf2"
8949   [(set (match_operand:XF 0 "register_operand" "=f")
8950         (absneg:XF (float_extend:XF
8951                      (match_operand:DF 1 "register_operand" "0"))))]
8952   "TARGET_80387"
8953   "f<absneg_mnemonic>"
8954   [(set_attr "type" "fsgn")
8955    (set_attr "mode" "XF")])
8956
8957 ;; Copysign instructions
8958
8959 (define_mode_iterator CSGNMODE [SF DF TF])
8960 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8961
8962 (define_expand "copysign<mode>3"
8963   [(match_operand:CSGNMODE 0 "register_operand" "")
8964    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8965    (match_operand:CSGNMODE 2 "register_operand" "")]
8966   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8967    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8968   "ix86_expand_copysign (operands); DONE;")
8969
8970 (define_insn_and_split "copysign<mode>3_const"
8971   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8972         (unspec:CSGNMODE
8973           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8974            (match_operand:CSGNMODE 2 "register_operand" "0")
8975            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8976           UNSPEC_COPYSIGN))]
8977   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8978    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8979   "#"
8980   "&& reload_completed"
8981   [(const_int 0)]
8982   "ix86_split_copysign_const (operands); DONE;")
8983
8984 (define_insn "copysign<mode>3_var"
8985   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8986         (unspec:CSGNMODE
8987           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8988            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8989            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8990            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8991           UNSPEC_COPYSIGN))
8992    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8993   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8994    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8995   "#")
8996
8997 (define_split
8998   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8999         (unspec:CSGNMODE
9000           [(match_operand:CSGNMODE 2 "register_operand" "")
9001            (match_operand:CSGNMODE 3 "register_operand" "")
9002            (match_operand:<CSGNVMODE> 4 "" "")
9003            (match_operand:<CSGNVMODE> 5 "" "")]
9004           UNSPEC_COPYSIGN))
9005    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9006   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9007     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9008    && reload_completed"
9009   [(const_int 0)]
9010   "ix86_split_copysign_var (operands); DONE;")
9011 \f
9012 ;; One complement instructions
9013
9014 (define_expand "one_cmpl<mode>2"
9015   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9016         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9017   ""
9018   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9019
9020 (define_insn "*one_cmpl<mode>2_1"
9021   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9022         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9023   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9024   "not{<imodesuffix>}\t%0"
9025   [(set_attr "type" "negnot")
9026    (set_attr "mode" "<MODE>")])
9027
9028 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9029 (define_insn "*one_cmplqi2_1"
9030   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9031         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9032   "ix86_unary_operator_ok (NOT, QImode, operands)"
9033   "@
9034    not{b}\t%0
9035    not{l}\t%k0"
9036   [(set_attr "type" "negnot")
9037    (set_attr "mode" "QI,SI")])
9038
9039 ;; ??? Currently never generated - xor is used instead.
9040 (define_insn "*one_cmplsi2_1_zext"
9041   [(set (match_operand:DI 0 "register_operand" "=r")
9042         (zero_extend:DI
9043           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9044   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9045   "not{l}\t%k0"
9046   [(set_attr "type" "negnot")
9047    (set_attr "mode" "SI")])
9048
9049 (define_insn "*one_cmpl<mode>2_2"
9050   [(set (reg FLAGS_REG)
9051         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9052                  (const_int 0)))
9053    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9054         (not:SWI (match_dup 1)))]
9055   "ix86_match_ccmode (insn, CCNOmode)
9056    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9057   "#"
9058   [(set_attr "type" "alu1")
9059    (set_attr "mode" "<MODE>")])
9060
9061 (define_split
9062   [(set (match_operand 0 "flags_reg_operand" "")
9063         (match_operator 2 "compare_operator"
9064           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9065            (const_int 0)]))
9066    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9067         (not:SWI (match_dup 3)))]
9068   "ix86_match_ccmode (insn, CCNOmode)"
9069   [(parallel [(set (match_dup 0)
9070                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9071                                     (const_int 0)]))
9072               (set (match_dup 1)
9073                    (xor:SWI (match_dup 3) (const_int -1)))])])
9074
9075 ;; ??? Currently never generated - xor is used instead.
9076 (define_insn "*one_cmplsi2_2_zext"
9077   [(set (reg FLAGS_REG)
9078         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9079                  (const_int 0)))
9080    (set (match_operand:DI 0 "register_operand" "=r")
9081         (zero_extend:DI (not:SI (match_dup 1))))]
9082   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9083    && ix86_unary_operator_ok (NOT, SImode, operands)"
9084   "#"
9085   [(set_attr "type" "alu1")
9086    (set_attr "mode" "SI")])
9087
9088 (define_split
9089   [(set (match_operand 0 "flags_reg_operand" "")
9090         (match_operator 2 "compare_operator"
9091           [(not:SI (match_operand:SI 3 "register_operand" ""))
9092            (const_int 0)]))
9093    (set (match_operand:DI 1 "register_operand" "")
9094         (zero_extend:DI (not:SI (match_dup 3))))]
9095   "ix86_match_ccmode (insn, CCNOmode)"
9096   [(parallel [(set (match_dup 0)
9097                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9098                                     (const_int 0)]))
9099               (set (match_dup 1)
9100                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9101 \f
9102 ;; Shift instructions
9103
9104 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9105 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9106 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9107 ;; from the assembler input.
9108 ;;
9109 ;; This instruction shifts the target reg/mem as usual, but instead of
9110 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9111 ;; is a left shift double, bits are taken from the high order bits of
9112 ;; reg, else if the insn is a shift right double, bits are taken from the
9113 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9114 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9115 ;;
9116 ;; Since sh[lr]d does not change the `reg' operand, that is done
9117 ;; separately, making all shifts emit pairs of shift double and normal
9118 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9119 ;; support a 63 bit shift, each shift where the count is in a reg expands
9120 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9121 ;;
9122 ;; If the shift count is a constant, we need never emit more than one
9123 ;; shift pair, instead using moves and sign extension for counts greater
9124 ;; than 31.
9125
9126 (define_expand "ashl<mode>3"
9127   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9128         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9129                       (match_operand:QI 2 "nonmemory_operand" "")))]
9130   ""
9131   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9132
9133 (define_insn "*ashl<mode>3_doubleword"
9134   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9135         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9136                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   ""
9139   "#"
9140   [(set_attr "type" "multi")])
9141
9142 (define_split
9143   [(set (match_operand:DWI 0 "register_operand" "")
9144         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9145                     (match_operand:QI 2 "nonmemory_operand" "")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9148   [(const_int 0)]
9149   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9150
9151 ;; By default we don't ask for a scratch register, because when DWImode
9152 ;; values are manipulated, registers are already at a premium.  But if
9153 ;; we have one handy, we won't turn it away.
9154
9155 (define_peephole2
9156   [(match_scratch:DWIH 3 "r")
9157    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9158                    (ashift:<DWI>
9159                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9160                      (match_operand:QI 2 "nonmemory_operand" "")))
9161               (clobber (reg:CC FLAGS_REG))])
9162    (match_dup 3)]
9163   "TARGET_CMOVE"
9164   [(const_int 0)]
9165   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9166
9167 (define_insn "x86_64_shld"
9168   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9169         (ior:DI (ashift:DI (match_dup 0)
9170                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9171                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9172                   (minus:QI (const_int 64) (match_dup 2)))))
9173    (clobber (reg:CC FLAGS_REG))]
9174   "TARGET_64BIT"
9175   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9176   [(set_attr "type" "ishift")
9177    (set_attr "prefix_0f" "1")
9178    (set_attr "mode" "DI")
9179    (set_attr "athlon_decode" "vector")
9180    (set_attr "amdfam10_decode" "vector")
9181    (set_attr "bdver1_decode" "vector")])
9182
9183 (define_insn "x86_shld"
9184   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9185         (ior:SI (ashift:SI (match_dup 0)
9186                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9187                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9188                   (minus:QI (const_int 32) (match_dup 2)))))
9189    (clobber (reg:CC FLAGS_REG))]
9190   ""
9191   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9192   [(set_attr "type" "ishift")
9193    (set_attr "prefix_0f" "1")
9194    (set_attr "mode" "SI")
9195    (set_attr "pent_pair" "np")
9196    (set_attr "athlon_decode" "vector")
9197    (set_attr "amdfam10_decode" "vector")
9198    (set_attr "bdver1_decode" "vector")])
9199
9200 (define_expand "x86_shift<mode>_adj_1"
9201   [(set (reg:CCZ FLAGS_REG)
9202         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9203                              (match_dup 4))
9204                      (const_int 0)))
9205    (set (match_operand:SWI48 0 "register_operand" "")
9206         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9207                             (match_operand:SWI48 1 "register_operand" "")
9208                             (match_dup 0)))
9209    (set (match_dup 1)
9210         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9211                             (match_operand:SWI48 3 "register_operand" "r")
9212                             (match_dup 1)))]
9213   "TARGET_CMOVE"
9214   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9215
9216 (define_expand "x86_shift<mode>_adj_2"
9217   [(use (match_operand:SWI48 0 "register_operand" ""))
9218    (use (match_operand:SWI48 1 "register_operand" ""))
9219    (use (match_operand:QI 2 "register_operand" ""))]
9220   ""
9221 {
9222   rtx label = gen_label_rtx ();
9223   rtx tmp;
9224
9225   emit_insn (gen_testqi_ccz_1 (operands[2],
9226                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9227
9228   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9229   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9230   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9231                               gen_rtx_LABEL_REF (VOIDmode, label),
9232                               pc_rtx);
9233   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9234   JUMP_LABEL (tmp) = label;
9235
9236   emit_move_insn (operands[0], operands[1]);
9237   ix86_expand_clear (operands[1]);
9238
9239   emit_label (label);
9240   LABEL_NUSES (label) = 1;
9241
9242   DONE;
9243 })
9244
9245 ;; Avoid useless masking of count operand.
9246 (define_insn_and_split "*ashl<mode>3_mask"
9247   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9248         (ashift:SWI48
9249           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9250           (subreg:QI
9251             (and:SI
9252               (match_operand:SI 2 "nonimmediate_operand" "c")
9253               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9254    (clobber (reg:CC FLAGS_REG))]
9255   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9256    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9257       == GET_MODE_BITSIZE (<MODE>mode)-1"
9258   "#"
9259   "&& 1"
9260   [(parallel [(set (match_dup 0)
9261                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9262               (clobber (reg:CC FLAGS_REG))])]
9263 {
9264   if (can_create_pseudo_p ())
9265     operands [2] = force_reg (SImode, operands[2]);
9266
9267   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9268 }
9269   [(set_attr "type" "ishift")
9270    (set_attr "mode" "<MODE>")])
9271
9272 (define_insn "*ashl<mode>3_1"
9273   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9274         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9275                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9276    (clobber (reg:CC FLAGS_REG))]
9277   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9278 {
9279   switch (get_attr_type (insn))
9280     {
9281     case TYPE_LEA:
9282       return "#";
9283
9284     case TYPE_ALU:
9285       gcc_assert (operands[2] == const1_rtx);
9286       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9287       return "add{<imodesuffix>}\t%0, %0";
9288
9289     default:
9290       if (operands[2] == const1_rtx
9291           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9292         return "sal{<imodesuffix>}\t%0";
9293       else
9294         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9295     }
9296 }
9297   [(set (attr "type")
9298      (cond [(eq_attr "alternative" "1")
9299               (const_string "lea")
9300             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9301                           (const_int 0))
9302                       (match_operand 0 "register_operand" ""))
9303                  (match_operand 2 "const1_operand" ""))
9304               (const_string "alu")
9305            ]
9306            (const_string "ishift")))
9307    (set (attr "length_immediate")
9308      (if_then_else
9309        (ior (eq_attr "type" "alu")
9310             (and (eq_attr "type" "ishift")
9311                  (and (match_operand 2 "const1_operand" "")
9312                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9313                           (const_int 0)))))
9314        (const_string "0")
9315        (const_string "*")))
9316    (set_attr "mode" "<MODE>")])
9317
9318 (define_insn "*ashlsi3_1_zext"
9319   [(set (match_operand:DI 0 "register_operand" "=r,r")
9320         (zero_extend:DI
9321           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9322                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9323    (clobber (reg:CC FLAGS_REG))]
9324   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9325 {
9326   switch (get_attr_type (insn))
9327     {
9328     case TYPE_LEA:
9329       return "#";
9330
9331     case TYPE_ALU:
9332       gcc_assert (operands[2] == const1_rtx);
9333       return "add{l}\t%k0, %k0";
9334
9335     default:
9336       if (operands[2] == const1_rtx
9337           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9338         return "sal{l}\t%k0";
9339       else
9340         return "sal{l}\t{%2, %k0|%k0, %2}";
9341     }
9342 }
9343   [(set (attr "type")
9344      (cond [(eq_attr "alternative" "1")
9345               (const_string "lea")
9346             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9347                      (const_int 0))
9348                  (match_operand 2 "const1_operand" ""))
9349               (const_string "alu")
9350            ]
9351            (const_string "ishift")))
9352    (set (attr "length_immediate")
9353      (if_then_else
9354        (ior (eq_attr "type" "alu")
9355             (and (eq_attr "type" "ishift")
9356                  (and (match_operand 2 "const1_operand" "")
9357                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9358                           (const_int 0)))))
9359        (const_string "0")
9360        (const_string "*")))
9361    (set_attr "mode" "SI")])
9362
9363 (define_insn "*ashlhi3_1"
9364   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9365         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9366                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9367    (clobber (reg:CC FLAGS_REG))]
9368   "TARGET_PARTIAL_REG_STALL
9369    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9370 {
9371   switch (get_attr_type (insn))
9372     {
9373     case TYPE_ALU:
9374       gcc_assert (operands[2] == const1_rtx);
9375       return "add{w}\t%0, %0";
9376
9377     default:
9378       if (operands[2] == const1_rtx
9379           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9380         return "sal{w}\t%0";
9381       else
9382         return "sal{w}\t{%2, %0|%0, %2}";
9383     }
9384 }
9385   [(set (attr "type")
9386      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9387                           (const_int 0))
9388                       (match_operand 0 "register_operand" ""))
9389                  (match_operand 2 "const1_operand" ""))
9390               (const_string "alu")
9391            ]
9392            (const_string "ishift")))
9393    (set (attr "length_immediate")
9394      (if_then_else
9395        (ior (eq_attr "type" "alu")
9396             (and (eq_attr "type" "ishift")
9397                  (and (match_operand 2 "const1_operand" "")
9398                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9399                           (const_int 0)))))
9400        (const_string "0")
9401        (const_string "*")))
9402    (set_attr "mode" "HI")])
9403
9404 (define_insn "*ashlhi3_1_lea"
9405   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9406         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9407                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9408    (clobber (reg:CC FLAGS_REG))]
9409   "!TARGET_PARTIAL_REG_STALL
9410    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9411 {
9412   switch (get_attr_type (insn))
9413     {
9414     case TYPE_LEA:
9415       return "#";
9416
9417     case TYPE_ALU:
9418       gcc_assert (operands[2] == const1_rtx);
9419       return "add{w}\t%0, %0";
9420
9421     default:
9422       if (operands[2] == const1_rtx
9423           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9424         return "sal{w}\t%0";
9425       else
9426         return "sal{w}\t{%2, %0|%0, %2}";
9427     }
9428 }
9429   [(set (attr "type")
9430      (cond [(eq_attr "alternative" "1")
9431               (const_string "lea")
9432             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9433                           (const_int 0))
9434                       (match_operand 0 "register_operand" ""))
9435                  (match_operand 2 "const1_operand" ""))
9436               (const_string "alu")
9437            ]
9438            (const_string "ishift")))
9439    (set (attr "length_immediate")
9440      (if_then_else
9441        (ior (eq_attr "type" "alu")
9442             (and (eq_attr "type" "ishift")
9443                  (and (match_operand 2 "const1_operand" "")
9444                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9445                           (const_int 0)))))
9446        (const_string "0")
9447        (const_string "*")))
9448    (set_attr "mode" "HI,SI")])
9449
9450 (define_insn "*ashlqi3_1"
9451   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9452         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9453                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "TARGET_PARTIAL_REG_STALL
9456    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9457 {
9458   switch (get_attr_type (insn))
9459     {
9460     case TYPE_ALU:
9461       gcc_assert (operands[2] == const1_rtx);
9462       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9463         return "add{l}\t%k0, %k0";
9464       else
9465         return "add{b}\t%0, %0";
9466
9467     default:
9468       if (operands[2] == const1_rtx
9469           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9470         {
9471           if (get_attr_mode (insn) == MODE_SI)
9472             return "sal{l}\t%k0";
9473           else
9474             return "sal{b}\t%0";
9475         }
9476       else
9477         {
9478           if (get_attr_mode (insn) == MODE_SI)
9479             return "sal{l}\t{%2, %k0|%k0, %2}";
9480           else
9481             return "sal{b}\t{%2, %0|%0, %2}";
9482         }
9483     }
9484 }
9485   [(set (attr "type")
9486      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9487                           (const_int 0))
9488                       (match_operand 0 "register_operand" ""))
9489                  (match_operand 2 "const1_operand" ""))
9490               (const_string "alu")
9491            ]
9492            (const_string "ishift")))
9493    (set (attr "length_immediate")
9494      (if_then_else
9495        (ior (eq_attr "type" "alu")
9496             (and (eq_attr "type" "ishift")
9497                  (and (match_operand 2 "const1_operand" "")
9498                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9499                           (const_int 0)))))
9500        (const_string "0")
9501        (const_string "*")))
9502    (set_attr "mode" "QI,SI")])
9503
9504 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9505 (define_insn "*ashlqi3_1_lea"
9506   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9507         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9508                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9509    (clobber (reg:CC FLAGS_REG))]
9510   "!TARGET_PARTIAL_REG_STALL
9511    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9512 {
9513   switch (get_attr_type (insn))
9514     {
9515     case TYPE_LEA:
9516       return "#";
9517
9518     case TYPE_ALU:
9519       gcc_assert (operands[2] == const1_rtx);
9520       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9521         return "add{l}\t%k0, %k0";
9522       else
9523         return "add{b}\t%0, %0";
9524
9525     default:
9526       if (operands[2] == const1_rtx
9527           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9528         {
9529           if (get_attr_mode (insn) == MODE_SI)
9530             return "sal{l}\t%k0";
9531           else
9532             return "sal{b}\t%0";
9533         }
9534       else
9535         {
9536           if (get_attr_mode (insn) == MODE_SI)
9537             return "sal{l}\t{%2, %k0|%k0, %2}";
9538           else
9539             return "sal{b}\t{%2, %0|%0, %2}";
9540         }
9541     }
9542 }
9543   [(set (attr "type")
9544      (cond [(eq_attr "alternative" "2")
9545               (const_string "lea")
9546             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9547                           (const_int 0))
9548                       (match_operand 0 "register_operand" ""))
9549                  (match_operand 2 "const1_operand" ""))
9550               (const_string "alu")
9551            ]
9552            (const_string "ishift")))
9553    (set (attr "length_immediate")
9554      (if_then_else
9555        (ior (eq_attr "type" "alu")
9556             (and (eq_attr "type" "ishift")
9557                  (and (match_operand 2 "const1_operand" "")
9558                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9559                           (const_int 0)))))
9560        (const_string "0")
9561        (const_string "*")))
9562    (set_attr "mode" "QI,SI,SI")])
9563
9564 (define_insn "*ashlqi3_1_slp"
9565   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9566         (ashift:QI (match_dup 0)
9567                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9568    (clobber (reg:CC FLAGS_REG))]
9569   "(optimize_function_for_size_p (cfun)
9570     || !TARGET_PARTIAL_FLAG_REG_STALL
9571     || (operands[1] == const1_rtx
9572         && (TARGET_SHIFT1
9573             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9574 {
9575   switch (get_attr_type (insn))
9576     {
9577     case TYPE_ALU:
9578       gcc_assert (operands[1] == const1_rtx);
9579       return "add{b}\t%0, %0";
9580
9581     default:
9582       if (operands[1] == const1_rtx
9583           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9584         return "sal{b}\t%0";
9585       else
9586         return "sal{b}\t{%1, %0|%0, %1}";
9587     }
9588 }
9589   [(set (attr "type")
9590      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9591                           (const_int 0))
9592                       (match_operand 0 "register_operand" ""))
9593                  (match_operand 1 "const1_operand" ""))
9594               (const_string "alu")
9595            ]
9596            (const_string "ishift1")))
9597    (set (attr "length_immediate")
9598      (if_then_else
9599        (ior (eq_attr "type" "alu")
9600             (and (eq_attr "type" "ishift1")
9601                  (and (match_operand 1 "const1_operand" "")
9602                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9603                           (const_int 0)))))
9604        (const_string "0")
9605        (const_string "*")))
9606    (set_attr "mode" "QI")])
9607
9608 ;; Convert lea to the lea pattern to avoid flags dependency.
9609 (define_split
9610   [(set (match_operand 0 "register_operand" "")
9611         (ashift (match_operand 1 "index_register_operand" "")
9612                 (match_operand:QI 2 "const_int_operand" "")))
9613    (clobber (reg:CC FLAGS_REG))]
9614   "reload_completed
9615    && true_regnum (operands[0]) != true_regnum (operands[1])"
9616   [(const_int 0)]
9617 {
9618   rtx pat;
9619   enum machine_mode mode = GET_MODE (operands[0]);
9620
9621   if (mode != Pmode)
9622     operands[1] = gen_lowpart (Pmode, operands[1]);
9623   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9624
9625   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9626
9627   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9628     operands[0] = gen_lowpart (SImode, operands[0]);
9629
9630   if (TARGET_64BIT && mode != Pmode)
9631     pat = gen_rtx_SUBREG (SImode, pat, 0);
9632
9633   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9634   DONE;
9635 })
9636
9637 ;; Convert lea to the lea pattern to avoid flags dependency.
9638 (define_split
9639   [(set (match_operand:DI 0 "register_operand" "")
9640         (zero_extend:DI
9641           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9642                      (match_operand:QI 2 "const_int_operand" ""))))
9643    (clobber (reg:CC FLAGS_REG))]
9644   "TARGET_64BIT && reload_completed
9645    && true_regnum (operands[0]) != true_regnum (operands[1])"
9646   [(set (match_dup 0)
9647         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9648 {
9649   operands[1] = gen_lowpart (DImode, operands[1]);
9650   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9651 })
9652
9653 ;; This pattern can't accept a variable shift count, since shifts by
9654 ;; zero don't affect the flags.  We assume that shifts by constant
9655 ;; zero are optimized away.
9656 (define_insn "*ashl<mode>3_cmp"
9657   [(set (reg FLAGS_REG)
9658         (compare
9659           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9660                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9661           (const_int 0)))
9662    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9663         (ashift:SWI (match_dup 1) (match_dup 2)))]
9664   "(optimize_function_for_size_p (cfun)
9665     || !TARGET_PARTIAL_FLAG_REG_STALL
9666     || (operands[2] == const1_rtx
9667         && (TARGET_SHIFT1
9668             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9669    && ix86_match_ccmode (insn, CCGOCmode)
9670    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9671 {
9672   switch (get_attr_type (insn))
9673     {
9674     case TYPE_ALU:
9675       gcc_assert (operands[2] == const1_rtx);
9676       return "add{<imodesuffix>}\t%0, %0";
9677
9678     default:
9679       if (operands[2] == const1_rtx
9680           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9681         return "sal{<imodesuffix>}\t%0";
9682       else
9683         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9684     }
9685 }
9686   [(set (attr "type")
9687      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9688                           (const_int 0))
9689                       (match_operand 0 "register_operand" ""))
9690                  (match_operand 2 "const1_operand" ""))
9691               (const_string "alu")
9692            ]
9693            (const_string "ishift")))
9694    (set (attr "length_immediate")
9695      (if_then_else
9696        (ior (eq_attr "type" "alu")
9697             (and (eq_attr "type" "ishift")
9698                  (and (match_operand 2 "const1_operand" "")
9699                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9700                           (const_int 0)))))
9701        (const_string "0")
9702        (const_string "*")))
9703    (set_attr "mode" "<MODE>")])
9704
9705 (define_insn "*ashlsi3_cmp_zext"
9706   [(set (reg FLAGS_REG)
9707         (compare
9708           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9709                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9710           (const_int 0)))
9711    (set (match_operand:DI 0 "register_operand" "=r")
9712         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9713   "TARGET_64BIT
9714    && (optimize_function_for_size_p (cfun)
9715        || !TARGET_PARTIAL_FLAG_REG_STALL
9716        || (operands[2] == const1_rtx
9717            && (TARGET_SHIFT1
9718                || TARGET_DOUBLE_WITH_ADD)))
9719    && ix86_match_ccmode (insn, CCGOCmode)
9720    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9721 {
9722   switch (get_attr_type (insn))
9723     {
9724     case TYPE_ALU:
9725       gcc_assert (operands[2] == const1_rtx);
9726       return "add{l}\t%k0, %k0";
9727
9728     default:
9729       if (operands[2] == const1_rtx
9730           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731         return "sal{l}\t%k0";
9732       else
9733         return "sal{l}\t{%2, %k0|%k0, %2}";
9734     }
9735 }
9736   [(set (attr "type")
9737      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9738                      (const_int 0))
9739                  (match_operand 2 "const1_operand" ""))
9740               (const_string "alu")
9741            ]
9742            (const_string "ishift")))
9743    (set (attr "length_immediate")
9744      (if_then_else
9745        (ior (eq_attr "type" "alu")
9746             (and (eq_attr "type" "ishift")
9747                  (and (match_operand 2 "const1_operand" "")
9748                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9749                           (const_int 0)))))
9750        (const_string "0")
9751        (const_string "*")))
9752    (set_attr "mode" "SI")])
9753
9754 (define_insn "*ashl<mode>3_cconly"
9755   [(set (reg FLAGS_REG)
9756         (compare
9757           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9758                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9759           (const_int 0)))
9760    (clobber (match_scratch:SWI 0 "=<r>"))]
9761   "(optimize_function_for_size_p (cfun)
9762     || !TARGET_PARTIAL_FLAG_REG_STALL
9763     || (operands[2] == const1_rtx
9764         && (TARGET_SHIFT1
9765             || TARGET_DOUBLE_WITH_ADD)))
9766    && ix86_match_ccmode (insn, CCGOCmode)"
9767 {
9768   switch (get_attr_type (insn))
9769     {
9770     case TYPE_ALU:
9771       gcc_assert (operands[2] == const1_rtx);
9772       return "add{<imodesuffix>}\t%0, %0";
9773
9774     default:
9775       if (operands[2] == const1_rtx
9776           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9777         return "sal{<imodesuffix>}\t%0";
9778       else
9779         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9780     }
9781 }
9782   [(set (attr "type")
9783      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9784                           (const_int 0))
9785                       (match_operand 0 "register_operand" ""))
9786                  (match_operand 2 "const1_operand" ""))
9787               (const_string "alu")
9788            ]
9789            (const_string "ishift")))
9790    (set (attr "length_immediate")
9791      (if_then_else
9792        (ior (eq_attr "type" "alu")
9793             (and (eq_attr "type" "ishift")
9794                  (and (match_operand 2 "const1_operand" "")
9795                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9796                           (const_int 0)))))
9797        (const_string "0")
9798        (const_string "*")))
9799    (set_attr "mode" "<MODE>")])
9800
9801 ;; See comment above `ashl<mode>3' about how this works.
9802
9803 (define_expand "<shiftrt_insn><mode>3"
9804   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9805         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9806                            (match_operand:QI 2 "nonmemory_operand" "")))]
9807   ""
9808   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9809
9810 ;; Avoid useless masking of count operand.
9811 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9812   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9813         (any_shiftrt:SWI48
9814           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9815           (subreg:QI
9816             (and:SI
9817               (match_operand:SI 2 "nonimmediate_operand" "c")
9818               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9819    (clobber (reg:CC FLAGS_REG))]
9820   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9821    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9822       == GET_MODE_BITSIZE (<MODE>mode)-1"
9823   "#"
9824   "&& 1"
9825   [(parallel [(set (match_dup 0)
9826                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9827               (clobber (reg:CC FLAGS_REG))])]
9828 {
9829   if (can_create_pseudo_p ())
9830     operands [2] = force_reg (SImode, operands[2]);
9831
9832   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9833 }
9834   [(set_attr "type" "ishift")
9835    (set_attr "mode" "<MODE>")])
9836
9837 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9838   [(set (match_operand:DWI 0 "register_operand" "=r")
9839         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9840                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9841    (clobber (reg:CC FLAGS_REG))]
9842   ""
9843   "#"
9844   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9845   [(const_int 0)]
9846   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9847   [(set_attr "type" "multi")])
9848
9849 ;; By default we don't ask for a scratch register, because when DWImode
9850 ;; values are manipulated, registers are already at a premium.  But if
9851 ;; we have one handy, we won't turn it away.
9852
9853 (define_peephole2
9854   [(match_scratch:DWIH 3 "r")
9855    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9856                    (any_shiftrt:<DWI>
9857                      (match_operand:<DWI> 1 "register_operand" "")
9858                      (match_operand:QI 2 "nonmemory_operand" "")))
9859               (clobber (reg:CC FLAGS_REG))])
9860    (match_dup 3)]
9861   "TARGET_CMOVE"
9862   [(const_int 0)]
9863   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9864
9865 (define_insn "x86_64_shrd"
9866   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9867         (ior:DI (ashiftrt:DI (match_dup 0)
9868                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9869                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9870                   (minus:QI (const_int 64) (match_dup 2)))))
9871    (clobber (reg:CC FLAGS_REG))]
9872   "TARGET_64BIT"
9873   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9874   [(set_attr "type" "ishift")
9875    (set_attr "prefix_0f" "1")
9876    (set_attr "mode" "DI")
9877    (set_attr "athlon_decode" "vector")
9878    (set_attr "amdfam10_decode" "vector")
9879    (set_attr "bdver1_decode" "vector")])
9880
9881 (define_insn "x86_shrd"
9882   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9883         (ior:SI (ashiftrt:SI (match_dup 0)
9884                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9885                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9886                   (minus:QI (const_int 32) (match_dup 2)))))
9887    (clobber (reg:CC FLAGS_REG))]
9888   ""
9889   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9890   [(set_attr "type" "ishift")
9891    (set_attr "prefix_0f" "1")
9892    (set_attr "mode" "SI")
9893    (set_attr "pent_pair" "np")
9894    (set_attr "athlon_decode" "vector")
9895    (set_attr "amdfam10_decode" "vector")
9896    (set_attr "bdver1_decode" "vector")])
9897
9898 (define_insn "ashrdi3_cvt"
9899   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9900         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9901                      (match_operand:QI 2 "const_int_operand" "")))
9902    (clobber (reg:CC FLAGS_REG))]
9903   "TARGET_64BIT && INTVAL (operands[2]) == 63
9904    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9905    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9906   "@
9907    {cqto|cqo}
9908    sar{q}\t{%2, %0|%0, %2}"
9909   [(set_attr "type" "imovx,ishift")
9910    (set_attr "prefix_0f" "0,*")
9911    (set_attr "length_immediate" "0,*")
9912    (set_attr "modrm" "0,1")
9913    (set_attr "mode" "DI")])
9914
9915 (define_insn "ashrsi3_cvt"
9916   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9917         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9918                      (match_operand:QI 2 "const_int_operand" "")))
9919    (clobber (reg:CC FLAGS_REG))]
9920   "INTVAL (operands[2]) == 31
9921    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9922    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9923   "@
9924    {cltd|cdq}
9925    sar{l}\t{%2, %0|%0, %2}"
9926   [(set_attr "type" "imovx,ishift")
9927    (set_attr "prefix_0f" "0,*")
9928    (set_attr "length_immediate" "0,*")
9929    (set_attr "modrm" "0,1")
9930    (set_attr "mode" "SI")])
9931
9932 (define_insn "*ashrsi3_cvt_zext"
9933   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9934         (zero_extend:DI
9935           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9936                        (match_operand:QI 2 "const_int_operand" ""))))
9937    (clobber (reg:CC FLAGS_REG))]
9938   "TARGET_64BIT && INTVAL (operands[2]) == 31
9939    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9940    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9941   "@
9942    {cltd|cdq}
9943    sar{l}\t{%2, %k0|%k0, %2}"
9944   [(set_attr "type" "imovx,ishift")
9945    (set_attr "prefix_0f" "0,*")
9946    (set_attr "length_immediate" "0,*")
9947    (set_attr "modrm" "0,1")
9948    (set_attr "mode" "SI")])
9949
9950 (define_expand "x86_shift<mode>_adj_3"
9951   [(use (match_operand:SWI48 0 "register_operand" ""))
9952    (use (match_operand:SWI48 1 "register_operand" ""))
9953    (use (match_operand:QI 2 "register_operand" ""))]
9954   ""
9955 {
9956   rtx label = gen_label_rtx ();
9957   rtx tmp;
9958
9959   emit_insn (gen_testqi_ccz_1 (operands[2],
9960                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9961
9962   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9963   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9964   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9965                               gen_rtx_LABEL_REF (VOIDmode, label),
9966                               pc_rtx);
9967   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9968   JUMP_LABEL (tmp) = label;
9969
9970   emit_move_insn (operands[0], operands[1]);
9971   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9972                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9973   emit_label (label);
9974   LABEL_NUSES (label) = 1;
9975
9976   DONE;
9977 })
9978
9979 (define_insn "*<shiftrt_insn><mode>3_1"
9980   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9981         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9982                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9983    (clobber (reg:CC FLAGS_REG))]
9984   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9985 {
9986   if (operands[2] == const1_rtx
9987       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9988     return "<shiftrt>{<imodesuffix>}\t%0";
9989   else
9990     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9991 }
9992   [(set_attr "type" "ishift")
9993    (set (attr "length_immediate")
9994      (if_then_else
9995        (and (match_operand 2 "const1_operand" "")
9996             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9997                 (const_int 0)))
9998        (const_string "0")
9999        (const_string "*")))
10000    (set_attr "mode" "<MODE>")])
10001
10002 (define_insn "*<shiftrt_insn>si3_1_zext"
10003   [(set (match_operand:DI 0 "register_operand" "=r")
10004         (zero_extend:DI
10005           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10006                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10007    (clobber (reg:CC FLAGS_REG))]
10008   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10009 {
10010   if (operands[2] == const1_rtx
10011       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10012     return "<shiftrt>{l}\t%k0";
10013   else
10014     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10015 }
10016   [(set_attr "type" "ishift")
10017    (set (attr "length_immediate")
10018      (if_then_else
10019        (and (match_operand 2 "const1_operand" "")
10020             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10021                 (const_int 0)))
10022        (const_string "0")
10023        (const_string "*")))
10024    (set_attr "mode" "SI")])
10025
10026 (define_insn "*<shiftrt_insn>qi3_1_slp"
10027   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10028         (any_shiftrt:QI (match_dup 0)
10029                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10030    (clobber (reg:CC FLAGS_REG))]
10031   "(optimize_function_for_size_p (cfun)
10032     || !TARGET_PARTIAL_REG_STALL
10033     || (operands[1] == const1_rtx
10034         && TARGET_SHIFT1))"
10035 {
10036   if (operands[1] == const1_rtx
10037       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10038     return "<shiftrt>{b}\t%0";
10039   else
10040     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10041 }
10042   [(set_attr "type" "ishift1")
10043    (set (attr "length_immediate")
10044      (if_then_else
10045        (and (match_operand 1 "const1_operand" "")
10046             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10047                 (const_int 0)))
10048        (const_string "0")
10049        (const_string "*")))
10050    (set_attr "mode" "QI")])
10051
10052 ;; This pattern can't accept a variable shift count, since shifts by
10053 ;; zero don't affect the flags.  We assume that shifts by constant
10054 ;; zero are optimized away.
10055 (define_insn "*<shiftrt_insn><mode>3_cmp"
10056   [(set (reg FLAGS_REG)
10057         (compare
10058           (any_shiftrt:SWI
10059             (match_operand:SWI 1 "nonimmediate_operand" "0")
10060             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10061           (const_int 0)))
10062    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10063         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10064   "(optimize_function_for_size_p (cfun)
10065     || !TARGET_PARTIAL_FLAG_REG_STALL
10066     || (operands[2] == const1_rtx
10067         && TARGET_SHIFT1))
10068    && ix86_match_ccmode (insn, CCGOCmode)
10069    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10070 {
10071   if (operands[2] == const1_rtx
10072       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10073     return "<shiftrt>{<imodesuffix>}\t%0";
10074   else
10075     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10076 }
10077   [(set_attr "type" "ishift")
10078    (set (attr "length_immediate")
10079      (if_then_else
10080        (and (match_operand 2 "const1_operand" "")
10081             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10082                 (const_int 0)))
10083        (const_string "0")
10084        (const_string "*")))
10085    (set_attr "mode" "<MODE>")])
10086
10087 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10088   [(set (reg FLAGS_REG)
10089         (compare
10090           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10091                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10092           (const_int 0)))
10093    (set (match_operand:DI 0 "register_operand" "=r")
10094         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10095   "TARGET_64BIT
10096    && (optimize_function_for_size_p (cfun)
10097        || !TARGET_PARTIAL_FLAG_REG_STALL
10098        || (operands[2] == const1_rtx
10099            && TARGET_SHIFT1))
10100    && ix86_match_ccmode (insn, CCGOCmode)
10101    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10102 {
10103   if (operands[2] == const1_rtx
10104       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10105     return "<shiftrt>{l}\t%k0";
10106   else
10107     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10108 }
10109   [(set_attr "type" "ishift")
10110    (set (attr "length_immediate")
10111      (if_then_else
10112        (and (match_operand 2 "const1_operand" "")
10113             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10114                 (const_int 0)))
10115        (const_string "0")
10116        (const_string "*")))
10117    (set_attr "mode" "SI")])
10118
10119 (define_insn "*<shiftrt_insn><mode>3_cconly"
10120   [(set (reg FLAGS_REG)
10121         (compare
10122           (any_shiftrt:SWI
10123             (match_operand:SWI 1 "register_operand" "0")
10124             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10125           (const_int 0)))
10126    (clobber (match_scratch:SWI 0 "=<r>"))]
10127   "(optimize_function_for_size_p (cfun)
10128     || !TARGET_PARTIAL_FLAG_REG_STALL
10129     || (operands[2] == const1_rtx
10130         && TARGET_SHIFT1))
10131    && ix86_match_ccmode (insn, CCGOCmode)"
10132 {
10133   if (operands[2] == const1_rtx
10134       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10135     return "<shiftrt>{<imodesuffix>}\t%0";
10136   else
10137     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10138 }
10139   [(set_attr "type" "ishift")
10140    (set (attr "length_immediate")
10141      (if_then_else
10142        (and (match_operand 2 "const1_operand" "")
10143             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10144                 (const_int 0)))
10145        (const_string "0")
10146        (const_string "*")))
10147    (set_attr "mode" "<MODE>")])
10148 \f
10149 ;; Rotate instructions
10150
10151 (define_expand "<rotate_insn>ti3"
10152   [(set (match_operand:TI 0 "register_operand" "")
10153         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10154                        (match_operand:QI 2 "nonmemory_operand" "")))]
10155   "TARGET_64BIT"
10156 {
10157   if (const_1_to_63_operand (operands[2], VOIDmode))
10158     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10159                 (operands[0], operands[1], operands[2]));
10160   else
10161     FAIL;
10162
10163   DONE;
10164 })
10165
10166 (define_expand "<rotate_insn>di3"
10167   [(set (match_operand:DI 0 "shiftdi_operand" "")
10168         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10169                        (match_operand:QI 2 "nonmemory_operand" "")))]
10170  ""
10171 {
10172   if (TARGET_64BIT)
10173     ix86_expand_binary_operator (<CODE>, DImode, operands);
10174   else if (const_1_to_31_operand (operands[2], VOIDmode))
10175     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10176                 (operands[0], operands[1], operands[2]));
10177   else
10178     FAIL;
10179
10180   DONE;
10181 })
10182
10183 (define_expand "<rotate_insn><mode>3"
10184   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10185         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10186                             (match_operand:QI 2 "nonmemory_operand" "")))]
10187   ""
10188   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10189
10190 ;; Avoid useless masking of count operand.
10191 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10192   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10193         (any_rotate:SWI48
10194           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10195           (subreg:QI
10196             (and:SI
10197               (match_operand:SI 2 "nonimmediate_operand" "c")
10198               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10199    (clobber (reg:CC FLAGS_REG))]
10200   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10201    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10202       == GET_MODE_BITSIZE (<MODE>mode)-1"
10203   "#"
10204   "&& 1"
10205   [(parallel [(set (match_dup 0)
10206                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10207               (clobber (reg:CC FLAGS_REG))])]
10208 {
10209   if (can_create_pseudo_p ())
10210     operands [2] = force_reg (SImode, operands[2]);
10211
10212   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10213 }
10214   [(set_attr "type" "rotate")
10215    (set_attr "mode" "<MODE>")])
10216
10217 ;; Implement rotation using two double-precision
10218 ;; shift instructions and a scratch register.
10219
10220 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10221  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10222        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10223                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10224   (clobber (reg:CC FLAGS_REG))
10225   (clobber (match_scratch:DWIH 3 "=&r"))]
10226  ""
10227  "#"
10228  "reload_completed"
10229  [(set (match_dup 3) (match_dup 4))
10230   (parallel
10231    [(set (match_dup 4)
10232          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10233                    (lshiftrt:DWIH (match_dup 5)
10234                                   (minus:QI (match_dup 6) (match_dup 2)))))
10235     (clobber (reg:CC FLAGS_REG))])
10236   (parallel
10237    [(set (match_dup 5)
10238          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10239                    (lshiftrt:DWIH (match_dup 3)
10240                                   (minus:QI (match_dup 6) (match_dup 2)))))
10241     (clobber (reg:CC FLAGS_REG))])]
10242 {
10243   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10244
10245   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10246 })
10247
10248 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10249  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10250        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10251                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10252   (clobber (reg:CC FLAGS_REG))
10253   (clobber (match_scratch:DWIH 3 "=&r"))]
10254  ""
10255  "#"
10256  "reload_completed"
10257  [(set (match_dup 3) (match_dup 4))
10258   (parallel
10259    [(set (match_dup 4)
10260          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10261                    (ashift:DWIH (match_dup 5)
10262                                 (minus:QI (match_dup 6) (match_dup 2)))))
10263     (clobber (reg:CC FLAGS_REG))])
10264   (parallel
10265    [(set (match_dup 5)
10266          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10267                    (ashift:DWIH (match_dup 3)
10268                                 (minus:QI (match_dup 6) (match_dup 2)))))
10269     (clobber (reg:CC FLAGS_REG))])]
10270 {
10271   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10272
10273   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10274 })
10275
10276 (define_insn "*<rotate_insn><mode>3_1"
10277   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10278         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10279                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10282 {
10283   if (operands[2] == const1_rtx
10284       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10285     return "<rotate>{<imodesuffix>}\t%0";
10286   else
10287     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10288 }
10289   [(set_attr "type" "rotate")
10290    (set (attr "length_immediate")
10291      (if_then_else
10292        (and (match_operand 2 "const1_operand" "")
10293             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10294                 (const_int 0)))
10295        (const_string "0")
10296        (const_string "*")))
10297    (set_attr "mode" "<MODE>")])
10298
10299 (define_insn "*<rotate_insn>si3_1_zext"
10300   [(set (match_operand:DI 0 "register_operand" "=r")
10301         (zero_extend:DI
10302           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10303                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10304    (clobber (reg:CC FLAGS_REG))]
10305   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10306 {
10307     if (operands[2] == const1_rtx
10308         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10309     return "<rotate>{l}\t%k0";
10310   else
10311     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10312 }
10313   [(set_attr "type" "rotate")
10314    (set (attr "length_immediate")
10315      (if_then_else
10316        (and (match_operand 2 "const1_operand" "")
10317             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10318                 (const_int 0)))
10319        (const_string "0")
10320        (const_string "*")))
10321    (set_attr "mode" "SI")])
10322
10323 (define_insn "*<rotate_insn>qi3_1_slp"
10324   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10325         (any_rotate:QI (match_dup 0)
10326                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10327    (clobber (reg:CC FLAGS_REG))]
10328   "(optimize_function_for_size_p (cfun)
10329     || !TARGET_PARTIAL_REG_STALL
10330     || (operands[1] == const1_rtx
10331         && TARGET_SHIFT1))"
10332 {
10333   if (operands[1] == const1_rtx
10334       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10335     return "<rotate>{b}\t%0";
10336   else
10337     return "<rotate>{b}\t{%1, %0|%0, %1}";
10338 }
10339   [(set_attr "type" "rotate1")
10340    (set (attr "length_immediate")
10341      (if_then_else
10342        (and (match_operand 1 "const1_operand" "")
10343             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10344                 (const_int 0)))
10345        (const_string "0")
10346        (const_string "*")))
10347    (set_attr "mode" "QI")])
10348
10349 (define_split
10350  [(set (match_operand:HI 0 "register_operand" "")
10351        (any_rotate:HI (match_dup 0) (const_int 8)))
10352   (clobber (reg:CC FLAGS_REG))]
10353  "reload_completed
10354   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10355  [(parallel [(set (strict_low_part (match_dup 0))
10356                   (bswap:HI (match_dup 0)))
10357              (clobber (reg:CC FLAGS_REG))])])
10358 \f
10359 ;; Bit set / bit test instructions
10360
10361 (define_expand "extv"
10362   [(set (match_operand:SI 0 "register_operand" "")
10363         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10364                          (match_operand:SI 2 "const8_operand" "")
10365                          (match_operand:SI 3 "const8_operand" "")))]
10366   ""
10367 {
10368   /* Handle extractions from %ah et al.  */
10369   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10370     FAIL;
10371
10372   /* From mips.md: extract_bit_field doesn't verify that our source
10373      matches the predicate, so check it again here.  */
10374   if (! ext_register_operand (operands[1], VOIDmode))
10375     FAIL;
10376 })
10377
10378 (define_expand "extzv"
10379   [(set (match_operand:SI 0 "register_operand" "")
10380         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10381                          (match_operand:SI 2 "const8_operand" "")
10382                          (match_operand:SI 3 "const8_operand" "")))]
10383   ""
10384 {
10385   /* Handle extractions from %ah et al.  */
10386   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10387     FAIL;
10388
10389   /* From mips.md: extract_bit_field doesn't verify that our source
10390      matches the predicate, so check it again here.  */
10391   if (! ext_register_operand (operands[1], VOIDmode))
10392     FAIL;
10393 })
10394
10395 (define_expand "insv"
10396   [(set (zero_extract (match_operand 0 "register_operand" "")
10397                       (match_operand 1 "const_int_operand" "")
10398                       (match_operand 2 "const_int_operand" ""))
10399         (match_operand 3 "register_operand" ""))]
10400   ""
10401 {
10402   rtx (*gen_mov_insv_1) (rtx, rtx);
10403
10404   if (ix86_expand_pinsr (operands))
10405     DONE;
10406
10407   /* Handle insertions to %ah et al.  */
10408   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10409     FAIL;
10410
10411   /* From mips.md: insert_bit_field doesn't verify that our source
10412      matches the predicate, so check it again here.  */
10413   if (! ext_register_operand (operands[0], VOIDmode))
10414     FAIL;
10415
10416   gen_mov_insv_1 = (TARGET_64BIT
10417                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10418
10419   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10420   DONE;
10421 })
10422
10423 ;; %%% bts, btr, btc, bt.
10424 ;; In general these instructions are *slow* when applied to memory,
10425 ;; since they enforce atomic operation.  When applied to registers,
10426 ;; it depends on the cpu implementation.  They're never faster than
10427 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10428 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10429 ;; within the instruction itself, so operating on bits in the high
10430 ;; 32-bits of a register becomes easier.
10431 ;;
10432 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10433 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10434 ;; negdf respectively, so they can never be disabled entirely.
10435
10436 (define_insn "*btsq"
10437   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10438                          (const_int 1)
10439                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10440         (const_int 1))
10441    (clobber (reg:CC FLAGS_REG))]
10442   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10443   "bts{q}\t{%1, %0|%0, %1}"
10444   [(set_attr "type" "alu1")
10445    (set_attr "prefix_0f" "1")
10446    (set_attr "mode" "DI")])
10447
10448 (define_insn "*btrq"
10449   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10450                          (const_int 1)
10451                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10452         (const_int 0))
10453    (clobber (reg:CC FLAGS_REG))]
10454   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10455   "btr{q}\t{%1, %0|%0, %1}"
10456   [(set_attr "type" "alu1")
10457    (set_attr "prefix_0f" "1")
10458    (set_attr "mode" "DI")])
10459
10460 (define_insn "*btcq"
10461   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10462                          (const_int 1)
10463                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10464         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10465    (clobber (reg:CC FLAGS_REG))]
10466   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10467   "btc{q}\t{%1, %0|%0, %1}"
10468   [(set_attr "type" "alu1")
10469    (set_attr "prefix_0f" "1")
10470    (set_attr "mode" "DI")])
10471
10472 ;; Allow Nocona to avoid these instructions if a register is available.
10473
10474 (define_peephole2
10475   [(match_scratch:DI 2 "r")
10476    (parallel [(set (zero_extract:DI
10477                      (match_operand:DI 0 "register_operand" "")
10478                      (const_int 1)
10479                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10480                    (const_int 1))
10481               (clobber (reg:CC FLAGS_REG))])]
10482   "TARGET_64BIT && !TARGET_USE_BT"
10483   [(const_int 0)]
10484 {
10485   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10486   rtx op1;
10487
10488   if (HOST_BITS_PER_WIDE_INT >= 64)
10489     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10490   else if (i < HOST_BITS_PER_WIDE_INT)
10491     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10492   else
10493     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10494
10495   op1 = immed_double_const (lo, hi, DImode);
10496   if (i >= 31)
10497     {
10498       emit_move_insn (operands[2], op1);
10499       op1 = operands[2];
10500     }
10501
10502   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10503   DONE;
10504 })
10505
10506 (define_peephole2
10507   [(match_scratch:DI 2 "r")
10508    (parallel [(set (zero_extract:DI
10509                      (match_operand:DI 0 "register_operand" "")
10510                      (const_int 1)
10511                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10512                    (const_int 0))
10513               (clobber (reg:CC FLAGS_REG))])]
10514   "TARGET_64BIT && !TARGET_USE_BT"
10515   [(const_int 0)]
10516 {
10517   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10518   rtx op1;
10519
10520   if (HOST_BITS_PER_WIDE_INT >= 64)
10521     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10522   else if (i < HOST_BITS_PER_WIDE_INT)
10523     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10524   else
10525     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10526
10527   op1 = immed_double_const (~lo, ~hi, DImode);
10528   if (i >= 32)
10529     {
10530       emit_move_insn (operands[2], op1);
10531       op1 = operands[2];
10532     }
10533
10534   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10535   DONE;
10536 })
10537
10538 (define_peephole2
10539   [(match_scratch:DI 2 "r")
10540    (parallel [(set (zero_extract:DI
10541                      (match_operand:DI 0 "register_operand" "")
10542                      (const_int 1)
10543                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10544               (not:DI (zero_extract:DI
10545                         (match_dup 0) (const_int 1) (match_dup 1))))
10546               (clobber (reg:CC FLAGS_REG))])]
10547   "TARGET_64BIT && !TARGET_USE_BT"
10548   [(const_int 0)]
10549 {
10550   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10551   rtx op1;
10552
10553   if (HOST_BITS_PER_WIDE_INT >= 64)
10554     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10555   else if (i < HOST_BITS_PER_WIDE_INT)
10556     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10557   else
10558     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10559
10560   op1 = immed_double_const (lo, hi, DImode);
10561   if (i >= 31)
10562     {
10563       emit_move_insn (operands[2], op1);
10564       op1 = operands[2];
10565     }
10566
10567   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10568   DONE;
10569 })
10570
10571 (define_insn "*bt<mode>"
10572   [(set (reg:CCC FLAGS_REG)
10573         (compare:CCC
10574           (zero_extract:SWI48
10575             (match_operand:SWI48 0 "register_operand" "r")
10576             (const_int 1)
10577             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10578           (const_int 0)))]
10579   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10580   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10581   [(set_attr "type" "alu1")
10582    (set_attr "prefix_0f" "1")
10583    (set_attr "mode" "<MODE>")])
10584 \f
10585 ;; Store-flag instructions.
10586
10587 ;; For all sCOND expanders, also expand the compare or test insn that
10588 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10589
10590 (define_insn_and_split "*setcc_di_1"
10591   [(set (match_operand:DI 0 "register_operand" "=q")
10592         (match_operator:DI 1 "ix86_comparison_operator"
10593           [(reg FLAGS_REG) (const_int 0)]))]
10594   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10595   "#"
10596   "&& reload_completed"
10597   [(set (match_dup 2) (match_dup 1))
10598    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10599 {
10600   PUT_MODE (operands[1], QImode);
10601   operands[2] = gen_lowpart (QImode, operands[0]);
10602 })
10603
10604 (define_insn_and_split "*setcc_si_1_and"
10605   [(set (match_operand:SI 0 "register_operand" "=q")
10606         (match_operator:SI 1 "ix86_comparison_operator"
10607           [(reg FLAGS_REG) (const_int 0)]))
10608    (clobber (reg:CC FLAGS_REG))]
10609   "!TARGET_PARTIAL_REG_STALL
10610    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10611   "#"
10612   "&& reload_completed"
10613   [(set (match_dup 2) (match_dup 1))
10614    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10615               (clobber (reg:CC FLAGS_REG))])]
10616 {
10617   PUT_MODE (operands[1], QImode);
10618   operands[2] = gen_lowpart (QImode, operands[0]);
10619 })
10620
10621 (define_insn_and_split "*setcc_si_1_movzbl"
10622   [(set (match_operand:SI 0 "register_operand" "=q")
10623         (match_operator:SI 1 "ix86_comparison_operator"
10624           [(reg FLAGS_REG) (const_int 0)]))]
10625   "!TARGET_PARTIAL_REG_STALL
10626    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10627   "#"
10628   "&& reload_completed"
10629   [(set (match_dup 2) (match_dup 1))
10630    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10631 {
10632   PUT_MODE (operands[1], QImode);
10633   operands[2] = gen_lowpart (QImode, operands[0]);
10634 })
10635
10636 (define_insn "*setcc_qi"
10637   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10638         (match_operator:QI 1 "ix86_comparison_operator"
10639           [(reg FLAGS_REG) (const_int 0)]))]
10640   ""
10641   "set%C1\t%0"
10642   [(set_attr "type" "setcc")
10643    (set_attr "mode" "QI")])
10644
10645 (define_insn "*setcc_qi_slp"
10646   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10647         (match_operator:QI 1 "ix86_comparison_operator"
10648           [(reg FLAGS_REG) (const_int 0)]))]
10649   ""
10650   "set%C1\t%0"
10651   [(set_attr "type" "setcc")
10652    (set_attr "mode" "QI")])
10653
10654 ;; In general it is not safe to assume too much about CCmode registers,
10655 ;; so simplify-rtx stops when it sees a second one.  Under certain
10656 ;; conditions this is safe on x86, so help combine not create
10657 ;;
10658 ;;      seta    %al
10659 ;;      testb   %al, %al
10660 ;;      sete    %al
10661
10662 (define_split
10663   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10664         (ne:QI (match_operator 1 "ix86_comparison_operator"
10665                  [(reg FLAGS_REG) (const_int 0)])
10666             (const_int 0)))]
10667   ""
10668   [(set (match_dup 0) (match_dup 1))]
10669   "PUT_MODE (operands[1], QImode);")
10670
10671 (define_split
10672   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10673         (ne:QI (match_operator 1 "ix86_comparison_operator"
10674                  [(reg FLAGS_REG) (const_int 0)])
10675             (const_int 0)))]
10676   ""
10677   [(set (match_dup 0) (match_dup 1))]
10678   "PUT_MODE (operands[1], QImode);")
10679
10680 (define_split
10681   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10682         (eq:QI (match_operator 1 "ix86_comparison_operator"
10683                  [(reg FLAGS_REG) (const_int 0)])
10684             (const_int 0)))]
10685   ""
10686   [(set (match_dup 0) (match_dup 1))]
10687 {
10688   rtx new_op1 = copy_rtx (operands[1]);
10689   operands[1] = new_op1;
10690   PUT_MODE (new_op1, QImode);
10691   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10692                                              GET_MODE (XEXP (new_op1, 0))));
10693
10694   /* Make sure that (a) the CCmode we have for the flags is strong
10695      enough for the reversed compare or (b) we have a valid FP compare.  */
10696   if (! ix86_comparison_operator (new_op1, VOIDmode))
10697     FAIL;
10698 })
10699
10700 (define_split
10701   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10702         (eq:QI (match_operator 1 "ix86_comparison_operator"
10703                  [(reg FLAGS_REG) (const_int 0)])
10704             (const_int 0)))]
10705   ""
10706   [(set (match_dup 0) (match_dup 1))]
10707 {
10708   rtx new_op1 = copy_rtx (operands[1]);
10709   operands[1] = new_op1;
10710   PUT_MODE (new_op1, QImode);
10711   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10712                                              GET_MODE (XEXP (new_op1, 0))));
10713
10714   /* Make sure that (a) the CCmode we have for the flags is strong
10715      enough for the reversed compare or (b) we have a valid FP compare.  */
10716   if (! ix86_comparison_operator (new_op1, VOIDmode))
10717     FAIL;
10718 })
10719
10720 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10721 ;; subsequent logical operations are used to imitate conditional moves.
10722 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10723 ;; it directly.
10724
10725 (define_insn "setcc_<mode>_sse"
10726   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10727         (match_operator:MODEF 3 "sse_comparison_operator"
10728           [(match_operand:MODEF 1 "register_operand" "0,x")
10729            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10730   "SSE_FLOAT_MODE_P (<MODE>mode)"
10731   "@
10732    cmp%D3s<ssemodefsuffix>\t{%2, %0|%0, %2}
10733    vcmp%D3s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
10734   [(set_attr "isa" "noavx,avx")
10735    (set_attr "type" "ssecmp")
10736    (set_attr "length_immediate" "1")
10737    (set_attr "prefix" "orig,vex")
10738    (set_attr "mode" "<MODE>")])
10739 \f
10740 ;; Basic conditional jump instructions.
10741 ;; We ignore the overflow flag for signed branch instructions.
10742
10743 (define_insn "*jcc_1"
10744   [(set (pc)
10745         (if_then_else (match_operator 1 "ix86_comparison_operator"
10746                                       [(reg FLAGS_REG) (const_int 0)])
10747                       (label_ref (match_operand 0 "" ""))
10748                       (pc)))]
10749   ""
10750   "%+j%C1\t%l0"
10751   [(set_attr "type" "ibr")
10752    (set_attr "modrm" "0")
10753    (set (attr "length")
10754            (if_then_else (and (ge (minus (match_dup 0) (pc))
10755                                   (const_int -126))
10756                               (lt (minus (match_dup 0) (pc))
10757                                   (const_int 128)))
10758              (const_int 2)
10759              (const_int 6)))])
10760
10761 (define_insn "*jcc_2"
10762   [(set (pc)
10763         (if_then_else (match_operator 1 "ix86_comparison_operator"
10764                                       [(reg FLAGS_REG) (const_int 0)])
10765                       (pc)
10766                       (label_ref (match_operand 0 "" ""))))]
10767   ""
10768   "%+j%c1\t%l0"
10769   [(set_attr "type" "ibr")
10770    (set_attr "modrm" "0")
10771    (set (attr "length")
10772            (if_then_else (and (ge (minus (match_dup 0) (pc))
10773                                   (const_int -126))
10774                               (lt (minus (match_dup 0) (pc))
10775                                   (const_int 128)))
10776              (const_int 2)
10777              (const_int 6)))])
10778
10779 ;; In general it is not safe to assume too much about CCmode registers,
10780 ;; so simplify-rtx stops when it sees a second one.  Under certain
10781 ;; conditions this is safe on x86, so help combine not create
10782 ;;
10783 ;;      seta    %al
10784 ;;      testb   %al, %al
10785 ;;      je      Lfoo
10786
10787 (define_split
10788   [(set (pc)
10789         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10790                                       [(reg FLAGS_REG) (const_int 0)])
10791                           (const_int 0))
10792                       (label_ref (match_operand 1 "" ""))
10793                       (pc)))]
10794   ""
10795   [(set (pc)
10796         (if_then_else (match_dup 0)
10797                       (label_ref (match_dup 1))
10798                       (pc)))]
10799   "PUT_MODE (operands[0], VOIDmode);")
10800
10801 (define_split
10802   [(set (pc)
10803         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10804                                       [(reg FLAGS_REG) (const_int 0)])
10805                           (const_int 0))
10806                       (label_ref (match_operand 1 "" ""))
10807                       (pc)))]
10808   ""
10809   [(set (pc)
10810         (if_then_else (match_dup 0)
10811                       (label_ref (match_dup 1))
10812                       (pc)))]
10813 {
10814   rtx new_op0 = copy_rtx (operands[0]);
10815   operands[0] = new_op0;
10816   PUT_MODE (new_op0, VOIDmode);
10817   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10818                                              GET_MODE (XEXP (new_op0, 0))));
10819
10820   /* Make sure that (a) the CCmode we have for the flags is strong
10821      enough for the reversed compare or (b) we have a valid FP compare.  */
10822   if (! ix86_comparison_operator (new_op0, VOIDmode))
10823     FAIL;
10824 })
10825
10826 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10827 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10828 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10829 ;; appropriate modulo of the bit offset value.
10830
10831 (define_insn_and_split "*jcc_bt<mode>"
10832   [(set (pc)
10833         (if_then_else (match_operator 0 "bt_comparison_operator"
10834                         [(zero_extract:SWI48
10835                            (match_operand:SWI48 1 "register_operand" "r")
10836                            (const_int 1)
10837                            (zero_extend:SI
10838                              (match_operand:QI 2 "register_operand" "r")))
10839                          (const_int 0)])
10840                       (label_ref (match_operand 3 "" ""))
10841                       (pc)))
10842    (clobber (reg:CC FLAGS_REG))]
10843   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10844   "#"
10845   "&& 1"
10846   [(set (reg:CCC FLAGS_REG)
10847         (compare:CCC
10848           (zero_extract:SWI48
10849             (match_dup 1)
10850             (const_int 1)
10851             (match_dup 2))
10852           (const_int 0)))
10853    (set (pc)
10854         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10855                       (label_ref (match_dup 3))
10856                       (pc)))]
10857 {
10858   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10859
10860   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10861 })
10862
10863 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10864 ;; also for DImode, this is what combine produces.
10865 (define_insn_and_split "*jcc_bt<mode>_mask"
10866   [(set (pc)
10867         (if_then_else (match_operator 0 "bt_comparison_operator"
10868                         [(zero_extract:SWI48
10869                            (match_operand:SWI48 1 "register_operand" "r")
10870                            (const_int 1)
10871                            (and:SI
10872                              (match_operand:SI 2 "register_operand" "r")
10873                              (match_operand:SI 3 "const_int_operand" "n")))])
10874                       (label_ref (match_operand 4 "" ""))
10875                       (pc)))
10876    (clobber (reg:CC FLAGS_REG))]
10877   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10878    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10879       == GET_MODE_BITSIZE (<MODE>mode)-1"
10880   "#"
10881   "&& 1"
10882   [(set (reg:CCC FLAGS_REG)
10883         (compare:CCC
10884           (zero_extract:SWI48
10885             (match_dup 1)
10886             (const_int 1)
10887             (match_dup 2))
10888           (const_int 0)))
10889    (set (pc)
10890         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10891                       (label_ref (match_dup 4))
10892                       (pc)))]
10893 {
10894   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10895
10896   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10897 })
10898
10899 (define_insn_and_split "*jcc_btsi_1"
10900   [(set (pc)
10901         (if_then_else (match_operator 0 "bt_comparison_operator"
10902                         [(and:SI
10903                            (lshiftrt:SI
10904                              (match_operand:SI 1 "register_operand" "r")
10905                              (match_operand:QI 2 "register_operand" "r"))
10906                            (const_int 1))
10907                          (const_int 0)])
10908                       (label_ref (match_operand 3 "" ""))
10909                       (pc)))
10910    (clobber (reg:CC FLAGS_REG))]
10911   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10912   "#"
10913   "&& 1"
10914   [(set (reg:CCC FLAGS_REG)
10915         (compare:CCC
10916           (zero_extract:SI
10917             (match_dup 1)
10918             (const_int 1)
10919             (match_dup 2))
10920           (const_int 0)))
10921    (set (pc)
10922         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10923                       (label_ref (match_dup 3))
10924                       (pc)))]
10925 {
10926   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10927
10928   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10929 })
10930
10931 ;; avoid useless masking of bit offset operand
10932 (define_insn_and_split "*jcc_btsi_mask_1"
10933   [(set (pc)
10934         (if_then_else
10935           (match_operator 0 "bt_comparison_operator"
10936             [(and:SI
10937                (lshiftrt:SI
10938                  (match_operand:SI 1 "register_operand" "r")
10939                  (subreg:QI
10940                    (and:SI
10941                      (match_operand:SI 2 "register_operand" "r")
10942                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10943                (const_int 1))
10944              (const_int 0)])
10945           (label_ref (match_operand 4 "" ""))
10946           (pc)))
10947    (clobber (reg:CC FLAGS_REG))]
10948   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10949    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10950   "#"
10951   "&& 1"
10952   [(set (reg:CCC FLAGS_REG)
10953         (compare:CCC
10954           (zero_extract:SI
10955             (match_dup 1)
10956             (const_int 1)
10957             (match_dup 2))
10958           (const_int 0)))
10959    (set (pc)
10960         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10961                       (label_ref (match_dup 4))
10962                       (pc)))]
10963   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10964
10965 ;; Define combination compare-and-branch fp compare instructions to help
10966 ;; combine.
10967
10968 (define_insn "*fp_jcc_1_387"
10969   [(set (pc)
10970         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10971                         [(match_operand 1 "register_operand" "f")
10972                          (match_operand 2 "nonimmediate_operand" "fm")])
10973           (label_ref (match_operand 3 "" ""))
10974           (pc)))
10975    (clobber (reg:CCFP FPSR_REG))
10976    (clobber (reg:CCFP FLAGS_REG))
10977    (clobber (match_scratch:HI 4 "=a"))]
10978   "TARGET_80387
10979    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10980    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10981    && SELECT_CC_MODE (GET_CODE (operands[0]),
10982                       operands[1], operands[2]) == CCFPmode
10983    && !TARGET_CMOVE"
10984   "#")
10985
10986 (define_insn "*fp_jcc_1r_387"
10987   [(set (pc)
10988         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10989                         [(match_operand 1 "register_operand" "f")
10990                          (match_operand 2 "nonimmediate_operand" "fm")])
10991           (pc)
10992           (label_ref (match_operand 3 "" ""))))
10993    (clobber (reg:CCFP FPSR_REG))
10994    (clobber (reg:CCFP FLAGS_REG))
10995    (clobber (match_scratch:HI 4 "=a"))]
10996   "TARGET_80387
10997    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10998    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10999    && SELECT_CC_MODE (GET_CODE (operands[0]),
11000                       operands[1], operands[2]) == CCFPmode
11001    && !TARGET_CMOVE"
11002   "#")
11003
11004 (define_insn "*fp_jcc_2_387"
11005   [(set (pc)
11006         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11007                         [(match_operand 1 "register_operand" "f")
11008                          (match_operand 2 "register_operand" "f")])
11009           (label_ref (match_operand 3 "" ""))
11010           (pc)))
11011    (clobber (reg:CCFP FPSR_REG))
11012    (clobber (reg:CCFP FLAGS_REG))
11013    (clobber (match_scratch:HI 4 "=a"))]
11014   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11015    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11016    && !TARGET_CMOVE"
11017   "#")
11018
11019 (define_insn "*fp_jcc_2r_387"
11020   [(set (pc)
11021         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11022                         [(match_operand 1 "register_operand" "f")
11023                          (match_operand 2 "register_operand" "f")])
11024           (pc)
11025           (label_ref (match_operand 3 "" ""))))
11026    (clobber (reg:CCFP FPSR_REG))
11027    (clobber (reg:CCFP FLAGS_REG))
11028    (clobber (match_scratch:HI 4 "=a"))]
11029   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11030    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11031    && !TARGET_CMOVE"
11032   "#")
11033
11034 (define_insn "*fp_jcc_3_387"
11035   [(set (pc)
11036         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11037                         [(match_operand 1 "register_operand" "f")
11038                          (match_operand 2 "const0_operand" "")])
11039           (label_ref (match_operand 3 "" ""))
11040           (pc)))
11041    (clobber (reg:CCFP FPSR_REG))
11042    (clobber (reg:CCFP FLAGS_REG))
11043    (clobber (match_scratch:HI 4 "=a"))]
11044   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11045    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11046    && SELECT_CC_MODE (GET_CODE (operands[0]),
11047                       operands[1], operands[2]) == CCFPmode
11048    && !TARGET_CMOVE"
11049   "#")
11050
11051 (define_split
11052   [(set (pc)
11053         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11054                         [(match_operand 1 "register_operand" "")
11055                          (match_operand 2 "nonimmediate_operand" "")])
11056           (match_operand 3 "" "")
11057           (match_operand 4 "" "")))
11058    (clobber (reg:CCFP FPSR_REG))
11059    (clobber (reg:CCFP FLAGS_REG))]
11060   "reload_completed"
11061   [(const_int 0)]
11062 {
11063   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11064                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11065   DONE;
11066 })
11067
11068 (define_split
11069   [(set (pc)
11070         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11071                         [(match_operand 1 "register_operand" "")
11072                          (match_operand 2 "general_operand" "")])
11073           (match_operand 3 "" "")
11074           (match_operand 4 "" "")))
11075    (clobber (reg:CCFP FPSR_REG))
11076    (clobber (reg:CCFP FLAGS_REG))
11077    (clobber (match_scratch:HI 5 "=a"))]
11078   "reload_completed"
11079   [(const_int 0)]
11080 {
11081   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11082                         operands[3], operands[4], operands[5], NULL_RTX);
11083   DONE;
11084 })
11085
11086 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11087 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11088 ;; with a precedence over other operators and is always put in the first
11089 ;; place. Swap condition and operands to match ficom instruction.
11090
11091 (define_insn "*fp_jcc_4_<mode>_387"
11092   [(set (pc)
11093         (if_then_else
11094           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11095             [(match_operator 1 "float_operator"
11096               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11097              (match_operand 3 "register_operand" "f,f")])
11098           (label_ref (match_operand 4 "" ""))
11099           (pc)))
11100    (clobber (reg:CCFP FPSR_REG))
11101    (clobber (reg:CCFP FLAGS_REG))
11102    (clobber (match_scratch:HI 5 "=a,a"))]
11103   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11104    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11105    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11106    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11107    && !TARGET_CMOVE"
11108   "#")
11109
11110 (define_split
11111   [(set (pc)
11112         (if_then_else
11113           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11114             [(match_operator 1 "float_operator"
11115               [(match_operand:X87MODEI12 2 "memory_operand" "")])
11116              (match_operand 3 "register_operand" "")])
11117           (match_operand 4 "" "")
11118           (match_operand 5 "" "")))
11119    (clobber (reg:CCFP FPSR_REG))
11120    (clobber (reg:CCFP FLAGS_REG))
11121    (clobber (match_scratch:HI 6 "=a"))]
11122   "reload_completed"
11123   [(const_int 0)]
11124 {
11125   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11126
11127   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11128                         operands[3], operands[7],
11129                         operands[4], operands[5], operands[6], NULL_RTX);
11130   DONE;
11131 })
11132
11133 ;; %%% Kill this when reload knows how to do it.
11134 (define_split
11135   [(set (pc)
11136         (if_then_else
11137           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11138             [(match_operator 1 "float_operator"
11139               [(match_operand:X87MODEI12 2 "register_operand" "")])
11140              (match_operand 3 "register_operand" "")])
11141           (match_operand 4 "" "")
11142           (match_operand 5 "" "")))
11143    (clobber (reg:CCFP FPSR_REG))
11144    (clobber (reg:CCFP FLAGS_REG))
11145    (clobber (match_scratch:HI 6 "=a"))]
11146   "reload_completed"
11147   [(const_int 0)]
11148 {
11149   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11150   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11151
11152   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11153                         operands[3], operands[7],
11154                         operands[4], operands[5], operands[6], operands[2]);
11155   DONE;
11156 })
11157 \f
11158 ;; Unconditional and other jump instructions
11159
11160 (define_insn "jump"
11161   [(set (pc)
11162         (label_ref (match_operand 0 "" "")))]
11163   ""
11164   "jmp\t%l0"
11165   [(set_attr "type" "ibr")
11166    (set (attr "length")
11167            (if_then_else (and (ge (minus (match_dup 0) (pc))
11168                                   (const_int -126))
11169                               (lt (minus (match_dup 0) (pc))
11170                                   (const_int 128)))
11171              (const_int 2)
11172              (const_int 5)))
11173    (set_attr "modrm" "0")])
11174
11175 (define_expand "indirect_jump"
11176   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11177   ""
11178   "")
11179
11180 (define_insn "*indirect_jump"
11181   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11182   ""
11183   "jmp\t%A0"
11184   [(set_attr "type" "ibr")
11185    (set_attr "length_immediate" "0")])
11186
11187 (define_expand "tablejump"
11188   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11189               (use (label_ref (match_operand 1 "" "")))])]
11190   ""
11191 {
11192   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11193      relative.  Convert the relative address to an absolute address.  */
11194   if (flag_pic)
11195     {
11196       rtx op0, op1;
11197       enum rtx_code code;
11198
11199       /* We can't use @GOTOFF for text labels on VxWorks;
11200          see gotoff_operand.  */
11201       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11202         {
11203           code = PLUS;
11204           op0 = operands[0];
11205           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11206         }
11207       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11208         {
11209           code = PLUS;
11210           op0 = operands[0];
11211           op1 = pic_offset_table_rtx;
11212         }
11213       else
11214         {
11215           code = MINUS;
11216           op0 = pic_offset_table_rtx;
11217           op1 = operands[0];
11218         }
11219
11220       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11221                                          OPTAB_DIRECT);
11222     }
11223 })
11224
11225 (define_insn "*tablejump_1"
11226   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11227    (use (label_ref (match_operand 1 "" "")))]
11228   ""
11229   "jmp\t%A0"
11230   [(set_attr "type" "ibr")
11231    (set_attr "length_immediate" "0")])
11232 \f
11233 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11234
11235 (define_peephole2
11236   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11237    (set (match_operand:QI 1 "register_operand" "")
11238         (match_operator:QI 2 "ix86_comparison_operator"
11239           [(reg FLAGS_REG) (const_int 0)]))
11240    (set (match_operand 3 "q_regs_operand" "")
11241         (zero_extend (match_dup 1)))]
11242   "(peep2_reg_dead_p (3, operands[1])
11243     || operands_match_p (operands[1], operands[3]))
11244    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11245   [(set (match_dup 4) (match_dup 0))
11246    (set (strict_low_part (match_dup 5))
11247         (match_dup 2))]
11248 {
11249   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11250   operands[5] = gen_lowpart (QImode, operands[3]);
11251   ix86_expand_clear (operands[3]);
11252 })
11253
11254 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11255
11256 (define_peephole2
11257   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11258    (set (match_operand:QI 1 "register_operand" "")
11259         (match_operator:QI 2 "ix86_comparison_operator"
11260           [(reg FLAGS_REG) (const_int 0)]))
11261    (parallel [(set (match_operand 3 "q_regs_operand" "")
11262                    (zero_extend (match_dup 1)))
11263               (clobber (reg:CC FLAGS_REG))])]
11264   "(peep2_reg_dead_p (3, operands[1])
11265     || operands_match_p (operands[1], operands[3]))
11266    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11267   [(set (match_dup 4) (match_dup 0))
11268    (set (strict_low_part (match_dup 5))
11269         (match_dup 2))]
11270 {
11271   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11272   operands[5] = gen_lowpart (QImode, operands[3]);
11273   ix86_expand_clear (operands[3]);
11274 })
11275 \f
11276 ;; Call instructions.
11277
11278 ;; The predicates normally associated with named expanders are not properly
11279 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11280 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11281
11282 ;; P6 processors will jump to the address after the decrement when %esp
11283 ;; is used as a call operand, so they will execute return address as a code.
11284 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11285  
11286 ;; Call subroutine returning no value.
11287
11288 (define_expand "call_pop"
11289   [(parallel [(call (match_operand:QI 0 "" "")
11290                     (match_operand:SI 1 "" ""))
11291               (set (reg:SI SP_REG)
11292                    (plus:SI (reg:SI SP_REG)
11293                             (match_operand:SI 3 "" "")))])]
11294   "!TARGET_64BIT"
11295 {
11296   ix86_expand_call (NULL, operands[0], operands[1],
11297                     operands[2], operands[3], 0);
11298   DONE;
11299 })
11300
11301 (define_insn_and_split "*call_pop_0_vzeroupper"
11302   [(parallel
11303     [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11304            (match_operand:SI 1 "" ""))
11305      (set (reg:SI SP_REG)
11306           (plus:SI (reg:SI SP_REG)
11307                    (match_operand:SI 2 "immediate_operand" "")))])
11308    (unspec [(match_operand 3 "const_int_operand" "")]
11309            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11310   "TARGET_VZEROUPPER && !TARGET_64BIT"
11311   "#"
11312   "&& reload_completed"
11313   [(const_int 0)]
11314   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11315   [(set_attr "type" "call")])
11316
11317 (define_insn "*call_pop_0"
11318   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11319          (match_operand:SI 1 "" ""))
11320    (set (reg:SI SP_REG)
11321         (plus:SI (reg:SI SP_REG)
11322                  (match_operand:SI 2 "immediate_operand" "")))]
11323   "!TARGET_64BIT"
11324 {
11325   if (SIBLING_CALL_P (insn))
11326     return "jmp\t%P0";
11327   else
11328     return "call\t%P0";
11329 }
11330   [(set_attr "type" "call")])
11331
11332 (define_insn_and_split "*call_pop_1_vzeroupper"
11333   [(parallel
11334     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11335            (match_operand:SI 1 "" ""))
11336      (set (reg:SI SP_REG)
11337           (plus:SI (reg:SI SP_REG)
11338                    (match_operand:SI 2 "immediate_operand" "i")))])
11339    (unspec [(match_operand 3 "const_int_operand" "")]
11340            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11341   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11342   "#"
11343   "&& reload_completed"
11344   [(const_int 0)]
11345   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11346   [(set_attr "type" "call")])
11347
11348 (define_insn "*call_pop_1"
11349   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11350          (match_operand:SI 1 "" ""))
11351    (set (reg:SI SP_REG)
11352         (plus:SI (reg:SI SP_REG)
11353                  (match_operand:SI 2 "immediate_operand" "i")))]
11354   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11355 {
11356   if (constant_call_address_operand (operands[0], Pmode))
11357     return "call\t%P0";
11358   return "call\t%A0";
11359 }
11360   [(set_attr "type" "call")])
11361
11362 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11363  [(parallel
11364    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11365            (match_operand:SI 1 "" ""))
11366      (set (reg:SI SP_REG)
11367           (plus:SI (reg:SI SP_REG)
11368                    (match_operand:SI 2 "immediate_operand" "i,i")))])
11369    (unspec [(match_operand 3 "const_int_operand" "")]
11370            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11371   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11372   "#"
11373   "&& reload_completed"
11374   [(const_int 0)]
11375   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11376   [(set_attr "type" "call")])
11377
11378 (define_insn "*sibcall_pop_1"
11379   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11380          (match_operand:SI 1 "" ""))
11381    (set (reg:SI SP_REG)
11382         (plus:SI (reg:SI SP_REG)
11383                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11384   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11385   "@
11386    jmp\t%P0
11387    jmp\t%A0"
11388   [(set_attr "type" "call")])
11389
11390 (define_expand "call"
11391   [(call (match_operand:QI 0 "" "")
11392          (match_operand 1 "" ""))
11393    (use (match_operand 2 "" ""))]
11394   ""
11395 {
11396   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11397   DONE;
11398 })
11399
11400 (define_expand "sibcall"
11401   [(call (match_operand:QI 0 "" "")
11402          (match_operand 1 "" ""))
11403    (use (match_operand 2 "" ""))]
11404   ""
11405 {
11406   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11407   DONE;
11408 })
11409
11410 (define_insn_and_split "*call_0_vzeroupper"
11411   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11412          (match_operand 1 "" ""))
11413    (unspec [(match_operand 2 "const_int_operand" "")]
11414            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11415   "TARGET_VZEROUPPER"
11416   "#"
11417   "&& reload_completed"
11418   [(const_int 0)]
11419   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11420   [(set_attr "type" "call")])
11421
11422 (define_insn "*call_0"
11423   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11424          (match_operand 1 "" ""))]
11425   ""
11426   { return ix86_output_call_insn (insn, operands[0], 0); }
11427   [(set_attr "type" "call")])
11428
11429 (define_insn_and_split "*call_1_vzeroupper"
11430   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11431          (match_operand 1 "" ""))
11432    (unspec [(match_operand 2 "const_int_operand" "")]
11433            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11434   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11435   "#"
11436   "&& reload_completed"
11437   [(const_int 0)]
11438   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11439   [(set_attr "type" "call")])
11440
11441 (define_insn "*call_1"
11442   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11443          (match_operand 1 "" ""))]
11444   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11445   { return ix86_output_call_insn (insn, operands[0], 0); }
11446   [(set_attr "type" "call")])
11447
11448 (define_insn_and_split "*sibcall_1_vzeroupper"
11449   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11450          (match_operand 1 "" ""))
11451    (unspec [(match_operand 2 "const_int_operand" "")]
11452            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11453   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11454   "#"
11455   "&& reload_completed"
11456   [(const_int 0)]
11457   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11458   [(set_attr "type" "call")])
11459
11460 (define_insn "*sibcall_1"
11461   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11462          (match_operand 1 "" ""))]
11463   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11464   { return ix86_output_call_insn (insn, operands[0], 0); }
11465   [(set_attr "type" "call")])
11466
11467 (define_insn_and_split "*call_1_rex64_vzeroupper"
11468   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11469          (match_operand 1 "" ""))
11470    (unspec [(match_operand 2 "const_int_operand" "")]
11471            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11472   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11473    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11474   "#"
11475   "&& reload_completed"
11476   [(const_int 0)]
11477   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11478   [(set_attr "type" "call")])
11479
11480 (define_insn "*call_1_rex64"
11481   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11482          (match_operand 1 "" ""))]
11483   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11484    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11485   { return ix86_output_call_insn (insn, operands[0], 0); }
11486   [(set_attr "type" "call")])
11487
11488 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11489   [(parallel
11490     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11491            (match_operand 1 "" ""))
11492      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11493      (clobber (reg:TI XMM6_REG))
11494      (clobber (reg:TI XMM7_REG))
11495      (clobber (reg:TI XMM8_REG))
11496      (clobber (reg:TI XMM9_REG))
11497      (clobber (reg:TI XMM10_REG))
11498      (clobber (reg:TI XMM11_REG))
11499      (clobber (reg:TI XMM12_REG))
11500      (clobber (reg:TI XMM13_REG))
11501      (clobber (reg:TI XMM14_REG))
11502      (clobber (reg:TI XMM15_REG))
11503      (clobber (reg:DI SI_REG))
11504      (clobber (reg:DI DI_REG))])
11505    (unspec [(match_operand 2 "const_int_operand" "")]
11506            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11507   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11508   "#"
11509   "&& reload_completed"
11510   [(const_int 0)]
11511   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11512   [(set_attr "type" "call")])
11513
11514 (define_insn "*call_1_rex64_ms_sysv"
11515   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11516          (match_operand 1 "" ""))
11517    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11518    (clobber (reg:TI XMM6_REG))
11519    (clobber (reg:TI XMM7_REG))
11520    (clobber (reg:TI XMM8_REG))
11521    (clobber (reg:TI XMM9_REG))
11522    (clobber (reg:TI XMM10_REG))
11523    (clobber (reg:TI XMM11_REG))
11524    (clobber (reg:TI XMM12_REG))
11525    (clobber (reg:TI XMM13_REG))
11526    (clobber (reg:TI XMM14_REG))
11527    (clobber (reg:TI XMM15_REG))
11528    (clobber (reg:DI SI_REG))
11529    (clobber (reg:DI DI_REG))]
11530   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11531   { return ix86_output_call_insn (insn, operands[0], 0); }
11532   [(set_attr "type" "call")])
11533
11534 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11535   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11536          (match_operand 1 "" ""))
11537    (unspec [(match_operand 2 "const_int_operand" "")]
11538            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11539   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11540   "#"
11541   "&& reload_completed"
11542   [(const_int 0)]
11543   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11544   [(set_attr "type" "call")])
11545
11546 (define_insn "*call_1_rex64_large"
11547   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11548          (match_operand 1 "" ""))]
11549   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11550   { return ix86_output_call_insn (insn, operands[0], 0); }
11551   [(set_attr "type" "call")])
11552
11553 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11554   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11555          (match_operand 1 "" ""))
11556    (unspec [(match_operand 2 "const_int_operand" "")]
11557            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11558   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11559   "#"
11560   "&& reload_completed"
11561   [(const_int 0)]
11562   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11563   [(set_attr "type" "call")])
11564
11565 (define_insn "*sibcall_1_rex64"
11566   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11567          (match_operand 1 "" ""))]
11568   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11569   { return ix86_output_call_insn (insn, operands[0], 0); }
11570   [(set_attr "type" "call")])
11571
11572 ;; Call subroutine, returning value in operand 0
11573 (define_expand "call_value_pop"
11574   [(parallel [(set (match_operand 0 "" "")
11575                    (call (match_operand:QI 1 "" "")
11576                          (match_operand:SI 2 "" "")))
11577               (set (reg:SI SP_REG)
11578                    (plus:SI (reg:SI SP_REG)
11579                             (match_operand:SI 4 "" "")))])]
11580   "!TARGET_64BIT"
11581 {
11582   ix86_expand_call (operands[0], operands[1], operands[2],
11583                     operands[3], operands[4], 0);
11584   DONE;
11585 })
11586
11587 (define_expand "call_value"
11588   [(set (match_operand 0 "" "")
11589         (call (match_operand:QI 1 "" "")
11590               (match_operand:SI 2 "" "")))
11591    (use (match_operand:SI 3 "" ""))]
11592   ;; Operand 3 is not used on the i386.
11593   ""
11594 {
11595   ix86_expand_call (operands[0], operands[1], operands[2],
11596                     operands[3], NULL, 0);
11597   DONE;
11598 })
11599
11600 (define_expand "sibcall_value"
11601   [(set (match_operand 0 "" "")
11602         (call (match_operand:QI 1 "" "")
11603               (match_operand:SI 2 "" "")))
11604    (use (match_operand:SI 3 "" ""))]
11605   ;; Operand 3 is not used on the i386.
11606   ""
11607 {
11608   ix86_expand_call (operands[0], operands[1], operands[2],
11609                     operands[3], NULL, 1);
11610   DONE;
11611 })
11612
11613 ;; Call subroutine returning any type.
11614
11615 (define_expand "untyped_call"
11616   [(parallel [(call (match_operand 0 "" "")
11617                     (const_int 0))
11618               (match_operand 1 "" "")
11619               (match_operand 2 "" "")])]
11620   ""
11621 {
11622   int i;
11623
11624   /* In order to give reg-stack an easier job in validating two
11625      coprocessor registers as containing a possible return value,
11626      simply pretend the untyped call returns a complex long double
11627      value. 
11628
11629      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11630      and should have the default ABI.  */
11631
11632   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11633                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11634                     operands[0], const0_rtx,
11635                     GEN_INT ((TARGET_64BIT
11636                               ? (ix86_abi == SYSV_ABI
11637                                  ? X86_64_SSE_REGPARM_MAX
11638                                  : X86_64_MS_SSE_REGPARM_MAX)
11639                               : X86_32_SSE_REGPARM_MAX)
11640                              - 1),
11641                     NULL, 0);
11642
11643   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11644     {
11645       rtx set = XVECEXP (operands[2], 0, i);
11646       emit_move_insn (SET_DEST (set), SET_SRC (set));
11647     }
11648
11649   /* The optimizer does not know that the call sets the function value
11650      registers we stored in the result block.  We avoid problems by
11651      claiming that all hard registers are used and clobbered at this
11652      point.  */
11653   emit_insn (gen_blockage ());
11654
11655   DONE;
11656 })
11657 \f
11658 ;; Prologue and epilogue instructions
11659
11660 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11661 ;; all of memory.  This blocks insns from being moved across this point.
11662
11663 (define_insn "blockage"
11664   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11665   ""
11666   ""
11667   [(set_attr "length" "0")])
11668
11669 ;; Do not schedule instructions accessing memory across this point.
11670
11671 (define_expand "memory_blockage"
11672   [(set (match_dup 0)
11673         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11674   ""
11675 {
11676   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11677   MEM_VOLATILE_P (operands[0]) = 1;
11678 })
11679
11680 (define_insn "*memory_blockage"
11681   [(set (match_operand:BLK 0 "" "")
11682         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11683   ""
11684   ""
11685   [(set_attr "length" "0")])
11686
11687 ;; As USE insns aren't meaningful after reload, this is used instead
11688 ;; to prevent deleting instructions setting registers for PIC code
11689 (define_insn "prologue_use"
11690   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11691   ""
11692   ""
11693   [(set_attr "length" "0")])
11694
11695 ;; Insn emitted into the body of a function to return from a function.
11696 ;; This is only done if the function's epilogue is known to be simple.
11697 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11698
11699 (define_expand "return"
11700   [(return)]
11701   "ix86_can_use_return_insn_p ()"
11702 {
11703   if (crtl->args.pops_args)
11704     {
11705       rtx popc = GEN_INT (crtl->args.pops_args);
11706       emit_jump_insn (gen_return_pop_internal (popc));
11707       DONE;
11708     }
11709 })
11710
11711 (define_insn "return_internal"
11712   [(return)]
11713   "reload_completed"
11714   "ret"
11715   [(set_attr "length" "1")
11716    (set_attr "atom_unit" "jeu")
11717    (set_attr "length_immediate" "0")
11718    (set_attr "modrm" "0")])
11719
11720 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11721 ;; instruction Athlon and K8 have.
11722
11723 (define_insn "return_internal_long"
11724   [(return)
11725    (unspec [(const_int 0)] UNSPEC_REP)]
11726   "reload_completed"
11727   "rep\;ret"
11728   [(set_attr "length" "2")
11729    (set_attr "atom_unit" "jeu")
11730    (set_attr "length_immediate" "0")
11731    (set_attr "prefix_rep" "1")
11732    (set_attr "modrm" "0")])
11733
11734 (define_insn "return_pop_internal"
11735   [(return)
11736    (use (match_operand:SI 0 "const_int_operand" ""))]
11737   "reload_completed"
11738   "ret\t%0"
11739   [(set_attr "length" "3")
11740    (set_attr "atom_unit" "jeu")
11741    (set_attr "length_immediate" "2")
11742    (set_attr "modrm" "0")])
11743
11744 (define_insn "return_indirect_internal"
11745   [(return)
11746    (use (match_operand:SI 0 "register_operand" "r"))]
11747   "reload_completed"
11748   "jmp\t%A0"
11749   [(set_attr "type" "ibr")
11750    (set_attr "length_immediate" "0")])
11751
11752 (define_insn "nop"
11753   [(const_int 0)]
11754   ""
11755   "nop"
11756   [(set_attr "length" "1")
11757    (set_attr "length_immediate" "0")
11758    (set_attr "modrm" "0")])
11759
11760 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11761 (define_insn "nops"
11762   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11763                     UNSPECV_NOPS)]
11764   "reload_completed"
11765 {
11766   int num = INTVAL (operands[0]);
11767
11768   gcc_assert (num >= 1 && num <= 8);
11769
11770   while (num--)
11771     fputs ("\tnop\n", asm_out_file);
11772
11773   return "";
11774 }
11775   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11776    (set_attr "length_immediate" "0")
11777    (set_attr "modrm" "0")])
11778
11779 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11780 ;; branch prediction penalty for the third jump in a 16-byte
11781 ;; block on K8.
11782
11783 (define_insn "pad"
11784   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11785   ""
11786 {
11787 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11788   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11789 #else
11790   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11791      The align insn is used to avoid 3 jump instructions in the row to improve
11792      branch prediction and the benefits hardly outweigh the cost of extra 8
11793      nops on the average inserted by full alignment pseudo operation.  */
11794 #endif
11795   return "";
11796 }
11797   [(set_attr "length" "16")])
11798
11799 (define_expand "prologue"
11800   [(const_int 0)]
11801   ""
11802   "ix86_expand_prologue (); DONE;")
11803
11804 (define_insn "set_got"
11805   [(set (match_operand:SI 0 "register_operand" "=r")
11806         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "!TARGET_64BIT"
11809   "* return output_set_got (operands[0], NULL_RTX);"
11810   [(set_attr "type" "multi")
11811    (set_attr "length" "12")])
11812
11813 (define_insn "set_got_labelled"
11814   [(set (match_operand:SI 0 "register_operand" "=r")
11815         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11816          UNSPEC_SET_GOT))
11817    (clobber (reg:CC FLAGS_REG))]
11818   "!TARGET_64BIT"
11819   "* return output_set_got (operands[0], operands[1]);"
11820   [(set_attr "type" "multi")
11821    (set_attr "length" "12")])
11822
11823 (define_insn "set_got_rex64"
11824   [(set (match_operand:DI 0 "register_operand" "=r")
11825         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11826   "TARGET_64BIT"
11827   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11828   [(set_attr "type" "lea")
11829    (set_attr "length_address" "4")
11830    (set_attr "mode" "DI")])
11831
11832 (define_insn "set_rip_rex64"
11833   [(set (match_operand:DI 0 "register_operand" "=r")
11834         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11835   "TARGET_64BIT"
11836   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11837   [(set_attr "type" "lea")
11838    (set_attr "length_address" "4")
11839    (set_attr "mode" "DI")])
11840
11841 (define_insn "set_got_offset_rex64"
11842   [(set (match_operand:DI 0 "register_operand" "=r")
11843         (unspec:DI
11844           [(label_ref (match_operand 1 "" ""))]
11845           UNSPEC_SET_GOT_OFFSET))]
11846   "TARGET_64BIT"
11847   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11848   [(set_attr "type" "imov")
11849    (set_attr "length_immediate" "0")
11850    (set_attr "length_address" "8")
11851    (set_attr "mode" "DI")])
11852
11853 (define_expand "epilogue"
11854   [(const_int 0)]
11855   ""
11856   "ix86_expand_epilogue (1); DONE;")
11857
11858 (define_expand "sibcall_epilogue"
11859   [(const_int 0)]
11860   ""
11861   "ix86_expand_epilogue (0); DONE;")
11862
11863 (define_expand "eh_return"
11864   [(use (match_operand 0 "register_operand" ""))]
11865   ""
11866 {
11867   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11868
11869   /* Tricky bit: we write the address of the handler to which we will
11870      be returning into someone else's stack frame, one word below the
11871      stack address we wish to restore.  */
11872   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11873   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11874   tmp = gen_rtx_MEM (Pmode, tmp);
11875   emit_move_insn (tmp, ra);
11876
11877   emit_jump_insn (gen_eh_return_internal ());
11878   emit_barrier ();
11879   DONE;
11880 })
11881
11882 (define_insn_and_split "eh_return_internal"
11883   [(eh_return)]
11884   ""
11885   "#"
11886   "epilogue_completed"
11887   [(const_int 0)]
11888   "ix86_expand_epilogue (2); DONE;")
11889
11890 (define_insn "leave"
11891   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11892    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11893    (clobber (mem:BLK (scratch)))]
11894   "!TARGET_64BIT"
11895   "leave"
11896   [(set_attr "type" "leave")])
11897
11898 (define_insn "leave_rex64"
11899   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11900    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11901    (clobber (mem:BLK (scratch)))]
11902   "TARGET_64BIT"
11903   "leave"
11904   [(set_attr "type" "leave")])
11905 \f
11906 ;; Handle -fsplit-stack.
11907
11908 (define_expand "split_stack_prologue"
11909   [(const_int 0)]
11910   ""
11911 {
11912   ix86_expand_split_stack_prologue ();
11913   DONE;
11914 })
11915
11916 ;; In order to support the call/return predictor, we use a return
11917 ;; instruction which the middle-end doesn't see.
11918 (define_insn "split_stack_return"
11919   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11920                      UNSPECV_SPLIT_STACK_RETURN)]
11921   ""
11922 {
11923   if (operands[0] == const0_rtx)
11924     return "ret";
11925   else
11926     return "ret\t%0";
11927 }
11928   [(set_attr "atom_unit" "jeu")
11929    (set_attr "modrm" "0")
11930    (set (attr "length")
11931         (if_then_else (match_operand:SI 0 "const0_operand" "")
11932                       (const_int 1)
11933                       (const_int 3)))
11934    (set (attr "length_immediate")
11935         (if_then_else (match_operand:SI 0 "const0_operand" "")
11936                       (const_int 0)
11937                       (const_int 2)))])
11938
11939 ;; If there are operand 0 bytes available on the stack, jump to
11940 ;; operand 1.
11941
11942 (define_expand "split_stack_space_check"
11943   [(set (pc) (if_then_else
11944               (ltu (minus (reg SP_REG)
11945                           (match_operand 0 "register_operand" ""))
11946                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11947               (label_ref (match_operand 1 "" ""))
11948               (pc)))]
11949   ""
11950 {
11951   rtx reg, size, limit;
11952
11953   reg = gen_reg_rtx (Pmode);
11954   size = force_reg (Pmode, operands[0]);
11955   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11956   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11957                           UNSPEC_STACK_CHECK);
11958   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11959   ix86_expand_branch (GEU, reg, limit, operands[1]);
11960
11961   DONE;
11962 })
11963 \f
11964 ;; Bit manipulation instructions.
11965
11966 (define_expand "ffs<mode>2"
11967   [(set (match_dup 2) (const_int -1))
11968    (parallel [(set (reg:CCZ FLAGS_REG)
11969                    (compare:CCZ
11970                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11971                      (const_int 0)))
11972               (set (match_operand:SWI48 0 "register_operand" "")
11973                    (ctz:SWI48 (match_dup 1)))])
11974    (set (match_dup 0) (if_then_else:SWI48
11975                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11976                         (match_dup 2)
11977                         (match_dup 0)))
11978    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11979               (clobber (reg:CC FLAGS_REG))])]
11980   ""
11981 {
11982   if (<MODE>mode == SImode && !TARGET_CMOVE)
11983     {
11984       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11985       DONE;
11986     }
11987   operands[2] = gen_reg_rtx (<MODE>mode);
11988 })
11989
11990 (define_insn_and_split "ffssi2_no_cmove"
11991   [(set (match_operand:SI 0 "register_operand" "=r")
11992         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11993    (clobber (match_scratch:SI 2 "=&q"))
11994    (clobber (reg:CC FLAGS_REG))]
11995   "!TARGET_CMOVE"
11996   "#"
11997   "&& reload_completed"
11998   [(parallel [(set (reg:CCZ FLAGS_REG)
11999                    (compare:CCZ (match_dup 1) (const_int 0)))
12000               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12001    (set (strict_low_part (match_dup 3))
12002         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12003    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12004               (clobber (reg:CC FLAGS_REG))])
12005    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12006               (clobber (reg:CC FLAGS_REG))])
12007    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12008               (clobber (reg:CC FLAGS_REG))])]
12009 {
12010   operands[3] = gen_lowpart (QImode, operands[2]);
12011   ix86_expand_clear (operands[2]);
12012 })
12013
12014 (define_insn "*ffs<mode>_1"
12015   [(set (reg:CCZ FLAGS_REG)
12016         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12017                      (const_int 0)))
12018    (set (match_operand:SWI48 0 "register_operand" "=r")
12019         (ctz:SWI48 (match_dup 1)))]
12020   ""
12021   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12022   [(set_attr "type" "alu1")
12023    (set_attr "prefix_0f" "1")
12024    (set_attr "mode" "<MODE>")])
12025
12026 (define_insn "ctz<mode>2"
12027   [(set (match_operand:SWI248 0 "register_operand" "=r")
12028         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12029    (clobber (reg:CC FLAGS_REG))]
12030   ""
12031 {
12032   if (TARGET_BMI)
12033     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12034   else
12035     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12036 }
12037   [(set_attr "type" "alu1")
12038    (set_attr "prefix_0f" "1")
12039    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12040    (set_attr "mode" "<MODE>")])
12041
12042 (define_expand "clz<mode>2"
12043   [(parallel
12044      [(set (match_operand:SWI248 0 "register_operand" "")
12045            (minus:SWI248
12046              (match_dup 2)
12047              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12048       (clobber (reg:CC FLAGS_REG))])
12049    (parallel
12050      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12051       (clobber (reg:CC FLAGS_REG))])]
12052   ""
12053 {
12054   if (TARGET_ABM)
12055     {
12056       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12057       DONE;
12058     }
12059   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12060 })
12061
12062 (define_insn "clz<mode>2_abm"
12063   [(set (match_operand:SWI248 0 "register_operand" "=r")
12064         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "TARGET_ABM || TARGET_BMI"
12067   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12068   [(set_attr "prefix_rep" "1")
12069    (set_attr "type" "bitmanip")
12070    (set_attr "mode" "<MODE>")])
12071
12072 ;; BMI instructions.
12073 (define_insn "*bmi_andn_<mode>"
12074   [(set (match_operand:SWI48 0 "register_operand" "=r")
12075         (and:SWI48
12076           (not:SWI48
12077             (match_operand:SWI48 1 "register_operand" "r"))
12078             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12079    (clobber (reg:CC FLAGS_REG))]
12080   "TARGET_BMI"
12081   "andn\t{%2, %1, %0|%0, %1, %2}"
12082   [(set_attr "type" "bitmanip")
12083    (set_attr "mode" "<MODE>")])
12084
12085 (define_insn "bmi_bextr_<mode>"
12086   [(set (match_operand:SWI48 0 "register_operand" "=r")
12087         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12088                        (match_operand:SWI48 2 "register_operand" "r")]
12089                        UNSPEC_BEXTR))
12090    (clobber (reg:CC FLAGS_REG))]
12091   "TARGET_BMI"
12092   "bextr\t{%2, %1, %0|%0, %1, %2}"
12093   [(set_attr "type" "bitmanip")
12094    (set_attr "mode" "<MODE>")])
12095
12096 (define_insn "*bmi_blsi_<mode>"
12097   [(set (match_operand:SWI48 0 "register_operand" "=r")
12098         (and:SWI48
12099           (neg:SWI48
12100             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12101           (match_dup 1)))
12102    (clobber (reg:CC FLAGS_REG))]
12103   "TARGET_BMI"
12104   "blsi\t{%1, %0|%0, %1}"
12105   [(set_attr "type" "bitmanip")
12106    (set_attr "mode" "<MODE>")])
12107
12108 (define_insn "*bmi_blsmsk_<mode>"
12109   [(set (match_operand:SWI48 0 "register_operand" "=r")
12110         (xor:SWI48
12111           (plus:SWI48
12112             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12113             (const_int -1))
12114           (match_dup 1)))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "TARGET_BMI"
12117   "blsmsk\t{%1, %0|%0, %1}"
12118   [(set_attr "type" "bitmanip")
12119    (set_attr "mode" "<MODE>")])
12120
12121 (define_insn "*bmi_blsr_<mode>"
12122   [(set (match_operand:SWI48 0 "register_operand" "=r")
12123         (and:SWI48
12124           (plus:SWI48
12125             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12126             (const_int -1))
12127           (match_dup 1)))
12128    (clobber (reg:CC FLAGS_REG))]
12129    "TARGET_BMI"
12130    "blsr\t{%1, %0|%0, %1}"
12131   [(set_attr "type" "bitmanip")
12132    (set_attr "mode" "<MODE>")])
12133
12134 ;; TBM instructions.
12135 (define_insn "tbm_bextri_<mode>"
12136   [(set (match_operand:SWI48 0 "register_operand" "=r")
12137         (zero_extract:SWI48
12138           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12139           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12140           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12141    (clobber (reg:CC FLAGS_REG))]
12142    "TARGET_TBM"
12143 {
12144   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12145   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12146 }
12147   [(set_attr "type" "bitmanip")
12148    (set_attr "mode" "<MODE>")])
12149
12150 (define_insn "*tbm_blcfill_<mode>"
12151   [(set (match_operand:SWI48 0 "register_operand" "=r")
12152         (and:SWI48
12153           (plus:SWI48
12154             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12155             (const_int 1))
12156           (match_dup 1)))
12157    (clobber (reg:CC FLAGS_REG))]
12158    "TARGET_TBM"
12159    "blcfill\t{%1, %0|%0, %1}"
12160   [(set_attr "type" "bitmanip")
12161    (set_attr "mode" "<MODE>")])
12162
12163 (define_insn "*tbm_blci_<mode>"
12164   [(set (match_operand:SWI48 0 "register_operand" "=r")
12165         (ior:SWI48
12166           (not:SWI48
12167             (plus:SWI48
12168               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12169               (const_int 1)))
12170           (match_dup 1)))
12171    (clobber (reg:CC FLAGS_REG))]
12172    "TARGET_TBM"
12173    "blci\t{%1, %0|%0, %1}"
12174   [(set_attr "type" "bitmanip")
12175    (set_attr "mode" "<MODE>")])
12176
12177 (define_insn "*tbm_blcic_<mode>"
12178   [(set (match_operand:SWI48 0 "register_operand" "=r")
12179         (and:SWI48
12180           (plus:SWI48
12181             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12182             (const_int 1))
12183           (not:SWI48
12184             (match_dup 1))))
12185    (clobber (reg:CC FLAGS_REG))]
12186    "TARGET_TBM"
12187    "blcic\t{%1, %0|%0, %1}"
12188   [(set_attr "type" "bitmanip")
12189    (set_attr "mode" "<MODE>")])
12190
12191 (define_insn "*tbm_blcmsk_<mode>"
12192   [(set (match_operand:SWI48 0 "register_operand" "=r")
12193         (xor:SWI48
12194           (plus:SWI48
12195             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12196             (const_int 1))
12197           (match_dup 1)))
12198    (clobber (reg:CC FLAGS_REG))]
12199    "TARGET_TBM"
12200    "blcmsk\t{%1, %0|%0, %1}"
12201   [(set_attr "type" "bitmanip")
12202    (set_attr "mode" "<MODE>")])
12203
12204 (define_insn "*tbm_blcs_<mode>"
12205   [(set (match_operand:SWI48 0 "register_operand" "=r")
12206         (ior:SWI48
12207           (plus:SWI48
12208             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12209             (const_int 1))
12210           (match_dup 1)))
12211    (clobber (reg:CC FLAGS_REG))]
12212    "TARGET_TBM"
12213    "blcs\t{%1, %0|%0, %1}"
12214   [(set_attr "type" "bitmanip")
12215    (set_attr "mode" "<MODE>")])
12216
12217 (define_insn "*tbm_blsfill_<mode>"
12218   [(set (match_operand:SWI48 0 "register_operand" "=r")
12219         (ior:SWI48
12220           (plus:SWI48
12221             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12222             (const_int -1))
12223           (match_dup 1)))
12224    (clobber (reg:CC FLAGS_REG))]
12225    "TARGET_TBM"
12226    "blsfill\t{%1, %0|%0, %1}"
12227   [(set_attr "type" "bitmanip")
12228    (set_attr "mode" "<MODE>")])
12229
12230 (define_insn "*tbm_blsic_<mode>"
12231   [(set (match_operand:SWI48 0 "register_operand" "=r")
12232         (ior:SWI48
12233           (plus:SWI48
12234             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235             (const_int -1))
12236           (not:SWI48
12237             (match_dup 1))))
12238    (clobber (reg:CC FLAGS_REG))]
12239    "TARGET_TBM"
12240    "blsic\t{%1, %0|%0, %1}"
12241   [(set_attr "type" "bitmanip")
12242    (set_attr "mode" "<MODE>")])
12243
12244 (define_insn "*tbm_t1mskc_<mode>"
12245   [(set (match_operand:SWI48 0 "register_operand" "=r")
12246         (ior:SWI48
12247           (plus:SWI48
12248             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12249             (const_int 1))
12250           (not:SWI48
12251             (match_dup 1))))
12252    (clobber (reg:CC FLAGS_REG))]
12253    "TARGET_TBM"
12254    "t1mskc\t{%1, %0|%0, %1}"
12255   [(set_attr "type" "bitmanip")
12256    (set_attr "mode" "<MODE>")])
12257
12258 (define_insn "*tbm_tzmsk_<mode>"
12259   [(set (match_operand:SWI48 0 "register_operand" "=r")
12260         (and:SWI48
12261           (plus:SWI48
12262             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12263             (const_int -1))
12264           (not:SWI48
12265             (match_dup 1))))
12266    (clobber (reg:CC FLAGS_REG))]
12267    "TARGET_TBM"
12268    "tzmsk\t{%1, %0|%0, %1}"
12269   [(set_attr "type" "bitmanip")
12270    (set_attr "mode" "<MODE>")])
12271
12272 (define_insn "bsr_rex64"
12273   [(set (match_operand:DI 0 "register_operand" "=r")
12274         (minus:DI (const_int 63)
12275                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12276    (clobber (reg:CC FLAGS_REG))]
12277   "TARGET_64BIT"
12278   "bsr{q}\t{%1, %0|%0, %1}"
12279   [(set_attr "type" "alu1")
12280    (set_attr "prefix_0f" "1")
12281    (set_attr "mode" "DI")])
12282
12283 (define_insn "bsr"
12284   [(set (match_operand:SI 0 "register_operand" "=r")
12285         (minus:SI (const_int 31)
12286                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12287    (clobber (reg:CC FLAGS_REG))]
12288   ""
12289   "bsr{l}\t{%1, %0|%0, %1}"
12290   [(set_attr "type" "alu1")
12291    (set_attr "prefix_0f" "1")
12292    (set_attr "mode" "SI")])
12293
12294 (define_insn "*bsrhi"
12295   [(set (match_operand:HI 0 "register_operand" "=r")
12296         (minus:HI (const_int 15)
12297                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12298    (clobber (reg:CC FLAGS_REG))]
12299   ""
12300   "bsr{w}\t{%1, %0|%0, %1}"
12301   [(set_attr "type" "alu1")
12302    (set_attr "prefix_0f" "1")
12303    (set_attr "mode" "HI")])
12304
12305 (define_insn "popcount<mode>2"
12306   [(set (match_operand:SWI248 0 "register_operand" "=r")
12307         (popcount:SWI248
12308           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12309    (clobber (reg:CC FLAGS_REG))]
12310   "TARGET_POPCNT"
12311 {
12312 #if TARGET_MACHO
12313   return "popcnt\t{%1, %0|%0, %1}";
12314 #else
12315   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12316 #endif
12317 }
12318   [(set_attr "prefix_rep" "1")
12319    (set_attr "type" "bitmanip")
12320    (set_attr "mode" "<MODE>")])
12321
12322 (define_insn "*popcount<mode>2_cmp"
12323   [(set (reg FLAGS_REG)
12324         (compare
12325           (popcount:SWI248
12326             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12327           (const_int 0)))
12328    (set (match_operand:SWI248 0 "register_operand" "=r")
12329         (popcount:SWI248 (match_dup 1)))]
12330   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12331 {
12332 #if TARGET_MACHO
12333   return "popcnt\t{%1, %0|%0, %1}";
12334 #else
12335   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12336 #endif
12337 }
12338   [(set_attr "prefix_rep" "1")
12339    (set_attr "type" "bitmanip")
12340    (set_attr "mode" "<MODE>")])
12341
12342 (define_insn "*popcountsi2_cmp_zext"
12343   [(set (reg FLAGS_REG)
12344         (compare
12345           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12346           (const_int 0)))
12347    (set (match_operand:DI 0 "register_operand" "=r")
12348         (zero_extend:DI(popcount:SI (match_dup 1))))]
12349   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12350 {
12351 #if TARGET_MACHO
12352   return "popcnt\t{%1, %0|%0, %1}";
12353 #else
12354   return "popcnt{l}\t{%1, %0|%0, %1}";
12355 #endif
12356 }
12357   [(set_attr "prefix_rep" "1")
12358    (set_attr "type" "bitmanip")
12359    (set_attr "mode" "SI")])
12360
12361 (define_expand "bswap<mode>2"
12362   [(set (match_operand:SWI48 0 "register_operand" "")
12363         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12364   ""
12365 {
12366   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12367     {
12368       rtx x = operands[0];
12369
12370       emit_move_insn (x, operands[1]);
12371       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12372       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12373       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12374       DONE;
12375     }
12376 })
12377
12378 (define_insn "*bswap<mode>2_movbe"
12379   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12380         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12381   "TARGET_MOVBE
12382    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12383   "@
12384     bswap\t%0
12385     movbe\t{%1, %0|%0, %1}
12386     movbe\t{%1, %0|%0, %1}"
12387   [(set_attr "type" "bitmanip,imov,imov")
12388    (set_attr "modrm" "0,1,1")
12389    (set_attr "prefix_0f" "*,1,1")
12390    (set_attr "prefix_extra" "*,1,1")
12391    (set_attr "mode" "<MODE>")])
12392
12393 (define_insn "*bswap<mode>2_1"
12394   [(set (match_operand:SWI48 0 "register_operand" "=r")
12395         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12396   "TARGET_BSWAP"
12397   "bswap\t%0"
12398   [(set_attr "type" "bitmanip")
12399    (set_attr "modrm" "0")
12400    (set_attr "mode" "<MODE>")])
12401
12402 (define_insn "*bswaphi_lowpart_1"
12403   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12404         (bswap:HI (match_dup 0)))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12407   "@
12408     xchg{b}\t{%h0, %b0|%b0, %h0}
12409     rol{w}\t{$8, %0|%0, 8}"
12410   [(set_attr "length" "2,4")
12411    (set_attr "mode" "QI,HI")])
12412
12413 (define_insn "bswaphi_lowpart"
12414   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12415         (bswap:HI (match_dup 0)))
12416    (clobber (reg:CC FLAGS_REG))]
12417   ""
12418   "rol{w}\t{$8, %0|%0, 8}"
12419   [(set_attr "length" "4")
12420    (set_attr "mode" "HI")])
12421
12422 (define_expand "paritydi2"
12423   [(set (match_operand:DI 0 "register_operand" "")
12424         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12425   "! TARGET_POPCNT"
12426 {
12427   rtx scratch = gen_reg_rtx (QImode);
12428   rtx cond;
12429
12430   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12431                                 NULL_RTX, operands[1]));
12432
12433   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12434                          gen_rtx_REG (CCmode, FLAGS_REG),
12435                          const0_rtx);
12436   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12437
12438   if (TARGET_64BIT)
12439     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12440   else
12441     {
12442       rtx tmp = gen_reg_rtx (SImode);
12443
12444       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12445       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12446     }
12447   DONE;
12448 })
12449
12450 (define_expand "paritysi2"
12451   [(set (match_operand:SI 0 "register_operand" "")
12452         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12453   "! TARGET_POPCNT"
12454 {
12455   rtx scratch = gen_reg_rtx (QImode);
12456   rtx cond;
12457
12458   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12459
12460   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12461                          gen_rtx_REG (CCmode, FLAGS_REG),
12462                          const0_rtx);
12463   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12464
12465   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12466   DONE;
12467 })
12468
12469 (define_insn_and_split "paritydi2_cmp"
12470   [(set (reg:CC FLAGS_REG)
12471         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12472                    UNSPEC_PARITY))
12473    (clobber (match_scratch:DI 0 "=r"))
12474    (clobber (match_scratch:SI 1 "=&r"))
12475    (clobber (match_scratch:HI 2 "=Q"))]
12476   "! TARGET_POPCNT"
12477   "#"
12478   "&& reload_completed"
12479   [(parallel
12480      [(set (match_dup 1)
12481            (xor:SI (match_dup 1) (match_dup 4)))
12482       (clobber (reg:CC FLAGS_REG))])
12483    (parallel
12484      [(set (reg:CC FLAGS_REG)
12485            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12486       (clobber (match_dup 1))
12487       (clobber (match_dup 2))])]
12488 {
12489   operands[4] = gen_lowpart (SImode, operands[3]);
12490
12491   if (TARGET_64BIT)
12492     {
12493       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12494       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12495     }
12496   else
12497     operands[1] = gen_highpart (SImode, operands[3]);
12498 })
12499
12500 (define_insn_and_split "paritysi2_cmp"
12501   [(set (reg:CC FLAGS_REG)
12502         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12503                    UNSPEC_PARITY))
12504    (clobber (match_scratch:SI 0 "=r"))
12505    (clobber (match_scratch:HI 1 "=&Q"))]
12506   "! TARGET_POPCNT"
12507   "#"
12508   "&& reload_completed"
12509   [(parallel
12510      [(set (match_dup 1)
12511            (xor:HI (match_dup 1) (match_dup 3)))
12512       (clobber (reg:CC FLAGS_REG))])
12513    (parallel
12514      [(set (reg:CC FLAGS_REG)
12515            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12516       (clobber (match_dup 1))])]
12517 {
12518   operands[3] = gen_lowpart (HImode, operands[2]);
12519
12520   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12521   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12522 })
12523
12524 (define_insn "*parityhi2_cmp"
12525   [(set (reg:CC FLAGS_REG)
12526         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12527                    UNSPEC_PARITY))
12528    (clobber (match_scratch:HI 0 "=Q"))]
12529   "! TARGET_POPCNT"
12530   "xor{b}\t{%h0, %b0|%b0, %h0}"
12531   [(set_attr "length" "2")
12532    (set_attr "mode" "HI")])
12533 \f
12534 ;; Thread-local storage patterns for ELF.
12535 ;;
12536 ;; Note that these code sequences must appear exactly as shown
12537 ;; in order to allow linker relaxation.
12538
12539 (define_insn "*tls_global_dynamic_32_gnu"
12540   [(set (match_operand:SI 0 "register_operand" "=a")
12541         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12542                     (match_operand:SI 2 "tls_symbolic_operand" "")
12543                     (match_operand:SI 3 "call_insn_operand" "")]
12544                     UNSPEC_TLS_GD))
12545    (clobber (match_scratch:SI 4 "=d"))
12546    (clobber (match_scratch:SI 5 "=c"))
12547    (clobber (reg:CC FLAGS_REG))]
12548   "!TARGET_64BIT && TARGET_GNU_TLS"
12549   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12550   [(set_attr "type" "multi")
12551    (set_attr "length" "12")])
12552
12553 (define_expand "tls_global_dynamic_32"
12554   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12555                    (unspec:SI
12556                     [(match_dup 2)
12557                      (match_operand:SI 1 "tls_symbolic_operand" "")
12558                      (match_dup 3)]
12559                     UNSPEC_TLS_GD))
12560               (clobber (match_scratch:SI 4 ""))
12561               (clobber (match_scratch:SI 5 ""))
12562               (clobber (reg:CC FLAGS_REG))])]
12563   ""
12564 {
12565   if (flag_pic)
12566     operands[2] = pic_offset_table_rtx;
12567   else
12568     {
12569       operands[2] = gen_reg_rtx (Pmode);
12570       emit_insn (gen_set_got (operands[2]));
12571     }
12572   if (TARGET_GNU2_TLS)
12573     {
12574        emit_insn (gen_tls_dynamic_gnu2_32
12575                   (operands[0], operands[1], operands[2]));
12576        DONE;
12577     }
12578   operands[3] = ix86_tls_get_addr ();
12579 })
12580
12581 (define_insn "*tls_global_dynamic_64"
12582   [(set (match_operand:DI 0 "register_operand" "=a")
12583         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12584                  (match_operand:DI 3 "" "")))
12585    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12586               UNSPEC_TLS_GD)]
12587   "TARGET_64BIT"
12588   { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12589   [(set_attr "type" "multi")
12590    (set_attr "length" "16")])
12591
12592 (define_expand "tls_global_dynamic_64"
12593   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12594                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12595               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12596                          UNSPEC_TLS_GD)])]
12597   ""
12598 {
12599   if (TARGET_GNU2_TLS)
12600     {
12601        emit_insn (gen_tls_dynamic_gnu2_64
12602                   (operands[0], operands[1]));
12603        DONE;
12604     }
12605   operands[2] = ix86_tls_get_addr ();
12606 })
12607
12608 (define_insn "*tls_local_dynamic_base_32_gnu"
12609   [(set (match_operand:SI 0 "register_operand" "=a")
12610         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12611                     (match_operand:SI 2 "call_insn_operand" "")]
12612                    UNSPEC_TLS_LD_BASE))
12613    (clobber (match_scratch:SI 3 "=d"))
12614    (clobber (match_scratch:SI 4 "=c"))
12615    (clobber (reg:CC FLAGS_REG))]
12616   "!TARGET_64BIT && TARGET_GNU_TLS"
12617   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12618   [(set_attr "type" "multi")
12619    (set_attr "length" "11")])
12620
12621 (define_expand "tls_local_dynamic_base_32"
12622   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12623                    (unspec:SI [(match_dup 1) (match_dup 2)]
12624                               UNSPEC_TLS_LD_BASE))
12625               (clobber (match_scratch:SI 3 ""))
12626               (clobber (match_scratch:SI 4 ""))
12627               (clobber (reg:CC FLAGS_REG))])]
12628   ""
12629 {
12630   if (flag_pic)
12631     operands[1] = pic_offset_table_rtx;
12632   else
12633     {
12634       operands[1] = gen_reg_rtx (Pmode);
12635       emit_insn (gen_set_got (operands[1]));
12636     }
12637   if (TARGET_GNU2_TLS)
12638     {
12639        emit_insn (gen_tls_dynamic_gnu2_32
12640                   (operands[0], ix86_tls_module_base (), operands[1]));
12641        DONE;
12642     }
12643   operands[2] = ix86_tls_get_addr ();
12644 })
12645
12646 (define_insn "*tls_local_dynamic_base_64"
12647   [(set (match_operand:DI 0 "register_operand" "=a")
12648         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12649                  (match_operand:DI 2 "" "")))
12650    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12651   "TARGET_64BIT"
12652   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12653   [(set_attr "type" "multi")
12654    (set_attr "length" "12")])
12655
12656 (define_expand "tls_local_dynamic_base_64"
12657   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12658                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12659               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12660   ""
12661 {
12662   if (TARGET_GNU2_TLS)
12663     {
12664        emit_insn (gen_tls_dynamic_gnu2_64
12665                   (operands[0], ix86_tls_module_base ()));
12666        DONE;
12667     }
12668   operands[1] = ix86_tls_get_addr ();
12669 })
12670
12671 ;; Local dynamic of a single variable is a lose.  Show combine how
12672 ;; to convert that back to global dynamic.
12673
12674 (define_insn_and_split "*tls_local_dynamic_32_once"
12675   [(set (match_operand:SI 0 "register_operand" "=a")
12676         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12677                              (match_operand:SI 2 "call_insn_operand" "")]
12678                             UNSPEC_TLS_LD_BASE)
12679                  (const:SI (unspec:SI
12680                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12681                             UNSPEC_DTPOFF))))
12682    (clobber (match_scratch:SI 4 "=d"))
12683    (clobber (match_scratch:SI 5 "=c"))
12684    (clobber (reg:CC FLAGS_REG))]
12685   ""
12686   "#"
12687   ""
12688   [(parallel [(set (match_dup 0)
12689                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12690                               UNSPEC_TLS_GD))
12691               (clobber (match_dup 4))
12692               (clobber (match_dup 5))
12693               (clobber (reg:CC FLAGS_REG))])])
12694
12695 ;; Segment register for the thread base ptr load
12696 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12697
12698 ;; Load and add the thread base pointer from %gs:0.
12699 (define_insn "*load_tp_<mode>"
12700   [(set (match_operand:P 0 "register_operand" "=r")
12701         (unspec:P [(const_int 0)] UNSPEC_TP))]
12702   ""
12703   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12704   [(set_attr "type" "imov")
12705    (set_attr "modrm" "0")
12706    (set_attr "length" "7")
12707    (set_attr "memory" "load")
12708    (set_attr "imm_disp" "false")])
12709
12710 (define_insn "*add_tp_<mode>"
12711   [(set (match_operand:P 0 "register_operand" "=r")
12712         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12713                 (match_operand:P 1 "register_operand" "0")))
12714    (clobber (reg:CC FLAGS_REG))]
12715   ""
12716   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12717   [(set_attr "type" "alu")
12718    (set_attr "modrm" "0")
12719    (set_attr "length" "7")
12720    (set_attr "memory" "load")
12721    (set_attr "imm_disp" "false")])
12722
12723 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12724 ;; %rax as destination of the initial executable code sequence.
12725 (define_insn "tls_initial_exec_64_sun"
12726   [(set (match_operand:DI 0 "register_operand" "=a")
12727         (unspec:DI
12728          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12729          UNSPEC_TLS_IE_SUN))
12730    (clobber (reg:CC FLAGS_REG))]
12731   "TARGET_64BIT && TARGET_SUN_TLS"
12732   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12733   [(set_attr "type" "multi")])
12734
12735 ;; GNU2 TLS patterns can be split.
12736
12737 (define_expand "tls_dynamic_gnu2_32"
12738   [(set (match_dup 3)
12739         (plus:SI (match_operand:SI 2 "register_operand" "")
12740                  (const:SI
12741                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12742                              UNSPEC_TLSDESC))))
12743    (parallel
12744     [(set (match_operand:SI 0 "register_operand" "")
12745           (unspec:SI [(match_dup 1) (match_dup 3)
12746                       (match_dup 2) (reg:SI SP_REG)]
12747                       UNSPEC_TLSDESC))
12748      (clobber (reg:CC FLAGS_REG))])]
12749   "!TARGET_64BIT && TARGET_GNU2_TLS"
12750 {
12751   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12752   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12753 })
12754
12755 (define_insn "*tls_dynamic_lea_32"
12756   [(set (match_operand:SI 0 "register_operand" "=r")
12757         (plus:SI (match_operand:SI 1 "register_operand" "b")
12758                  (const:SI
12759                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12760                               UNSPEC_TLSDESC))))]
12761   "!TARGET_64BIT && TARGET_GNU2_TLS"
12762   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12763   [(set_attr "type" "lea")
12764    (set_attr "mode" "SI")
12765    (set_attr "length" "6")
12766    (set_attr "length_address" "4")])
12767
12768 (define_insn "*tls_dynamic_call_32"
12769   [(set (match_operand:SI 0 "register_operand" "=a")
12770         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12771                     (match_operand:SI 2 "register_operand" "0")
12772                     ;; we have to make sure %ebx still points to the GOT
12773                     (match_operand:SI 3 "register_operand" "b")
12774                     (reg:SI SP_REG)]
12775                    UNSPEC_TLSDESC))
12776    (clobber (reg:CC FLAGS_REG))]
12777   "!TARGET_64BIT && TARGET_GNU2_TLS"
12778   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12779   [(set_attr "type" "call")
12780    (set_attr "length" "2")
12781    (set_attr "length_address" "0")])
12782
12783 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12784   [(set (match_operand:SI 0 "register_operand" "=&a")
12785         (plus:SI
12786          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12787                      (match_operand:SI 4 "" "")
12788                      (match_operand:SI 2 "register_operand" "b")
12789                      (reg:SI SP_REG)]
12790                     UNSPEC_TLSDESC)
12791          (const:SI (unspec:SI
12792                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12793                     UNSPEC_DTPOFF))))
12794    (clobber (reg:CC FLAGS_REG))]
12795   "!TARGET_64BIT && TARGET_GNU2_TLS"
12796   "#"
12797   ""
12798   [(set (match_dup 0) (match_dup 5))]
12799 {
12800   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12801   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12802 })
12803
12804 (define_expand "tls_dynamic_gnu2_64"
12805   [(set (match_dup 2)
12806         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12807                    UNSPEC_TLSDESC))
12808    (parallel
12809     [(set (match_operand:DI 0 "register_operand" "")
12810           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12811                      UNSPEC_TLSDESC))
12812      (clobber (reg:CC FLAGS_REG))])]
12813   "TARGET_64BIT && TARGET_GNU2_TLS"
12814 {
12815   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12816   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12817 })
12818
12819 (define_insn "*tls_dynamic_lea_64"
12820   [(set (match_operand:DI 0 "register_operand" "=r")
12821         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12822                    UNSPEC_TLSDESC))]
12823   "TARGET_64BIT && TARGET_GNU2_TLS"
12824   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12825   [(set_attr "type" "lea")
12826    (set_attr "mode" "DI")
12827    (set_attr "length" "7")
12828    (set_attr "length_address" "4")])
12829
12830 (define_insn "*tls_dynamic_call_64"
12831   [(set (match_operand:DI 0 "register_operand" "=a")
12832         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12833                     (match_operand:DI 2 "register_operand" "0")
12834                     (reg:DI SP_REG)]
12835                    UNSPEC_TLSDESC))
12836    (clobber (reg:CC FLAGS_REG))]
12837   "TARGET_64BIT && TARGET_GNU2_TLS"
12838   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12839   [(set_attr "type" "call")
12840    (set_attr "length" "2")
12841    (set_attr "length_address" "0")])
12842
12843 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12844   [(set (match_operand:DI 0 "register_operand" "=&a")
12845         (plus:DI
12846          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12847                      (match_operand:DI 3 "" "")
12848                      (reg:DI SP_REG)]
12849                     UNSPEC_TLSDESC)
12850          (const:DI (unspec:DI
12851                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12852                     UNSPEC_DTPOFF))))
12853    (clobber (reg:CC FLAGS_REG))]
12854   "TARGET_64BIT && TARGET_GNU2_TLS"
12855   "#"
12856   ""
12857   [(set (match_dup 0) (match_dup 4))]
12858 {
12859   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12860   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12861 })
12862 \f
12863 ;; These patterns match the binary 387 instructions for addM3, subM3,
12864 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12865 ;; SFmode.  The first is the normal insn, the second the same insn but
12866 ;; with one operand a conversion, and the third the same insn but with
12867 ;; the other operand a conversion.  The conversion may be SFmode or
12868 ;; SImode if the target mode DFmode, but only SImode if the target mode
12869 ;; is SFmode.
12870
12871 ;; Gcc is slightly more smart about handling normal two address instructions
12872 ;; so use special patterns for add and mull.
12873
12874 (define_insn "*fop_<mode>_comm_mixed"
12875   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12876         (match_operator:MODEF 3 "binary_fp_operator"
12877           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12878            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12879   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12880    && COMMUTATIVE_ARITH_P (operands[3])
12881    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12882   "* return output_387_binary_op (insn, operands);"
12883   [(set (attr "type")
12884         (if_then_else (eq_attr "alternative" "1,2")
12885            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12886               (const_string "ssemul")
12887               (const_string "sseadd"))
12888            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12889               (const_string "fmul")
12890               (const_string "fop"))))
12891    (set_attr "isa" "base,noavx,avx")
12892    (set_attr "prefix" "orig,orig,vex")
12893    (set_attr "mode" "<MODE>")])
12894
12895 (define_insn "*fop_<mode>_comm_sse"
12896   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12897         (match_operator:MODEF 3 "binary_fp_operator"
12898           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12899            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12900   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12901    && COMMUTATIVE_ARITH_P (operands[3])
12902    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12903   "* return output_387_binary_op (insn, operands);"
12904   [(set (attr "type")
12905         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12906            (const_string "ssemul")
12907            (const_string "sseadd")))
12908    (set_attr "isa" "noavx,avx")
12909    (set_attr "prefix" "orig,vex")
12910    (set_attr "mode" "<MODE>")])
12911
12912 (define_insn "*fop_<mode>_comm_i387"
12913   [(set (match_operand:MODEF 0 "register_operand" "=f")
12914         (match_operator:MODEF 3 "binary_fp_operator"
12915           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12916            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12917   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12918    && COMMUTATIVE_ARITH_P (operands[3])
12919    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12920   "* return output_387_binary_op (insn, operands);"
12921   [(set (attr "type")
12922         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12923            (const_string "fmul")
12924            (const_string "fop")))
12925    (set_attr "mode" "<MODE>")])
12926
12927 (define_insn "*fop_<mode>_1_mixed"
12928   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12929         (match_operator:MODEF 3 "binary_fp_operator"
12930           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12931            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12932   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12933    && !COMMUTATIVE_ARITH_P (operands[3])
12934    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12935   "* return output_387_binary_op (insn, operands);"
12936   [(set (attr "type")
12937         (cond [(and (eq_attr "alternative" "2,3")
12938                     (match_operand:MODEF 3 "mult_operator" ""))
12939                  (const_string "ssemul")
12940                (and (eq_attr "alternative" "2,3")
12941                     (match_operand:MODEF 3 "div_operator" ""))
12942                  (const_string "ssediv")
12943                (eq_attr "alternative" "2,3")
12944                  (const_string "sseadd")
12945                (match_operand:MODEF 3 "mult_operator" "")
12946                  (const_string "fmul")
12947                (match_operand:MODEF 3 "div_operator" "")
12948                  (const_string "fdiv")
12949               ]
12950               (const_string "fop")))
12951    (set_attr "isa" "base,base,noavx,avx")
12952    (set_attr "prefix" "orig,orig,orig,vex")
12953    (set_attr "mode" "<MODE>")])
12954
12955 (define_insn "*rcpsf2_sse"
12956   [(set (match_operand:SF 0 "register_operand" "=x")
12957         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12958                    UNSPEC_RCP))]
12959   "TARGET_SSE_MATH"
12960   "%vrcpss\t{%1, %d0|%d0, %1}"
12961   [(set_attr "type" "sse")
12962    (set_attr "atom_sse_attr" "rcp")
12963    (set_attr "prefix" "maybe_vex")
12964    (set_attr "mode" "SF")])
12965
12966 (define_insn "*fop_<mode>_1_sse"
12967   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12968         (match_operator:MODEF 3 "binary_fp_operator"
12969           [(match_operand:MODEF 1 "register_operand" "0,x")
12970            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12971   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12972    && !COMMUTATIVE_ARITH_P (operands[3])"
12973   "* return output_387_binary_op (insn, operands);"
12974   [(set (attr "type")
12975         (cond [(match_operand:MODEF 3 "mult_operator" "")
12976                  (const_string "ssemul")
12977                (match_operand:MODEF 3 "div_operator" "")
12978                  (const_string "ssediv")
12979               ]
12980               (const_string "sseadd")))
12981    (set_attr "isa" "noavx,avx")
12982    (set_attr "prefix" "orig,vex")
12983    (set_attr "mode" "<MODE>")])
12984
12985 ;; This pattern is not fully shadowed by the pattern above.
12986 (define_insn "*fop_<mode>_1_i387"
12987   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12988         (match_operator:MODEF 3 "binary_fp_operator"
12989           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12990            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12991   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12992    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12993    && !COMMUTATIVE_ARITH_P (operands[3])
12994    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12995   "* return output_387_binary_op (insn, operands);"
12996   [(set (attr "type")
12997         (cond [(match_operand:MODEF 3 "mult_operator" "")
12998                  (const_string "fmul")
12999                (match_operand:MODEF 3 "div_operator" "")
13000                  (const_string "fdiv")
13001               ]
13002               (const_string "fop")))
13003    (set_attr "mode" "<MODE>")])
13004
13005 ;; ??? Add SSE splitters for these!
13006 (define_insn "*fop_<MODEF:mode>_2_i387"
13007   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13008         (match_operator:MODEF 3 "binary_fp_operator"
13009           [(float:MODEF
13010              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13011            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13012   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13013    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13014    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13015   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13016   [(set (attr "type")
13017         (cond [(match_operand:MODEF 3 "mult_operator" "")
13018                  (const_string "fmul")
13019                (match_operand:MODEF 3 "div_operator" "")
13020                  (const_string "fdiv")
13021               ]
13022               (const_string "fop")))
13023    (set_attr "fp_int_src" "true")
13024    (set_attr "mode" "<X87MODEI12:MODE>")])
13025
13026 (define_insn "*fop_<MODEF:mode>_3_i387"
13027   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13028         (match_operator:MODEF 3 "binary_fp_operator"
13029           [(match_operand:MODEF 1 "register_operand" "0,0")
13030            (float:MODEF
13031              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13032   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13033    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13034    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13035   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13036   [(set (attr "type")
13037         (cond [(match_operand:MODEF 3 "mult_operator" "")
13038                  (const_string "fmul")
13039                (match_operand:MODEF 3 "div_operator" "")
13040                  (const_string "fdiv")
13041               ]
13042               (const_string "fop")))
13043    (set_attr "fp_int_src" "true")
13044    (set_attr "mode" "<MODE>")])
13045
13046 (define_insn "*fop_df_4_i387"
13047   [(set (match_operand:DF 0 "register_operand" "=f,f")
13048         (match_operator:DF 3 "binary_fp_operator"
13049            [(float_extend:DF
13050              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13051             (match_operand:DF 2 "register_operand" "0,f")]))]
13052   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13053    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13054    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13055   "* return output_387_binary_op (insn, operands);"
13056   [(set (attr "type")
13057         (cond [(match_operand:DF 3 "mult_operator" "")
13058                  (const_string "fmul")
13059                (match_operand:DF 3 "div_operator" "")
13060                  (const_string "fdiv")
13061               ]
13062               (const_string "fop")))
13063    (set_attr "mode" "SF")])
13064
13065 (define_insn "*fop_df_5_i387"
13066   [(set (match_operand:DF 0 "register_operand" "=f,f")
13067         (match_operator:DF 3 "binary_fp_operator"
13068           [(match_operand:DF 1 "register_operand" "0,f")
13069            (float_extend:DF
13070             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13071   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13072    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13073   "* return output_387_binary_op (insn, operands);"
13074   [(set (attr "type")
13075         (cond [(match_operand:DF 3 "mult_operator" "")
13076                  (const_string "fmul")
13077                (match_operand:DF 3 "div_operator" "")
13078                  (const_string "fdiv")
13079               ]
13080               (const_string "fop")))
13081    (set_attr "mode" "SF")])
13082
13083 (define_insn "*fop_df_6_i387"
13084   [(set (match_operand:DF 0 "register_operand" "=f,f")
13085         (match_operator:DF 3 "binary_fp_operator"
13086           [(float_extend:DF
13087             (match_operand:SF 1 "register_operand" "0,f"))
13088            (float_extend:DF
13089             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13090   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13091    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13092   "* return output_387_binary_op (insn, operands);"
13093   [(set (attr "type")
13094         (cond [(match_operand:DF 3 "mult_operator" "")
13095                  (const_string "fmul")
13096                (match_operand:DF 3 "div_operator" "")
13097                  (const_string "fdiv")
13098               ]
13099               (const_string "fop")))
13100    (set_attr "mode" "SF")])
13101
13102 (define_insn "*fop_xf_comm_i387"
13103   [(set (match_operand:XF 0 "register_operand" "=f")
13104         (match_operator:XF 3 "binary_fp_operator"
13105                         [(match_operand:XF 1 "register_operand" "%0")
13106                          (match_operand:XF 2 "register_operand" "f")]))]
13107   "TARGET_80387
13108    && COMMUTATIVE_ARITH_P (operands[3])"
13109   "* return output_387_binary_op (insn, operands);"
13110   [(set (attr "type")
13111         (if_then_else (match_operand:XF 3 "mult_operator" "")
13112            (const_string "fmul")
13113            (const_string "fop")))
13114    (set_attr "mode" "XF")])
13115
13116 (define_insn "*fop_xf_1_i387"
13117   [(set (match_operand:XF 0 "register_operand" "=f,f")
13118         (match_operator:XF 3 "binary_fp_operator"
13119                         [(match_operand:XF 1 "register_operand" "0,f")
13120                          (match_operand:XF 2 "register_operand" "f,0")]))]
13121   "TARGET_80387
13122    && !COMMUTATIVE_ARITH_P (operands[3])"
13123   "* return output_387_binary_op (insn, operands);"
13124   [(set (attr "type")
13125         (cond [(match_operand:XF 3 "mult_operator" "")
13126                  (const_string "fmul")
13127                (match_operand:XF 3 "div_operator" "")
13128                  (const_string "fdiv")
13129               ]
13130               (const_string "fop")))
13131    (set_attr "mode" "XF")])
13132
13133 (define_insn "*fop_xf_2_i387"
13134   [(set (match_operand:XF 0 "register_operand" "=f,f")
13135         (match_operator:XF 3 "binary_fp_operator"
13136           [(float:XF
13137              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13138            (match_operand:XF 2 "register_operand" "0,0")]))]
13139   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13140   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13141   [(set (attr "type")
13142         (cond [(match_operand:XF 3 "mult_operator" "")
13143                  (const_string "fmul")
13144                (match_operand:XF 3 "div_operator" "")
13145                  (const_string "fdiv")
13146               ]
13147               (const_string "fop")))
13148    (set_attr "fp_int_src" "true")
13149    (set_attr "mode" "<MODE>")])
13150
13151 (define_insn "*fop_xf_3_i387"
13152   [(set (match_operand:XF 0 "register_operand" "=f,f")
13153         (match_operator:XF 3 "binary_fp_operator"
13154           [(match_operand:XF 1 "register_operand" "0,0")
13155            (float:XF
13156              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13157   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13158   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13159   [(set (attr "type")
13160         (cond [(match_operand:XF 3 "mult_operator" "")
13161                  (const_string "fmul")
13162                (match_operand:XF 3 "div_operator" "")
13163                  (const_string "fdiv")
13164               ]
13165               (const_string "fop")))
13166    (set_attr "fp_int_src" "true")
13167    (set_attr "mode" "<MODE>")])
13168
13169 (define_insn "*fop_xf_4_i387"
13170   [(set (match_operand:XF 0 "register_operand" "=f,f")
13171         (match_operator:XF 3 "binary_fp_operator"
13172            [(float_extend:XF
13173               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13174             (match_operand:XF 2 "register_operand" "0,f")]))]
13175   "TARGET_80387"
13176   "* return output_387_binary_op (insn, operands);"
13177   [(set (attr "type")
13178         (cond [(match_operand:XF 3 "mult_operator" "")
13179                  (const_string "fmul")
13180                (match_operand:XF 3 "div_operator" "")
13181                  (const_string "fdiv")
13182               ]
13183               (const_string "fop")))
13184    (set_attr "mode" "<MODE>")])
13185
13186 (define_insn "*fop_xf_5_i387"
13187   [(set (match_operand:XF 0 "register_operand" "=f,f")
13188         (match_operator:XF 3 "binary_fp_operator"
13189           [(match_operand:XF 1 "register_operand" "0,f")
13190            (float_extend:XF
13191              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13192   "TARGET_80387"
13193   "* return output_387_binary_op (insn, operands);"
13194   [(set (attr "type")
13195         (cond [(match_operand:XF 3 "mult_operator" "")
13196                  (const_string "fmul")
13197                (match_operand:XF 3 "div_operator" "")
13198                  (const_string "fdiv")
13199               ]
13200               (const_string "fop")))
13201    (set_attr "mode" "<MODE>")])
13202
13203 (define_insn "*fop_xf_6_i387"
13204   [(set (match_operand:XF 0 "register_operand" "=f,f")
13205         (match_operator:XF 3 "binary_fp_operator"
13206           [(float_extend:XF
13207              (match_operand:MODEF 1 "register_operand" "0,f"))
13208            (float_extend:XF
13209              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13210   "TARGET_80387"
13211   "* return output_387_binary_op (insn, operands);"
13212   [(set (attr "type")
13213         (cond [(match_operand:XF 3 "mult_operator" "")
13214                  (const_string "fmul")
13215                (match_operand:XF 3 "div_operator" "")
13216                  (const_string "fdiv")
13217               ]
13218               (const_string "fop")))
13219    (set_attr "mode" "<MODE>")])
13220
13221 (define_split
13222   [(set (match_operand 0 "register_operand" "")
13223         (match_operator 3 "binary_fp_operator"
13224            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13225             (match_operand 2 "register_operand" "")]))]
13226   "reload_completed
13227    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13228    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13229   [(const_int 0)]
13230 {
13231   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13232   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13233   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13234                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13235                                           GET_MODE (operands[3]),
13236                                           operands[4],
13237                                           operands[2])));
13238   ix86_free_from_memory (GET_MODE (operands[1]));
13239   DONE;
13240 })
13241
13242 (define_split
13243   [(set (match_operand 0 "register_operand" "")
13244         (match_operator 3 "binary_fp_operator"
13245            [(match_operand 1 "register_operand" "")
13246             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13247   "reload_completed
13248    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13249    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13250   [(const_int 0)]
13251 {
13252   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13253   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13254   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13255                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13256                                           GET_MODE (operands[3]),
13257                                           operands[1],
13258                                           operands[4])));
13259   ix86_free_from_memory (GET_MODE (operands[2]));
13260   DONE;
13261 })
13262 \f
13263 ;; FPU special functions.
13264
13265 ;; This pattern implements a no-op XFmode truncation for
13266 ;; all fancy i386 XFmode math functions.
13267
13268 (define_insn "truncxf<mode>2_i387_noop_unspec"
13269   [(set (match_operand:MODEF 0 "register_operand" "=f")
13270         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13271         UNSPEC_TRUNC_NOOP))]
13272   "TARGET_USE_FANCY_MATH_387"
13273   "* return output_387_reg_move (insn, operands);"
13274   [(set_attr "type" "fmov")
13275    (set_attr "mode" "<MODE>")])
13276
13277 (define_insn "sqrtxf2"
13278   [(set (match_operand:XF 0 "register_operand" "=f")
13279         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13280   "TARGET_USE_FANCY_MATH_387"
13281   "fsqrt"
13282   [(set_attr "type" "fpspc")
13283    (set_attr "mode" "XF")
13284    (set_attr "athlon_decode" "direct")
13285    (set_attr "amdfam10_decode" "direct")
13286    (set_attr "bdver1_decode" "direct")])
13287
13288 (define_insn "sqrt_extend<mode>xf2_i387"
13289   [(set (match_operand:XF 0 "register_operand" "=f")
13290         (sqrt:XF
13291           (float_extend:XF
13292             (match_operand:MODEF 1 "register_operand" "0"))))]
13293   "TARGET_USE_FANCY_MATH_387"
13294   "fsqrt"
13295   [(set_attr "type" "fpspc")
13296    (set_attr "mode" "XF")
13297    (set_attr "athlon_decode" "direct")
13298    (set_attr "amdfam10_decode" "direct")
13299    (set_attr "bdver1_decode" "direct")])
13300
13301 (define_insn "*rsqrtsf2_sse"
13302   [(set (match_operand:SF 0 "register_operand" "=x")
13303         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13304                    UNSPEC_RSQRT))]
13305   "TARGET_SSE_MATH"
13306   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13307   [(set_attr "type" "sse")
13308    (set_attr "atom_sse_attr" "rcp")
13309    (set_attr "prefix" "maybe_vex")
13310    (set_attr "mode" "SF")])
13311
13312 (define_expand "rsqrtsf2"
13313   [(set (match_operand:SF 0 "register_operand" "")
13314         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13315                    UNSPEC_RSQRT))]
13316   "TARGET_SSE_MATH"
13317 {
13318   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13319   DONE;
13320 })
13321
13322 (define_insn "*sqrt<mode>2_sse"
13323   [(set (match_operand:MODEF 0 "register_operand" "=x")
13324         (sqrt:MODEF
13325           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13326   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13327   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13328   [(set_attr "type" "sse")
13329    (set_attr "atom_sse_attr" "sqrt")
13330    (set_attr "prefix" "maybe_vex")
13331    (set_attr "mode" "<MODE>")
13332    (set_attr "athlon_decode" "*")
13333    (set_attr "amdfam10_decode" "*")
13334    (set_attr "bdver1_decode" "*")])
13335
13336 (define_expand "sqrt<mode>2"
13337   [(set (match_operand:MODEF 0 "register_operand" "")
13338         (sqrt:MODEF
13339           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13340   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13341    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13342 {
13343   if (<MODE>mode == SFmode
13344       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13345       && flag_finite_math_only && !flag_trapping_math
13346       && flag_unsafe_math_optimizations)
13347     {
13348       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13349       DONE;
13350     }
13351
13352   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13353     {
13354       rtx op0 = gen_reg_rtx (XFmode);
13355       rtx op1 = force_reg (<MODE>mode, operands[1]);
13356
13357       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13358       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13359       DONE;
13360    }
13361 })
13362
13363 (define_insn "fpremxf4_i387"
13364   [(set (match_operand:XF 0 "register_operand" "=f")
13365         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13366                     (match_operand:XF 3 "register_operand" "1")]
13367                    UNSPEC_FPREM_F))
13368    (set (match_operand:XF 1 "register_operand" "=u")
13369         (unspec:XF [(match_dup 2) (match_dup 3)]
13370                    UNSPEC_FPREM_U))
13371    (set (reg:CCFP FPSR_REG)
13372         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13373                      UNSPEC_C2_FLAG))]
13374   "TARGET_USE_FANCY_MATH_387"
13375   "fprem"
13376   [(set_attr "type" "fpspc")
13377    (set_attr "mode" "XF")])
13378
13379 (define_expand "fmodxf3"
13380   [(use (match_operand:XF 0 "register_operand" ""))
13381    (use (match_operand:XF 1 "general_operand" ""))
13382    (use (match_operand:XF 2 "general_operand" ""))]
13383   "TARGET_USE_FANCY_MATH_387"
13384 {
13385   rtx label = gen_label_rtx ();
13386
13387   rtx op1 = gen_reg_rtx (XFmode);
13388   rtx op2 = gen_reg_rtx (XFmode);
13389
13390   emit_move_insn (op2, operands[2]);
13391   emit_move_insn (op1, operands[1]);
13392
13393   emit_label (label);
13394   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13395   ix86_emit_fp_unordered_jump (label);
13396   LABEL_NUSES (label) = 1;
13397
13398   emit_move_insn (operands[0], op1);
13399   DONE;
13400 })
13401
13402 (define_expand "fmod<mode>3"
13403   [(use (match_operand:MODEF 0 "register_operand" ""))
13404    (use (match_operand:MODEF 1 "general_operand" ""))
13405    (use (match_operand:MODEF 2 "general_operand" ""))]
13406   "TARGET_USE_FANCY_MATH_387"
13407 {
13408   rtx (*gen_truncxf) (rtx, rtx);
13409
13410   rtx label = gen_label_rtx ();
13411
13412   rtx op1 = gen_reg_rtx (XFmode);
13413   rtx op2 = gen_reg_rtx (XFmode);
13414
13415   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13416   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13417
13418   emit_label (label);
13419   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13420   ix86_emit_fp_unordered_jump (label);
13421   LABEL_NUSES (label) = 1;
13422
13423   /* Truncate the result properly for strict SSE math.  */
13424   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13425       && !TARGET_MIX_SSE_I387)
13426     gen_truncxf = gen_truncxf<mode>2;
13427   else
13428     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13429
13430   emit_insn (gen_truncxf (operands[0], op1));
13431   DONE;
13432 })
13433
13434 (define_insn "fprem1xf4_i387"
13435   [(set (match_operand:XF 0 "register_operand" "=f")
13436         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13437                     (match_operand:XF 3 "register_operand" "1")]
13438                    UNSPEC_FPREM1_F))
13439    (set (match_operand:XF 1 "register_operand" "=u")
13440         (unspec:XF [(match_dup 2) (match_dup 3)]
13441                    UNSPEC_FPREM1_U))
13442    (set (reg:CCFP FPSR_REG)
13443         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13444                      UNSPEC_C2_FLAG))]
13445   "TARGET_USE_FANCY_MATH_387"
13446   "fprem1"
13447   [(set_attr "type" "fpspc")
13448    (set_attr "mode" "XF")])
13449
13450 (define_expand "remainderxf3"
13451   [(use (match_operand:XF 0 "register_operand" ""))
13452    (use (match_operand:XF 1 "general_operand" ""))
13453    (use (match_operand:XF 2 "general_operand" ""))]
13454   "TARGET_USE_FANCY_MATH_387"
13455 {
13456   rtx label = gen_label_rtx ();
13457
13458   rtx op1 = gen_reg_rtx (XFmode);
13459   rtx op2 = gen_reg_rtx (XFmode);
13460
13461   emit_move_insn (op2, operands[2]);
13462   emit_move_insn (op1, operands[1]);
13463
13464   emit_label (label);
13465   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13466   ix86_emit_fp_unordered_jump (label);
13467   LABEL_NUSES (label) = 1;
13468
13469   emit_move_insn (operands[0], op1);
13470   DONE;
13471 })
13472
13473 (define_expand "remainder<mode>3"
13474   [(use (match_operand:MODEF 0 "register_operand" ""))
13475    (use (match_operand:MODEF 1 "general_operand" ""))
13476    (use (match_operand:MODEF 2 "general_operand" ""))]
13477   "TARGET_USE_FANCY_MATH_387"
13478 {
13479   rtx (*gen_truncxf) (rtx, rtx);
13480
13481   rtx label = gen_label_rtx ();
13482
13483   rtx op1 = gen_reg_rtx (XFmode);
13484   rtx op2 = gen_reg_rtx (XFmode);
13485
13486   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13487   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13488
13489   emit_label (label);
13490
13491   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13492   ix86_emit_fp_unordered_jump (label);
13493   LABEL_NUSES (label) = 1;
13494
13495   /* Truncate the result properly for strict SSE math.  */
13496   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13497       && !TARGET_MIX_SSE_I387)
13498     gen_truncxf = gen_truncxf<mode>2;
13499   else
13500     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13501
13502   emit_insn (gen_truncxf (operands[0], op1));
13503   DONE;
13504 })
13505
13506 (define_insn "*sinxf2_i387"
13507   [(set (match_operand:XF 0 "register_operand" "=f")
13508         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13509   "TARGET_USE_FANCY_MATH_387
13510    && flag_unsafe_math_optimizations"
13511   "fsin"
13512   [(set_attr "type" "fpspc")
13513    (set_attr "mode" "XF")])
13514
13515 (define_insn "*sin_extend<mode>xf2_i387"
13516   [(set (match_operand:XF 0 "register_operand" "=f")
13517         (unspec:XF [(float_extend:XF
13518                       (match_operand:MODEF 1 "register_operand" "0"))]
13519                    UNSPEC_SIN))]
13520   "TARGET_USE_FANCY_MATH_387
13521    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13522        || TARGET_MIX_SSE_I387)
13523    && flag_unsafe_math_optimizations"
13524   "fsin"
13525   [(set_attr "type" "fpspc")
13526    (set_attr "mode" "XF")])
13527
13528 (define_insn "*cosxf2_i387"
13529   [(set (match_operand:XF 0 "register_operand" "=f")
13530         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13531   "TARGET_USE_FANCY_MATH_387
13532    && flag_unsafe_math_optimizations"
13533   "fcos"
13534   [(set_attr "type" "fpspc")
13535    (set_attr "mode" "XF")])
13536
13537 (define_insn "*cos_extend<mode>xf2_i387"
13538   [(set (match_operand:XF 0 "register_operand" "=f")
13539         (unspec:XF [(float_extend:XF
13540                       (match_operand:MODEF 1 "register_operand" "0"))]
13541                    UNSPEC_COS))]
13542   "TARGET_USE_FANCY_MATH_387
13543    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544        || TARGET_MIX_SSE_I387)
13545    && flag_unsafe_math_optimizations"
13546   "fcos"
13547   [(set_attr "type" "fpspc")
13548    (set_attr "mode" "XF")])
13549
13550 ;; When sincos pattern is defined, sin and cos builtin functions will be
13551 ;; expanded to sincos pattern with one of its outputs left unused.
13552 ;; CSE pass will figure out if two sincos patterns can be combined,
13553 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13554 ;; depending on the unused output.
13555
13556 (define_insn "sincosxf3"
13557   [(set (match_operand:XF 0 "register_operand" "=f")
13558         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13559                    UNSPEC_SINCOS_COS))
13560    (set (match_operand:XF 1 "register_operand" "=u")
13561         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13562   "TARGET_USE_FANCY_MATH_387
13563    && flag_unsafe_math_optimizations"
13564   "fsincos"
13565   [(set_attr "type" "fpspc")
13566    (set_attr "mode" "XF")])
13567
13568 (define_split
13569   [(set (match_operand:XF 0 "register_operand" "")
13570         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13571                    UNSPEC_SINCOS_COS))
13572    (set (match_operand:XF 1 "register_operand" "")
13573         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13574   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13575    && !(reload_completed || reload_in_progress)"
13576   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13577
13578 (define_split
13579   [(set (match_operand:XF 0 "register_operand" "")
13580         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13581                    UNSPEC_SINCOS_COS))
13582    (set (match_operand:XF 1 "register_operand" "")
13583         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13584   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13585    && !(reload_completed || reload_in_progress)"
13586   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13587
13588 (define_insn "sincos_extend<mode>xf3_i387"
13589   [(set (match_operand:XF 0 "register_operand" "=f")
13590         (unspec:XF [(float_extend:XF
13591                       (match_operand:MODEF 2 "register_operand" "0"))]
13592                    UNSPEC_SINCOS_COS))
13593    (set (match_operand:XF 1 "register_operand" "=u")
13594         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13595   "TARGET_USE_FANCY_MATH_387
13596    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13597        || TARGET_MIX_SSE_I387)
13598    && flag_unsafe_math_optimizations"
13599   "fsincos"
13600   [(set_attr "type" "fpspc")
13601    (set_attr "mode" "XF")])
13602
13603 (define_split
13604   [(set (match_operand:XF 0 "register_operand" "")
13605         (unspec:XF [(float_extend:XF
13606                       (match_operand:MODEF 2 "register_operand" ""))]
13607                    UNSPEC_SINCOS_COS))
13608    (set (match_operand:XF 1 "register_operand" "")
13609         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13610   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13611    && !(reload_completed || reload_in_progress)"
13612   [(set (match_dup 1)
13613         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13614
13615 (define_split
13616   [(set (match_operand:XF 0 "register_operand" "")
13617         (unspec:XF [(float_extend:XF
13618                       (match_operand:MODEF 2 "register_operand" ""))]
13619                    UNSPEC_SINCOS_COS))
13620    (set (match_operand:XF 1 "register_operand" "")
13621         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13622   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13623    && !(reload_completed || reload_in_progress)"
13624   [(set (match_dup 0)
13625         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13626
13627 (define_expand "sincos<mode>3"
13628   [(use (match_operand:MODEF 0 "register_operand" ""))
13629    (use (match_operand:MODEF 1 "register_operand" ""))
13630    (use (match_operand:MODEF 2 "register_operand" ""))]
13631   "TARGET_USE_FANCY_MATH_387
13632    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13633        || TARGET_MIX_SSE_I387)
13634    && flag_unsafe_math_optimizations"
13635 {
13636   rtx op0 = gen_reg_rtx (XFmode);
13637   rtx op1 = gen_reg_rtx (XFmode);
13638
13639   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13640   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13641   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13642   DONE;
13643 })
13644
13645 (define_insn "fptanxf4_i387"
13646   [(set (match_operand:XF 0 "register_operand" "=f")
13647         (match_operand:XF 3 "const_double_operand" "F"))
13648    (set (match_operand:XF 1 "register_operand" "=u")
13649         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13650                    UNSPEC_TAN))]
13651   "TARGET_USE_FANCY_MATH_387
13652    && flag_unsafe_math_optimizations
13653    && standard_80387_constant_p (operands[3]) == 2"
13654   "fptan"
13655   [(set_attr "type" "fpspc")
13656    (set_attr "mode" "XF")])
13657
13658 (define_insn "fptan_extend<mode>xf4_i387"
13659   [(set (match_operand:MODEF 0 "register_operand" "=f")
13660         (match_operand:MODEF 3 "const_double_operand" "F"))
13661    (set (match_operand:XF 1 "register_operand" "=u")
13662         (unspec:XF [(float_extend:XF
13663                       (match_operand:MODEF 2 "register_operand" "0"))]
13664                    UNSPEC_TAN))]
13665   "TARGET_USE_FANCY_MATH_387
13666    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13667        || TARGET_MIX_SSE_I387)
13668    && flag_unsafe_math_optimizations
13669    && standard_80387_constant_p (operands[3]) == 2"
13670   "fptan"
13671   [(set_attr "type" "fpspc")
13672    (set_attr "mode" "XF")])
13673
13674 (define_expand "tanxf2"
13675   [(use (match_operand:XF 0 "register_operand" ""))
13676    (use (match_operand:XF 1 "register_operand" ""))]
13677   "TARGET_USE_FANCY_MATH_387
13678    && flag_unsafe_math_optimizations"
13679 {
13680   rtx one = gen_reg_rtx (XFmode);
13681   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13682
13683   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13684   DONE;
13685 })
13686
13687 (define_expand "tan<mode>2"
13688   [(use (match_operand:MODEF 0 "register_operand" ""))
13689    (use (match_operand:MODEF 1 "register_operand" ""))]
13690   "TARGET_USE_FANCY_MATH_387
13691    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13692        || TARGET_MIX_SSE_I387)
13693    && flag_unsafe_math_optimizations"
13694 {
13695   rtx op0 = gen_reg_rtx (XFmode);
13696
13697   rtx one = gen_reg_rtx (<MODE>mode);
13698   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13699
13700   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13701                                              operands[1], op2));
13702   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13703   DONE;
13704 })
13705
13706 (define_insn "*fpatanxf3_i387"
13707   [(set (match_operand:XF 0 "register_operand" "=f")
13708         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13709                     (match_operand:XF 2 "register_operand" "u")]
13710                    UNSPEC_FPATAN))
13711    (clobber (match_scratch:XF 3 "=2"))]
13712   "TARGET_USE_FANCY_MATH_387
13713    && flag_unsafe_math_optimizations"
13714   "fpatan"
13715   [(set_attr "type" "fpspc")
13716    (set_attr "mode" "XF")])
13717
13718 (define_insn "fpatan_extend<mode>xf3_i387"
13719   [(set (match_operand:XF 0 "register_operand" "=f")
13720         (unspec:XF [(float_extend:XF
13721                       (match_operand:MODEF 1 "register_operand" "0"))
13722                     (float_extend:XF
13723                       (match_operand:MODEF 2 "register_operand" "u"))]
13724                    UNSPEC_FPATAN))
13725    (clobber (match_scratch:XF 3 "=2"))]
13726   "TARGET_USE_FANCY_MATH_387
13727    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13728        || TARGET_MIX_SSE_I387)
13729    && flag_unsafe_math_optimizations"
13730   "fpatan"
13731   [(set_attr "type" "fpspc")
13732    (set_attr "mode" "XF")])
13733
13734 (define_expand "atan2xf3"
13735   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13736                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13737                                (match_operand:XF 1 "register_operand" "")]
13738                               UNSPEC_FPATAN))
13739               (clobber (match_scratch:XF 3 ""))])]
13740   "TARGET_USE_FANCY_MATH_387
13741    && flag_unsafe_math_optimizations")
13742
13743 (define_expand "atan2<mode>3"
13744   [(use (match_operand:MODEF 0 "register_operand" ""))
13745    (use (match_operand:MODEF 1 "register_operand" ""))
13746    (use (match_operand:MODEF 2 "register_operand" ""))]
13747   "TARGET_USE_FANCY_MATH_387
13748    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13749        || TARGET_MIX_SSE_I387)
13750    && flag_unsafe_math_optimizations"
13751 {
13752   rtx op0 = gen_reg_rtx (XFmode);
13753
13754   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13755   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13756   DONE;
13757 })
13758
13759 (define_expand "atanxf2"
13760   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13761                    (unspec:XF [(match_dup 2)
13762                                (match_operand:XF 1 "register_operand" "")]
13763                               UNSPEC_FPATAN))
13764               (clobber (match_scratch:XF 3 ""))])]
13765   "TARGET_USE_FANCY_MATH_387
13766    && flag_unsafe_math_optimizations"
13767 {
13768   operands[2] = gen_reg_rtx (XFmode);
13769   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13770 })
13771
13772 (define_expand "atan<mode>2"
13773   [(use (match_operand:MODEF 0 "register_operand" ""))
13774    (use (match_operand:MODEF 1 "register_operand" ""))]
13775   "TARGET_USE_FANCY_MATH_387
13776    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13777        || TARGET_MIX_SSE_I387)
13778    && flag_unsafe_math_optimizations"
13779 {
13780   rtx op0 = gen_reg_rtx (XFmode);
13781
13782   rtx op2 = gen_reg_rtx (<MODE>mode);
13783   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13784
13785   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13786   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13787   DONE;
13788 })
13789
13790 (define_expand "asinxf2"
13791   [(set (match_dup 2)
13792         (mult:XF (match_operand:XF 1 "register_operand" "")
13793                  (match_dup 1)))
13794    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13795    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13796    (parallel [(set (match_operand:XF 0 "register_operand" "")
13797                    (unspec:XF [(match_dup 5) (match_dup 1)]
13798                               UNSPEC_FPATAN))
13799               (clobber (match_scratch:XF 6 ""))])]
13800   "TARGET_USE_FANCY_MATH_387
13801    && flag_unsafe_math_optimizations"
13802 {
13803   int i;
13804
13805   if (optimize_insn_for_size_p ())
13806     FAIL;
13807
13808   for (i = 2; i < 6; i++)
13809     operands[i] = gen_reg_rtx (XFmode);
13810
13811   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13812 })
13813
13814 (define_expand "asin<mode>2"
13815   [(use (match_operand:MODEF 0 "register_operand" ""))
13816    (use (match_operand:MODEF 1 "general_operand" ""))]
13817  "TARGET_USE_FANCY_MATH_387
13818    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13819        || TARGET_MIX_SSE_I387)
13820    && flag_unsafe_math_optimizations"
13821 {
13822   rtx op0 = gen_reg_rtx (XFmode);
13823   rtx op1 = gen_reg_rtx (XFmode);
13824
13825   if (optimize_insn_for_size_p ())
13826     FAIL;
13827
13828   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13829   emit_insn (gen_asinxf2 (op0, op1));
13830   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13831   DONE;
13832 })
13833
13834 (define_expand "acosxf2"
13835   [(set (match_dup 2)
13836         (mult:XF (match_operand:XF 1 "register_operand" "")
13837                  (match_dup 1)))
13838    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13839    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13840    (parallel [(set (match_operand:XF 0 "register_operand" "")
13841                    (unspec:XF [(match_dup 1) (match_dup 5)]
13842                               UNSPEC_FPATAN))
13843               (clobber (match_scratch:XF 6 ""))])]
13844   "TARGET_USE_FANCY_MATH_387
13845    && flag_unsafe_math_optimizations"
13846 {
13847   int i;
13848
13849   if (optimize_insn_for_size_p ())
13850     FAIL;
13851
13852   for (i = 2; i < 6; i++)
13853     operands[i] = gen_reg_rtx (XFmode);
13854
13855   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13856 })
13857
13858 (define_expand "acos<mode>2"
13859   [(use (match_operand:MODEF 0 "register_operand" ""))
13860    (use (match_operand:MODEF 1 "general_operand" ""))]
13861  "TARGET_USE_FANCY_MATH_387
13862    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13863        || TARGET_MIX_SSE_I387)
13864    && flag_unsafe_math_optimizations"
13865 {
13866   rtx op0 = gen_reg_rtx (XFmode);
13867   rtx op1 = gen_reg_rtx (XFmode);
13868
13869   if (optimize_insn_for_size_p ())
13870     FAIL;
13871
13872   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13873   emit_insn (gen_acosxf2 (op0, op1));
13874   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13875   DONE;
13876 })
13877
13878 (define_insn "fyl2xxf3_i387"
13879   [(set (match_operand:XF 0 "register_operand" "=f")
13880         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13881                     (match_operand:XF 2 "register_operand" "u")]
13882                    UNSPEC_FYL2X))
13883    (clobber (match_scratch:XF 3 "=2"))]
13884   "TARGET_USE_FANCY_MATH_387
13885    && flag_unsafe_math_optimizations"
13886   "fyl2x"
13887   [(set_attr "type" "fpspc")
13888    (set_attr "mode" "XF")])
13889
13890 (define_insn "fyl2x_extend<mode>xf3_i387"
13891   [(set (match_operand:XF 0 "register_operand" "=f")
13892         (unspec:XF [(float_extend:XF
13893                       (match_operand:MODEF 1 "register_operand" "0"))
13894                     (match_operand:XF 2 "register_operand" "u")]
13895                    UNSPEC_FYL2X))
13896    (clobber (match_scratch:XF 3 "=2"))]
13897   "TARGET_USE_FANCY_MATH_387
13898    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13899        || TARGET_MIX_SSE_I387)
13900    && flag_unsafe_math_optimizations"
13901   "fyl2x"
13902   [(set_attr "type" "fpspc")
13903    (set_attr "mode" "XF")])
13904
13905 (define_expand "logxf2"
13906   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13907                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13908                                (match_dup 2)] UNSPEC_FYL2X))
13909               (clobber (match_scratch:XF 3 ""))])]
13910   "TARGET_USE_FANCY_MATH_387
13911    && flag_unsafe_math_optimizations"
13912 {
13913   operands[2] = gen_reg_rtx (XFmode);
13914   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13915 })
13916
13917 (define_expand "log<mode>2"
13918   [(use (match_operand:MODEF 0 "register_operand" ""))
13919    (use (match_operand:MODEF 1 "register_operand" ""))]
13920   "TARGET_USE_FANCY_MATH_387
13921    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13922        || TARGET_MIX_SSE_I387)
13923    && flag_unsafe_math_optimizations"
13924 {
13925   rtx op0 = gen_reg_rtx (XFmode);
13926
13927   rtx op2 = gen_reg_rtx (XFmode);
13928   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13929
13930   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13931   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13932   DONE;
13933 })
13934
13935 (define_expand "log10xf2"
13936   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13937                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13938                                (match_dup 2)] UNSPEC_FYL2X))
13939               (clobber (match_scratch:XF 3 ""))])]
13940   "TARGET_USE_FANCY_MATH_387
13941    && flag_unsafe_math_optimizations"
13942 {
13943   operands[2] = gen_reg_rtx (XFmode);
13944   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13945 })
13946
13947 (define_expand "log10<mode>2"
13948   [(use (match_operand:MODEF 0 "register_operand" ""))
13949    (use (match_operand:MODEF 1 "register_operand" ""))]
13950   "TARGET_USE_FANCY_MATH_387
13951    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13952        || TARGET_MIX_SSE_I387)
13953    && flag_unsafe_math_optimizations"
13954 {
13955   rtx op0 = gen_reg_rtx (XFmode);
13956
13957   rtx op2 = gen_reg_rtx (XFmode);
13958   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13959
13960   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13961   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13962   DONE;
13963 })
13964
13965 (define_expand "log2xf2"
13966   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13967                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13968                                (match_dup 2)] UNSPEC_FYL2X))
13969               (clobber (match_scratch:XF 3 ""))])]
13970   "TARGET_USE_FANCY_MATH_387
13971    && flag_unsafe_math_optimizations"
13972 {
13973   operands[2] = gen_reg_rtx (XFmode);
13974   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13975 })
13976
13977 (define_expand "log2<mode>2"
13978   [(use (match_operand:MODEF 0 "register_operand" ""))
13979    (use (match_operand:MODEF 1 "register_operand" ""))]
13980   "TARGET_USE_FANCY_MATH_387
13981    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13982        || TARGET_MIX_SSE_I387)
13983    && flag_unsafe_math_optimizations"
13984 {
13985   rtx op0 = gen_reg_rtx (XFmode);
13986
13987   rtx op2 = gen_reg_rtx (XFmode);
13988   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13989
13990   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13991   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13992   DONE;
13993 })
13994
13995 (define_insn "fyl2xp1xf3_i387"
13996   [(set (match_operand:XF 0 "register_operand" "=f")
13997         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13998                     (match_operand:XF 2 "register_operand" "u")]
13999                    UNSPEC_FYL2XP1))
14000    (clobber (match_scratch:XF 3 "=2"))]
14001   "TARGET_USE_FANCY_MATH_387
14002    && flag_unsafe_math_optimizations"
14003   "fyl2xp1"
14004   [(set_attr "type" "fpspc")
14005    (set_attr "mode" "XF")])
14006
14007 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14008   [(set (match_operand:XF 0 "register_operand" "=f")
14009         (unspec:XF [(float_extend:XF
14010                       (match_operand:MODEF 1 "register_operand" "0"))
14011                     (match_operand:XF 2 "register_operand" "u")]
14012                    UNSPEC_FYL2XP1))
14013    (clobber (match_scratch:XF 3 "=2"))]
14014   "TARGET_USE_FANCY_MATH_387
14015    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14016        || TARGET_MIX_SSE_I387)
14017    && flag_unsafe_math_optimizations"
14018   "fyl2xp1"
14019   [(set_attr "type" "fpspc")
14020    (set_attr "mode" "XF")])
14021
14022 (define_expand "log1pxf2"
14023   [(use (match_operand:XF 0 "register_operand" ""))
14024    (use (match_operand:XF 1 "register_operand" ""))]
14025   "TARGET_USE_FANCY_MATH_387
14026    && flag_unsafe_math_optimizations"
14027 {
14028   if (optimize_insn_for_size_p ())
14029     FAIL;
14030
14031   ix86_emit_i387_log1p (operands[0], operands[1]);
14032   DONE;
14033 })
14034
14035 (define_expand "log1p<mode>2"
14036   [(use (match_operand:MODEF 0 "register_operand" ""))
14037    (use (match_operand:MODEF 1 "register_operand" ""))]
14038   "TARGET_USE_FANCY_MATH_387
14039    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040        || TARGET_MIX_SSE_I387)
14041    && flag_unsafe_math_optimizations"
14042 {
14043   rtx op0;
14044
14045   if (optimize_insn_for_size_p ())
14046     FAIL;
14047
14048   op0 = gen_reg_rtx (XFmode);
14049
14050   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14051
14052   ix86_emit_i387_log1p (op0, operands[1]);
14053   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054   DONE;
14055 })
14056
14057 (define_insn "fxtractxf3_i387"
14058   [(set (match_operand:XF 0 "register_operand" "=f")
14059         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14060                    UNSPEC_XTRACT_FRACT))
14061    (set (match_operand:XF 1 "register_operand" "=u")
14062         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14063   "TARGET_USE_FANCY_MATH_387
14064    && flag_unsafe_math_optimizations"
14065   "fxtract"
14066   [(set_attr "type" "fpspc")
14067    (set_attr "mode" "XF")])
14068
14069 (define_insn "fxtract_extend<mode>xf3_i387"
14070   [(set (match_operand:XF 0 "register_operand" "=f")
14071         (unspec:XF [(float_extend:XF
14072                       (match_operand:MODEF 2 "register_operand" "0"))]
14073                    UNSPEC_XTRACT_FRACT))
14074    (set (match_operand:XF 1 "register_operand" "=u")
14075         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14076   "TARGET_USE_FANCY_MATH_387
14077    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14078        || TARGET_MIX_SSE_I387)
14079    && flag_unsafe_math_optimizations"
14080   "fxtract"
14081   [(set_attr "type" "fpspc")
14082    (set_attr "mode" "XF")])
14083
14084 (define_expand "logbxf2"
14085   [(parallel [(set (match_dup 2)
14086                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14087                               UNSPEC_XTRACT_FRACT))
14088               (set (match_operand:XF 0 "register_operand" "")
14089                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14090   "TARGET_USE_FANCY_MATH_387
14091    && flag_unsafe_math_optimizations"
14092   "operands[2] = gen_reg_rtx (XFmode);")
14093
14094 (define_expand "logb<mode>2"
14095   [(use (match_operand:MODEF 0 "register_operand" ""))
14096    (use (match_operand:MODEF 1 "register_operand" ""))]
14097   "TARGET_USE_FANCY_MATH_387
14098    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14099        || TARGET_MIX_SSE_I387)
14100    && flag_unsafe_math_optimizations"
14101 {
14102   rtx op0 = gen_reg_rtx (XFmode);
14103   rtx op1 = gen_reg_rtx (XFmode);
14104
14105   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14106   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14107   DONE;
14108 })
14109
14110 (define_expand "ilogbxf2"
14111   [(use (match_operand:SI 0 "register_operand" ""))
14112    (use (match_operand:XF 1 "register_operand" ""))]
14113   "TARGET_USE_FANCY_MATH_387
14114    && flag_unsafe_math_optimizations"
14115 {
14116   rtx op0, op1;
14117
14118   if (optimize_insn_for_size_p ())
14119     FAIL;
14120
14121   op0 = gen_reg_rtx (XFmode);
14122   op1 = gen_reg_rtx (XFmode);
14123
14124   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14125   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14126   DONE;
14127 })
14128
14129 (define_expand "ilogb<mode>2"
14130   [(use (match_operand:SI 0 "register_operand" ""))
14131    (use (match_operand:MODEF 1 "register_operand" ""))]
14132   "TARGET_USE_FANCY_MATH_387
14133    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14134        || TARGET_MIX_SSE_I387)
14135    && flag_unsafe_math_optimizations"
14136 {
14137   rtx op0, op1;
14138
14139   if (optimize_insn_for_size_p ())
14140     FAIL;
14141
14142   op0 = gen_reg_rtx (XFmode);
14143   op1 = gen_reg_rtx (XFmode);
14144
14145   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14146   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14147   DONE;
14148 })
14149
14150 (define_insn "*f2xm1xf2_i387"
14151   [(set (match_operand:XF 0 "register_operand" "=f")
14152         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14153                    UNSPEC_F2XM1))]
14154   "TARGET_USE_FANCY_MATH_387
14155    && flag_unsafe_math_optimizations"
14156   "f2xm1"
14157   [(set_attr "type" "fpspc")
14158    (set_attr "mode" "XF")])
14159
14160 (define_insn "*fscalexf4_i387"
14161   [(set (match_operand:XF 0 "register_operand" "=f")
14162         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14163                     (match_operand:XF 3 "register_operand" "1")]
14164                    UNSPEC_FSCALE_FRACT))
14165    (set (match_operand:XF 1 "register_operand" "=u")
14166         (unspec:XF [(match_dup 2) (match_dup 3)]
14167                    UNSPEC_FSCALE_EXP))]
14168   "TARGET_USE_FANCY_MATH_387
14169    && flag_unsafe_math_optimizations"
14170   "fscale"
14171   [(set_attr "type" "fpspc")
14172    (set_attr "mode" "XF")])
14173
14174 (define_expand "expNcorexf3"
14175   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14176                                (match_operand:XF 2 "register_operand" "")))
14177    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14178    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14179    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14180    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14181    (parallel [(set (match_operand:XF 0 "register_operand" "")
14182                    (unspec:XF [(match_dup 8) (match_dup 4)]
14183                               UNSPEC_FSCALE_FRACT))
14184               (set (match_dup 9)
14185                    (unspec:XF [(match_dup 8) (match_dup 4)]
14186                               UNSPEC_FSCALE_EXP))])]
14187   "TARGET_USE_FANCY_MATH_387
14188    && flag_unsafe_math_optimizations"
14189 {
14190   int i;
14191
14192   if (optimize_insn_for_size_p ())
14193     FAIL;
14194
14195   for (i = 3; i < 10; i++)
14196     operands[i] = gen_reg_rtx (XFmode);
14197
14198   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14199 })
14200
14201 (define_expand "expxf2"
14202   [(use (match_operand:XF 0 "register_operand" ""))
14203    (use (match_operand:XF 1 "register_operand" ""))]
14204   "TARGET_USE_FANCY_MATH_387
14205    && flag_unsafe_math_optimizations"
14206 {
14207   rtx op2;
14208
14209   if (optimize_insn_for_size_p ())
14210     FAIL;
14211
14212   op2 = gen_reg_rtx (XFmode);
14213   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14214
14215   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14216   DONE;
14217 })
14218
14219 (define_expand "exp<mode>2"
14220   [(use (match_operand:MODEF 0 "register_operand" ""))
14221    (use (match_operand:MODEF 1 "general_operand" ""))]
14222  "TARGET_USE_FANCY_MATH_387
14223    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14224        || TARGET_MIX_SSE_I387)
14225    && flag_unsafe_math_optimizations"
14226 {
14227   rtx op0, op1;
14228
14229   if (optimize_insn_for_size_p ())
14230     FAIL;
14231
14232   op0 = gen_reg_rtx (XFmode);
14233   op1 = gen_reg_rtx (XFmode);
14234
14235   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14236   emit_insn (gen_expxf2 (op0, op1));
14237   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14238   DONE;
14239 })
14240
14241 (define_expand "exp10xf2"
14242   [(use (match_operand:XF 0 "register_operand" ""))
14243    (use (match_operand:XF 1 "register_operand" ""))]
14244   "TARGET_USE_FANCY_MATH_387
14245    && flag_unsafe_math_optimizations"
14246 {
14247   rtx op2;
14248
14249   if (optimize_insn_for_size_p ())
14250     FAIL;
14251
14252   op2 = gen_reg_rtx (XFmode);
14253   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14254
14255   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14256   DONE;
14257 })
14258
14259 (define_expand "exp10<mode>2"
14260   [(use (match_operand:MODEF 0 "register_operand" ""))
14261    (use (match_operand:MODEF 1 "general_operand" ""))]
14262  "TARGET_USE_FANCY_MATH_387
14263    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264        || TARGET_MIX_SSE_I387)
14265    && flag_unsafe_math_optimizations"
14266 {
14267   rtx op0, op1;
14268
14269   if (optimize_insn_for_size_p ())
14270     FAIL;
14271
14272   op0 = gen_reg_rtx (XFmode);
14273   op1 = gen_reg_rtx (XFmode);
14274
14275   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14276   emit_insn (gen_exp10xf2 (op0, op1));
14277   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14278   DONE;
14279 })
14280
14281 (define_expand "exp2xf2"
14282   [(use (match_operand:XF 0 "register_operand" ""))
14283    (use (match_operand:XF 1 "register_operand" ""))]
14284   "TARGET_USE_FANCY_MATH_387
14285    && flag_unsafe_math_optimizations"
14286 {
14287   rtx op2;
14288
14289   if (optimize_insn_for_size_p ())
14290     FAIL;
14291
14292   op2 = gen_reg_rtx (XFmode);
14293   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14294
14295   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14296   DONE;
14297 })
14298
14299 (define_expand "exp2<mode>2"
14300   [(use (match_operand:MODEF 0 "register_operand" ""))
14301    (use (match_operand:MODEF 1 "general_operand" ""))]
14302  "TARGET_USE_FANCY_MATH_387
14303    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14304        || TARGET_MIX_SSE_I387)
14305    && flag_unsafe_math_optimizations"
14306 {
14307   rtx op0, op1;
14308
14309   if (optimize_insn_for_size_p ())
14310     FAIL;
14311
14312   op0 = gen_reg_rtx (XFmode);
14313   op1 = gen_reg_rtx (XFmode);
14314
14315   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14316   emit_insn (gen_exp2xf2 (op0, op1));
14317   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14318   DONE;
14319 })
14320
14321 (define_expand "expm1xf2"
14322   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14323                                (match_dup 2)))
14324    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14325    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14326    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14327    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14328    (parallel [(set (match_dup 7)
14329                    (unspec:XF [(match_dup 6) (match_dup 4)]
14330                               UNSPEC_FSCALE_FRACT))
14331               (set (match_dup 8)
14332                    (unspec:XF [(match_dup 6) (match_dup 4)]
14333                               UNSPEC_FSCALE_EXP))])
14334    (parallel [(set (match_dup 10)
14335                    (unspec:XF [(match_dup 9) (match_dup 8)]
14336                               UNSPEC_FSCALE_FRACT))
14337               (set (match_dup 11)
14338                    (unspec:XF [(match_dup 9) (match_dup 8)]
14339                               UNSPEC_FSCALE_EXP))])
14340    (set (match_dup 12) (minus:XF (match_dup 10)
14341                                  (float_extend:XF (match_dup 13))))
14342    (set (match_operand:XF 0 "register_operand" "")
14343         (plus:XF (match_dup 12) (match_dup 7)))]
14344   "TARGET_USE_FANCY_MATH_387
14345    && flag_unsafe_math_optimizations"
14346 {
14347   int i;
14348
14349   if (optimize_insn_for_size_p ())
14350     FAIL;
14351
14352   for (i = 2; i < 13; i++)
14353     operands[i] = gen_reg_rtx (XFmode);
14354
14355   operands[13]
14356     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14357
14358   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14359 })
14360
14361 (define_expand "expm1<mode>2"
14362   [(use (match_operand:MODEF 0 "register_operand" ""))
14363    (use (match_operand:MODEF 1 "general_operand" ""))]
14364  "TARGET_USE_FANCY_MATH_387
14365    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14366        || TARGET_MIX_SSE_I387)
14367    && flag_unsafe_math_optimizations"
14368 {
14369   rtx op0, op1;
14370
14371   if (optimize_insn_for_size_p ())
14372     FAIL;
14373
14374   op0 = gen_reg_rtx (XFmode);
14375   op1 = gen_reg_rtx (XFmode);
14376
14377   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14378   emit_insn (gen_expm1xf2 (op0, op1));
14379   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14380   DONE;
14381 })
14382
14383 (define_expand "ldexpxf3"
14384   [(set (match_dup 3)
14385         (float:XF (match_operand:SI 2 "register_operand" "")))
14386    (parallel [(set (match_operand:XF 0 " register_operand" "")
14387                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14388                                (match_dup 3)]
14389                               UNSPEC_FSCALE_FRACT))
14390               (set (match_dup 4)
14391                    (unspec:XF [(match_dup 1) (match_dup 3)]
14392                               UNSPEC_FSCALE_EXP))])]
14393   "TARGET_USE_FANCY_MATH_387
14394    && flag_unsafe_math_optimizations"
14395 {
14396   if (optimize_insn_for_size_p ())
14397     FAIL;
14398
14399   operands[3] = gen_reg_rtx (XFmode);
14400   operands[4] = gen_reg_rtx (XFmode);
14401 })
14402
14403 (define_expand "ldexp<mode>3"
14404   [(use (match_operand:MODEF 0 "register_operand" ""))
14405    (use (match_operand:MODEF 1 "general_operand" ""))
14406    (use (match_operand:SI 2 "register_operand" ""))]
14407  "TARGET_USE_FANCY_MATH_387
14408    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14409        || TARGET_MIX_SSE_I387)
14410    && flag_unsafe_math_optimizations"
14411 {
14412   rtx op0, op1;
14413
14414   if (optimize_insn_for_size_p ())
14415     FAIL;
14416
14417   op0 = gen_reg_rtx (XFmode);
14418   op1 = gen_reg_rtx (XFmode);
14419
14420   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14421   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14422   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14423   DONE;
14424 })
14425
14426 (define_expand "scalbxf3"
14427   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14428                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14429                                (match_operand:XF 2 "register_operand" "")]
14430                               UNSPEC_FSCALE_FRACT))
14431               (set (match_dup 3)
14432                    (unspec:XF [(match_dup 1) (match_dup 2)]
14433                               UNSPEC_FSCALE_EXP))])]
14434   "TARGET_USE_FANCY_MATH_387
14435    && flag_unsafe_math_optimizations"
14436 {
14437   if (optimize_insn_for_size_p ())
14438     FAIL;
14439
14440   operands[3] = gen_reg_rtx (XFmode);
14441 })
14442
14443 (define_expand "scalb<mode>3"
14444   [(use (match_operand:MODEF 0 "register_operand" ""))
14445    (use (match_operand:MODEF 1 "general_operand" ""))
14446    (use (match_operand:MODEF 2 "general_operand" ""))]
14447  "TARGET_USE_FANCY_MATH_387
14448    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449        || TARGET_MIX_SSE_I387)
14450    && flag_unsafe_math_optimizations"
14451 {
14452   rtx op0, op1, op2;
14453
14454   if (optimize_insn_for_size_p ())
14455     FAIL;
14456
14457   op0 = gen_reg_rtx (XFmode);
14458   op1 = gen_reg_rtx (XFmode);
14459   op2 = gen_reg_rtx (XFmode);
14460
14461   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14462   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14463   emit_insn (gen_scalbxf3 (op0, op1, op2));
14464   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14465   DONE;
14466 })
14467
14468 (define_expand "significandxf2"
14469   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14470                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14471                               UNSPEC_XTRACT_FRACT))
14472               (set (match_dup 2)
14473                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14474   "TARGET_USE_FANCY_MATH_387
14475    && flag_unsafe_math_optimizations"
14476   "operands[2] = gen_reg_rtx (XFmode);")
14477
14478 (define_expand "significand<mode>2"
14479   [(use (match_operand:MODEF 0 "register_operand" ""))
14480    (use (match_operand:MODEF 1 "register_operand" ""))]
14481   "TARGET_USE_FANCY_MATH_387
14482    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14483        || TARGET_MIX_SSE_I387)
14484    && flag_unsafe_math_optimizations"
14485 {
14486   rtx op0 = gen_reg_rtx (XFmode);
14487   rtx op1 = gen_reg_rtx (XFmode);
14488
14489   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14490   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14491   DONE;
14492 })
14493 \f
14494
14495 (define_insn "sse4_1_round<mode>2"
14496   [(set (match_operand:MODEF 0 "register_operand" "=x")
14497         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14498                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14499                       UNSPEC_ROUND))]
14500   "TARGET_ROUND"
14501   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14502   [(set_attr "type" "ssecvt")
14503    (set_attr "prefix_extra" "1")
14504    (set_attr "prefix" "maybe_vex")
14505    (set_attr "mode" "<MODE>")])
14506
14507 (define_insn "rintxf2"
14508   [(set (match_operand:XF 0 "register_operand" "=f")
14509         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14510                    UNSPEC_FRNDINT))]
14511   "TARGET_USE_FANCY_MATH_387
14512    && flag_unsafe_math_optimizations"
14513   "frndint"
14514   [(set_attr "type" "fpspc")
14515    (set_attr "mode" "XF")])
14516
14517 (define_expand "rint<mode>2"
14518   [(use (match_operand:MODEF 0 "register_operand" ""))
14519    (use (match_operand:MODEF 1 "register_operand" ""))]
14520   "(TARGET_USE_FANCY_MATH_387
14521     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14522         || TARGET_MIX_SSE_I387)
14523     && flag_unsafe_math_optimizations)
14524    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14525        && !flag_trapping_math)"
14526 {
14527   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14528       && !flag_trapping_math)
14529     {
14530       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14531         FAIL;
14532       if (TARGET_ROUND)
14533         emit_insn (gen_sse4_1_round<mode>2
14534                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14535       else
14536         ix86_expand_rint (operand0, operand1);
14537     }
14538   else
14539     {
14540       rtx op0 = gen_reg_rtx (XFmode);
14541       rtx op1 = gen_reg_rtx (XFmode);
14542
14543       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14544       emit_insn (gen_rintxf2 (op0, op1));
14545
14546       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14547     }
14548   DONE;
14549 })
14550
14551 (define_expand "round<mode>2"
14552   [(match_operand:MODEF 0 "register_operand" "")
14553    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14554   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14555    && !flag_trapping_math && !flag_rounding_math"
14556 {
14557   if (optimize_insn_for_size_p ())
14558     FAIL;
14559   if (TARGET_64BIT || (<MODE>mode != DFmode))
14560     ix86_expand_round (operand0, operand1);
14561   else
14562     ix86_expand_rounddf_32 (operand0, operand1);
14563   DONE;
14564 })
14565
14566 (define_insn_and_split "*fistdi2_1"
14567   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14568         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14569                    UNSPEC_FIST))]
14570   "TARGET_USE_FANCY_MATH_387
14571    && can_create_pseudo_p ()"
14572   "#"
14573   "&& 1"
14574   [(const_int 0)]
14575 {
14576   if (memory_operand (operands[0], VOIDmode))
14577     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14578   else
14579     {
14580       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14581       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14582                                          operands[2]));
14583     }
14584   DONE;
14585 }
14586   [(set_attr "type" "fpspc")
14587    (set_attr "mode" "DI")])
14588
14589 (define_insn "fistdi2"
14590   [(set (match_operand:DI 0 "memory_operand" "=m")
14591         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14592                    UNSPEC_FIST))
14593    (clobber (match_scratch:XF 2 "=&1f"))]
14594   "TARGET_USE_FANCY_MATH_387"
14595   "* return output_fix_trunc (insn, operands, 0);"
14596   [(set_attr "type" "fpspc")
14597    (set_attr "mode" "DI")])
14598
14599 (define_insn "fistdi2_with_temp"
14600   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14601         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14602                    UNSPEC_FIST))
14603    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14604    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14605   "TARGET_USE_FANCY_MATH_387"
14606   "#"
14607   [(set_attr "type" "fpspc")
14608    (set_attr "mode" "DI")])
14609
14610 (define_split
14611   [(set (match_operand:DI 0 "register_operand" "")
14612         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14613                    UNSPEC_FIST))
14614    (clobber (match_operand:DI 2 "memory_operand" ""))
14615    (clobber (match_scratch 3 ""))]
14616   "reload_completed"
14617   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14618               (clobber (match_dup 3))])
14619    (set (match_dup 0) (match_dup 2))])
14620
14621 (define_split
14622   [(set (match_operand:DI 0 "memory_operand" "")
14623         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14624                    UNSPEC_FIST))
14625    (clobber (match_operand:DI 2 "memory_operand" ""))
14626    (clobber (match_scratch 3 ""))]
14627   "reload_completed"
14628   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14629               (clobber (match_dup 3))])])
14630
14631 (define_insn_and_split "*fist<mode>2_1"
14632   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14633         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14634                            UNSPEC_FIST))]
14635   "TARGET_USE_FANCY_MATH_387
14636    && can_create_pseudo_p ()"
14637   "#"
14638   "&& 1"
14639   [(const_int 0)]
14640 {
14641   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14642   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14643                                         operands[2]));
14644   DONE;
14645 }
14646   [(set_attr "type" "fpspc")
14647    (set_attr "mode" "<MODE>")])
14648
14649 (define_insn "fist<mode>2"
14650   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14651         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14652                            UNSPEC_FIST))]
14653   "TARGET_USE_FANCY_MATH_387"
14654   "* return output_fix_trunc (insn, operands, 0);"
14655   [(set_attr "type" "fpspc")
14656    (set_attr "mode" "<MODE>")])
14657
14658 (define_insn "fist<mode>2_with_temp"
14659   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14660         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14661                            UNSPEC_FIST))
14662    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14663   "TARGET_USE_FANCY_MATH_387"
14664   "#"
14665   [(set_attr "type" "fpspc")
14666    (set_attr "mode" "<MODE>")])
14667
14668 (define_split
14669   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14670         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14671                            UNSPEC_FIST))
14672    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14673   "reload_completed"
14674   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14675    (set (match_dup 0) (match_dup 2))])
14676
14677 (define_split
14678   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14679         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14680                            UNSPEC_FIST))
14681    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14682   "reload_completed"
14683   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14684
14685 (define_expand "lrintxf<mode>2"
14686   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14687      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14688                       UNSPEC_FIST))]
14689   "TARGET_USE_FANCY_MATH_387")
14690
14691 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14692   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14693      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14694                         UNSPEC_FIX_NOTRUNC))]
14695   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14696    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14697
14698 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14699   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14700    (match_operand:MODEF 1 "register_operand" "")]
14701   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14702    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14703    && !flag_trapping_math && !flag_rounding_math"
14704 {
14705   if (optimize_insn_for_size_p ())
14706     FAIL;
14707   ix86_expand_lround (operand0, operand1);
14708   DONE;
14709 })
14710
14711 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14712 (define_insn_and_split "frndintxf2_floor"
14713   [(set (match_operand:XF 0 "register_operand" "")
14714         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14715          UNSPEC_FRNDINT_FLOOR))
14716    (clobber (reg:CC FLAGS_REG))]
14717   "TARGET_USE_FANCY_MATH_387
14718    && flag_unsafe_math_optimizations
14719    && can_create_pseudo_p ()"
14720   "#"
14721   "&& 1"
14722   [(const_int 0)]
14723 {
14724   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14725
14726   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14727   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14728
14729   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14730                                         operands[2], operands[3]));
14731   DONE;
14732 }
14733   [(set_attr "type" "frndint")
14734    (set_attr "i387_cw" "floor")
14735    (set_attr "mode" "XF")])
14736
14737 (define_insn "frndintxf2_floor_i387"
14738   [(set (match_operand:XF 0 "register_operand" "=f")
14739         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14740          UNSPEC_FRNDINT_FLOOR))
14741    (use (match_operand:HI 2 "memory_operand" "m"))
14742    (use (match_operand:HI 3 "memory_operand" "m"))]
14743   "TARGET_USE_FANCY_MATH_387
14744    && flag_unsafe_math_optimizations"
14745   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14746   [(set_attr "type" "frndint")
14747    (set_attr "i387_cw" "floor")
14748    (set_attr "mode" "XF")])
14749
14750 (define_expand "floorxf2"
14751   [(use (match_operand:XF 0 "register_operand" ""))
14752    (use (match_operand:XF 1 "register_operand" ""))]
14753   "TARGET_USE_FANCY_MATH_387
14754    && flag_unsafe_math_optimizations"
14755 {
14756   if (optimize_insn_for_size_p ())
14757     FAIL;
14758   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14759   DONE;
14760 })
14761
14762 (define_expand "floor<mode>2"
14763   [(use (match_operand:MODEF 0 "register_operand" ""))
14764    (use (match_operand:MODEF 1 "register_operand" ""))]
14765   "(TARGET_USE_FANCY_MATH_387
14766     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14767         || TARGET_MIX_SSE_I387)
14768     && flag_unsafe_math_optimizations)
14769    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14770        && !flag_trapping_math)"
14771 {
14772   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14773       && !flag_trapping_math
14774       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14775     {
14776       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14777         FAIL;
14778       if (TARGET_ROUND)
14779         emit_insn (gen_sse4_1_round<mode>2
14780                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14781       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14782         ix86_expand_floorceil (operand0, operand1, true);
14783       else
14784         ix86_expand_floorceildf_32 (operand0, operand1, true);
14785     }
14786   else
14787     {
14788       rtx op0, op1;
14789
14790       if (optimize_insn_for_size_p ())
14791         FAIL;
14792
14793       op0 = gen_reg_rtx (XFmode);
14794       op1 = gen_reg_rtx (XFmode);
14795       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14796       emit_insn (gen_frndintxf2_floor (op0, op1));
14797
14798       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14799     }
14800   DONE;
14801 })
14802
14803 (define_insn_and_split "*fist<mode>2_floor_1"
14804   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14805         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14806          UNSPEC_FIST_FLOOR))
14807    (clobber (reg:CC FLAGS_REG))]
14808   "TARGET_USE_FANCY_MATH_387
14809    && flag_unsafe_math_optimizations
14810    && can_create_pseudo_p ()"
14811   "#"
14812   "&& 1"
14813   [(const_int 0)]
14814 {
14815   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14816
14817   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14818   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14819   if (memory_operand (operands[0], VOIDmode))
14820     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14821                                       operands[2], operands[3]));
14822   else
14823     {
14824       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14825       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14826                                                   operands[2], operands[3],
14827                                                   operands[4]));
14828     }
14829   DONE;
14830 }
14831   [(set_attr "type" "fistp")
14832    (set_attr "i387_cw" "floor")
14833    (set_attr "mode" "<MODE>")])
14834
14835 (define_insn "fistdi2_floor"
14836   [(set (match_operand:DI 0 "memory_operand" "=m")
14837         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14838          UNSPEC_FIST_FLOOR))
14839    (use (match_operand:HI 2 "memory_operand" "m"))
14840    (use (match_operand:HI 3 "memory_operand" "m"))
14841    (clobber (match_scratch:XF 4 "=&1f"))]
14842   "TARGET_USE_FANCY_MATH_387
14843    && flag_unsafe_math_optimizations"
14844   "* return output_fix_trunc (insn, operands, 0);"
14845   [(set_attr "type" "fistp")
14846    (set_attr "i387_cw" "floor")
14847    (set_attr "mode" "DI")])
14848
14849 (define_insn "fistdi2_floor_with_temp"
14850   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14851         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14852          UNSPEC_FIST_FLOOR))
14853    (use (match_operand:HI 2 "memory_operand" "m,m"))
14854    (use (match_operand:HI 3 "memory_operand" "m,m"))
14855    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14856    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14857   "TARGET_USE_FANCY_MATH_387
14858    && flag_unsafe_math_optimizations"
14859   "#"
14860   [(set_attr "type" "fistp")
14861    (set_attr "i387_cw" "floor")
14862    (set_attr "mode" "DI")])
14863
14864 (define_split
14865   [(set (match_operand:DI 0 "register_operand" "")
14866         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14867          UNSPEC_FIST_FLOOR))
14868    (use (match_operand:HI 2 "memory_operand" ""))
14869    (use (match_operand:HI 3 "memory_operand" ""))
14870    (clobber (match_operand:DI 4 "memory_operand" ""))
14871    (clobber (match_scratch 5 ""))]
14872   "reload_completed"
14873   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14874               (use (match_dup 2))
14875               (use (match_dup 3))
14876               (clobber (match_dup 5))])
14877    (set (match_dup 0) (match_dup 4))])
14878
14879 (define_split
14880   [(set (match_operand:DI 0 "memory_operand" "")
14881         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14882          UNSPEC_FIST_FLOOR))
14883    (use (match_operand:HI 2 "memory_operand" ""))
14884    (use (match_operand:HI 3 "memory_operand" ""))
14885    (clobber (match_operand:DI 4 "memory_operand" ""))
14886    (clobber (match_scratch 5 ""))]
14887   "reload_completed"
14888   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14889               (use (match_dup 2))
14890               (use (match_dup 3))
14891               (clobber (match_dup 5))])])
14892
14893 (define_insn "fist<mode>2_floor"
14894   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14895         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14896          UNSPEC_FIST_FLOOR))
14897    (use (match_operand:HI 2 "memory_operand" "m"))
14898    (use (match_operand:HI 3 "memory_operand" "m"))]
14899   "TARGET_USE_FANCY_MATH_387
14900    && flag_unsafe_math_optimizations"
14901   "* return output_fix_trunc (insn, operands, 0);"
14902   [(set_attr "type" "fistp")
14903    (set_attr "i387_cw" "floor")
14904    (set_attr "mode" "<MODE>")])
14905
14906 (define_insn "fist<mode>2_floor_with_temp"
14907   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14908         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14909          UNSPEC_FIST_FLOOR))
14910    (use (match_operand:HI 2 "memory_operand" "m,m"))
14911    (use (match_operand:HI 3 "memory_operand" "m,m"))
14912    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14913   "TARGET_USE_FANCY_MATH_387
14914    && flag_unsafe_math_optimizations"
14915   "#"
14916   [(set_attr "type" "fistp")
14917    (set_attr "i387_cw" "floor")
14918    (set_attr "mode" "<MODE>")])
14919
14920 (define_split
14921   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14922         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14923          UNSPEC_FIST_FLOOR))
14924    (use (match_operand:HI 2 "memory_operand" ""))
14925    (use (match_operand:HI 3 "memory_operand" ""))
14926    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14927   "reload_completed"
14928   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14929                                   UNSPEC_FIST_FLOOR))
14930               (use (match_dup 2))
14931               (use (match_dup 3))])
14932    (set (match_dup 0) (match_dup 4))])
14933
14934 (define_split
14935   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14936         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14937          UNSPEC_FIST_FLOOR))
14938    (use (match_operand:HI 2 "memory_operand" ""))
14939    (use (match_operand:HI 3 "memory_operand" ""))
14940    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14941   "reload_completed"
14942   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14943                                   UNSPEC_FIST_FLOOR))
14944               (use (match_dup 2))
14945               (use (match_dup 3))])])
14946
14947 (define_expand "lfloorxf<mode>2"
14948   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14949                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14950                     UNSPEC_FIST_FLOOR))
14951               (clobber (reg:CC FLAGS_REG))])]
14952   "TARGET_USE_FANCY_MATH_387
14953    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14954    && flag_unsafe_math_optimizations")
14955
14956 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14957   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14958    (match_operand:MODEF 1 "register_operand" "")]
14959   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14960    && !flag_trapping_math"
14961 {
14962   if (TARGET_64BIT && optimize_insn_for_size_p ())
14963     FAIL;
14964   ix86_expand_lfloorceil (operand0, operand1, true);
14965   DONE;
14966 })
14967
14968 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14969 (define_insn_and_split "frndintxf2_ceil"
14970   [(set (match_operand:XF 0 "register_operand" "")
14971         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14972          UNSPEC_FRNDINT_CEIL))
14973    (clobber (reg:CC FLAGS_REG))]
14974   "TARGET_USE_FANCY_MATH_387
14975    && flag_unsafe_math_optimizations
14976    && can_create_pseudo_p ()"
14977   "#"
14978   "&& 1"
14979   [(const_int 0)]
14980 {
14981   ix86_optimize_mode_switching[I387_CEIL] = 1;
14982
14983   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14984   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14985
14986   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14987                                        operands[2], operands[3]));
14988   DONE;
14989 }
14990   [(set_attr "type" "frndint")
14991    (set_attr "i387_cw" "ceil")
14992    (set_attr "mode" "XF")])
14993
14994 (define_insn "frndintxf2_ceil_i387"
14995   [(set (match_operand:XF 0 "register_operand" "=f")
14996         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14997          UNSPEC_FRNDINT_CEIL))
14998    (use (match_operand:HI 2 "memory_operand" "m"))
14999    (use (match_operand:HI 3 "memory_operand" "m"))]
15000   "TARGET_USE_FANCY_MATH_387
15001    && flag_unsafe_math_optimizations"
15002   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15003   [(set_attr "type" "frndint")
15004    (set_attr "i387_cw" "ceil")
15005    (set_attr "mode" "XF")])
15006
15007 (define_expand "ceilxf2"
15008   [(use (match_operand:XF 0 "register_operand" ""))
15009    (use (match_operand:XF 1 "register_operand" ""))]
15010   "TARGET_USE_FANCY_MATH_387
15011    && flag_unsafe_math_optimizations"
15012 {
15013   if (optimize_insn_for_size_p ())
15014     FAIL;
15015   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15016   DONE;
15017 })
15018
15019 (define_expand "ceil<mode>2"
15020   [(use (match_operand:MODEF 0 "register_operand" ""))
15021    (use (match_operand:MODEF 1 "register_operand" ""))]
15022   "(TARGET_USE_FANCY_MATH_387
15023     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15024         || TARGET_MIX_SSE_I387)
15025     && flag_unsafe_math_optimizations)
15026    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15027        && !flag_trapping_math)"
15028 {
15029   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15030       && !flag_trapping_math
15031       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15032     {
15033       if (TARGET_ROUND)
15034         emit_insn (gen_sse4_1_round<mode>2
15035                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15036       else if (optimize_insn_for_size_p ())
15037         FAIL;
15038       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15039         ix86_expand_floorceil (operand0, operand1, false);
15040       else
15041         ix86_expand_floorceildf_32 (operand0, operand1, false);
15042     }
15043   else
15044     {
15045       rtx op0, op1;
15046
15047       if (optimize_insn_for_size_p ())
15048         FAIL;
15049
15050       op0 = gen_reg_rtx (XFmode);
15051       op1 = gen_reg_rtx (XFmode);
15052       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15053       emit_insn (gen_frndintxf2_ceil (op0, op1));
15054
15055       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15056     }
15057   DONE;
15058 })
15059
15060 (define_insn_and_split "*fist<mode>2_ceil_1"
15061   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15062         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15063          UNSPEC_FIST_CEIL))
15064    (clobber (reg:CC FLAGS_REG))]
15065   "TARGET_USE_FANCY_MATH_387
15066    && flag_unsafe_math_optimizations
15067    && can_create_pseudo_p ()"
15068   "#"
15069   "&& 1"
15070   [(const_int 0)]
15071 {
15072   ix86_optimize_mode_switching[I387_CEIL] = 1;
15073
15074   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15075   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15076   if (memory_operand (operands[0], VOIDmode))
15077     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15078                                      operands[2], operands[3]));
15079   else
15080     {
15081       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15082       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15083                                                  operands[2], operands[3],
15084                                                  operands[4]));
15085     }
15086   DONE;
15087 }
15088   [(set_attr "type" "fistp")
15089    (set_attr "i387_cw" "ceil")
15090    (set_attr "mode" "<MODE>")])
15091
15092 (define_insn "fistdi2_ceil"
15093   [(set (match_operand:DI 0 "memory_operand" "=m")
15094         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15095          UNSPEC_FIST_CEIL))
15096    (use (match_operand:HI 2 "memory_operand" "m"))
15097    (use (match_operand:HI 3 "memory_operand" "m"))
15098    (clobber (match_scratch:XF 4 "=&1f"))]
15099   "TARGET_USE_FANCY_MATH_387
15100    && flag_unsafe_math_optimizations"
15101   "* return output_fix_trunc (insn, operands, 0);"
15102   [(set_attr "type" "fistp")
15103    (set_attr "i387_cw" "ceil")
15104    (set_attr "mode" "DI")])
15105
15106 (define_insn "fistdi2_ceil_with_temp"
15107   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15108         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15109          UNSPEC_FIST_CEIL))
15110    (use (match_operand:HI 2 "memory_operand" "m,m"))
15111    (use (match_operand:HI 3 "memory_operand" "m,m"))
15112    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15113    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15114   "TARGET_USE_FANCY_MATH_387
15115    && flag_unsafe_math_optimizations"
15116   "#"
15117   [(set_attr "type" "fistp")
15118    (set_attr "i387_cw" "ceil")
15119    (set_attr "mode" "DI")])
15120
15121 (define_split
15122   [(set (match_operand:DI 0 "register_operand" "")
15123         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15124          UNSPEC_FIST_CEIL))
15125    (use (match_operand:HI 2 "memory_operand" ""))
15126    (use (match_operand:HI 3 "memory_operand" ""))
15127    (clobber (match_operand:DI 4 "memory_operand" ""))
15128    (clobber (match_scratch 5 ""))]
15129   "reload_completed"
15130   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15131               (use (match_dup 2))
15132               (use (match_dup 3))
15133               (clobber (match_dup 5))])
15134    (set (match_dup 0) (match_dup 4))])
15135
15136 (define_split
15137   [(set (match_operand:DI 0 "memory_operand" "")
15138         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15139          UNSPEC_FIST_CEIL))
15140    (use (match_operand:HI 2 "memory_operand" ""))
15141    (use (match_operand:HI 3 "memory_operand" ""))
15142    (clobber (match_operand:DI 4 "memory_operand" ""))
15143    (clobber (match_scratch 5 ""))]
15144   "reload_completed"
15145   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15146               (use (match_dup 2))
15147               (use (match_dup 3))
15148               (clobber (match_dup 5))])])
15149
15150 (define_insn "fist<mode>2_ceil"
15151   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15152         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15153          UNSPEC_FIST_CEIL))
15154    (use (match_operand:HI 2 "memory_operand" "m"))
15155    (use (match_operand:HI 3 "memory_operand" "m"))]
15156   "TARGET_USE_FANCY_MATH_387
15157    && flag_unsafe_math_optimizations"
15158   "* return output_fix_trunc (insn, operands, 0);"
15159   [(set_attr "type" "fistp")
15160    (set_attr "i387_cw" "ceil")
15161    (set_attr "mode" "<MODE>")])
15162
15163 (define_insn "fist<mode>2_ceil_with_temp"
15164   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15165         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15166          UNSPEC_FIST_CEIL))
15167    (use (match_operand:HI 2 "memory_operand" "m,m"))
15168    (use (match_operand:HI 3 "memory_operand" "m,m"))
15169    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15170   "TARGET_USE_FANCY_MATH_387
15171    && flag_unsafe_math_optimizations"
15172   "#"
15173   [(set_attr "type" "fistp")
15174    (set_attr "i387_cw" "ceil")
15175    (set_attr "mode" "<MODE>")])
15176
15177 (define_split
15178   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15179         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15180          UNSPEC_FIST_CEIL))
15181    (use (match_operand:HI 2 "memory_operand" ""))
15182    (use (match_operand:HI 3 "memory_operand" ""))
15183    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15184   "reload_completed"
15185   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15186                                   UNSPEC_FIST_CEIL))
15187               (use (match_dup 2))
15188               (use (match_dup 3))])
15189    (set (match_dup 0) (match_dup 4))])
15190
15191 (define_split
15192   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15193         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15194          UNSPEC_FIST_CEIL))
15195    (use (match_operand:HI 2 "memory_operand" ""))
15196    (use (match_operand:HI 3 "memory_operand" ""))
15197    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15198   "reload_completed"
15199   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15200                                   UNSPEC_FIST_CEIL))
15201               (use (match_dup 2))
15202               (use (match_dup 3))])])
15203
15204 (define_expand "lceilxf<mode>2"
15205   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15206                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15207                     UNSPEC_FIST_CEIL))
15208               (clobber (reg:CC FLAGS_REG))])]
15209   "TARGET_USE_FANCY_MATH_387
15210    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15211    && flag_unsafe_math_optimizations")
15212
15213 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15214   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15215    (match_operand:MODEF 1 "register_operand" "")]
15216   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15217    && !flag_trapping_math"
15218 {
15219   ix86_expand_lfloorceil (operand0, operand1, false);
15220   DONE;
15221 })
15222
15223 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15224 (define_insn_and_split "frndintxf2_trunc"
15225   [(set (match_operand:XF 0 "register_operand" "")
15226         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15227          UNSPEC_FRNDINT_TRUNC))
15228    (clobber (reg:CC FLAGS_REG))]
15229   "TARGET_USE_FANCY_MATH_387
15230    && flag_unsafe_math_optimizations
15231    && can_create_pseudo_p ()"
15232   "#"
15233   "&& 1"
15234   [(const_int 0)]
15235 {
15236   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15237
15238   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15239   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15240
15241   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15242                                         operands[2], operands[3]));
15243   DONE;
15244 }
15245   [(set_attr "type" "frndint")
15246    (set_attr "i387_cw" "trunc")
15247    (set_attr "mode" "XF")])
15248
15249 (define_insn "frndintxf2_trunc_i387"
15250   [(set (match_operand:XF 0 "register_operand" "=f")
15251         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15252          UNSPEC_FRNDINT_TRUNC))
15253    (use (match_operand:HI 2 "memory_operand" "m"))
15254    (use (match_operand:HI 3 "memory_operand" "m"))]
15255   "TARGET_USE_FANCY_MATH_387
15256    && flag_unsafe_math_optimizations"
15257   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15258   [(set_attr "type" "frndint")
15259    (set_attr "i387_cw" "trunc")
15260    (set_attr "mode" "XF")])
15261
15262 (define_expand "btruncxf2"
15263   [(use (match_operand:XF 0 "register_operand" ""))
15264    (use (match_operand:XF 1 "register_operand" ""))]
15265   "TARGET_USE_FANCY_MATH_387
15266    && flag_unsafe_math_optimizations"
15267 {
15268   if (optimize_insn_for_size_p ())
15269     FAIL;
15270   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15271   DONE;
15272 })
15273
15274 (define_expand "btrunc<mode>2"
15275   [(use (match_operand:MODEF 0 "register_operand" ""))
15276    (use (match_operand:MODEF 1 "register_operand" ""))]
15277   "(TARGET_USE_FANCY_MATH_387
15278     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15279         || TARGET_MIX_SSE_I387)
15280     && flag_unsafe_math_optimizations)
15281    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15282        && !flag_trapping_math)"
15283 {
15284   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15285       && !flag_trapping_math
15286       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15287     {
15288       if (TARGET_ROUND)
15289         emit_insn (gen_sse4_1_round<mode>2
15290                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15291       else if (optimize_insn_for_size_p ())
15292         FAIL;
15293       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15294         ix86_expand_trunc (operand0, operand1);
15295       else
15296         ix86_expand_truncdf_32 (operand0, operand1);
15297     }
15298   else
15299     {
15300       rtx op0, op1;
15301
15302       if (optimize_insn_for_size_p ())
15303         FAIL;
15304
15305       op0 = gen_reg_rtx (XFmode);
15306       op1 = gen_reg_rtx (XFmode);
15307       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15308       emit_insn (gen_frndintxf2_trunc (op0, op1));
15309
15310       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15311     }
15312   DONE;
15313 })
15314
15315 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15316 (define_insn_and_split "frndintxf2_mask_pm"
15317   [(set (match_operand:XF 0 "register_operand" "")
15318         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15319          UNSPEC_FRNDINT_MASK_PM))
15320    (clobber (reg:CC FLAGS_REG))]
15321   "TARGET_USE_FANCY_MATH_387
15322    && flag_unsafe_math_optimizations
15323    && can_create_pseudo_p ()"
15324   "#"
15325   "&& 1"
15326   [(const_int 0)]
15327 {
15328   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15329
15330   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15331   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15332
15333   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15334                                           operands[2], operands[3]));
15335   DONE;
15336 }
15337   [(set_attr "type" "frndint")
15338    (set_attr "i387_cw" "mask_pm")
15339    (set_attr "mode" "XF")])
15340
15341 (define_insn "frndintxf2_mask_pm_i387"
15342   [(set (match_operand:XF 0 "register_operand" "=f")
15343         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15344          UNSPEC_FRNDINT_MASK_PM))
15345    (use (match_operand:HI 2 "memory_operand" "m"))
15346    (use (match_operand:HI 3 "memory_operand" "m"))]
15347   "TARGET_USE_FANCY_MATH_387
15348    && flag_unsafe_math_optimizations"
15349   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15350   [(set_attr "type" "frndint")
15351    (set_attr "i387_cw" "mask_pm")
15352    (set_attr "mode" "XF")])
15353
15354 (define_expand "nearbyintxf2"
15355   [(use (match_operand:XF 0 "register_operand" ""))
15356    (use (match_operand:XF 1 "register_operand" ""))]
15357   "TARGET_USE_FANCY_MATH_387
15358    && flag_unsafe_math_optimizations"
15359 {
15360   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15361   DONE;
15362 })
15363
15364 (define_expand "nearbyint<mode>2"
15365   [(use (match_operand:MODEF 0 "register_operand" ""))
15366    (use (match_operand:MODEF 1 "register_operand" ""))]
15367   "TARGET_USE_FANCY_MATH_387
15368    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15369        || TARGET_MIX_SSE_I387)
15370    && flag_unsafe_math_optimizations"
15371 {
15372   rtx op0 = gen_reg_rtx (XFmode);
15373   rtx op1 = gen_reg_rtx (XFmode);
15374
15375   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15376   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15377
15378   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15379   DONE;
15380 })
15381
15382 (define_insn "fxam<mode>2_i387"
15383   [(set (match_operand:HI 0 "register_operand" "=a")
15384         (unspec:HI
15385           [(match_operand:X87MODEF 1 "register_operand" "f")]
15386           UNSPEC_FXAM))]
15387   "TARGET_USE_FANCY_MATH_387"
15388   "fxam\n\tfnstsw\t%0"
15389   [(set_attr "type" "multi")
15390    (set_attr "length" "4")
15391    (set_attr "unit" "i387")
15392    (set_attr "mode" "<MODE>")])
15393
15394 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15395   [(set (match_operand:HI 0 "register_operand" "")
15396         (unspec:HI
15397           [(match_operand:MODEF 1 "memory_operand" "")]
15398           UNSPEC_FXAM_MEM))]
15399   "TARGET_USE_FANCY_MATH_387
15400    && can_create_pseudo_p ()"
15401   "#"
15402   "&& 1"
15403   [(set (match_dup 2)(match_dup 1))
15404    (set (match_dup 0)
15405         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15406 {
15407   operands[2] = gen_reg_rtx (<MODE>mode);
15408
15409   MEM_VOLATILE_P (operands[1]) = 1;
15410 }
15411   [(set_attr "type" "multi")
15412    (set_attr "unit" "i387")
15413    (set_attr "mode" "<MODE>")])
15414
15415 (define_expand "isinfxf2"
15416   [(use (match_operand:SI 0 "register_operand" ""))
15417    (use (match_operand:XF 1 "register_operand" ""))]
15418   "TARGET_USE_FANCY_MATH_387
15419    && TARGET_C99_FUNCTIONS"
15420 {
15421   rtx mask = GEN_INT (0x45);
15422   rtx val = GEN_INT (0x05);
15423
15424   rtx cond;
15425
15426   rtx scratch = gen_reg_rtx (HImode);
15427   rtx res = gen_reg_rtx (QImode);
15428
15429   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15430
15431   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15432   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15433   cond = gen_rtx_fmt_ee (EQ, QImode,
15434                          gen_rtx_REG (CCmode, FLAGS_REG),
15435                          const0_rtx);
15436   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15437   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15438   DONE;
15439 })
15440
15441 (define_expand "isinf<mode>2"
15442   [(use (match_operand:SI 0 "register_operand" ""))
15443    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15444   "TARGET_USE_FANCY_MATH_387
15445    && TARGET_C99_FUNCTIONS
15446    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15447 {
15448   rtx mask = GEN_INT (0x45);
15449   rtx val = GEN_INT (0x05);
15450
15451   rtx cond;
15452
15453   rtx scratch = gen_reg_rtx (HImode);
15454   rtx res = gen_reg_rtx (QImode);
15455
15456   /* Remove excess precision by forcing value through memory. */
15457   if (memory_operand (operands[1], VOIDmode))
15458     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15459   else
15460     {
15461       enum ix86_stack_slot slot = (virtuals_instantiated
15462                                    ? SLOT_TEMP
15463                                    : SLOT_VIRTUAL);
15464       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15465
15466       emit_move_insn (temp, operands[1]);
15467       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15468     }
15469
15470   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15471   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15472   cond = gen_rtx_fmt_ee (EQ, QImode,
15473                          gen_rtx_REG (CCmode, FLAGS_REG),
15474                          const0_rtx);
15475   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15476   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15477   DONE;
15478 })
15479
15480 (define_expand "signbitxf2"
15481   [(use (match_operand:SI 0 "register_operand" ""))
15482    (use (match_operand:XF 1 "register_operand" ""))]
15483   "TARGET_USE_FANCY_MATH_387"
15484 {
15485   rtx scratch = gen_reg_rtx (HImode);
15486
15487   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15488   emit_insn (gen_andsi3 (operands[0],
15489              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15490   DONE;
15491 })
15492
15493 (define_insn "movmsk_df"
15494   [(set (match_operand:SI 0 "register_operand" "=r")
15495         (unspec:SI
15496           [(match_operand:DF 1 "register_operand" "x")]
15497           UNSPEC_MOVMSK))]
15498   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15499   "%vmovmskpd\t{%1, %0|%0, %1}"
15500   [(set_attr "type" "ssemov")
15501    (set_attr "prefix" "maybe_vex")
15502    (set_attr "mode" "DF")])
15503
15504 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15505 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15506 (define_expand "signbitdf2"
15507   [(use (match_operand:SI 0 "register_operand" ""))
15508    (use (match_operand:DF 1 "register_operand" ""))]
15509   "TARGET_USE_FANCY_MATH_387
15510    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15511 {
15512   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15513     {
15514       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15515       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15516     }
15517   else
15518     {
15519       rtx scratch = gen_reg_rtx (HImode);
15520
15521       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15522       emit_insn (gen_andsi3 (operands[0],
15523                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15524     }
15525   DONE;
15526 })
15527
15528 (define_expand "signbitsf2"
15529   [(use (match_operand:SI 0 "register_operand" ""))
15530    (use (match_operand:SF 1 "register_operand" ""))]
15531   "TARGET_USE_FANCY_MATH_387
15532    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15533 {
15534   rtx scratch = gen_reg_rtx (HImode);
15535
15536   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15537   emit_insn (gen_andsi3 (operands[0],
15538              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15539   DONE;
15540 })
15541 \f
15542 ;; Block operation instructions
15543
15544 (define_insn "cld"
15545   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15546   ""
15547   "cld"
15548   [(set_attr "length" "1")
15549    (set_attr "length_immediate" "0")
15550    (set_attr "modrm" "0")])
15551
15552 (define_expand "movmem<mode>"
15553   [(use (match_operand:BLK 0 "memory_operand" ""))
15554    (use (match_operand:BLK 1 "memory_operand" ""))
15555    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15556    (use (match_operand:SWI48 3 "const_int_operand" ""))
15557    (use (match_operand:SI 4 "const_int_operand" ""))
15558    (use (match_operand:SI 5 "const_int_operand" ""))]
15559   ""
15560 {
15561  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15562                          operands[4], operands[5]))
15563    DONE;
15564  else
15565    FAIL;
15566 })
15567
15568 ;; Most CPUs don't like single string operations
15569 ;; Handle this case here to simplify previous expander.
15570
15571 (define_expand "strmov"
15572   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15573    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15574    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15575               (clobber (reg:CC FLAGS_REG))])
15576    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15577               (clobber (reg:CC FLAGS_REG))])]
15578   ""
15579 {
15580   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15581
15582   /* If .md ever supports :P for Pmode, these can be directly
15583      in the pattern above.  */
15584   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15585   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15586
15587   /* Can't use this if the user has appropriated esi or edi.  */
15588   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15589       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15590     {
15591       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15592                                       operands[2], operands[3],
15593                                       operands[5], operands[6]));
15594       DONE;
15595     }
15596
15597   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15598 })
15599
15600 (define_expand "strmov_singleop"
15601   [(parallel [(set (match_operand 1 "memory_operand" "")
15602                    (match_operand 3 "memory_operand" ""))
15603               (set (match_operand 0 "register_operand" "")
15604                    (match_operand 4 "" ""))
15605               (set (match_operand 2 "register_operand" "")
15606                    (match_operand 5 "" ""))])]
15607   ""
15608   "ix86_current_function_needs_cld = 1;")
15609
15610 (define_insn "*strmovdi_rex_1"
15611   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15612         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15613    (set (match_operand:DI 0 "register_operand" "=D")
15614         (plus:DI (match_dup 2)
15615                  (const_int 8)))
15616    (set (match_operand:DI 1 "register_operand" "=S")
15617         (plus:DI (match_dup 3)
15618                  (const_int 8)))]
15619   "TARGET_64BIT"
15620   "movsq"
15621   [(set_attr "type" "str")
15622    (set_attr "memory" "both")
15623    (set_attr "mode" "DI")])
15624
15625 (define_insn "*strmovsi_1"
15626   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15627         (mem:SI (match_operand:P 3 "register_operand" "1")))
15628    (set (match_operand:P 0 "register_operand" "=D")
15629         (plus:P (match_dup 2)
15630                 (const_int 4)))
15631    (set (match_operand:P 1 "register_operand" "=S")
15632         (plus:P (match_dup 3)
15633                 (const_int 4)))]
15634   ""
15635   "movs{l|d}"
15636   [(set_attr "type" "str")
15637    (set_attr "memory" "both")
15638    (set_attr "mode" "SI")])
15639
15640 (define_insn "*strmovhi_1"
15641   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15642         (mem:HI (match_operand:P 3 "register_operand" "1")))
15643    (set (match_operand:P 0 "register_operand" "=D")
15644         (plus:P (match_dup 2)
15645                 (const_int 2)))
15646    (set (match_operand:P 1 "register_operand" "=S")
15647         (plus:P (match_dup 3)
15648                 (const_int 2)))]
15649   ""
15650   "movsw"
15651   [(set_attr "type" "str")
15652    (set_attr "memory" "both")
15653    (set_attr "mode" "HI")])
15654
15655 (define_insn "*strmovqi_1"
15656   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15657         (mem:QI (match_operand:P 3 "register_operand" "1")))
15658    (set (match_operand:P 0 "register_operand" "=D")
15659         (plus:P (match_dup 2)
15660                 (const_int 1)))
15661    (set (match_operand:P 1 "register_operand" "=S")
15662         (plus:P (match_dup 3)
15663                 (const_int 1)))]
15664   ""
15665   "movsb"
15666   [(set_attr "type" "str")
15667    (set_attr "memory" "both")
15668    (set (attr "prefix_rex")
15669         (if_then_else
15670           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15671           (const_string "0")
15672           (const_string "*")))
15673    (set_attr "mode" "QI")])
15674
15675 (define_expand "rep_mov"
15676   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15677               (set (match_operand 0 "register_operand" "")
15678                    (match_operand 5 "" ""))
15679               (set (match_operand 2 "register_operand" "")
15680                    (match_operand 6 "" ""))
15681               (set (match_operand 1 "memory_operand" "")
15682                    (match_operand 3 "memory_operand" ""))
15683               (use (match_dup 4))])]
15684   ""
15685   "ix86_current_function_needs_cld = 1;")
15686
15687 (define_insn "*rep_movdi_rex64"
15688   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15689    (set (match_operand:DI 0 "register_operand" "=D")
15690         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15691                             (const_int 3))
15692                  (match_operand:DI 3 "register_operand" "0")))
15693    (set (match_operand:DI 1 "register_operand" "=S")
15694         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15695                  (match_operand:DI 4 "register_operand" "1")))
15696    (set (mem:BLK (match_dup 3))
15697         (mem:BLK (match_dup 4)))
15698    (use (match_dup 5))]
15699   "TARGET_64BIT"
15700   "rep{%;} movsq"
15701   [(set_attr "type" "str")
15702    (set_attr "prefix_rep" "1")
15703    (set_attr "memory" "both")
15704    (set_attr "mode" "DI")])
15705
15706 (define_insn "*rep_movsi"
15707   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15708    (set (match_operand:P 0 "register_operand" "=D")
15709         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15710                           (const_int 2))
15711                  (match_operand:P 3 "register_operand" "0")))
15712    (set (match_operand:P 1 "register_operand" "=S")
15713         (plus:P (ashift:P (match_dup 5) (const_int 2))
15714                 (match_operand:P 4 "register_operand" "1")))
15715    (set (mem:BLK (match_dup 3))
15716         (mem:BLK (match_dup 4)))
15717    (use (match_dup 5))]
15718   ""
15719   "rep{%;} movs{l|d}"
15720   [(set_attr "type" "str")
15721    (set_attr "prefix_rep" "1")
15722    (set_attr "memory" "both")
15723    (set_attr "mode" "SI")])
15724
15725 (define_insn "*rep_movqi"
15726   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15727    (set (match_operand:P 0 "register_operand" "=D")
15728         (plus:P (match_operand:P 3 "register_operand" "0")
15729                 (match_operand:P 5 "register_operand" "2")))
15730    (set (match_operand:P 1 "register_operand" "=S")
15731         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15732    (set (mem:BLK (match_dup 3))
15733         (mem:BLK (match_dup 4)))
15734    (use (match_dup 5))]
15735   ""
15736   "rep{%;} movsb"
15737   [(set_attr "type" "str")
15738    (set_attr "prefix_rep" "1")
15739    (set_attr "memory" "both")
15740    (set_attr "mode" "QI")])
15741
15742 (define_expand "setmem<mode>"
15743    [(use (match_operand:BLK 0 "memory_operand" ""))
15744     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15745     (use (match_operand:QI 2 "nonmemory_operand" ""))
15746     (use (match_operand 3 "const_int_operand" ""))
15747     (use (match_operand:SI 4 "const_int_operand" ""))
15748     (use (match_operand:SI 5 "const_int_operand" ""))]
15749   ""
15750 {
15751  if (ix86_expand_setmem (operands[0], operands[1],
15752                          operands[2], operands[3],
15753                          operands[4], operands[5]))
15754    DONE;
15755  else
15756    FAIL;
15757 })
15758
15759 ;; Most CPUs don't like single string operations
15760 ;; Handle this case here to simplify previous expander.
15761
15762 (define_expand "strset"
15763   [(set (match_operand 1 "memory_operand" "")
15764         (match_operand 2 "register_operand" ""))
15765    (parallel [(set (match_operand 0 "register_operand" "")
15766                    (match_dup 3))
15767               (clobber (reg:CC FLAGS_REG))])]
15768   ""
15769 {
15770   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15771     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15772
15773   /* If .md ever supports :P for Pmode, this can be directly
15774      in the pattern above.  */
15775   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15776                               GEN_INT (GET_MODE_SIZE (GET_MODE
15777                                                       (operands[2]))));
15778   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15779     {
15780       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15781                                       operands[3]));
15782       DONE;
15783     }
15784 })
15785
15786 (define_expand "strset_singleop"
15787   [(parallel [(set (match_operand 1 "memory_operand" "")
15788                    (match_operand 2 "register_operand" ""))
15789               (set (match_operand 0 "register_operand" "")
15790                    (match_operand 3 "" ""))])]
15791   ""
15792   "ix86_current_function_needs_cld = 1;")
15793
15794 (define_insn "*strsetdi_rex_1"
15795   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15796         (match_operand:DI 2 "register_operand" "a"))
15797    (set (match_operand:DI 0 "register_operand" "=D")
15798         (plus:DI (match_dup 1)
15799                  (const_int 8)))]
15800   "TARGET_64BIT"
15801   "stosq"
15802   [(set_attr "type" "str")
15803    (set_attr "memory" "store")
15804    (set_attr "mode" "DI")])
15805
15806 (define_insn "*strsetsi_1"
15807   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15808         (match_operand:SI 2 "register_operand" "a"))
15809    (set (match_operand:P 0 "register_operand" "=D")
15810         (plus:P (match_dup 1)
15811                 (const_int 4)))]
15812   ""
15813   "stos{l|d}"
15814   [(set_attr "type" "str")
15815    (set_attr "memory" "store")
15816    (set_attr "mode" "SI")])
15817
15818 (define_insn "*strsethi_1"
15819   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15820         (match_operand:HI 2 "register_operand" "a"))
15821    (set (match_operand:P 0 "register_operand" "=D")
15822         (plus:P (match_dup 1)
15823                 (const_int 2)))]
15824   ""
15825   "stosw"
15826   [(set_attr "type" "str")
15827    (set_attr "memory" "store")
15828    (set_attr "mode" "HI")])
15829
15830 (define_insn "*strsetqi_1"
15831   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15832         (match_operand:QI 2 "register_operand" "a"))
15833    (set (match_operand:P 0 "register_operand" "=D")
15834         (plus:P (match_dup 1)
15835                 (const_int 1)))]
15836   ""
15837   "stosb"
15838   [(set_attr "type" "str")
15839    (set_attr "memory" "store")
15840    (set (attr "prefix_rex")
15841         (if_then_else
15842           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15843           (const_string "0")
15844           (const_string "*")))
15845    (set_attr "mode" "QI")])
15846
15847 (define_expand "rep_stos"
15848   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15849               (set (match_operand 0 "register_operand" "")
15850                    (match_operand 4 "" ""))
15851               (set (match_operand 2 "memory_operand" "") (const_int 0))
15852               (use (match_operand 3 "register_operand" ""))
15853               (use (match_dup 1))])]
15854   ""
15855   "ix86_current_function_needs_cld = 1;")
15856
15857 (define_insn "*rep_stosdi_rex64"
15858   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15859    (set (match_operand:DI 0 "register_operand" "=D")
15860         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15861                             (const_int 3))
15862                  (match_operand:DI 3 "register_operand" "0")))
15863    (set (mem:BLK (match_dup 3))
15864         (const_int 0))
15865    (use (match_operand:DI 2 "register_operand" "a"))
15866    (use (match_dup 4))]
15867   "TARGET_64BIT"
15868   "rep{%;} stosq"
15869   [(set_attr "type" "str")
15870    (set_attr "prefix_rep" "1")
15871    (set_attr "memory" "store")
15872    (set_attr "mode" "DI")])
15873
15874 (define_insn "*rep_stossi"
15875   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15876    (set (match_operand:P 0 "register_operand" "=D")
15877         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15878                           (const_int 2))
15879                  (match_operand:P 3 "register_operand" "0")))
15880    (set (mem:BLK (match_dup 3))
15881         (const_int 0))
15882    (use (match_operand:SI 2 "register_operand" "a"))
15883    (use (match_dup 4))]
15884   ""
15885   "rep{%;} stos{l|d}"
15886   [(set_attr "type" "str")
15887    (set_attr "prefix_rep" "1")
15888    (set_attr "memory" "store")
15889    (set_attr "mode" "SI")])
15890
15891 (define_insn "*rep_stosqi"
15892   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15893    (set (match_operand:P 0 "register_operand" "=D")
15894         (plus:P (match_operand:P 3 "register_operand" "0")
15895                 (match_operand:P 4 "register_operand" "1")))
15896    (set (mem:BLK (match_dup 3))
15897         (const_int 0))
15898    (use (match_operand:QI 2 "register_operand" "a"))
15899    (use (match_dup 4))]
15900   ""
15901   "rep{%;} stosb"
15902   [(set_attr "type" "str")
15903    (set_attr "prefix_rep" "1")
15904    (set_attr "memory" "store")
15905    (set (attr "prefix_rex")
15906         (if_then_else
15907           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15908           (const_string "0")
15909           (const_string "*")))
15910    (set_attr "mode" "QI")])
15911
15912 (define_expand "cmpstrnsi"
15913   [(set (match_operand:SI 0 "register_operand" "")
15914         (compare:SI (match_operand:BLK 1 "general_operand" "")
15915                     (match_operand:BLK 2 "general_operand" "")))
15916    (use (match_operand 3 "general_operand" ""))
15917    (use (match_operand 4 "immediate_operand" ""))]
15918   ""
15919 {
15920   rtx addr1, addr2, out, outlow, count, countreg, align;
15921
15922   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15923     FAIL;
15924
15925   /* Can't use this if the user has appropriated esi or edi.  */
15926   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15927     FAIL;
15928
15929   out = operands[0];
15930   if (!REG_P (out))
15931     out = gen_reg_rtx (SImode);
15932
15933   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15934   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15935   if (addr1 != XEXP (operands[1], 0))
15936     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15937   if (addr2 != XEXP (operands[2], 0))
15938     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15939
15940   count = operands[3];
15941   countreg = ix86_zero_extend_to_Pmode (count);
15942
15943   /* %%% Iff we are testing strict equality, we can use known alignment
15944      to good advantage.  This may be possible with combine, particularly
15945      once cc0 is dead.  */
15946   align = operands[4];
15947
15948   if (CONST_INT_P (count))
15949     {
15950       if (INTVAL (count) == 0)
15951         {
15952           emit_move_insn (operands[0], const0_rtx);
15953           DONE;
15954         }
15955       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15956                                      operands[1], operands[2]));
15957     }
15958   else
15959     {
15960       rtx (*gen_cmp) (rtx, rtx);
15961
15962       gen_cmp = (TARGET_64BIT
15963                  ? gen_cmpdi_1 : gen_cmpsi_1);
15964
15965       emit_insn (gen_cmp (countreg, countreg));
15966       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15967                                   operands[1], operands[2]));
15968     }
15969
15970   outlow = gen_lowpart (QImode, out);
15971   emit_insn (gen_cmpintqi (outlow));
15972   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15973
15974   if (operands[0] != out)
15975     emit_move_insn (operands[0], out);
15976
15977   DONE;
15978 })
15979
15980 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15981
15982 (define_expand "cmpintqi"
15983   [(set (match_dup 1)
15984         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15985    (set (match_dup 2)
15986         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15987    (parallel [(set (match_operand:QI 0 "register_operand" "")
15988                    (minus:QI (match_dup 1)
15989                              (match_dup 2)))
15990               (clobber (reg:CC FLAGS_REG))])]
15991   ""
15992 {
15993   operands[1] = gen_reg_rtx (QImode);
15994   operands[2] = gen_reg_rtx (QImode);
15995 })
15996
15997 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15998 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15999
16000 (define_expand "cmpstrnqi_nz_1"
16001   [(parallel [(set (reg:CC FLAGS_REG)
16002                    (compare:CC (match_operand 4 "memory_operand" "")
16003                                (match_operand 5 "memory_operand" "")))
16004               (use (match_operand 2 "register_operand" ""))
16005               (use (match_operand:SI 3 "immediate_operand" ""))
16006               (clobber (match_operand 0 "register_operand" ""))
16007               (clobber (match_operand 1 "register_operand" ""))
16008               (clobber (match_dup 2))])]
16009   ""
16010   "ix86_current_function_needs_cld = 1;")
16011
16012 (define_insn "*cmpstrnqi_nz_1"
16013   [(set (reg:CC FLAGS_REG)
16014         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16015                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16016    (use (match_operand:P 6 "register_operand" "2"))
16017    (use (match_operand:SI 3 "immediate_operand" "i"))
16018    (clobber (match_operand:P 0 "register_operand" "=S"))
16019    (clobber (match_operand:P 1 "register_operand" "=D"))
16020    (clobber (match_operand:P 2 "register_operand" "=c"))]
16021   ""
16022   "repz{%;} cmpsb"
16023   [(set_attr "type" "str")
16024    (set_attr "mode" "QI")
16025    (set (attr "prefix_rex")
16026         (if_then_else
16027           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16028           (const_string "0")
16029           (const_string "*")))
16030    (set_attr "prefix_rep" "1")])
16031
16032 ;; The same, but the count is not known to not be zero.
16033
16034 (define_expand "cmpstrnqi_1"
16035   [(parallel [(set (reg:CC FLAGS_REG)
16036                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16037                                      (const_int 0))
16038                   (compare:CC (match_operand 4 "memory_operand" "")
16039                               (match_operand 5 "memory_operand" ""))
16040                   (const_int 0)))
16041               (use (match_operand:SI 3 "immediate_operand" ""))
16042               (use (reg:CC FLAGS_REG))
16043               (clobber (match_operand 0 "register_operand" ""))
16044               (clobber (match_operand 1 "register_operand" ""))
16045               (clobber (match_dup 2))])]
16046   ""
16047   "ix86_current_function_needs_cld = 1;")
16048
16049 (define_insn "*cmpstrnqi_1"
16050   [(set (reg:CC FLAGS_REG)
16051         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16052                              (const_int 0))
16053           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16054                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16055           (const_int 0)))
16056    (use (match_operand:SI 3 "immediate_operand" "i"))
16057    (use (reg:CC FLAGS_REG))
16058    (clobber (match_operand:P 0 "register_operand" "=S"))
16059    (clobber (match_operand:P 1 "register_operand" "=D"))
16060    (clobber (match_operand:P 2 "register_operand" "=c"))]
16061   ""
16062   "repz{%;} cmpsb"
16063   [(set_attr "type" "str")
16064    (set_attr "mode" "QI")
16065    (set (attr "prefix_rex")
16066         (if_then_else
16067           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16068           (const_string "0")
16069           (const_string "*")))
16070    (set_attr "prefix_rep" "1")])
16071
16072 (define_expand "strlen<mode>"
16073   [(set (match_operand:SWI48x 0 "register_operand" "")
16074         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16075                         (match_operand:QI 2 "immediate_operand" "")
16076                         (match_operand 3 "immediate_operand" "")]
16077                        UNSPEC_SCAS))]
16078   ""
16079 {
16080  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16081    DONE;
16082  else
16083    FAIL;
16084 })
16085
16086 (define_expand "strlenqi_1"
16087   [(parallel [(set (match_operand 0 "register_operand" "")
16088                    (match_operand 2 "" ""))
16089               (clobber (match_operand 1 "register_operand" ""))
16090               (clobber (reg:CC FLAGS_REG))])]
16091   ""
16092   "ix86_current_function_needs_cld = 1;")
16093
16094 (define_insn "*strlenqi_1"
16095   [(set (match_operand:P 0 "register_operand" "=&c")
16096         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16097                    (match_operand:QI 2 "register_operand" "a")
16098                    (match_operand:P 3 "immediate_operand" "i")
16099                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16100    (clobber (match_operand:P 1 "register_operand" "=D"))
16101    (clobber (reg:CC FLAGS_REG))]
16102   ""
16103   "repnz{%;} scasb"
16104   [(set_attr "type" "str")
16105    (set_attr "mode" "QI")
16106    (set (attr "prefix_rex")
16107         (if_then_else
16108           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16109           (const_string "0")
16110           (const_string "*")))
16111    (set_attr "prefix_rep" "1")])
16112
16113 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16114 ;; handled in combine, but it is not currently up to the task.
16115 ;; When used for their truth value, the cmpstrn* expanders generate
16116 ;; code like this:
16117 ;;
16118 ;;   repz cmpsb
16119 ;;   seta       %al
16120 ;;   setb       %dl
16121 ;;   cmpb       %al, %dl
16122 ;;   jcc        label
16123 ;;
16124 ;; The intermediate three instructions are unnecessary.
16125
16126 ;; This one handles cmpstrn*_nz_1...
16127 (define_peephole2
16128   [(parallel[
16129      (set (reg:CC FLAGS_REG)
16130           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16131                       (mem:BLK (match_operand 5 "register_operand" ""))))
16132      (use (match_operand 6 "register_operand" ""))
16133      (use (match_operand:SI 3 "immediate_operand" ""))
16134      (clobber (match_operand 0 "register_operand" ""))
16135      (clobber (match_operand 1 "register_operand" ""))
16136      (clobber (match_operand 2 "register_operand" ""))])
16137    (set (match_operand:QI 7 "register_operand" "")
16138         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16139    (set (match_operand:QI 8 "register_operand" "")
16140         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16141    (set (reg FLAGS_REG)
16142         (compare (match_dup 7) (match_dup 8)))
16143   ]
16144   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16145   [(parallel[
16146      (set (reg:CC FLAGS_REG)
16147           (compare:CC (mem:BLK (match_dup 4))
16148                       (mem:BLK (match_dup 5))))
16149      (use (match_dup 6))
16150      (use (match_dup 3))
16151      (clobber (match_dup 0))
16152      (clobber (match_dup 1))
16153      (clobber (match_dup 2))])])
16154
16155 ;; ...and this one handles cmpstrn*_1.
16156 (define_peephole2
16157   [(parallel[
16158      (set (reg:CC FLAGS_REG)
16159           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16160                                (const_int 0))
16161             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16162                         (mem:BLK (match_operand 5 "register_operand" "")))
16163             (const_int 0)))
16164      (use (match_operand:SI 3 "immediate_operand" ""))
16165      (use (reg:CC FLAGS_REG))
16166      (clobber (match_operand 0 "register_operand" ""))
16167      (clobber (match_operand 1 "register_operand" ""))
16168      (clobber (match_operand 2 "register_operand" ""))])
16169    (set (match_operand:QI 7 "register_operand" "")
16170         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16171    (set (match_operand:QI 8 "register_operand" "")
16172         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16173    (set (reg FLAGS_REG)
16174         (compare (match_dup 7) (match_dup 8)))
16175   ]
16176   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16177   [(parallel[
16178      (set (reg:CC FLAGS_REG)
16179           (if_then_else:CC (ne (match_dup 6)
16180                                (const_int 0))
16181             (compare:CC (mem:BLK (match_dup 4))
16182                         (mem:BLK (match_dup 5)))
16183             (const_int 0)))
16184      (use (match_dup 3))
16185      (use (reg:CC FLAGS_REG))
16186      (clobber (match_dup 0))
16187      (clobber (match_dup 1))
16188      (clobber (match_dup 2))])])
16189 \f
16190 ;; Conditional move instructions.
16191
16192 (define_expand "mov<mode>cc"
16193   [(set (match_operand:SWIM 0 "register_operand" "")
16194         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16195                            (match_operand:SWIM 2 "general_operand" "")
16196                            (match_operand:SWIM 3 "general_operand" "")))]
16197   ""
16198   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16199
16200 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16201 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16202 ;; So just document what we're doing explicitly.
16203
16204 (define_expand "x86_mov<mode>cc_0_m1"
16205   [(parallel
16206     [(set (match_operand:SWI48 0 "register_operand" "")
16207           (if_then_else:SWI48
16208             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16209              [(match_operand 1 "flags_reg_operand" "")
16210               (const_int 0)])
16211             (const_int -1)
16212             (const_int 0)))
16213      (clobber (reg:CC FLAGS_REG))])])
16214
16215 (define_insn "*x86_mov<mode>cc_0_m1"
16216   [(set (match_operand:SWI48 0 "register_operand" "=r")
16217         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16218                              [(reg FLAGS_REG) (const_int 0)])
16219           (const_int -1)
16220           (const_int 0)))
16221    (clobber (reg:CC FLAGS_REG))]
16222   ""
16223   "sbb{<imodesuffix>}\t%0, %0"
16224   ; Since we don't have the proper number of operands for an alu insn,
16225   ; fill in all the blanks.
16226   [(set_attr "type" "alu")
16227    (set_attr "use_carry" "1")
16228    (set_attr "pent_pair" "pu")
16229    (set_attr "memory" "none")
16230    (set_attr "imm_disp" "false")
16231    (set_attr "mode" "<MODE>")
16232    (set_attr "length_immediate" "0")])
16233
16234 (define_insn "*x86_mov<mode>cc_0_m1_se"
16235   [(set (match_operand:SWI48 0 "register_operand" "=r")
16236         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16237                              [(reg FLAGS_REG) (const_int 0)])
16238                             (const_int 1)
16239                             (const_int 0)))
16240    (clobber (reg:CC FLAGS_REG))]
16241   ""
16242   "sbb{<imodesuffix>}\t%0, %0"
16243   [(set_attr "type" "alu")
16244    (set_attr "use_carry" "1")
16245    (set_attr "pent_pair" "pu")
16246    (set_attr "memory" "none")
16247    (set_attr "imm_disp" "false")
16248    (set_attr "mode" "<MODE>")
16249    (set_attr "length_immediate" "0")])
16250
16251 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16252   [(set (match_operand:SWI48 0 "register_operand" "=r")
16253         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16254                     [(reg FLAGS_REG) (const_int 0)])))]
16255   ""
16256   "sbb{<imodesuffix>}\t%0, %0"
16257   [(set_attr "type" "alu")
16258    (set_attr "use_carry" "1")
16259    (set_attr "pent_pair" "pu")
16260    (set_attr "memory" "none")
16261    (set_attr "imm_disp" "false")
16262    (set_attr "mode" "<MODE>")
16263    (set_attr "length_immediate" "0")])
16264
16265 (define_insn "*mov<mode>cc_noc"
16266   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16267         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16268                                [(reg FLAGS_REG) (const_int 0)])
16269           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16270           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16271   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16272   "@
16273    cmov%O2%C1\t{%2, %0|%0, %2}
16274    cmov%O2%c1\t{%3, %0|%0, %3}"
16275   [(set_attr "type" "icmov")
16276    (set_attr "mode" "<MODE>")])
16277
16278 (define_insn_and_split "*movqicc_noc"
16279   [(set (match_operand:QI 0 "register_operand" "=r,r")
16280         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16281                            [(match_operand 4 "flags_reg_operand" "")
16282                             (const_int 0)])
16283                       (match_operand:QI 2 "register_operand" "r,0")
16284                       (match_operand:QI 3 "register_operand" "0,r")))]
16285   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16286   "#"
16287   "&& reload_completed"
16288   [(set (match_dup 0)
16289         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16290                       (match_dup 2)
16291                       (match_dup 3)))]
16292   "operands[0] = gen_lowpart (SImode, operands[0]);
16293    operands[2] = gen_lowpart (SImode, operands[2]);
16294    operands[3] = gen_lowpart (SImode, operands[3]);"
16295   [(set_attr "type" "icmov")
16296    (set_attr "mode" "SI")])
16297
16298 (define_expand "mov<mode>cc"
16299   [(set (match_operand:X87MODEF 0 "register_operand" "")
16300         (if_then_else:X87MODEF
16301           (match_operand 1 "ix86_fp_comparison_operator" "")
16302           (match_operand:X87MODEF 2 "register_operand" "")
16303           (match_operand:X87MODEF 3 "register_operand" "")))]
16304   "(TARGET_80387 && TARGET_CMOVE)
16305    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16306   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16307
16308 (define_insn "*movxfcc_1"
16309   [(set (match_operand:XF 0 "register_operand" "=f,f")
16310         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16311                                 [(reg FLAGS_REG) (const_int 0)])
16312                       (match_operand:XF 2 "register_operand" "f,0")
16313                       (match_operand:XF 3 "register_operand" "0,f")))]
16314   "TARGET_80387 && TARGET_CMOVE"
16315   "@
16316    fcmov%F1\t{%2, %0|%0, %2}
16317    fcmov%f1\t{%3, %0|%0, %3}"
16318   [(set_attr "type" "fcmov")
16319    (set_attr "mode" "XF")])
16320
16321 (define_insn "*movdfcc_1_rex64"
16322   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16323         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16324                                 [(reg FLAGS_REG) (const_int 0)])
16325                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16326                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16327   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16328    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16329   "@
16330    fcmov%F1\t{%2, %0|%0, %2}
16331    fcmov%f1\t{%3, %0|%0, %3}
16332    cmov%O2%C1\t{%2, %0|%0, %2}
16333    cmov%O2%c1\t{%3, %0|%0, %3}"
16334   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16335    (set_attr "mode" "DF,DF,DI,DI")])
16336
16337 (define_insn "*movdfcc_1"
16338   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16339         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16340                                 [(reg FLAGS_REG) (const_int 0)])
16341                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16342                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16343   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16344    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16345   "@
16346    fcmov%F1\t{%2, %0|%0, %2}
16347    fcmov%f1\t{%3, %0|%0, %3}
16348    #
16349    #"
16350   [(set_attr "type" "fcmov,fcmov,multi,multi")
16351    (set_attr "mode" "DF,DF,DI,DI")])
16352
16353 (define_split
16354   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16355         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16356                                 [(match_operand 4 "flags_reg_operand" "")
16357                                  (const_int 0)])
16358                       (match_operand:DF 2 "nonimmediate_operand" "")
16359                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16360   "!TARGET_64BIT && reload_completed"
16361   [(set (match_dup 2)
16362         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16363                       (match_dup 5)
16364                       (match_dup 6)))
16365    (set (match_dup 3)
16366         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16367                       (match_dup 7)
16368                       (match_dup 8)))]
16369 {
16370   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16371   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16372 })
16373
16374 (define_insn "*movsfcc_1_387"
16375   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16376         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16377                                 [(reg FLAGS_REG) (const_int 0)])
16378                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16379                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16380   "TARGET_80387 && TARGET_CMOVE
16381    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16382   "@
16383    fcmov%F1\t{%2, %0|%0, %2}
16384    fcmov%f1\t{%3, %0|%0, %3}
16385    cmov%O2%C1\t{%2, %0|%0, %2}
16386    cmov%O2%c1\t{%3, %0|%0, %3}"
16387   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16388    (set_attr "mode" "SF,SF,SI,SI")])
16389
16390 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16391 ;; the scalar versions to have only XMM registers as operands.
16392
16393 ;; XOP conditional move
16394 (define_insn "*xop_pcmov_<mode>"
16395   [(set (match_operand:MODEF 0 "register_operand" "=x")
16396         (if_then_else:MODEF
16397           (match_operand:MODEF 1 "register_operand" "x")
16398           (match_operand:MODEF 2 "register_operand" "x")
16399           (match_operand:MODEF 3 "register_operand" "x")))]
16400   "TARGET_XOP"
16401   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16402   [(set_attr "type" "sse4arg")])
16403
16404 ;; These versions of the min/max patterns are intentionally ignorant of
16405 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16406 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16407 ;; are undefined in this condition, we're certain this is correct.
16408
16409 (define_insn "<code><mode>3"
16410   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16411         (smaxmin:MODEF
16412           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16413           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16414   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16415   "@
16416    <maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}
16417    v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16418   [(set_attr "isa" "noavx,avx")
16419    (set_attr "prefix" "orig,vex")
16420    (set_attr "type" "sseadd")
16421    (set_attr "mode" "<MODE>")])
16422
16423 ;; These versions of the min/max patterns implement exactly the operations
16424 ;;   min = (op1 < op2 ? op1 : op2)
16425 ;;   max = (!(op1 < op2) ? op1 : op2)
16426 ;; Their operands are not commutative, and thus they may be used in the
16427 ;; presence of -0.0 and NaN.
16428
16429 (define_insn "*ieee_smin<mode>3"
16430   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16431         (unspec:MODEF
16432           [(match_operand:MODEF 1 "register_operand" "0,x")
16433            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16434          UNSPEC_IEEE_MIN))]
16435   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16436   "@
16437    mins<ssemodefsuffix>\t{%2, %0|%0, %2}
16438    vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16439   [(set_attr "isa" "noavx,avx")
16440    (set_attr "prefix" "orig,vex")
16441    (set_attr "type" "sseadd")
16442    (set_attr "mode" "<MODE>")])
16443
16444 (define_insn "*ieee_smax<mode>3"
16445   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16446         (unspec:MODEF
16447           [(match_operand:MODEF 1 "register_operand" "0,x")
16448            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16449          UNSPEC_IEEE_MAX))]
16450   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16451   "@
16452    maxs<ssemodefsuffix>\t{%2, %0|%0, %2}
16453    vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16454   [(set_attr "isa" "noavx,avx")
16455    (set_attr "prefix" "orig,vex")
16456    (set_attr "type" "sseadd")
16457    (set_attr "mode" "<MODE>")])
16458
16459 ;; Make two stack loads independent:
16460 ;;   fld aa              fld aa
16461 ;;   fld %st(0)     ->   fld bb
16462 ;;   fmul bb             fmul %st(1), %st
16463 ;;
16464 ;; Actually we only match the last two instructions for simplicity.
16465 (define_peephole2
16466   [(set (match_operand 0 "fp_register_operand" "")
16467         (match_operand 1 "fp_register_operand" ""))
16468    (set (match_dup 0)
16469         (match_operator 2 "binary_fp_operator"
16470            [(match_dup 0)
16471             (match_operand 3 "memory_operand" "")]))]
16472   "REGNO (operands[0]) != REGNO (operands[1])"
16473   [(set (match_dup 0) (match_dup 3))
16474    (set (match_dup 0) (match_dup 4))]
16475
16476   ;; The % modifier is not operational anymore in peephole2's, so we have to
16477   ;; swap the operands manually in the case of addition and multiplication.
16478   "if (COMMUTATIVE_ARITH_P (operands[2]))
16479      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16480                                    GET_MODE (operands[2]),
16481                                    operands[0], operands[1]);
16482    else
16483      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16484                                    GET_MODE (operands[2]),
16485                                    operands[1], operands[0]);")
16486
16487 ;; Conditional addition patterns
16488 (define_expand "add<mode>cc"
16489   [(match_operand:SWI 0 "register_operand" "")
16490    (match_operand 1 "ordered_comparison_operator" "")
16491    (match_operand:SWI 2 "register_operand" "")
16492    (match_operand:SWI 3 "const_int_operand" "")]
16493   ""
16494   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16495 \f
16496 ;; Misc patterns (?)
16497
16498 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16499 ;; Otherwise there will be nothing to keep
16500 ;;
16501 ;; [(set (reg ebp) (reg esp))]
16502 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16503 ;;  (clobber (eflags)]
16504 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16505 ;;
16506 ;; in proper program order.
16507
16508 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16509   [(set (match_operand:P 0 "register_operand" "=r,r")
16510         (plus:P (match_operand:P 1 "register_operand" "0,r")
16511                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16512    (clobber (reg:CC FLAGS_REG))
16513    (clobber (mem:BLK (scratch)))]
16514   ""
16515 {
16516   switch (get_attr_type (insn))
16517     {
16518     case TYPE_IMOV:
16519       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16520
16521     case TYPE_ALU:
16522       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16523       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16524         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16525
16526       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16527
16528     default:
16529       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16530       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16531     }
16532 }
16533   [(set (attr "type")
16534         (cond [(and (eq_attr "alternative" "0")
16535                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16536                  (const_string "alu")
16537                (match_operand:<MODE> 2 "const0_operand" "")
16538                  (const_string "imov")
16539               ]
16540               (const_string "lea")))
16541    (set (attr "length_immediate")
16542         (cond [(eq_attr "type" "imov")
16543                  (const_string "0")
16544                (and (eq_attr "type" "alu")
16545                     (match_operand 2 "const128_operand" ""))
16546                  (const_string "1")
16547               ]
16548               (const_string "*")))
16549    (set_attr "mode" "<MODE>")])
16550
16551 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16552   [(set (match_operand:P 0 "register_operand" "=r")
16553         (minus:P (match_operand:P 1 "register_operand" "0")
16554                  (match_operand:P 2 "register_operand" "r")))
16555    (clobber (reg:CC FLAGS_REG))
16556    (clobber (mem:BLK (scratch)))]
16557   ""
16558   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16559   [(set_attr "type" "alu")
16560    (set_attr "mode" "<MODE>")])
16561
16562 (define_insn "allocate_stack_worker_probe_<mode>"
16563   [(set (match_operand:P 0 "register_operand" "=a")
16564         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16565                             UNSPECV_STACK_PROBE))
16566    (clobber (reg:CC FLAGS_REG))]
16567   "ix86_target_stack_probe ()"
16568   "call\t___chkstk_ms"
16569   [(set_attr "type" "multi")
16570    (set_attr "length" "5")])
16571
16572 (define_expand "allocate_stack"
16573   [(match_operand 0 "register_operand" "")
16574    (match_operand 1 "general_operand" "")]
16575   "ix86_target_stack_probe ()"
16576 {
16577   rtx x;
16578
16579 #ifndef CHECK_STACK_LIMIT
16580 #define CHECK_STACK_LIMIT 0
16581 #endif
16582
16583   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16584       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16585     {
16586       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16587                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16588       if (x != stack_pointer_rtx)
16589         emit_move_insn (stack_pointer_rtx, x);
16590     }
16591   else
16592     {
16593       x = copy_to_mode_reg (Pmode, operands[1]);
16594       if (TARGET_64BIT)
16595         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16596       else
16597         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16598       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16599                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16600       if (x != stack_pointer_rtx)
16601         emit_move_insn (stack_pointer_rtx, x);
16602     }
16603
16604   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16605   DONE;
16606 })
16607
16608 ;; Use IOR for stack probes, this is shorter.
16609 (define_expand "probe_stack"
16610   [(match_operand 0 "memory_operand" "")]
16611   ""
16612 {
16613   rtx (*gen_ior3) (rtx, rtx, rtx);
16614
16615   gen_ior3 = (GET_MODE (operands[0]) == DImode
16616               ? gen_iordi3 : gen_iorsi3);
16617
16618   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16619   DONE;
16620 })
16621
16622 (define_insn "adjust_stack_and_probe<mode>"
16623   [(set (match_operand:P 0 "register_operand" "=r")
16624         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16625                             UNSPECV_PROBE_STACK_RANGE))
16626    (set (reg:P SP_REG)
16627         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16628    (clobber (reg:CC FLAGS_REG))
16629    (clobber (mem:BLK (scratch)))]
16630   ""
16631   "* return output_adjust_stack_and_probe (operands[0]);"
16632   [(set_attr "type" "multi")])
16633
16634 (define_insn "probe_stack_range<mode>"
16635   [(set (match_operand:P 0 "register_operand" "=r")
16636         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16637                             (match_operand:P 2 "const_int_operand" "n")]
16638                             UNSPECV_PROBE_STACK_RANGE))
16639    (clobber (reg:CC FLAGS_REG))]
16640   ""
16641   "* return output_probe_stack_range (operands[0], operands[2]);"
16642   [(set_attr "type" "multi")])
16643
16644 (define_expand "builtin_setjmp_receiver"
16645   [(label_ref (match_operand 0 "" ""))]
16646   "!TARGET_64BIT && flag_pic"
16647 {
16648 #if TARGET_MACHO
16649   if (TARGET_MACHO)
16650     {
16651       rtx xops[3];
16652       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16653       rtx label_rtx = gen_label_rtx ();
16654       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16655       xops[0] = xops[1] = picreg;
16656       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16657       ix86_expand_binary_operator (MINUS, SImode, xops);
16658     }
16659   else
16660 #endif
16661     emit_insn (gen_set_got (pic_offset_table_rtx));
16662   DONE;
16663 })
16664 \f
16665 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16666
16667 (define_split
16668   [(set (match_operand 0 "register_operand" "")
16669         (match_operator 3 "promotable_binary_operator"
16670            [(match_operand 1 "register_operand" "")
16671             (match_operand 2 "aligned_operand" "")]))
16672    (clobber (reg:CC FLAGS_REG))]
16673   "! TARGET_PARTIAL_REG_STALL && reload_completed
16674    && ((GET_MODE (operands[0]) == HImode
16675         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16676             /* ??? next two lines just !satisfies_constraint_K (...) */
16677             || !CONST_INT_P (operands[2])
16678             || satisfies_constraint_K (operands[2])))
16679        || (GET_MODE (operands[0]) == QImode
16680            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16681   [(parallel [(set (match_dup 0)
16682                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16683               (clobber (reg:CC FLAGS_REG))])]
16684   "operands[0] = gen_lowpart (SImode, operands[0]);
16685    operands[1] = gen_lowpart (SImode, operands[1]);
16686    if (GET_CODE (operands[3]) != ASHIFT)
16687      operands[2] = gen_lowpart (SImode, operands[2]);
16688    PUT_MODE (operands[3], SImode);")
16689
16690 ; Promote the QImode tests, as i386 has encoding of the AND
16691 ; instruction with 32-bit sign-extended immediate and thus the
16692 ; instruction size is unchanged, except in the %eax case for
16693 ; which it is increased by one byte, hence the ! optimize_size.
16694 (define_split
16695   [(set (match_operand 0 "flags_reg_operand" "")
16696         (match_operator 2 "compare_operator"
16697           [(and (match_operand 3 "aligned_operand" "")
16698                 (match_operand 4 "const_int_operand" ""))
16699            (const_int 0)]))
16700    (set (match_operand 1 "register_operand" "")
16701         (and (match_dup 3) (match_dup 4)))]
16702   "! TARGET_PARTIAL_REG_STALL && reload_completed
16703    && optimize_insn_for_speed_p ()
16704    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16705        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16706    /* Ensure that the operand will remain sign-extended immediate.  */
16707    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16708   [(parallel [(set (match_dup 0)
16709                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16710                                     (const_int 0)]))
16711               (set (match_dup 1)
16712                    (and:SI (match_dup 3) (match_dup 4)))])]
16713 {
16714   operands[4]
16715     = gen_int_mode (INTVAL (operands[4])
16716                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16717   operands[1] = gen_lowpart (SImode, operands[1]);
16718   operands[3] = gen_lowpart (SImode, operands[3]);
16719 })
16720
16721 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16722 ; the TEST instruction with 32-bit sign-extended immediate and thus
16723 ; the instruction size would at least double, which is not what we
16724 ; want even with ! optimize_size.
16725 (define_split
16726   [(set (match_operand 0 "flags_reg_operand" "")
16727         (match_operator 1 "compare_operator"
16728           [(and (match_operand:HI 2 "aligned_operand" "")
16729                 (match_operand:HI 3 "const_int_operand" ""))
16730            (const_int 0)]))]
16731   "! TARGET_PARTIAL_REG_STALL && reload_completed
16732    && ! TARGET_FAST_PREFIX
16733    && optimize_insn_for_speed_p ()
16734    /* Ensure that the operand will remain sign-extended immediate.  */
16735    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16736   [(set (match_dup 0)
16737         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16738                          (const_int 0)]))]
16739 {
16740   operands[3]
16741     = gen_int_mode (INTVAL (operands[3])
16742                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16743   operands[2] = gen_lowpart (SImode, operands[2]);
16744 })
16745
16746 (define_split
16747   [(set (match_operand 0 "register_operand" "")
16748         (neg (match_operand 1 "register_operand" "")))
16749    (clobber (reg:CC FLAGS_REG))]
16750   "! TARGET_PARTIAL_REG_STALL && reload_completed
16751    && (GET_MODE (operands[0]) == HImode
16752        || (GET_MODE (operands[0]) == QImode
16753            && (TARGET_PROMOTE_QImode
16754                || optimize_insn_for_size_p ())))"
16755   [(parallel [(set (match_dup 0)
16756                    (neg:SI (match_dup 1)))
16757               (clobber (reg:CC FLAGS_REG))])]
16758   "operands[0] = gen_lowpart (SImode, operands[0]);
16759    operands[1] = gen_lowpart (SImode, operands[1]);")
16760
16761 (define_split
16762   [(set (match_operand 0 "register_operand" "")
16763         (not (match_operand 1 "register_operand" "")))]
16764   "! TARGET_PARTIAL_REG_STALL && reload_completed
16765    && (GET_MODE (operands[0]) == HImode
16766        || (GET_MODE (operands[0]) == QImode
16767            && (TARGET_PROMOTE_QImode
16768                || optimize_insn_for_size_p ())))"
16769   [(set (match_dup 0)
16770         (not:SI (match_dup 1)))]
16771   "operands[0] = gen_lowpart (SImode, operands[0]);
16772    operands[1] = gen_lowpart (SImode, operands[1]);")
16773
16774 (define_split
16775   [(set (match_operand 0 "register_operand" "")
16776         (if_then_else (match_operator 1 "ordered_comparison_operator"
16777                                 [(reg FLAGS_REG) (const_int 0)])
16778                       (match_operand 2 "register_operand" "")
16779                       (match_operand 3 "register_operand" "")))]
16780   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16781    && (GET_MODE (operands[0]) == HImode
16782        || (GET_MODE (operands[0]) == QImode
16783            && (TARGET_PROMOTE_QImode
16784                || optimize_insn_for_size_p ())))"
16785   [(set (match_dup 0)
16786         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16787   "operands[0] = gen_lowpart (SImode, operands[0]);
16788    operands[2] = gen_lowpart (SImode, operands[2]);
16789    operands[3] = gen_lowpart (SImode, operands[3]);")
16790 \f
16791 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16792 ;; transform a complex memory operation into two memory to register operations.
16793
16794 ;; Don't push memory operands
16795 (define_peephole2
16796   [(set (match_operand:SWI 0 "push_operand" "")
16797         (match_operand:SWI 1 "memory_operand" ""))
16798    (match_scratch:SWI 2 "<r>")]
16799   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16800    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16801   [(set (match_dup 2) (match_dup 1))
16802    (set (match_dup 0) (match_dup 2))])
16803
16804 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16805 ;; SImode pushes.
16806 (define_peephole2
16807   [(set (match_operand:SF 0 "push_operand" "")
16808         (match_operand:SF 1 "memory_operand" ""))
16809    (match_scratch:SF 2 "r")]
16810   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16811    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16812   [(set (match_dup 2) (match_dup 1))
16813    (set (match_dup 0) (match_dup 2))])
16814
16815 ;; Don't move an immediate directly to memory when the instruction
16816 ;; gets too big.
16817 (define_peephole2
16818   [(match_scratch:SWI124 1 "<r>")
16819    (set (match_operand:SWI124 0 "memory_operand" "")
16820         (const_int 0))]
16821   "optimize_insn_for_speed_p ()
16822    && !TARGET_USE_MOV0
16823    && TARGET_SPLIT_LONG_MOVES
16824    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16825    && peep2_regno_dead_p (0, FLAGS_REG)"
16826   [(parallel [(set (match_dup 2) (const_int 0))
16827               (clobber (reg:CC FLAGS_REG))])
16828    (set (match_dup 0) (match_dup 1))]
16829   "operands[2] = gen_lowpart (SImode, operands[1]);")
16830
16831 (define_peephole2
16832   [(match_scratch:SWI124 2 "<r>")
16833    (set (match_operand:SWI124 0 "memory_operand" "")
16834         (match_operand:SWI124 1 "immediate_operand" ""))]
16835   "optimize_insn_for_speed_p ()
16836    && TARGET_SPLIT_LONG_MOVES
16837    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16838   [(set (match_dup 2) (match_dup 1))
16839    (set (match_dup 0) (match_dup 2))])
16840
16841 ;; Don't compare memory with zero, load and use a test instead.
16842 (define_peephole2
16843   [(set (match_operand 0 "flags_reg_operand" "")
16844         (match_operator 1 "compare_operator"
16845           [(match_operand:SI 2 "memory_operand" "")
16846            (const_int 0)]))
16847    (match_scratch:SI 3 "r")]
16848   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16849   [(set (match_dup 3) (match_dup 2))
16850    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16851
16852 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16853 ;; Don't split NOTs with a displacement operand, because resulting XOR
16854 ;; will not be pairable anyway.
16855 ;;
16856 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16857 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16858 ;; so this split helps here as well.
16859 ;;
16860 ;; Note: Can't do this as a regular split because we can't get proper
16861 ;; lifetime information then.
16862
16863 (define_peephole2
16864   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16865         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16866   "optimize_insn_for_speed_p ()
16867    && ((TARGET_NOT_UNPAIRABLE
16868         && (!MEM_P (operands[0])
16869             || !memory_displacement_operand (operands[0], <MODE>mode)))
16870        || (TARGET_NOT_VECTORMODE
16871            && long_memory_operand (operands[0], <MODE>mode)))
16872    && peep2_regno_dead_p (0, FLAGS_REG)"
16873   [(parallel [(set (match_dup 0)
16874                    (xor:SWI124 (match_dup 1) (const_int -1)))
16875               (clobber (reg:CC FLAGS_REG))])])
16876
16877 ;; Non pairable "test imm, reg" instructions can be translated to
16878 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16879 ;; byte opcode instead of two, have a short form for byte operands),
16880 ;; so do it for other CPUs as well.  Given that the value was dead,
16881 ;; this should not create any new dependencies.  Pass on the sub-word
16882 ;; versions if we're concerned about partial register stalls.
16883
16884 (define_peephole2
16885   [(set (match_operand 0 "flags_reg_operand" "")
16886         (match_operator 1 "compare_operator"
16887           [(and:SI (match_operand:SI 2 "register_operand" "")
16888                    (match_operand:SI 3 "immediate_operand" ""))
16889            (const_int 0)]))]
16890   "ix86_match_ccmode (insn, CCNOmode)
16891    && (true_regnum (operands[2]) != AX_REG
16892        || satisfies_constraint_K (operands[3]))
16893    && peep2_reg_dead_p (1, operands[2])"
16894   [(parallel
16895      [(set (match_dup 0)
16896            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16897                             (const_int 0)]))
16898       (set (match_dup 2)
16899            (and:SI (match_dup 2) (match_dup 3)))])])
16900
16901 ;; We don't need to handle HImode case, because it will be promoted to SImode
16902 ;; on ! TARGET_PARTIAL_REG_STALL
16903
16904 (define_peephole2
16905   [(set (match_operand 0 "flags_reg_operand" "")
16906         (match_operator 1 "compare_operator"
16907           [(and:QI (match_operand:QI 2 "register_operand" "")
16908                    (match_operand:QI 3 "immediate_operand" ""))
16909            (const_int 0)]))]
16910   "! TARGET_PARTIAL_REG_STALL
16911    && ix86_match_ccmode (insn, CCNOmode)
16912    && true_regnum (operands[2]) != AX_REG
16913    && peep2_reg_dead_p (1, operands[2])"
16914   [(parallel
16915      [(set (match_dup 0)
16916            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16917                             (const_int 0)]))
16918       (set (match_dup 2)
16919            (and:QI (match_dup 2) (match_dup 3)))])])
16920
16921 (define_peephole2
16922   [(set (match_operand 0 "flags_reg_operand" "")
16923         (match_operator 1 "compare_operator"
16924           [(and:SI
16925              (zero_extract:SI
16926                (match_operand 2 "ext_register_operand" "")
16927                (const_int 8)
16928                (const_int 8))
16929              (match_operand 3 "const_int_operand" ""))
16930            (const_int 0)]))]
16931   "! TARGET_PARTIAL_REG_STALL
16932    && ix86_match_ccmode (insn, CCNOmode)
16933    && true_regnum (operands[2]) != AX_REG
16934    && peep2_reg_dead_p (1, operands[2])"
16935   [(parallel [(set (match_dup 0)
16936                    (match_op_dup 1
16937                      [(and:SI
16938                         (zero_extract:SI
16939                           (match_dup 2)
16940                           (const_int 8)
16941                           (const_int 8))
16942                         (match_dup 3))
16943                       (const_int 0)]))
16944               (set (zero_extract:SI (match_dup 2)
16945                                     (const_int 8)
16946                                     (const_int 8))
16947                    (and:SI
16948                      (zero_extract:SI
16949                        (match_dup 2)
16950                        (const_int 8)
16951                        (const_int 8))
16952                      (match_dup 3)))])])
16953
16954 ;; Don't do logical operations with memory inputs.
16955 (define_peephole2
16956   [(match_scratch:SI 2 "r")
16957    (parallel [(set (match_operand:SI 0 "register_operand" "")
16958                    (match_operator:SI 3 "arith_or_logical_operator"
16959                      [(match_dup 0)
16960                       (match_operand:SI 1 "memory_operand" "")]))
16961               (clobber (reg:CC FLAGS_REG))])]
16962   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16963   [(set (match_dup 2) (match_dup 1))
16964    (parallel [(set (match_dup 0)
16965                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16966               (clobber (reg:CC FLAGS_REG))])])
16967
16968 (define_peephole2
16969   [(match_scratch:SI 2 "r")
16970    (parallel [(set (match_operand:SI 0 "register_operand" "")
16971                    (match_operator:SI 3 "arith_or_logical_operator"
16972                      [(match_operand:SI 1 "memory_operand" "")
16973                       (match_dup 0)]))
16974               (clobber (reg:CC FLAGS_REG))])]
16975   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16976   [(set (match_dup 2) (match_dup 1))
16977    (parallel [(set (match_dup 0)
16978                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16979               (clobber (reg:CC FLAGS_REG))])])
16980
16981 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16982 ;; refers to the destination of the load!
16983
16984 (define_peephole2
16985   [(set (match_operand:SI 0 "register_operand" "")
16986         (match_operand:SI 1 "register_operand" ""))
16987    (parallel [(set (match_dup 0)
16988                    (match_operator:SI 3 "commutative_operator"
16989                      [(match_dup 0)
16990                       (match_operand:SI 2 "memory_operand" "")]))
16991               (clobber (reg:CC FLAGS_REG))])]
16992   "REGNO (operands[0]) != REGNO (operands[1])
16993    && GENERAL_REGNO_P (REGNO (operands[0]))
16994    && GENERAL_REGNO_P (REGNO (operands[1]))"
16995   [(set (match_dup 0) (match_dup 4))
16996    (parallel [(set (match_dup 0)
16997                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16998               (clobber (reg:CC FLAGS_REG))])]
16999   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17000
17001 (define_peephole2
17002   [(set (match_operand 0 "register_operand" "")
17003         (match_operand 1 "register_operand" ""))
17004    (set (match_dup 0)
17005                    (match_operator 3 "commutative_operator"
17006                      [(match_dup 0)
17007                       (match_operand 2 "memory_operand" "")]))]
17008   "REGNO (operands[0]) != REGNO (operands[1])
17009    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17010        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17011   [(set (match_dup 0) (match_dup 2))
17012    (set (match_dup 0)
17013         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17014
17015 ; Don't do logical operations with memory outputs
17016 ;
17017 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17018 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17019 ; the same decoder scheduling characteristics as the original.
17020
17021 (define_peephole2
17022   [(match_scratch:SI 2 "r")
17023    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17024                    (match_operator:SI 3 "arith_or_logical_operator"
17025                      [(match_dup 0)
17026                       (match_operand:SI 1 "nonmemory_operand" "")]))
17027               (clobber (reg:CC FLAGS_REG))])]
17028   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17029    /* Do not split stack checking probes.  */
17030    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17031   [(set (match_dup 2) (match_dup 0))
17032    (parallel [(set (match_dup 2)
17033                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17034               (clobber (reg:CC FLAGS_REG))])
17035    (set (match_dup 0) (match_dup 2))])
17036
17037 (define_peephole2
17038   [(match_scratch:SI 2 "r")
17039    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17040                    (match_operator:SI 3 "arith_or_logical_operator"
17041                      [(match_operand:SI 1 "nonmemory_operand" "")
17042                       (match_dup 0)]))
17043               (clobber (reg:CC FLAGS_REG))])]
17044   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17045    /* Do not split stack checking probes.  */
17046    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17047   [(set (match_dup 2) (match_dup 0))
17048    (parallel [(set (match_dup 2)
17049                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17050               (clobber (reg:CC FLAGS_REG))])
17051    (set (match_dup 0) (match_dup 2))])
17052
17053 ;; Attempt to always use XOR for zeroing registers.
17054 (define_peephole2
17055   [(set (match_operand 0 "register_operand" "")
17056         (match_operand 1 "const0_operand" ""))]
17057   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17058    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17059    && GENERAL_REG_P (operands[0])
17060    && peep2_regno_dead_p (0, FLAGS_REG)"
17061   [(parallel [(set (match_dup 0) (const_int 0))
17062               (clobber (reg:CC FLAGS_REG))])]
17063   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17064
17065 (define_peephole2
17066   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17067         (const_int 0))]
17068   "(GET_MODE (operands[0]) == QImode
17069     || GET_MODE (operands[0]) == HImode)
17070    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17071    && peep2_regno_dead_p (0, FLAGS_REG)"
17072   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17073               (clobber (reg:CC FLAGS_REG))])])
17074
17075 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17076 (define_peephole2
17077   [(set (match_operand:SWI248 0 "register_operand" "")
17078         (const_int -1))]
17079   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17080    && peep2_regno_dead_p (0, FLAGS_REG)"
17081   [(parallel [(set (match_dup 0) (const_int -1))
17082               (clobber (reg:CC FLAGS_REG))])]
17083 {
17084   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17085     operands[0] = gen_lowpart (SImode, operands[0]);
17086 })
17087
17088 ;; Attempt to convert simple lea to add/shift.
17089 ;; These can be created by move expanders.
17090
17091 (define_peephole2
17092   [(set (match_operand:SWI48 0 "register_operand" "")
17093         (plus:SWI48 (match_dup 0)
17094                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17095   "peep2_regno_dead_p (0, FLAGS_REG)"
17096   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17097               (clobber (reg:CC FLAGS_REG))])])
17098
17099 (define_peephole2
17100   [(set (match_operand:SI 0 "register_operand" "")
17101         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17102                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17103   "TARGET_64BIT
17104    && peep2_regno_dead_p (0, FLAGS_REG)
17105    && REGNO (operands[0]) == REGNO (operands[1])"
17106   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17107               (clobber (reg:CC FLAGS_REG))])]
17108   "operands[2] = gen_lowpart (SImode, operands[2]);")
17109
17110 (define_peephole2
17111   [(set (match_operand:SWI48 0 "register_operand" "")
17112         (mult:SWI48 (match_dup 0)
17113                     (match_operand:SWI48 1 "const_int_operand" "")))]
17114   "exact_log2 (INTVAL (operands[1])) >= 0
17115    && peep2_regno_dead_p (0, FLAGS_REG)"
17116   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17117               (clobber (reg:CC FLAGS_REG))])]
17118   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17119
17120 (define_peephole2
17121   [(set (match_operand:SI 0 "register_operand" "")
17122         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17123                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17124   "TARGET_64BIT
17125    && exact_log2 (INTVAL (operands[2])) >= 0
17126    && REGNO (operands[0]) == REGNO (operands[1])
17127    && peep2_regno_dead_p (0, FLAGS_REG)"
17128   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17129               (clobber (reg:CC FLAGS_REG))])]
17130   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17131
17132 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17133 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17134 ;; On many CPUs it is also faster, since special hardware to avoid esp
17135 ;; dependencies is present.
17136
17137 ;; While some of these conversions may be done using splitters, we use
17138 ;; peepholes in order to allow combine_stack_adjustments pass to see
17139 ;; nonobfuscated RTL.
17140
17141 ;; Convert prologue esp subtractions to push.
17142 ;; We need register to push.  In order to keep verify_flow_info happy we have
17143 ;; two choices
17144 ;; - use scratch and clobber it in order to avoid dependencies
17145 ;; - use already live register
17146 ;; We can't use the second way right now, since there is no reliable way how to
17147 ;; verify that given register is live.  First choice will also most likely in
17148 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17149 ;; call clobbered registers are dead.  We may want to use base pointer as an
17150 ;; alternative when no register is available later.
17151
17152 (define_peephole2
17153   [(match_scratch:P 1 "r")
17154    (parallel [(set (reg:P SP_REG)
17155                    (plus:P (reg:P SP_REG)
17156                            (match_operand:P 0 "const_int_operand" "")))
17157               (clobber (reg:CC FLAGS_REG))
17158               (clobber (mem:BLK (scratch)))])]
17159   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17160    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17161   [(clobber (match_dup 1))
17162    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17163               (clobber (mem:BLK (scratch)))])])
17164
17165 (define_peephole2
17166   [(match_scratch:P 1 "r")
17167    (parallel [(set (reg:P SP_REG)
17168                    (plus:P (reg:P SP_REG)
17169                            (match_operand:P 0 "const_int_operand" "")))
17170               (clobber (reg:CC FLAGS_REG))
17171               (clobber (mem:BLK (scratch)))])]
17172   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17173    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17174   [(clobber (match_dup 1))
17175    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17176    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17177               (clobber (mem:BLK (scratch)))])])
17178
17179 ;; Convert esp subtractions to push.
17180 (define_peephole2
17181   [(match_scratch:P 1 "r")
17182    (parallel [(set (reg:P SP_REG)
17183                    (plus:P (reg:P SP_REG)
17184                            (match_operand:P 0 "const_int_operand" "")))
17185               (clobber (reg:CC FLAGS_REG))])]
17186   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17187    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17188   [(clobber (match_dup 1))
17189    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17190
17191 (define_peephole2
17192   [(match_scratch:P 1 "r")
17193    (parallel [(set (reg:P SP_REG)
17194                    (plus:P (reg:P SP_REG)
17195                            (match_operand:P 0 "const_int_operand" "")))
17196               (clobber (reg:CC FLAGS_REG))])]
17197   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17198    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17199   [(clobber (match_dup 1))
17200    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17201    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17202
17203 ;; Convert epilogue deallocator to pop.
17204 (define_peephole2
17205   [(match_scratch:P 1 "r")
17206    (parallel [(set (reg:P SP_REG)
17207                    (plus:P (reg:P SP_REG)
17208                            (match_operand:P 0 "const_int_operand" "")))
17209               (clobber (reg:CC FLAGS_REG))
17210               (clobber (mem:BLK (scratch)))])]
17211   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17212    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17213   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17214               (clobber (mem:BLK (scratch)))])])
17215
17216 ;; Two pops case is tricky, since pop causes dependency
17217 ;; on destination register.  We use two registers if available.
17218 (define_peephole2
17219   [(match_scratch:P 1 "r")
17220    (match_scratch:P 2 "r")
17221    (parallel [(set (reg:P SP_REG)
17222                    (plus:P (reg:P SP_REG)
17223                            (match_operand:P 0 "const_int_operand" "")))
17224               (clobber (reg:CC FLAGS_REG))
17225               (clobber (mem:BLK (scratch)))])]
17226   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17227    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17228   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17229               (clobber (mem:BLK (scratch)))])
17230    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17231
17232 (define_peephole2
17233   [(match_scratch:P 1 "r")
17234    (parallel [(set (reg:P SP_REG)
17235                    (plus:P (reg:P SP_REG)
17236                            (match_operand:P 0 "const_int_operand" "")))
17237               (clobber (reg:CC FLAGS_REG))
17238               (clobber (mem:BLK (scratch)))])]
17239   "optimize_insn_for_size_p ()
17240    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17241   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17242               (clobber (mem:BLK (scratch)))])
17243    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17244
17245 ;; Convert esp additions to pop.
17246 (define_peephole2
17247   [(match_scratch:P 1 "r")
17248    (parallel [(set (reg:P SP_REG)
17249                    (plus:P (reg:P SP_REG)
17250                            (match_operand:P 0 "const_int_operand" "")))
17251               (clobber (reg:CC FLAGS_REG))])]
17252   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17253   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17254
17255 ;; Two pops case is tricky, since pop causes dependency
17256 ;; on destination register.  We use two registers if available.
17257 (define_peephole2
17258   [(match_scratch:P 1 "r")
17259    (match_scratch:P 2 "r")
17260    (parallel [(set (reg:P SP_REG)
17261                    (plus:P (reg:P SP_REG)
17262                            (match_operand:P 0 "const_int_operand" "")))
17263               (clobber (reg:CC FLAGS_REG))])]
17264   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17265   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17266    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17267
17268 (define_peephole2
17269   [(match_scratch:P 1 "r")
17270    (parallel [(set (reg:P SP_REG)
17271                    (plus:P (reg:P SP_REG)
17272                            (match_operand:P 0 "const_int_operand" "")))
17273               (clobber (reg:CC FLAGS_REG))])]
17274   "optimize_insn_for_size_p ()
17275    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17276   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17277    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17278 \f
17279 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17280 ;; required and register dies.  Similarly for 128 to -128.
17281 (define_peephole2
17282   [(set (match_operand 0 "flags_reg_operand" "")
17283         (match_operator 1 "compare_operator"
17284           [(match_operand 2 "register_operand" "")
17285            (match_operand 3 "const_int_operand" "")]))]
17286   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17287      && incdec_operand (operands[3], GET_MODE (operands[3])))
17288     || (!TARGET_FUSE_CMP_AND_BRANCH
17289         && INTVAL (operands[3]) == 128))
17290    && ix86_match_ccmode (insn, CCGCmode)
17291    && peep2_reg_dead_p (1, operands[2])"
17292   [(parallel [(set (match_dup 0)
17293                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17294               (clobber (match_dup 2))])])
17295 \f
17296 ;; Convert imul by three, five and nine into lea
17297 (define_peephole2
17298   [(parallel
17299     [(set (match_operand:SWI48 0 "register_operand" "")
17300           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17301                       (match_operand:SWI48 2 "const_int_operand" "")))
17302      (clobber (reg:CC FLAGS_REG))])]
17303   "INTVAL (operands[2]) == 3
17304    || INTVAL (operands[2]) == 5
17305    || INTVAL (operands[2]) == 9"
17306   [(set (match_dup 0)
17307         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17308                     (match_dup 1)))]
17309   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17310
17311 (define_peephole2
17312   [(parallel
17313     [(set (match_operand:SWI48 0 "register_operand" "")
17314           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17315                       (match_operand:SWI48 2 "const_int_operand" "")))
17316      (clobber (reg:CC FLAGS_REG))])]
17317   "optimize_insn_for_speed_p ()
17318    && (INTVAL (operands[2]) == 3
17319        || INTVAL (operands[2]) == 5
17320        || INTVAL (operands[2]) == 9)"
17321   [(set (match_dup 0) (match_dup 1))
17322    (set (match_dup 0)
17323         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17324                     (match_dup 0)))]
17325   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17326
17327 ;; imul $32bit_imm, mem, reg is vector decoded, while
17328 ;; imul $32bit_imm, reg, reg is direct decoded.
17329 (define_peephole2
17330   [(match_scratch:SWI48 3 "r")
17331    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17332                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17333                                (match_operand:SWI48 2 "immediate_operand" "")))
17334               (clobber (reg:CC FLAGS_REG))])]
17335   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17336    && !satisfies_constraint_K (operands[2])"
17337   [(set (match_dup 3) (match_dup 1))
17338    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17339               (clobber (reg:CC FLAGS_REG))])])
17340
17341 (define_peephole2
17342   [(match_scratch:SI 3 "r")
17343    (parallel [(set (match_operand:DI 0 "register_operand" "")
17344                    (zero_extend:DI
17345                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17346                               (match_operand:SI 2 "immediate_operand" ""))))
17347               (clobber (reg:CC FLAGS_REG))])]
17348   "TARGET_64BIT
17349    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17350    && !satisfies_constraint_K (operands[2])"
17351   [(set (match_dup 3) (match_dup 1))
17352    (parallel [(set (match_dup 0)
17353                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17354               (clobber (reg:CC FLAGS_REG))])])
17355
17356 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17357 ;; Convert it into imul reg, reg
17358 ;; It would be better to force assembler to encode instruction using long
17359 ;; immediate, but there is apparently no way to do so.
17360 (define_peephole2
17361   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17362                    (mult:SWI248
17363                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17364                     (match_operand:SWI248 2 "const_int_operand" "")))
17365               (clobber (reg:CC FLAGS_REG))])
17366    (match_scratch:SWI248 3 "r")]
17367   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17368    && satisfies_constraint_K (operands[2])"
17369   [(set (match_dup 3) (match_dup 2))
17370    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17371               (clobber (reg:CC FLAGS_REG))])]
17372 {
17373   if (!rtx_equal_p (operands[0], operands[1]))
17374     emit_move_insn (operands[0], operands[1]);
17375 })
17376
17377 ;; After splitting up read-modify operations, array accesses with memory
17378 ;; operands might end up in form:
17379 ;;  sall    $2, %eax
17380 ;;  movl    4(%esp), %edx
17381 ;;  addl    %edx, %eax
17382 ;; instead of pre-splitting:
17383 ;;  sall    $2, %eax
17384 ;;  addl    4(%esp), %eax
17385 ;; Turn it into:
17386 ;;  movl    4(%esp), %edx
17387 ;;  leal    (%edx,%eax,4), %eax
17388
17389 (define_peephole2
17390   [(match_scratch:P 5 "r")
17391    (parallel [(set (match_operand 0 "register_operand" "")
17392                    (ashift (match_operand 1 "register_operand" "")
17393                            (match_operand 2 "const_int_operand" "")))
17394                (clobber (reg:CC FLAGS_REG))])
17395    (parallel [(set (match_operand 3 "register_operand" "")
17396                    (plus (match_dup 0)
17397                          (match_operand 4 "x86_64_general_operand" "")))
17398                    (clobber (reg:CC FLAGS_REG))])]
17399   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17400    /* Validate MODE for lea.  */
17401    && ((!TARGET_PARTIAL_REG_STALL
17402         && (GET_MODE (operands[0]) == QImode
17403             || GET_MODE (operands[0]) == HImode))
17404        || GET_MODE (operands[0]) == SImode
17405        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17406    && (rtx_equal_p (operands[0], operands[3])
17407        || peep2_reg_dead_p (2, operands[0]))
17408    /* We reorder load and the shift.  */
17409    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17410   [(set (match_dup 5) (match_dup 4))
17411    (set (match_dup 0) (match_dup 1))]
17412 {
17413   enum machine_mode op1mode = GET_MODE (operands[1]);
17414   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17415   int scale = 1 << INTVAL (operands[2]);
17416   rtx index = gen_lowpart (Pmode, operands[1]);
17417   rtx base = gen_lowpart (Pmode, operands[5]);
17418   rtx dest = gen_lowpart (mode, operands[3]);
17419
17420   operands[1] = gen_rtx_PLUS (Pmode, base,
17421                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17422   operands[5] = base;
17423   if (mode != Pmode)
17424     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17425   if (op1mode != Pmode)
17426     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17427   operands[0] = dest;
17428 })
17429 \f
17430 ;; Call-value patterns last so that the wildcard operand does not
17431 ;; disrupt insn-recog's switch tables.
17432
17433 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17434   [(parallel
17435     [(set (match_operand 0 "" "")
17436           (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17437                 (match_operand:SI 2 "" "")))
17438      (set (reg:SI SP_REG)
17439           (plus:SI (reg:SI SP_REG)
17440                    (match_operand:SI 3 "immediate_operand" "")))])
17441    (unspec [(match_operand 4 "const_int_operand" "")]
17442            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17443   "TARGET_VZEROUPPER && !TARGET_64BIT"
17444   "#"
17445   "&& reload_completed"
17446   [(const_int 0)]
17447   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17448   [(set_attr "type" "callv")])
17449
17450 (define_insn "*call_value_pop_0"
17451   [(set (match_operand 0 "" "")
17452         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17453               (match_operand:SI 2 "" "")))
17454    (set (reg:SI SP_REG)
17455         (plus:SI (reg:SI SP_REG)
17456                  (match_operand:SI 3 "immediate_operand" "")))]
17457   "!TARGET_64BIT"
17458   { return ix86_output_call_insn (insn, operands[1], 1); }
17459   [(set_attr "type" "callv")])
17460
17461 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17462   [(parallel
17463     [(set (match_operand 0 "" "")
17464           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17465                 (match_operand:SI 2 "" "")))
17466      (set (reg:SI SP_REG)
17467           (plus:SI (reg:SI SP_REG)
17468                    (match_operand:SI 3 "immediate_operand" "i")))])
17469    (unspec [(match_operand 4 "const_int_operand" "")]
17470            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17471   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17472   "#"
17473   "&& reload_completed"
17474   [(const_int 0)]
17475   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17476   [(set_attr "type" "callv")])
17477
17478 (define_insn "*call_value_pop_1"
17479   [(set (match_operand 0 "" "")
17480         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17481               (match_operand:SI 2 "" "")))
17482    (set (reg:SI SP_REG)
17483         (plus:SI (reg:SI SP_REG)
17484                  (match_operand:SI 3 "immediate_operand" "i")))]
17485   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17486   { return ix86_output_call_insn (insn, operands[1], 1); }
17487   [(set_attr "type" "callv")])
17488
17489 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17490  [(parallel
17491    [(set (match_operand 0 "" "")
17492           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17493                 (match_operand:SI 2 "" "")))
17494      (set (reg:SI SP_REG)
17495           (plus:SI (reg:SI SP_REG)
17496                    (match_operand:SI 3 "immediate_operand" "i,i")))])
17497    (unspec [(match_operand 4 "const_int_operand" "")]
17498            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17499   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17500   "#"
17501   "&& reload_completed"
17502   [(const_int 0)]
17503   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17504   [(set_attr "type" "callv")])
17505
17506 (define_insn "*sibcall_value_pop_1"
17507   [(set (match_operand 0 "" "")
17508         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17509               (match_operand:SI 2 "" "")))
17510    (set (reg:SI SP_REG)
17511         (plus:SI (reg:SI SP_REG)
17512                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17513   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17514   { return ix86_output_call_insn (insn, operands[1], 1); }
17515   [(set_attr "type" "callv")])
17516
17517 (define_insn_and_split "*call_value_0_vzeroupper"
17518   [(set (match_operand 0 "" "")
17519         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17520               (match_operand:SI 2 "" "")))
17521    (unspec [(match_operand 3 "const_int_operand" "")]
17522            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17523   "TARGET_VZEROUPPER && !TARGET_64BIT"
17524   "#"
17525   "&& reload_completed"
17526   [(const_int 0)]
17527   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17528   [(set_attr "type" "callv")])
17529
17530 (define_insn "*call_value_0"
17531   [(set (match_operand 0 "" "")
17532         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17533               (match_operand:SI 2 "" "")))]
17534   "!TARGET_64BIT"
17535   { return ix86_output_call_insn (insn, operands[1], 1); }
17536   [(set_attr "type" "callv")])
17537
17538 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17539   [(set (match_operand 0 "" "")
17540         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17541               (match_operand:DI 2 "const_int_operand" "")))
17542    (unspec [(match_operand 3 "const_int_operand" "")]
17543            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17544   "TARGET_VZEROUPPER && TARGET_64BIT"
17545   "#"
17546   "&& reload_completed"
17547   [(const_int 0)]
17548   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17549   [(set_attr "type" "callv")])
17550
17551 (define_insn "*call_value_0_rex64"
17552   [(set (match_operand 0 "" "")
17553         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17554               (match_operand:DI 2 "const_int_operand" "")))]
17555   "TARGET_64BIT"
17556   { return ix86_output_call_insn (insn, operands[1], 1); }
17557   [(set_attr "type" "callv")])
17558
17559 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17560   [(parallel
17561     [(set (match_operand 0 "" "")
17562           (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17563                 (match_operand:DI 2 "const_int_operand" "")))
17564      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17565      (clobber (reg:TI XMM6_REG))
17566      (clobber (reg:TI XMM7_REG))
17567      (clobber (reg:TI XMM8_REG))
17568      (clobber (reg:TI XMM9_REG))
17569      (clobber (reg:TI XMM10_REG))
17570      (clobber (reg:TI XMM11_REG))
17571      (clobber (reg:TI XMM12_REG))
17572      (clobber (reg:TI XMM13_REG))
17573      (clobber (reg:TI XMM14_REG))
17574      (clobber (reg:TI XMM15_REG))
17575      (clobber (reg:DI SI_REG))
17576      (clobber (reg:DI DI_REG))])
17577    (unspec [(match_operand 3 "const_int_operand" "")]
17578            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17579   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17580   "#"
17581   "&& reload_completed"
17582   [(const_int 0)]
17583   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17584   [(set_attr "type" "callv")])
17585
17586 (define_insn "*call_value_0_rex64_ms_sysv"
17587   [(set (match_operand 0 "" "")
17588         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17589               (match_operand:DI 2 "const_int_operand" "")))
17590    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17591    (clobber (reg:TI XMM6_REG))
17592    (clobber (reg:TI XMM7_REG))
17593    (clobber (reg:TI XMM8_REG))
17594    (clobber (reg:TI XMM9_REG))
17595    (clobber (reg:TI XMM10_REG))
17596    (clobber (reg:TI XMM11_REG))
17597    (clobber (reg:TI XMM12_REG))
17598    (clobber (reg:TI XMM13_REG))
17599    (clobber (reg:TI XMM14_REG))
17600    (clobber (reg:TI XMM15_REG))
17601    (clobber (reg:DI SI_REG))
17602    (clobber (reg:DI DI_REG))]
17603   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17604   { return ix86_output_call_insn (insn, operands[1], 1); }
17605   [(set_attr "type" "callv")])
17606
17607 (define_insn_and_split "*call_value_1_vzeroupper"
17608   [(set (match_operand 0 "" "")
17609         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17610               (match_operand:SI 2 "" "")))
17611    (unspec [(match_operand 3 "const_int_operand" "")]
17612            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17613   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17614   "#"
17615   "&& reload_completed"
17616   [(const_int 0)]
17617   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17618   [(set_attr "type" "callv")])
17619
17620 (define_insn "*call_value_1"
17621   [(set (match_operand 0 "" "")
17622         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17623               (match_operand:SI 2 "" "")))]
17624   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17625   { return ix86_output_call_insn (insn, operands[1], 1); }
17626   [(set_attr "type" "callv")])
17627
17628 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17629   [(set (match_operand 0 "" "")
17630         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17631               (match_operand:SI 2 "" "")))
17632    (unspec [(match_operand 3 "const_int_operand" "")]
17633            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17634   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17635   "#"
17636   "&& reload_completed"
17637   [(const_int 0)]
17638   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17639   [(set_attr "type" "callv")])
17640
17641 (define_insn "*sibcall_value_1"
17642   [(set (match_operand 0 "" "")
17643         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17644               (match_operand:SI 2 "" "")))]
17645   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17646   { return ix86_output_call_insn (insn, operands[1], 1); }
17647   [(set_attr "type" "callv")])
17648
17649 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17650   [(set (match_operand 0 "" "")
17651         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17652               (match_operand:DI 2 "" "")))
17653    (unspec [(match_operand 3 "const_int_operand" "")]
17654            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17655   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17656    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17657   "#"
17658   "&& reload_completed"
17659   [(const_int 0)]
17660   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17661   [(set_attr "type" "callv")])
17662
17663 (define_insn "*call_value_1_rex64"
17664   [(set (match_operand 0 "" "")
17665         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17666               (match_operand:DI 2 "" "")))]
17667   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17668    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17669   { return ix86_output_call_insn (insn, operands[1], 1); }
17670   [(set_attr "type" "callv")])
17671
17672 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17673   [(parallel
17674     [(set (match_operand 0 "" "")
17675           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17676                 (match_operand:DI 2 "" "")))
17677      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17678      (clobber (reg:TI XMM6_REG))
17679      (clobber (reg:TI XMM7_REG))
17680      (clobber (reg:TI XMM8_REG))
17681      (clobber (reg:TI XMM9_REG))
17682      (clobber (reg:TI XMM10_REG))
17683      (clobber (reg:TI XMM11_REG))
17684      (clobber (reg:TI XMM12_REG))
17685      (clobber (reg:TI XMM13_REG))
17686      (clobber (reg:TI XMM14_REG))
17687      (clobber (reg:TI XMM15_REG))
17688      (clobber (reg:DI SI_REG))
17689      (clobber (reg:DI DI_REG))])
17690    (unspec [(match_operand 3 "const_int_operand" "")]
17691            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17692   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17693   "#"
17694   "&& reload_completed"
17695   [(const_int 0)]
17696   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17697   [(set_attr "type" "callv")])
17698
17699 (define_insn "*call_value_1_rex64_ms_sysv"
17700   [(set (match_operand 0 "" "")
17701         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17702               (match_operand:DI 2 "" "")))
17703    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17704    (clobber (reg:TI XMM6_REG))
17705    (clobber (reg:TI XMM7_REG))
17706    (clobber (reg:TI XMM8_REG))
17707    (clobber (reg:TI XMM9_REG))
17708    (clobber (reg:TI XMM10_REG))
17709    (clobber (reg:TI XMM11_REG))
17710    (clobber (reg:TI XMM12_REG))
17711    (clobber (reg:TI XMM13_REG))
17712    (clobber (reg:TI XMM14_REG))
17713    (clobber (reg:TI XMM15_REG))
17714    (clobber (reg:DI SI_REG))
17715    (clobber (reg:DI DI_REG))]
17716   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17717   { return ix86_output_call_insn (insn, operands[1], 1); }
17718   [(set_attr "type" "callv")])
17719
17720 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17721   [(set (match_operand 0 "" "")
17722         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17723               (match_operand:DI 2 "" "")))
17724    (unspec [(match_operand 3 "const_int_operand" "")]
17725            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17726   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17727   "#"
17728   "&& reload_completed"
17729   [(const_int 0)]
17730   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17731   [(set_attr "type" "callv")])
17732
17733 (define_insn "*call_value_1_rex64_large"
17734   [(set (match_operand 0 "" "")
17735         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17736               (match_operand:DI 2 "" "")))]
17737   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17738   { return ix86_output_call_insn (insn, operands[1], 1); }
17739   [(set_attr "type" "callv")])
17740
17741 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17742   [(set (match_operand 0 "" "")
17743         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17744               (match_operand:DI 2 "" "")))
17745    (unspec [(match_operand 3 "const_int_operand" "")]
17746            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17747   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17748   "#"
17749   "&& reload_completed"
17750   [(const_int 0)]
17751   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17752   [(set_attr "type" "callv")])
17753
17754 (define_insn "*sibcall_value_1_rex64"
17755   [(set (match_operand 0 "" "")
17756         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17757               (match_operand:DI 2 "" "")))]
17758   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17759   { return ix86_output_call_insn (insn, operands[1], 1); }
17760   [(set_attr "type" "callv")])
17761 \f
17762 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17763 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17764 ;; caught for use by garbage collectors and the like.  Using an insn that
17765 ;; maps to SIGILL makes it more likely the program will rightfully die.
17766 ;; Keeping with tradition, "6" is in honor of #UD.
17767 (define_insn "trap"
17768   [(trap_if (const_int 1) (const_int 6))]
17769   ""
17770   { return ASM_SHORT "0x0b0f"; }
17771   [(set_attr "length" "2")])
17772
17773 (define_expand "prefetch"
17774   [(prefetch (match_operand 0 "address_operand" "")
17775              (match_operand:SI 1 "const_int_operand" "")
17776              (match_operand:SI 2 "const_int_operand" ""))]
17777   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17778 {
17779   int rw = INTVAL (operands[1]);
17780   int locality = INTVAL (operands[2]);
17781
17782   gcc_assert (rw == 0 || rw == 1);
17783   gcc_assert (locality >= 0 && locality <= 3);
17784   gcc_assert (GET_MODE (operands[0]) == Pmode
17785               || GET_MODE (operands[0]) == VOIDmode);
17786
17787   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17788      supported by SSE counterpart or the SSE prefetch is not available
17789      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17790      of locality.  */
17791   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17792     operands[2] = GEN_INT (3);
17793   else
17794     operands[1] = const0_rtx;
17795 })
17796
17797 (define_insn "*prefetch_sse_<mode>"
17798   [(prefetch (match_operand:P 0 "address_operand" "p")
17799              (const_int 0)
17800              (match_operand:SI 1 "const_int_operand" ""))]
17801   "TARGET_PREFETCH_SSE"
17802 {
17803   static const char * const patterns[4] = {
17804    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17805   };
17806
17807   int locality = INTVAL (operands[1]);
17808   gcc_assert (locality >= 0 && locality <= 3);
17809
17810   return patterns[locality];
17811 }
17812   [(set_attr "type" "sse")
17813    (set_attr "atom_sse_attr" "prefetch")
17814    (set (attr "length_address")
17815         (symbol_ref "memory_address_length (operands[0])"))
17816    (set_attr "memory" "none")])
17817
17818 (define_insn "*prefetch_3dnow_<mode>"
17819   [(prefetch (match_operand:P 0 "address_operand" "p")
17820              (match_operand:SI 1 "const_int_operand" "n")
17821              (const_int 3))]
17822   "TARGET_3DNOW"
17823 {
17824   if (INTVAL (operands[1]) == 0)
17825     return "prefetch\t%a0";
17826   else
17827     return "prefetchw\t%a0";
17828 }
17829   [(set_attr "type" "mmx")
17830    (set (attr "length_address")
17831         (symbol_ref "memory_address_length (operands[0])"))
17832    (set_attr "memory" "none")])
17833
17834 (define_expand "stack_protect_set"
17835   [(match_operand 0 "memory_operand" "")
17836    (match_operand 1 "memory_operand" "")]
17837   ""
17838 {
17839   rtx (*insn)(rtx, rtx);
17840
17841 #ifdef TARGET_THREAD_SSP_OFFSET
17842   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17843   insn = (TARGET_64BIT
17844           ? gen_stack_tls_protect_set_di
17845           : gen_stack_tls_protect_set_si);
17846 #else
17847   insn = (TARGET_64BIT
17848           ? gen_stack_protect_set_di
17849           : gen_stack_protect_set_si);
17850 #endif
17851
17852   emit_insn (insn (operands[0], operands[1]));
17853   DONE;
17854 })
17855
17856 (define_insn "stack_protect_set_<mode>"
17857   [(set (match_operand:P 0 "memory_operand" "=m")
17858         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17859    (set (match_scratch:P 2 "=&r") (const_int 0))
17860    (clobber (reg:CC FLAGS_REG))]
17861   ""
17862   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17863   [(set_attr "type" "multi")])
17864
17865 (define_insn "stack_tls_protect_set_<mode>"
17866   [(set (match_operand:P 0 "memory_operand" "=m")
17867         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17868                   UNSPEC_SP_TLS_SET))
17869    (set (match_scratch:P 2 "=&r") (const_int 0))
17870    (clobber (reg:CC FLAGS_REG))]
17871   ""
17872   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17873   [(set_attr "type" "multi")])
17874
17875 (define_expand "stack_protect_test"
17876   [(match_operand 0 "memory_operand" "")
17877    (match_operand 1 "memory_operand" "")
17878    (match_operand 2 "" "")]
17879   ""
17880 {
17881   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17882
17883   rtx (*insn)(rtx, rtx, rtx);
17884
17885 #ifdef TARGET_THREAD_SSP_OFFSET
17886   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17887   insn = (TARGET_64BIT
17888           ? gen_stack_tls_protect_test_di
17889           : gen_stack_tls_protect_test_si);
17890 #else
17891   insn = (TARGET_64BIT
17892           ? gen_stack_protect_test_di
17893           : gen_stack_protect_test_si);
17894 #endif
17895
17896   emit_insn (insn (flags, operands[0], operands[1]));
17897
17898   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17899                                   flags, const0_rtx, operands[2]));
17900   DONE;
17901 })
17902
17903 (define_insn "stack_protect_test_<mode>"
17904   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17905         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17906                      (match_operand:P 2 "memory_operand" "m")]
17907                     UNSPEC_SP_TEST))
17908    (clobber (match_scratch:P 3 "=&r"))]
17909   ""
17910   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17911   [(set_attr "type" "multi")])
17912
17913 (define_insn "stack_tls_protect_test_<mode>"
17914   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17915         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17916                      (match_operand:P 2 "const_int_operand" "i")]
17917                     UNSPEC_SP_TLS_TEST))
17918    (clobber (match_scratch:P 3 "=r"))]
17919   ""
17920   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17921   [(set_attr "type" "multi")])
17922
17923 (define_insn "sse4_2_crc32<mode>"
17924   [(set (match_operand:SI 0 "register_operand" "=r")
17925         (unspec:SI
17926           [(match_operand:SI 1 "register_operand" "0")
17927            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17928           UNSPEC_CRC32))]
17929   "TARGET_SSE4_2 || TARGET_CRC32"
17930   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17931   [(set_attr "type" "sselog1")
17932    (set_attr "prefix_rep" "1")
17933    (set_attr "prefix_extra" "1")
17934    (set (attr "prefix_data16")
17935      (if_then_else (match_operand:HI 2 "" "")
17936        (const_string "1")
17937        (const_string "*")))
17938    (set (attr "prefix_rex")
17939      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17940        (const_string "1")
17941        (const_string "*")))
17942    (set_attr "mode" "SI")])
17943
17944 (define_insn "sse4_2_crc32di"
17945   [(set (match_operand:DI 0 "register_operand" "=r")
17946         (unspec:DI
17947           [(match_operand:DI 1 "register_operand" "0")
17948            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17949           UNSPEC_CRC32))]
17950   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17951   "crc32{q}\t{%2, %0|%0, %2}"
17952   [(set_attr "type" "sselog1")
17953    (set_attr "prefix_rep" "1")
17954    (set_attr "prefix_extra" "1")
17955    (set_attr "mode" "DI")])
17956
17957 (define_expand "rdpmc"
17958   [(match_operand:DI 0 "register_operand" "")
17959    (match_operand:SI 1 "register_operand" "")]
17960   ""
17961 {
17962   rtx reg = gen_reg_rtx (DImode);
17963   rtx si;
17964
17965   /* Force operand 1 into ECX.  */
17966   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17967   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17968   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17969                                 UNSPECV_RDPMC);
17970
17971   if (TARGET_64BIT)
17972     {
17973       rtvec vec = rtvec_alloc (2);
17974       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17975       rtx upper = gen_reg_rtx (DImode);
17976       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17977                                         gen_rtvec (1, const0_rtx),
17978                                         UNSPECV_RDPMC);
17979       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17980       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17981       emit_insn (load);
17982       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17983                                    NULL, 1, OPTAB_DIRECT);
17984       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17985                                  OPTAB_DIRECT);
17986     }
17987   else
17988     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17989   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17990   DONE;
17991 })
17992
17993 (define_insn "*rdpmc"
17994   [(set (match_operand:DI 0 "register_operand" "=A")
17995         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17996                             UNSPECV_RDPMC))]
17997   "!TARGET_64BIT"
17998   "rdpmc"
17999   [(set_attr "type" "other")
18000    (set_attr "length" "2")])
18001
18002 (define_insn "*rdpmc_rex64"
18003   [(set (match_operand:DI 0 "register_operand" "=a")
18004         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18005                             UNSPECV_RDPMC))
18006   (set (match_operand:DI 1 "register_operand" "=d")
18007        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18008   "TARGET_64BIT"
18009   "rdpmc"
18010   [(set_attr "type" "other")
18011    (set_attr "length" "2")])
18012
18013 (define_expand "rdtsc"
18014   [(set (match_operand:DI 0 "register_operand" "")
18015         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18016   ""
18017 {
18018   if (TARGET_64BIT)
18019     {
18020       rtvec vec = rtvec_alloc (2);
18021       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18022       rtx upper = gen_reg_rtx (DImode);
18023       rtx lower = gen_reg_rtx (DImode);
18024       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18025                                          gen_rtvec (1, const0_rtx),
18026                                          UNSPECV_RDTSC);
18027       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18028       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18029       emit_insn (load);
18030       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18031                                    NULL, 1, OPTAB_DIRECT);
18032       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18033                                    OPTAB_DIRECT);
18034       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18035       DONE;
18036     }
18037 })
18038
18039 (define_insn "*rdtsc"
18040   [(set (match_operand:DI 0 "register_operand" "=A")
18041         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18042   "!TARGET_64BIT"
18043   "rdtsc"
18044   [(set_attr "type" "other")
18045    (set_attr "length" "2")])
18046
18047 (define_insn "*rdtsc_rex64"
18048   [(set (match_operand:DI 0 "register_operand" "=a")
18049         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18050    (set (match_operand:DI 1 "register_operand" "=d")
18051         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18052   "TARGET_64BIT"
18053   "rdtsc"
18054   [(set_attr "type" "other")
18055    (set_attr "length" "2")])
18056
18057 (define_expand "rdtscp"
18058   [(match_operand:DI 0 "register_operand" "")
18059    (match_operand:SI 1 "memory_operand" "")]
18060   ""
18061 {
18062   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18063                                     gen_rtvec (1, const0_rtx),
18064                                     UNSPECV_RDTSCP);
18065   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18066                                     gen_rtvec (1, const0_rtx),
18067                                     UNSPECV_RDTSCP);
18068   rtx reg = gen_reg_rtx (DImode);
18069   rtx tmp = gen_reg_rtx (SImode);
18070
18071   if (TARGET_64BIT)
18072     {
18073       rtvec vec = rtvec_alloc (3);
18074       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18075       rtx upper = gen_reg_rtx (DImode);
18076       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18077       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18078       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18079       emit_insn (load);
18080       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18081                                    NULL, 1, OPTAB_DIRECT);
18082       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18083                                  OPTAB_DIRECT);
18084     }
18085   else
18086     {
18087       rtvec vec = rtvec_alloc (2);
18088       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18089       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18090       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18091       emit_insn (load);
18092     }
18093   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18094   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18095   DONE;
18096 })
18097
18098 (define_insn "*rdtscp"
18099   [(set (match_operand:DI 0 "register_operand" "=A")
18100         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18101    (set (match_operand:SI 1 "register_operand" "=c")
18102         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18103   "!TARGET_64BIT"
18104   "rdtscp"
18105   [(set_attr "type" "other")
18106    (set_attr "length" "3")])
18107
18108 (define_insn "*rdtscp_rex64"
18109   [(set (match_operand:DI 0 "register_operand" "=a")
18110         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18111    (set (match_operand:DI 1 "register_operand" "=d")
18112         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18113    (set (match_operand:SI 2 "register_operand" "=c")
18114         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18115   "TARGET_64BIT"
18116   "rdtscp"
18117   [(set_attr "type" "other")
18118    (set_attr "length" "3")])
18119
18120 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18121 ;;
18122 ;; LWP instructions
18123 ;;
18124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18125
18126 (define_expand "lwp_llwpcb"
18127   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18128                     UNSPECV_LLWP_INTRINSIC)]
18129   "TARGET_LWP")
18130
18131 (define_insn "*lwp_llwpcb<mode>1"
18132   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18133                     UNSPECV_LLWP_INTRINSIC)]
18134   "TARGET_LWP"
18135   "llwpcb\t%0"
18136   [(set_attr "type" "lwp")
18137    (set_attr "mode" "<MODE>")
18138    (set_attr "length" "5")])
18139
18140 (define_expand "lwp_slwpcb"
18141   [(set (match_operand 0 "register_operand" "=r")
18142         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18143   "TARGET_LWP"
18144 {
18145   rtx (*insn)(rtx);
18146
18147   insn = (TARGET_64BIT
18148           ? gen_lwp_slwpcbdi
18149           : gen_lwp_slwpcbsi);
18150
18151   emit_insn (insn (operands[0]));
18152   DONE;
18153 })
18154
18155 (define_insn "lwp_slwpcb<mode>"
18156   [(set (match_operand:P 0 "register_operand" "=r")
18157         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18158   "TARGET_LWP"
18159   "slwpcb\t%0"
18160   [(set_attr "type" "lwp")
18161    (set_attr "mode" "<MODE>")
18162    (set_attr "length" "5")])
18163
18164 (define_expand "lwp_lwpval<mode>3"
18165   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18166                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18167                      (match_operand:SI 3 "const_int_operand" "i")]
18168                     UNSPECV_LWPVAL_INTRINSIC)]
18169   "TARGET_LWP"
18170   "/* Avoid unused variable warning.  */
18171    (void) operand0;")
18172
18173 (define_insn "*lwp_lwpval<mode>3_1"
18174   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18175                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18176                      (match_operand:SI 2 "const_int_operand" "i")]
18177                     UNSPECV_LWPVAL_INTRINSIC)]
18178   "TARGET_LWP"
18179   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18180   [(set_attr "type" "lwp")
18181    (set_attr "mode" "<MODE>")
18182    (set (attr "length")
18183         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18184
18185 (define_expand "lwp_lwpins<mode>3"
18186   [(set (reg:CCC FLAGS_REG)
18187         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18188                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18189                               (match_operand:SI 3 "const_int_operand" "i")]
18190                              UNSPECV_LWPINS_INTRINSIC))
18191    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18192         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18193   "TARGET_LWP")
18194
18195 (define_insn "*lwp_lwpins<mode>3_1"
18196   [(set (reg:CCC FLAGS_REG)
18197         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18198                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18199                               (match_operand:SI 2 "const_int_operand" "i")]
18200                              UNSPECV_LWPINS_INTRINSIC))]
18201   "TARGET_LWP"
18202   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18203   [(set_attr "type" "lwp")
18204    (set_attr "mode" "<MODE>")
18205    (set (attr "length")
18206         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18207
18208 (define_insn "rdfsbase<mode>"
18209   [(set (match_operand:SWI48 0 "register_operand" "=r")
18210         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18211   "TARGET_64BIT && TARGET_FSGSBASE"
18212   "rdfsbase %0"
18213   [(set_attr "type" "other")
18214    (set_attr "prefix_extra" "2")])
18215
18216 (define_insn "rdgsbase<mode>"
18217   [(set (match_operand:SWI48 0 "register_operand" "=r")
18218         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18219   "TARGET_64BIT && TARGET_FSGSBASE"
18220   "rdgsbase %0"
18221   [(set_attr "type" "other")
18222    (set_attr "prefix_extra" "2")])
18223
18224 (define_insn "wrfsbase<mode>"
18225   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18226                     UNSPECV_WRFSBASE)]
18227   "TARGET_64BIT && TARGET_FSGSBASE"
18228   "wrfsbase %0"
18229   [(set_attr "type" "other")
18230    (set_attr "prefix_extra" "2")])
18231
18232 (define_insn "wrgsbase<mode>"
18233   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18234                     UNSPECV_WRGSBASE)]
18235   "TARGET_64BIT && TARGET_FSGSBASE"
18236   "wrgsbase %0"
18237   [(set_attr "type" "other")
18238    (set_attr "prefix_extra" "2")])
18239
18240 (define_insn "rdrand<mode>_1"
18241   [(set (match_operand:SWI248 0 "register_operand" "=r")
18242         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18243    (set (reg:CCC FLAGS_REG)
18244         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18245   "TARGET_RDRND"
18246   "rdrand\t%0"
18247   [(set_attr "type" "other")
18248    (set_attr "prefix_extra" "1")])
18249
18250 (include "mmx.md")
18251 (include "sse.md")
18252 (include "sync.md")