OSDN Git Service

2010-11-05 Kai Tietz <kai.tietz@onevision.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
63
64 ;; UNSPEC usage:
65
66 (define_c_enum "unspec" [
67   ;; Relocation specifiers
68   UNSPEC_GOT
69   UNSPEC_GOTOFF
70   UNSPEC_GOTPCREL
71   UNSPEC_GOTTPOFF
72   UNSPEC_TPOFF
73   UNSPEC_NTPOFF
74   UNSPEC_DTPOFF
75   UNSPEC_GOTNTPOFF
76   UNSPEC_INDNTPOFF
77   UNSPEC_PLTOFF
78   UNSPEC_MACHOPIC_OFFSET
79   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
97   ;; Other random patterns
98   UNSPEC_SCAS
99   UNSPEC_FNSTSW
100   UNSPEC_SAHF
101   UNSPEC_PARITY
102   UNSPEC_FSTCW
103   UNSPEC_ADD_CARRY
104   UNSPEC_FLDCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_CALL_NEEDS_VZEROUPPER
110
111   ;; For SSE/MMX support:
112   UNSPEC_FIX_NOTRUNC
113   UNSPEC_MASKMOV
114   UNSPEC_MOVMSK
115   UNSPEC_MOVNT
116   UNSPEC_MOVU
117   UNSPEC_RCP
118   UNSPEC_RSQRT
119   UNSPEC_SFENCE
120   UNSPEC_PFRCP
121   UNSPEC_PFRCPIT1
122   UNSPEC_PFRCPIT2
123   UNSPEC_PFRSQRT
124   UNSPEC_PFRSQIT1
125   UNSPEC_MFENCE
126   UNSPEC_LFENCE
127   UNSPEC_PSADBW
128   UNSPEC_LDDQU
129   UNSPEC_MS_TO_SYSV_CALL
130
131   ;; Generic math support
132   UNSPEC_COPYSIGN
133   UNSPEC_IEEE_MIN       ; not commutative
134   UNSPEC_IEEE_MAX       ; not commutative
135
136   ;; x87 Floating point
137   UNSPEC_SIN
138   UNSPEC_COS
139   UNSPEC_FPATAN
140   UNSPEC_FYL2X
141   UNSPEC_FYL2XP1
142   UNSPEC_FRNDINT
143   UNSPEC_FIST
144   UNSPEC_F2XM1
145   UNSPEC_TAN
146   UNSPEC_FXAM
147
148   ;; x87 Rounding
149   UNSPEC_FRNDINT_FLOOR
150   UNSPEC_FRNDINT_CEIL
151   UNSPEC_FRNDINT_TRUNC
152   UNSPEC_FRNDINT_MASK_PM
153   UNSPEC_FIST_FLOOR
154   UNSPEC_FIST_CEIL
155
156   ;; x87 Double output FP
157   UNSPEC_SINCOS_COS
158   UNSPEC_SINCOS_SIN
159   UNSPEC_XTRACT_FRACT
160   UNSPEC_XTRACT_EXP
161   UNSPEC_FSCALE_FRACT
162   UNSPEC_FSCALE_EXP
163   UNSPEC_FPREM_F
164   UNSPEC_FPREM_U
165   UNSPEC_FPREM1_F
166   UNSPEC_FPREM1_U
167
168   UNSPEC_C2_FLAG
169   UNSPEC_FXAM_MEM
170
171   ;; SSP patterns
172   UNSPEC_SP_SET
173   UNSPEC_SP_TEST
174   UNSPEC_SP_TLS_SET
175   UNSPEC_SP_TLS_TEST
176
177   ;; SSSE3
178   UNSPEC_PSHUFB
179   UNSPEC_PSIGN
180   UNSPEC_PALIGNR
181
182   ;; For SSE4A support
183   UNSPEC_EXTRQI
184   UNSPEC_EXTRQ
185   UNSPEC_INSERTQI
186   UNSPEC_INSERTQ
187
188   ;; For SSE4.1 support
189   UNSPEC_BLENDV
190   UNSPEC_INSERTPS
191   UNSPEC_DP
192   UNSPEC_MOVNTDQA
193   UNSPEC_MPSADBW
194   UNSPEC_PHMINPOSUW
195   UNSPEC_PTEST
196   UNSPEC_ROUND
197
198   ;; For SSE4.2 support
199   UNSPEC_CRC32
200   UNSPEC_PCMPESTR
201   UNSPEC_PCMPISTR
202
203   ;; For FMA4 support
204   UNSPEC_FMADDSUB
205   UNSPEC_XOP_UNSIGNED_CMP
206   UNSPEC_XOP_TRUEFALSE
207   UNSPEC_XOP_PERMUTE
208   UNSPEC_FRCZ
209
210   ;; For AES support
211   UNSPEC_AESENC
212   UNSPEC_AESENCLAST
213   UNSPEC_AESDEC
214   UNSPEC_AESDECLAST
215   UNSPEC_AESIMC
216   UNSPEC_AESKEYGENASSIST
217
218   ;; For PCLMUL support
219   UNSPEC_PCLMUL
220
221   ;; For AVX support
222   UNSPEC_PCMP
223   UNSPEC_VPERMIL
224   UNSPEC_VPERMIL2
225   UNSPEC_VPERMIL2F128
226   UNSPEC_MASKLOAD
227   UNSPEC_MASKSTORE
228   UNSPEC_CAST
229   UNSPEC_VTESTP
230   UNSPEC_VCVTPH2PS
231   UNSPEC_VCVTPS2PH
232 ])
233
234 (define_c_enum "unspecv" [
235   UNSPECV_BLOCKAGE
236   UNSPECV_STACK_PROBE
237   UNSPECV_PROBE_STACK_RANGE
238   UNSPECV_EMMS
239   UNSPECV_LDMXCSR
240   UNSPECV_STMXCSR
241   UNSPECV_FEMMS
242   UNSPECV_CLFLUSH
243   UNSPECV_ALIGN
244   UNSPECV_MONITOR
245   UNSPECV_MWAIT
246   UNSPECV_CMPXCHG
247   UNSPECV_XCHG
248   UNSPECV_LOCK
249   UNSPECV_PROLOGUE_USE
250   UNSPECV_CLD
251   UNSPECV_NOPS
252   UNSPECV_VZEROALL
253   UNSPECV_VZEROUPPER
254   UNSPECV_RDTSC
255   UNSPECV_RDTSCP
256   UNSPECV_RDPMC
257   UNSPECV_LLWP_INTRINSIC
258   UNSPECV_SLWP_INTRINSIC
259   UNSPECV_LWPVAL_INTRINSIC
260   UNSPECV_LWPINS_INTRINSIC
261   UNSPECV_RDFSBASE
262   UNSPECV_RDGSBASE
263   UNSPECV_WRFSBASE
264   UNSPECV_WRGSBASE
265   UNSPECV_RDRAND
266   UNSPECV_SPLIT_STACK_RETURN
267 ])
268
269 ;; Constants to represent pcomtrue/pcomfalse variants
270 (define_constants
271   [(PCOM_FALSE                  0)
272    (PCOM_TRUE                   1)
273    (COM_FALSE_S                 2)
274    (COM_FALSE_P                 3)
275    (COM_TRUE_S                  4)
276    (COM_TRUE_P                  5)
277   ])
278
279 ;; Constants used in the XOP pperm instruction
280 (define_constants
281   [(PPERM_SRC                   0x00)   /* copy source */
282    (PPERM_INVERT                0x20)   /* invert source */
283    (PPERM_REVERSE               0x40)   /* bit reverse source */
284    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
285    (PPERM_ZERO                  0x80)   /* all 0's */
286    (PPERM_ONES                  0xa0)   /* all 1's */
287    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
288    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
289    (PPERM_SRC1                  0x00)   /* use first source byte */
290    (PPERM_SRC2                  0x10)   /* use second source byte */
291    ])
292
293 ;; Registers by name.
294 (define_constants
295   [(AX_REG                       0)
296    (DX_REG                       1)
297    (CX_REG                       2)
298    (BX_REG                       3)
299    (SI_REG                       4)
300    (DI_REG                       5)
301    (BP_REG                       6)
302    (SP_REG                       7)
303    (ST0_REG                      8)
304    (ST1_REG                      9)
305    (ST2_REG                     10)
306    (ST3_REG                     11)
307    (ST4_REG                     12)
308    (ST5_REG                     13)
309    (ST6_REG                     14)
310    (ST7_REG                     15)
311    (FLAGS_REG                   17)
312    (FPSR_REG                    18)
313    (FPCR_REG                    19)
314    (XMM0_REG                    21)
315    (XMM1_REG                    22)
316    (XMM2_REG                    23)
317    (XMM3_REG                    24)
318    (XMM4_REG                    25)
319    (XMM5_REG                    26)
320    (XMM6_REG                    27)
321    (XMM7_REG                    28)
322    (MM0_REG                     29)
323    (MM1_REG                     30)
324    (MM2_REG                     31)
325    (MM3_REG                     32)
326    (MM4_REG                     33)
327    (MM5_REG                     34)
328    (MM6_REG                     35)
329    (MM7_REG                     36)
330    (R8_REG                      37)
331    (R9_REG                      38)
332    (R10_REG                     39)
333    (R11_REG                     40)
334    (R12_REG                     41)
335    (R13_REG                     42)
336    (XMM8_REG                    45)
337    (XMM9_REG                    46)
338    (XMM10_REG                   47)
339    (XMM11_REG                   48)
340    (XMM12_REG                   49)
341    (XMM13_REG                   50)
342    (XMM14_REG                   51)
343    (XMM15_REG                   52)
344   ])
345
346 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
347 ;; from i386.c.
348
349 ;; In C guard expressions, put expressions which may be compile-time
350 ;; constants first.  This allows for better optimization.  For
351 ;; example, write "TARGET_64BIT && reload_completed", not
352 ;; "reload_completed && TARGET_64BIT".
353
354 \f
355 ;; Processor type.
356 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
357                     generic64,amdfam10,bdver1"
358   (const (symbol_ref "ix86_schedule")))
359
360 ;; A basic instruction type.  Refinements due to arguments to be
361 ;; provided in other attributes.
362 (define_attr "type"
363   "other,multi,
364    alu,alu1,negnot,imov,imovx,lea,
365    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
366    icmp,test,ibr,setcc,icmov,
367    push,pop,call,callv,leave,
368    str,bitmanip,
369    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
370    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
371    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
372    ssemuladd,sse4arg,lwp,
373    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
374   (const_string "other"))
375
376 ;; Main data type used by the insn
377 (define_attr "mode"
378   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
379   (const_string "unknown"))
380
381 ;; The CPU unit operations uses.
382 (define_attr "unit" "integer,i387,sse,mmx,unknown"
383   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
384            (const_string "i387")
385          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
387                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
388            (const_string "sse")
389          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
390            (const_string "mmx")
391          (eq_attr "type" "other")
392            (const_string "unknown")]
393          (const_string "integer")))
394
395 ;; The (bounding maximum) length of an instruction immediate.
396 (define_attr "length_immediate" ""
397   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
398                           bitmanip")
399            (const_int 0)
400          (eq_attr "unit" "i387,sse,mmx")
401            (const_int 0)
402          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
403                           imul,icmp,push,pop")
404            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
405          (eq_attr "type" "imov,test")
406            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
407          (eq_attr "type" "call")
408            (if_then_else (match_operand 0 "constant_call_address_operand" "")
409              (const_int 4)
410              (const_int 0))
411          (eq_attr "type" "callv")
412            (if_then_else (match_operand 1 "constant_call_address_operand" "")
413              (const_int 4)
414              (const_int 0))
415          ;; We don't know the size before shorten_branches.  Expect
416          ;; the instruction to fit for better scheduling.
417          (eq_attr "type" "ibr")
418            (const_int 1)
419          ]
420          (symbol_ref "/* Update immediate_length and other attributes! */
421                       gcc_unreachable (),1")))
422
423 ;; The (bounding maximum) length of an instruction address.
424 (define_attr "length_address" ""
425   (cond [(eq_attr "type" "str,other,multi,fxch")
426            (const_int 0)
427          (and (eq_attr "type" "call")
428               (match_operand 0 "constant_call_address_operand" ""))
429              (const_int 0)
430          (and (eq_attr "type" "callv")
431               (match_operand 1 "constant_call_address_operand" ""))
432              (const_int 0)
433          ]
434          (symbol_ref "ix86_attr_length_address_default (insn)")))
435
436 ;; Set when length prefix is used.
437 (define_attr "prefix_data16" ""
438   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439            (const_int 0)
440          (eq_attr "mode" "HI")
441            (const_int 1)
442          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
443            (const_int 1)
444         ]
445         (const_int 0)))
446
447 ;; Set when string REP prefix is used.
448 (define_attr "prefix_rep" ""
449   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
450            (const_int 0)
451          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
452            (const_int 1)
453         ]
454         (const_int 0)))
455
456 ;; Set when 0f opcode prefix is used.
457 (define_attr "prefix_0f" ""
458   (if_then_else
459     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
460          (eq_attr "unit" "sse,mmx"))
461     (const_int 1)
462     (const_int 0)))
463
464 ;; Set when REX opcode prefix is used.
465 (define_attr "prefix_rex" ""
466   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
467            (const_int 0)
468          (and (eq_attr "mode" "DI")
469               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
470                    (eq_attr "unit" "!mmx")))
471            (const_int 1)
472          (and (eq_attr "mode" "QI")
473               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
474                   (const_int 0)))
475            (const_int 1)
476          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
477              (const_int 0))
478            (const_int 1)
479          (and (eq_attr "type" "imovx")
480               (match_operand:QI 1 "ext_QIreg_operand" ""))
481            (const_int 1)
482         ]
483         (const_int 0)))
484
485 ;; There are also additional prefixes in 3DNOW, SSSE3.
486 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
487 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
488 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
489 (define_attr "prefix_extra" ""
490   (cond [(eq_attr "type" "ssemuladd,sse4arg")
491            (const_int 2)
492          (eq_attr "type" "sseiadd1,ssecvt1")
493            (const_int 1)
494         ]
495         (const_int 0)))
496
497 ;; Prefix used: original, VEX or maybe VEX.
498 (define_attr "prefix" "orig,vex,maybe_vex"
499   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
500     (const_string "vex")
501     (const_string "orig")))
502
503 ;; VEX W bit is used.
504 (define_attr "prefix_vex_w" "" (const_int 0))
505
506 ;; The length of VEX prefix
507 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
508 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
509 ;; still prefix_0f 1, with prefix_extra 1.
510 (define_attr "length_vex" ""
511   (if_then_else (and (eq_attr "prefix_0f" "1")
512                      (eq_attr "prefix_extra" "0"))
513     (if_then_else (eq_attr "prefix_vex_w" "1")
514       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
515       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
516     (if_then_else (eq_attr "prefix_vex_w" "1")
517       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
518       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
519
520 ;; Set when modrm byte is used.
521 (define_attr "modrm" ""
522   (cond [(eq_attr "type" "str,leave")
523            (const_int 0)
524          (eq_attr "unit" "i387")
525            (const_int 0)
526          (and (eq_attr "type" "incdec")
527               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
528                    (ior (match_operand:SI 1 "register_operand" "")
529                         (match_operand:HI 1 "register_operand" ""))))
530            (const_int 0)
531          (and (eq_attr "type" "push")
532               (not (match_operand 1 "memory_operand" "")))
533            (const_int 0)
534          (and (eq_attr "type" "pop")
535               (not (match_operand 0 "memory_operand" "")))
536            (const_int 0)
537          (and (eq_attr "type" "imov")
538               (and (not (eq_attr "mode" "DI"))
539                    (ior (and (match_operand 0 "register_operand" "")
540                              (match_operand 1 "immediate_operand" ""))
541                         (ior (and (match_operand 0 "ax_reg_operand" "")
542                                   (match_operand 1 "memory_displacement_only_operand" ""))
543                              (and (match_operand 0 "memory_displacement_only_operand" "")
544                                   (match_operand 1 "ax_reg_operand" ""))))))
545            (const_int 0)
546          (and (eq_attr "type" "call")
547               (match_operand 0 "constant_call_address_operand" ""))
548              (const_int 0)
549          (and (eq_attr "type" "callv")
550               (match_operand 1 "constant_call_address_operand" ""))
551              (const_int 0)
552          (and (eq_attr "type" "alu,alu1,icmp,test")
553               (match_operand 0 "ax_reg_operand" ""))
554              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
555          ]
556          (const_int 1)))
557
558 ;; The (bounding maximum) length of an instruction in bytes.
559 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
560 ;; Later we may want to split them and compute proper length as for
561 ;; other insns.
562 (define_attr "length" ""
563   (cond [(eq_attr "type" "other,multi,fistp,frndint")
564            (const_int 16)
565          (eq_attr "type" "fcmp")
566            (const_int 4)
567          (eq_attr "unit" "i387")
568            (plus (const_int 2)
569                  (plus (attr "prefix_data16")
570                        (attr "length_address")))
571          (ior (eq_attr "prefix" "vex")
572               (and (eq_attr "prefix" "maybe_vex")
573                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
574            (plus (attr "length_vex")
575                  (plus (attr "length_immediate")
576                        (plus (attr "modrm")
577                              (attr "length_address"))))]
578          (plus (plus (attr "modrm")
579                      (plus (attr "prefix_0f")
580                            (plus (attr "prefix_rex")
581                                  (plus (attr "prefix_extra")
582                                        (const_int 1)))))
583                (plus (attr "prefix_rep")
584                      (plus (attr "prefix_data16")
585                            (plus (attr "length_immediate")
586                                  (attr "length_address")))))))
587
588 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
589 ;; `store' if there is a simple memory reference therein, or `unknown'
590 ;; if the instruction is complex.
591
592 (define_attr "memory" "none,load,store,both,unknown"
593   (cond [(eq_attr "type" "other,multi,str,lwp")
594            (const_string "unknown")
595          (eq_attr "type" "lea,fcmov,fpspc")
596            (const_string "none")
597          (eq_attr "type" "fistp,leave")
598            (const_string "both")
599          (eq_attr "type" "frndint")
600            (const_string "load")
601          (eq_attr "type" "push")
602            (if_then_else (match_operand 1 "memory_operand" "")
603              (const_string "both")
604              (const_string "store"))
605          (eq_attr "type" "pop")
606            (if_then_else (match_operand 0 "memory_operand" "")
607              (const_string "both")
608              (const_string "load"))
609          (eq_attr "type" "setcc")
610            (if_then_else (match_operand 0 "memory_operand" "")
611              (const_string "store")
612              (const_string "none"))
613          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
614            (if_then_else (ior (match_operand 0 "memory_operand" "")
615                               (match_operand 1 "memory_operand" ""))
616              (const_string "load")
617              (const_string "none"))
618          (eq_attr "type" "ibr")
619            (if_then_else (match_operand 0 "memory_operand" "")
620              (const_string "load")
621              (const_string "none"))
622          (eq_attr "type" "call")
623            (if_then_else (match_operand 0 "constant_call_address_operand" "")
624              (const_string "none")
625              (const_string "load"))
626          (eq_attr "type" "callv")
627            (if_then_else (match_operand 1 "constant_call_address_operand" "")
628              (const_string "none")
629              (const_string "load"))
630          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
631               (match_operand 1 "memory_operand" ""))
632            (const_string "both")
633          (and (match_operand 0 "memory_operand" "")
634               (match_operand 1 "memory_operand" ""))
635            (const_string "both")
636          (match_operand 0 "memory_operand" "")
637            (const_string "store")
638          (match_operand 1 "memory_operand" "")
639            (const_string "load")
640          (and (eq_attr "type"
641                  "!alu1,negnot,ishift1,
642                    imov,imovx,icmp,test,bitmanip,
643                    fmov,fcmp,fsgn,
644                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
645                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
646               (match_operand 2 "memory_operand" ""))
647            (const_string "load")
648          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
649               (match_operand 3 "memory_operand" ""))
650            (const_string "load")
651         ]
652         (const_string "none")))
653
654 ;; Indicates if an instruction has both an immediate and a displacement.
655
656 (define_attr "imm_disp" "false,true,unknown"
657   (cond [(eq_attr "type" "other,multi")
658            (const_string "unknown")
659          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
660               (and (match_operand 0 "memory_displacement_operand" "")
661                    (match_operand 1 "immediate_operand" "")))
662            (const_string "true")
663          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
664               (and (match_operand 0 "memory_displacement_operand" "")
665                    (match_operand 2 "immediate_operand" "")))
666            (const_string "true")
667         ]
668         (const_string "false")))
669
670 ;; Indicates if an FP operation has an integer source.
671
672 (define_attr "fp_int_src" "false,true"
673   (const_string "false"))
674
675 ;; Defines rounding mode of an FP operation.
676
677 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
678   (const_string "any"))
679
680 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
681 (define_attr "use_carry" "0,1" (const_string "0"))
682
683 ;; Define attribute to indicate unaligned ssemov insns
684 (define_attr "movu" "0,1" (const_string "0"))
685
686 ;; Describe a user's asm statement.
687 (define_asm_attributes
688   [(set_attr "length" "128")
689    (set_attr "type" "multi")])
690
691 (define_code_iterator plusminus [plus minus])
692
693 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
694
695 ;; Base name for define_insn
696 (define_code_attr plusminus_insn
697   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
698    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
699
700 ;; Base name for insn mnemonic.
701 (define_code_attr plusminus_mnemonic
702   [(plus "add") (ss_plus "adds") (us_plus "addus")
703    (minus "sub") (ss_minus "subs") (us_minus "subus")])
704 (define_code_attr plusminus_carry_mnemonic
705   [(plus "adc") (minus "sbb")])
706
707 ;; Mark commutative operators as such in constraints.
708 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
709                         (minus "") (ss_minus "") (us_minus "")])
710
711 ;; Mapping of signed max and min
712 (define_code_iterator smaxmin [smax smin])
713
714 ;; Mapping of unsigned max and min
715 (define_code_iterator umaxmin [umax umin])
716
717 ;; Base name for integer and FP insn mnemonic
718 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
719                               (umax "maxu") (umin "minu")])
720 (define_code_attr maxmin_float [(smax "max") (smin "min")])
721
722 ;; Mapping of logic operators
723 (define_code_iterator any_logic [and ior xor])
724 (define_code_iterator any_or [ior xor])
725
726 ;; Base name for insn mnemonic.
727 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
728
729 ;; Mapping of shift-right operators
730 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
731
732 ;; Base name for define_insn
733 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
734
735 ;; Base name for insn mnemonic.
736 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
737
738 ;; Mapping of rotate operators
739 (define_code_iterator any_rotate [rotate rotatert])
740
741 ;; Base name for define_insn
742 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
743
744 ;; Base name for insn mnemonic.
745 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
746
747 ;; Mapping of abs neg operators
748 (define_code_iterator absneg [abs neg])
749
750 ;; Base name for x87 insn mnemonic.
751 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
752
753 ;; Used in signed and unsigned widening multiplications.
754 (define_code_iterator any_extend [sign_extend zero_extend])
755
756 ;; Various insn prefixes for signed and unsigned operations.
757 (define_code_attr u [(sign_extend "") (zero_extend "u")
758                      (div "") (udiv "u")])
759 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
760
761 ;; Used in signed and unsigned divisions.
762 (define_code_iterator any_div [div udiv])
763
764 ;; Instruction prefix for signed and unsigned operations.
765 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
766                              (div "i") (udiv "")])
767
768 ;; 64bit single word integer modes.
769 (define_mode_iterator SWI1248x [QI HI SI DI])
770
771 ;; 64bit single word integer modes without QImode and HImode.
772 (define_mode_iterator SWI48x [SI DI])
773
774 ;; Single word integer modes.
775 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
776
777 ;; Single word integer modes without SImode and DImode.
778 (define_mode_iterator SWI12 [QI HI])
779
780 ;; Single word integer modes without DImode.
781 (define_mode_iterator SWI124 [QI HI SI])
782
783 ;; Single word integer modes without QImode and DImode.
784 (define_mode_iterator SWI24 [HI SI])
785
786 ;; Single word integer modes without QImode.
787 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
788
789 ;; Single word integer modes without QImode and HImode.
790 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
791
792 ;; All math-dependant single and double word integer modes.
793 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
794                              (HI "TARGET_HIMODE_MATH")
795                              SI DI (TI "TARGET_64BIT")])
796
797 ;; Math-dependant single word integer modes.
798 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
799                             (HI "TARGET_HIMODE_MATH")
800                             SI (DI "TARGET_64BIT")])
801
802 ;; Math-dependant single word integer modes without DImode.
803 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
804                                (HI "TARGET_HIMODE_MATH")
805                                SI])
806
807 ;; Math-dependant single word integer modes without QImode.
808 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
809                                SI (DI "TARGET_64BIT")])
810
811 ;; Double word integer modes.
812 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
813                            (TI "TARGET_64BIT")])
814
815 ;; Double word integer modes as mode attribute.
816 (define_mode_attr DWI [(SI "DI") (DI "TI")])
817 (define_mode_attr dwi [(SI "di") (DI "ti")])
818
819 ;; Half mode for double word integer modes.
820 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
821                             (DI "TARGET_64BIT")])
822
823 ;; Instruction suffix for integer modes.
824 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
825
826 ;; Pointer size prefix for integer modes (Intel asm dialect)
827 (define_mode_attr iptrsize [(QI "BYTE")
828                             (HI "WORD")
829                             (SI "DWORD")
830                             (DI "QWORD")])
831
832 ;; Register class for integer modes.
833 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
834
835 ;; Immediate operand constraint for integer modes.
836 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
837
838 ;; General operand constraint for word modes.
839 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
840
841 ;; Immediate operand constraint for double integer modes.
842 (define_mode_attr di [(SI "iF") (DI "e")])
843
844 ;; Immediate operand constraint for shifts.
845 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
846
847 ;; General operand predicate for integer modes.
848 (define_mode_attr general_operand
849         [(QI "general_operand")
850          (HI "general_operand")
851          (SI "general_operand")
852          (DI "x86_64_general_operand")
853          (TI "x86_64_general_operand")])
854
855 ;; General sign/zero extend operand predicate for integer modes.
856 (define_mode_attr general_szext_operand
857         [(QI "general_operand")
858          (HI "general_operand")
859          (SI "general_operand")
860          (DI "x86_64_szext_general_operand")])
861
862 ;; Immediate operand predicate for integer modes.
863 (define_mode_attr immediate_operand
864         [(QI "immediate_operand")
865          (HI "immediate_operand")
866          (SI "immediate_operand")
867          (DI "x86_64_immediate_operand")])
868
869 ;; Nonmemory operand predicate for integer modes.
870 (define_mode_attr nonmemory_operand
871         [(QI "nonmemory_operand")
872          (HI "nonmemory_operand")
873          (SI "nonmemory_operand")
874          (DI "x86_64_nonmemory_operand")])
875
876 ;; Operand predicate for shifts.
877 (define_mode_attr shift_operand
878         [(QI "nonimmediate_operand")
879          (HI "nonimmediate_operand")
880          (SI "nonimmediate_operand")
881          (DI "shiftdi_operand")
882          (TI "register_operand")])
883
884 ;; Operand predicate for shift argument.
885 (define_mode_attr shift_immediate_operand
886         [(QI "const_1_to_31_operand")
887          (HI "const_1_to_31_operand")
888          (SI "const_1_to_31_operand")
889          (DI "const_1_to_63_operand")])
890
891 ;; Input operand predicate for arithmetic left shifts.
892 (define_mode_attr ashl_input_operand
893         [(QI "nonimmediate_operand")
894          (HI "nonimmediate_operand")
895          (SI "nonimmediate_operand")
896          (DI "ashldi_input_operand")
897          (TI "reg_or_pm1_operand")])
898
899 ;; SSE and x87 SFmode and DFmode floating point modes
900 (define_mode_iterator MODEF [SF DF])
901
902 ;; All x87 floating point modes
903 (define_mode_iterator X87MODEF [SF DF XF])
904
905 ;; All integer modes handled by x87 fisttp operator.
906 (define_mode_iterator X87MODEI [HI SI DI])
907
908 ;; All integer modes handled by integer x87 operators.
909 (define_mode_iterator X87MODEI12 [HI SI])
910
911 ;; All integer modes handled by SSE cvtts?2si* operators.
912 (define_mode_iterator SSEMODEI24 [SI DI])
913
914 ;; SSE asm suffix for floating point modes
915 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
916
917 ;; SSE vector mode corresponding to a scalar mode
918 (define_mode_attr ssevecmode
919   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
920
921 ;; Instruction suffix for REX 64bit operators.
922 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
923
924 ;; This mode iterator allows :P to be used for patterns that operate on
925 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
926 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
927 \f
928 ;; Scheduling descriptions
929
930 (include "pentium.md")
931 (include "ppro.md")
932 (include "k6.md")
933 (include "athlon.md")
934 (include "bdver1.md")
935 (include "geode.md")
936 (include "atom.md")
937
938 \f
939 ;; Operand and operator predicates and constraints
940
941 (include "predicates.md")
942 (include "constraints.md")
943
944 \f
945 ;; Compare and branch/compare and store instructions.
946
947 (define_expand "cbranch<mode>4"
948   [(set (reg:CC FLAGS_REG)
949         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
950                     (match_operand:SDWIM 2 "<general_operand>" "")))
951    (set (pc) (if_then_else
952                (match_operator 0 "ordered_comparison_operator"
953                 [(reg:CC FLAGS_REG) (const_int 0)])
954                (label_ref (match_operand 3 "" ""))
955                (pc)))]
956   ""
957 {
958   if (MEM_P (operands[1]) && MEM_P (operands[2]))
959     operands[1] = force_reg (<MODE>mode, operands[1]);
960   ix86_expand_branch (GET_CODE (operands[0]),
961                       operands[1], operands[2], operands[3]);
962   DONE;
963 })
964
965 (define_expand "cstore<mode>4"
966   [(set (reg:CC FLAGS_REG)
967         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
968                     (match_operand:SWIM 3 "<general_operand>" "")))
969    (set (match_operand:QI 0 "register_operand" "")
970         (match_operator 1 "ordered_comparison_operator"
971           [(reg:CC FLAGS_REG) (const_int 0)]))]
972   ""
973 {
974   if (MEM_P (operands[2]) && MEM_P (operands[3]))
975     operands[2] = force_reg (<MODE>mode, operands[2]);
976   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
977                      operands[2], operands[3]);
978   DONE;
979 })
980
981 (define_expand "cmp<mode>_1"
982   [(set (reg:CC FLAGS_REG)
983         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
984                     (match_operand:SWI48 1 "<general_operand>" "")))])
985
986 (define_insn "*cmp<mode>_ccno_1"
987   [(set (reg FLAGS_REG)
988         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
989                  (match_operand:SWI 1 "const0_operand" "")))]
990   "ix86_match_ccmode (insn, CCNOmode)"
991   "@
992    test{<imodesuffix>}\t%0, %0
993    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
994   [(set_attr "type" "test,icmp")
995    (set_attr "length_immediate" "0,1")
996    (set_attr "mode" "<MODE>")])
997
998 (define_insn "*cmp<mode>_1"
999   [(set (reg FLAGS_REG)
1000         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1001                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1002   "ix86_match_ccmode (insn, CCmode)"
1003   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1004   [(set_attr "type" "icmp")
1005    (set_attr "mode" "<MODE>")])
1006
1007 (define_insn "*cmp<mode>_minus_1"
1008   [(set (reg FLAGS_REG)
1009         (compare
1010           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1011                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1012           (const_int 0)))]
1013   "ix86_match_ccmode (insn, CCGOCmode)"
1014   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1015   [(set_attr "type" "icmp")
1016    (set_attr "mode" "<MODE>")])
1017
1018 (define_insn "*cmpqi_ext_1"
1019   [(set (reg FLAGS_REG)
1020         (compare
1021           (match_operand:QI 0 "general_operand" "Qm")
1022           (subreg:QI
1023             (zero_extract:SI
1024               (match_operand 1 "ext_register_operand" "Q")
1025               (const_int 8)
1026               (const_int 8)) 0)))]
1027   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1028   "cmp{b}\t{%h1, %0|%0, %h1}"
1029   [(set_attr "type" "icmp")
1030    (set_attr "mode" "QI")])
1031
1032 (define_insn "*cmpqi_ext_1_rex64"
1033   [(set (reg FLAGS_REG)
1034         (compare
1035           (match_operand:QI 0 "register_operand" "Q")
1036           (subreg:QI
1037             (zero_extract:SI
1038               (match_operand 1 "ext_register_operand" "Q")
1039               (const_int 8)
1040               (const_int 8)) 0)))]
1041   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1042   "cmp{b}\t{%h1, %0|%0, %h1}"
1043   [(set_attr "type" "icmp")
1044    (set_attr "mode" "QI")])
1045
1046 (define_insn "*cmpqi_ext_2"
1047   [(set (reg FLAGS_REG)
1048         (compare
1049           (subreg:QI
1050             (zero_extract:SI
1051               (match_operand 0 "ext_register_operand" "Q")
1052               (const_int 8)
1053               (const_int 8)) 0)
1054           (match_operand:QI 1 "const0_operand" "")))]
1055   "ix86_match_ccmode (insn, CCNOmode)"
1056   "test{b}\t%h0, %h0"
1057   [(set_attr "type" "test")
1058    (set_attr "length_immediate" "0")
1059    (set_attr "mode" "QI")])
1060
1061 (define_expand "cmpqi_ext_3"
1062   [(set (reg:CC FLAGS_REG)
1063         (compare:CC
1064           (subreg:QI
1065             (zero_extract:SI
1066               (match_operand 0 "ext_register_operand" "")
1067               (const_int 8)
1068               (const_int 8)) 0)
1069           (match_operand:QI 1 "immediate_operand" "")))])
1070
1071 (define_insn "*cmpqi_ext_3_insn"
1072   [(set (reg FLAGS_REG)
1073         (compare
1074           (subreg:QI
1075             (zero_extract:SI
1076               (match_operand 0 "ext_register_operand" "Q")
1077               (const_int 8)
1078               (const_int 8)) 0)
1079           (match_operand:QI 1 "general_operand" "Qmn")))]
1080   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1081   "cmp{b}\t{%1, %h0|%h0, %1}"
1082   [(set_attr "type" "icmp")
1083    (set_attr "modrm" "1")
1084    (set_attr "mode" "QI")])
1085
1086 (define_insn "*cmpqi_ext_3_insn_rex64"
1087   [(set (reg FLAGS_REG)
1088         (compare
1089           (subreg:QI
1090             (zero_extract:SI
1091               (match_operand 0 "ext_register_operand" "Q")
1092               (const_int 8)
1093               (const_int 8)) 0)
1094           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1095   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1096   "cmp{b}\t{%1, %h0|%h0, %1}"
1097   [(set_attr "type" "icmp")
1098    (set_attr "modrm" "1")
1099    (set_attr "mode" "QI")])
1100
1101 (define_insn "*cmpqi_ext_4"
1102   [(set (reg FLAGS_REG)
1103         (compare
1104           (subreg:QI
1105             (zero_extract:SI
1106               (match_operand 0 "ext_register_operand" "Q")
1107               (const_int 8)
1108               (const_int 8)) 0)
1109           (subreg:QI
1110             (zero_extract:SI
1111               (match_operand 1 "ext_register_operand" "Q")
1112               (const_int 8)
1113               (const_int 8)) 0)))]
1114   "ix86_match_ccmode (insn, CCmode)"
1115   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1116   [(set_attr "type" "icmp")
1117    (set_attr "mode" "QI")])
1118
1119 ;; These implement float point compares.
1120 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1121 ;; which would allow mix and match FP modes on the compares.  Which is what
1122 ;; the old patterns did, but with many more of them.
1123
1124 (define_expand "cbranchxf4"
1125   [(set (reg:CC FLAGS_REG)
1126         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1127                     (match_operand:XF 2 "nonmemory_operand" "")))
1128    (set (pc) (if_then_else
1129               (match_operator 0 "ix86_fp_comparison_operator"
1130                [(reg:CC FLAGS_REG)
1131                 (const_int 0)])
1132               (label_ref (match_operand 3 "" ""))
1133               (pc)))]
1134   "TARGET_80387"
1135 {
1136   ix86_expand_branch (GET_CODE (operands[0]),
1137                       operands[1], operands[2], operands[3]);
1138   DONE;
1139 })
1140
1141 (define_expand "cstorexf4"
1142   [(set (reg:CC FLAGS_REG)
1143         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1144                     (match_operand:XF 3 "nonmemory_operand" "")))
1145    (set (match_operand:QI 0 "register_operand" "")
1146               (match_operator 1 "ix86_fp_comparison_operator"
1147                [(reg:CC FLAGS_REG)
1148                 (const_int 0)]))]
1149   "TARGET_80387"
1150 {
1151   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1152                      operands[2], operands[3]);
1153   DONE;
1154 })
1155
1156 (define_expand "cbranch<mode>4"
1157   [(set (reg:CC FLAGS_REG)
1158         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1159                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1160    (set (pc) (if_then_else
1161               (match_operator 0 "ix86_fp_comparison_operator"
1162                [(reg:CC FLAGS_REG)
1163                 (const_int 0)])
1164               (label_ref (match_operand 3 "" ""))
1165               (pc)))]
1166   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1167 {
1168   ix86_expand_branch (GET_CODE (operands[0]),
1169                       operands[1], operands[2], operands[3]);
1170   DONE;
1171 })
1172
1173 (define_expand "cstore<mode>4"
1174   [(set (reg:CC FLAGS_REG)
1175         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1176                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1177    (set (match_operand:QI 0 "register_operand" "")
1178               (match_operator 1 "ix86_fp_comparison_operator"
1179                [(reg:CC FLAGS_REG)
1180                 (const_int 0)]))]
1181   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1182 {
1183   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184                      operands[2], operands[3]);
1185   DONE;
1186 })
1187
1188 (define_expand "cbranchcc4"
1189   [(set (pc) (if_then_else
1190               (match_operator 0 "comparison_operator"
1191                [(match_operand 1 "flags_reg_operand" "")
1192                 (match_operand 2 "const0_operand" "")])
1193               (label_ref (match_operand 3 "" ""))
1194               (pc)))]
1195   ""
1196 {
1197   ix86_expand_branch (GET_CODE (operands[0]),
1198                       operands[1], operands[2], operands[3]);
1199   DONE;
1200 })
1201
1202 (define_expand "cstorecc4"
1203   [(set (match_operand:QI 0 "register_operand" "")
1204               (match_operator 1 "comparison_operator"
1205                [(match_operand 2 "flags_reg_operand" "")
1206                 (match_operand 3 "const0_operand" "")]))]
1207   ""
1208 {
1209   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1210                      operands[2], operands[3]);
1211   DONE;
1212 })
1213
1214
1215 ;; FP compares, step 1:
1216 ;; Set the FP condition codes.
1217 ;;
1218 ;; CCFPmode     compare with exceptions
1219 ;; CCFPUmode    compare with no exceptions
1220
1221 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1222 ;; used to manage the reg stack popping would not be preserved.
1223
1224 (define_insn "*cmpfp_0"
1225   [(set (match_operand:HI 0 "register_operand" "=a")
1226         (unspec:HI
1227           [(compare:CCFP
1228              (match_operand 1 "register_operand" "f")
1229              (match_operand 2 "const0_operand" ""))]
1230         UNSPEC_FNSTSW))]
1231   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1232    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233   "* return output_fp_compare (insn, operands, 0, 0);"
1234   [(set_attr "type" "multi")
1235    (set_attr "unit" "i387")
1236    (set (attr "mode")
1237      (cond [(match_operand:SF 1 "" "")
1238               (const_string "SF")
1239             (match_operand:DF 1 "" "")
1240               (const_string "DF")
1241            ]
1242            (const_string "XF")))])
1243
1244 (define_insn_and_split "*cmpfp_0_cc"
1245   [(set (reg:CCFP FLAGS_REG)
1246         (compare:CCFP
1247           (match_operand 1 "register_operand" "f")
1248           (match_operand 2 "const0_operand" "")))
1249    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1250   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1251    && TARGET_SAHF && !TARGET_CMOVE
1252    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1253   "#"
1254   "&& reload_completed"
1255   [(set (match_dup 0)
1256         (unspec:HI
1257           [(compare:CCFP (match_dup 1)(match_dup 2))]
1258         UNSPEC_FNSTSW))
1259    (set (reg:CC FLAGS_REG)
1260         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1261   ""
1262   [(set_attr "type" "multi")
1263    (set_attr "unit" "i387")
1264    (set (attr "mode")
1265      (cond [(match_operand:SF 1 "" "")
1266               (const_string "SF")
1267             (match_operand:DF 1 "" "")
1268               (const_string "DF")
1269            ]
1270            (const_string "XF")))])
1271
1272 (define_insn "*cmpfp_xf"
1273   [(set (match_operand:HI 0 "register_operand" "=a")
1274         (unspec:HI
1275           [(compare:CCFP
1276              (match_operand:XF 1 "register_operand" "f")
1277              (match_operand:XF 2 "register_operand" "f"))]
1278           UNSPEC_FNSTSW))]
1279   "TARGET_80387"
1280   "* return output_fp_compare (insn, operands, 0, 0);"
1281   [(set_attr "type" "multi")
1282    (set_attr "unit" "i387")
1283    (set_attr "mode" "XF")])
1284
1285 (define_insn_and_split "*cmpfp_xf_cc"
1286   [(set (reg:CCFP FLAGS_REG)
1287         (compare:CCFP
1288           (match_operand:XF 1 "register_operand" "f")
1289           (match_operand:XF 2 "register_operand" "f")))
1290    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1291   "TARGET_80387
1292    && TARGET_SAHF && !TARGET_CMOVE"
1293   "#"
1294   "&& reload_completed"
1295   [(set (match_dup 0)
1296         (unspec:HI
1297           [(compare:CCFP (match_dup 1)(match_dup 2))]
1298         UNSPEC_FNSTSW))
1299    (set (reg:CC FLAGS_REG)
1300         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1301   ""
1302   [(set_attr "type" "multi")
1303    (set_attr "unit" "i387")
1304    (set_attr "mode" "XF")])
1305
1306 (define_insn "*cmpfp_<mode>"
1307   [(set (match_operand:HI 0 "register_operand" "=a")
1308         (unspec:HI
1309           [(compare:CCFP
1310              (match_operand:MODEF 1 "register_operand" "f")
1311              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1312           UNSPEC_FNSTSW))]
1313   "TARGET_80387"
1314   "* return output_fp_compare (insn, operands, 0, 0);"
1315   [(set_attr "type" "multi")
1316    (set_attr "unit" "i387")
1317    (set_attr "mode" "<MODE>")])
1318
1319 (define_insn_and_split "*cmpfp_<mode>_cc"
1320   [(set (reg:CCFP FLAGS_REG)
1321         (compare:CCFP
1322           (match_operand:MODEF 1 "register_operand" "f")
1323           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1324    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1325   "TARGET_80387
1326    && TARGET_SAHF && !TARGET_CMOVE"
1327   "#"
1328   "&& reload_completed"
1329   [(set (match_dup 0)
1330         (unspec:HI
1331           [(compare:CCFP (match_dup 1)(match_dup 2))]
1332         UNSPEC_FNSTSW))
1333    (set (reg:CC FLAGS_REG)
1334         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1335   ""
1336   [(set_attr "type" "multi")
1337    (set_attr "unit" "i387")
1338    (set_attr "mode" "<MODE>")])
1339
1340 (define_insn "*cmpfp_u"
1341   [(set (match_operand:HI 0 "register_operand" "=a")
1342         (unspec:HI
1343           [(compare:CCFPU
1344              (match_operand 1 "register_operand" "f")
1345              (match_operand 2 "register_operand" "f"))]
1346           UNSPEC_FNSTSW))]
1347   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1348    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1349   "* return output_fp_compare (insn, operands, 0, 1);"
1350   [(set_attr "type" "multi")
1351    (set_attr "unit" "i387")
1352    (set (attr "mode")
1353      (cond [(match_operand:SF 1 "" "")
1354               (const_string "SF")
1355             (match_operand:DF 1 "" "")
1356               (const_string "DF")
1357            ]
1358            (const_string "XF")))])
1359
1360 (define_insn_and_split "*cmpfp_u_cc"
1361   [(set (reg:CCFPU FLAGS_REG)
1362         (compare:CCFPU
1363           (match_operand 1 "register_operand" "f")
1364           (match_operand 2 "register_operand" "f")))
1365    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1366   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1367    && TARGET_SAHF && !TARGET_CMOVE
1368    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1369   "#"
1370   "&& reload_completed"
1371   [(set (match_dup 0)
1372         (unspec:HI
1373           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1374         UNSPEC_FNSTSW))
1375    (set (reg:CC FLAGS_REG)
1376         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1377   ""
1378   [(set_attr "type" "multi")
1379    (set_attr "unit" "i387")
1380    (set (attr "mode")
1381      (cond [(match_operand:SF 1 "" "")
1382               (const_string "SF")
1383             (match_operand:DF 1 "" "")
1384               (const_string "DF")
1385            ]
1386            (const_string "XF")))])
1387
1388 (define_insn "*cmpfp_<mode>"
1389   [(set (match_operand:HI 0 "register_operand" "=a")
1390         (unspec:HI
1391           [(compare:CCFP
1392              (match_operand 1 "register_operand" "f")
1393              (match_operator 3 "float_operator"
1394                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1395           UNSPEC_FNSTSW))]
1396   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1397    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1398    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1399   "* return output_fp_compare (insn, operands, 0, 0);"
1400   [(set_attr "type" "multi")
1401    (set_attr "unit" "i387")
1402    (set_attr "fp_int_src" "true")
1403    (set_attr "mode" "<MODE>")])
1404
1405 (define_insn_and_split "*cmpfp_<mode>_cc"
1406   [(set (reg:CCFP FLAGS_REG)
1407         (compare:CCFP
1408           (match_operand 1 "register_operand" "f")
1409           (match_operator 3 "float_operator"
1410             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1411    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1412   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1413    && TARGET_SAHF && !TARGET_CMOVE
1414    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1415    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1416   "#"
1417   "&& reload_completed"
1418   [(set (match_dup 0)
1419         (unspec:HI
1420           [(compare:CCFP
1421              (match_dup 1)
1422              (match_op_dup 3 [(match_dup 2)]))]
1423         UNSPEC_FNSTSW))
1424    (set (reg:CC FLAGS_REG)
1425         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1426   ""
1427   [(set_attr "type" "multi")
1428    (set_attr "unit" "i387")
1429    (set_attr "fp_int_src" "true")
1430    (set_attr "mode" "<MODE>")])
1431
1432 ;; FP compares, step 2
1433 ;; Move the fpsw to ax.
1434
1435 (define_insn "x86_fnstsw_1"
1436   [(set (match_operand:HI 0 "register_operand" "=a")
1437         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1438   "TARGET_80387"
1439   "fnstsw\t%0"
1440   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1441    (set_attr "mode" "SI")
1442    (set_attr "unit" "i387")])
1443
1444 ;; FP compares, step 3
1445 ;; Get ax into flags, general case.
1446
1447 (define_insn "x86_sahf_1"
1448   [(set (reg:CC FLAGS_REG)
1449         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1450                    UNSPEC_SAHF))]
1451   "TARGET_SAHF"
1452 {
1453 #ifndef HAVE_AS_IX86_SAHF
1454   if (TARGET_64BIT)
1455     return ASM_BYTE "0x9e";
1456   else
1457 #endif
1458   return "sahf";
1459 }
1460   [(set_attr "length" "1")
1461    (set_attr "athlon_decode" "vector")
1462    (set_attr "amdfam10_decode" "direct")
1463    (set_attr "bdver1_decode" "direct")
1464    (set_attr "mode" "SI")])
1465
1466 ;; Pentium Pro can do steps 1 through 3 in one go.
1467 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1468 (define_insn "*cmpfp_i_mixed"
1469   [(set (reg:CCFP FLAGS_REG)
1470         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1471                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1472   "TARGET_MIX_SSE_I387
1473    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1474    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1475   "* return output_fp_compare (insn, operands, 1, 0);"
1476   [(set_attr "type" "fcmp,ssecomi")
1477    (set_attr "prefix" "orig,maybe_vex")
1478    (set (attr "mode")
1479      (if_then_else (match_operand:SF 1 "" "")
1480         (const_string "SF")
1481         (const_string "DF")))
1482    (set (attr "prefix_rep")
1483         (if_then_else (eq_attr "type" "ssecomi")
1484                       (const_string "0")
1485                       (const_string "*")))
1486    (set (attr "prefix_data16")
1487         (cond [(eq_attr "type" "fcmp")
1488                  (const_string "*")
1489                (eq_attr "mode" "DF")
1490                  (const_string "1")
1491               ]
1492               (const_string "0")))
1493    (set_attr "athlon_decode" "vector")
1494    (set_attr "amdfam10_decode" "direct")
1495    (set_attr "bdver1_decode" "double")])
1496
1497 (define_insn "*cmpfp_i_sse"
1498   [(set (reg:CCFP FLAGS_REG)
1499         (compare:CCFP (match_operand 0 "register_operand" "x")
1500                       (match_operand 1 "nonimmediate_operand" "xm")))]
1501   "TARGET_SSE_MATH
1502    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1503    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1504   "* return output_fp_compare (insn, operands, 1, 0);"
1505   [(set_attr "type" "ssecomi")
1506    (set_attr "prefix" "maybe_vex")
1507    (set (attr "mode")
1508      (if_then_else (match_operand:SF 1 "" "")
1509         (const_string "SF")
1510         (const_string "DF")))
1511    (set_attr "prefix_rep" "0")
1512    (set (attr "prefix_data16")
1513         (if_then_else (eq_attr "mode" "DF")
1514                       (const_string "1")
1515                       (const_string "0")))
1516    (set_attr "athlon_decode" "vector")
1517    (set_attr "amdfam10_decode" "direct")
1518    (set_attr "bdver1_decode" "double")])
1519
1520 (define_insn "*cmpfp_i_i387"
1521   [(set (reg:CCFP FLAGS_REG)
1522         (compare:CCFP (match_operand 0 "register_operand" "f")
1523                       (match_operand 1 "register_operand" "f")))]
1524   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1525    && TARGET_CMOVE
1526    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1527    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1528   "* return output_fp_compare (insn, operands, 1, 0);"
1529   [(set_attr "type" "fcmp")
1530    (set (attr "mode")
1531      (cond [(match_operand:SF 1 "" "")
1532               (const_string "SF")
1533             (match_operand:DF 1 "" "")
1534               (const_string "DF")
1535            ]
1536            (const_string "XF")))
1537    (set_attr "athlon_decode" "vector")
1538    (set_attr "amdfam10_decode" "direct")
1539    (set_attr "bdver1_decode" "double")])
1540
1541 (define_insn "*cmpfp_iu_mixed"
1542   [(set (reg:CCFPU FLAGS_REG)
1543         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1544                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1545   "TARGET_MIX_SSE_I387
1546    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1547    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548   "* return output_fp_compare (insn, operands, 1, 1);"
1549   [(set_attr "type" "fcmp,ssecomi")
1550    (set_attr "prefix" "orig,maybe_vex")
1551    (set (attr "mode")
1552      (if_then_else (match_operand:SF 1 "" "")
1553         (const_string "SF")
1554         (const_string "DF")))
1555    (set (attr "prefix_rep")
1556         (if_then_else (eq_attr "type" "ssecomi")
1557                       (const_string "0")
1558                       (const_string "*")))
1559    (set (attr "prefix_data16")
1560         (cond [(eq_attr "type" "fcmp")
1561                  (const_string "*")
1562                (eq_attr "mode" "DF")
1563                  (const_string "1")
1564               ]
1565               (const_string "0")))
1566    (set_attr "athlon_decode" "vector")
1567    (set_attr "amdfam10_decode" "direct")
1568    (set_attr "bdver1_decode" "double")])
1569
1570 (define_insn "*cmpfp_iu_sse"
1571   [(set (reg:CCFPU FLAGS_REG)
1572         (compare:CCFPU (match_operand 0 "register_operand" "x")
1573                        (match_operand 1 "nonimmediate_operand" "xm")))]
1574   "TARGET_SSE_MATH
1575    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1576    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1577   "* return output_fp_compare (insn, operands, 1, 1);"
1578   [(set_attr "type" "ssecomi")
1579    (set_attr "prefix" "maybe_vex")
1580    (set (attr "mode")
1581      (if_then_else (match_operand:SF 1 "" "")
1582         (const_string "SF")
1583         (const_string "DF")))
1584    (set_attr "prefix_rep" "0")
1585    (set (attr "prefix_data16")
1586         (if_then_else (eq_attr "mode" "DF")
1587                       (const_string "1")
1588                       (const_string "0")))
1589    (set_attr "athlon_decode" "vector")
1590    (set_attr "amdfam10_decode" "direct")
1591    (set_attr "bdver1_decode" "double")])
1592
1593 (define_insn "*cmpfp_iu_387"
1594   [(set (reg:CCFPU FLAGS_REG)
1595         (compare:CCFPU (match_operand 0 "register_operand" "f")
1596                        (match_operand 1 "register_operand" "f")))]
1597   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1598    && TARGET_CMOVE
1599    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1600    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1601   "* return output_fp_compare (insn, operands, 1, 1);"
1602   [(set_attr "type" "fcmp")
1603    (set (attr "mode")
1604      (cond [(match_operand:SF 1 "" "")
1605               (const_string "SF")
1606             (match_operand:DF 1 "" "")
1607               (const_string "DF")
1608            ]
1609            (const_string "XF")))
1610    (set_attr "athlon_decode" "vector")
1611    (set_attr "amdfam10_decode" "direct")
1612    (set_attr "bdver1_decode" "direct")])
1613 \f
1614 ;; Push/pop instructions.
1615
1616 (define_insn "*push<mode>2"
1617   [(set (match_operand:DWI 0 "push_operand" "=<")
1618         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1619   ""
1620   "#")
1621
1622 (define_split
1623   [(set (match_operand:TI 0 "push_operand" "")
1624         (match_operand:TI 1 "general_operand" ""))]
1625   "TARGET_64BIT && reload_completed
1626    && !SSE_REG_P (operands[1])"
1627   [(const_int 0)]
1628   "ix86_split_long_move (operands); DONE;")
1629
1630 (define_insn "*pushdi2_rex64"
1631   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1632         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1633   "TARGET_64BIT"
1634   "@
1635    push{q}\t%1
1636    #"
1637   [(set_attr "type" "push,multi")
1638    (set_attr "mode" "DI")])
1639
1640 ;; Convert impossible pushes of immediate to existing instructions.
1641 ;; First try to get scratch register and go through it.  In case this
1642 ;; fails, push sign extended lower part first and then overwrite
1643 ;; upper part by 32bit move.
1644 (define_peephole2
1645   [(match_scratch:DI 2 "r")
1646    (set (match_operand:DI 0 "push_operand" "")
1647         (match_operand:DI 1 "immediate_operand" ""))]
1648   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1649    && !x86_64_immediate_operand (operands[1], DImode)"
1650   [(set (match_dup 2) (match_dup 1))
1651    (set (match_dup 0) (match_dup 2))])
1652
1653 ;; We need to define this as both peepholer and splitter for case
1654 ;; peephole2 pass is not run.
1655 ;; "&& 1" is needed to keep it from matching the previous pattern.
1656 (define_peephole2
1657   [(set (match_operand:DI 0 "push_operand" "")
1658         (match_operand:DI 1 "immediate_operand" ""))]
1659   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1660    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1661   [(set (match_dup 0) (match_dup 1))
1662    (set (match_dup 2) (match_dup 3))]
1663 {
1664   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1665
1666   operands[1] = gen_lowpart (DImode, operands[2]);
1667   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1668                                                    GEN_INT (4)));
1669 })
1670
1671 (define_split
1672   [(set (match_operand:DI 0 "push_operand" "")
1673         (match_operand:DI 1 "immediate_operand" ""))]
1674   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1675                     ? epilogue_completed : reload_completed)
1676    && !symbolic_operand (operands[1], DImode)
1677    && !x86_64_immediate_operand (operands[1], DImode)"
1678   [(set (match_dup 0) (match_dup 1))
1679    (set (match_dup 2) (match_dup 3))]
1680 {
1681   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1682
1683   operands[1] = gen_lowpart (DImode, operands[2]);
1684   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1685                                                    GEN_INT (4)));
1686 })
1687
1688 (define_split
1689   [(set (match_operand:DI 0 "push_operand" "")
1690         (match_operand:DI 1 "general_operand" ""))]
1691   "!TARGET_64BIT && reload_completed
1692    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1693   [(const_int 0)]
1694   "ix86_split_long_move (operands); DONE;")
1695
1696 (define_insn "*pushsi2"
1697   [(set (match_operand:SI 0 "push_operand" "=<")
1698         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1699   "!TARGET_64BIT"
1700   "push{l}\t%1"
1701   [(set_attr "type" "push")
1702    (set_attr "mode" "SI")])
1703
1704 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1705 ;; "push a byte/word".  But actually we use pushl, which has the effect
1706 ;; of rounding the amount pushed up to a word.
1707
1708 ;; For TARGET_64BIT we always round up to 8 bytes.
1709 (define_insn "*push<mode>2_rex64"
1710   [(set (match_operand:SWI124 0 "push_operand" "=X")
1711         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1712   "TARGET_64BIT"
1713   "push{q}\t%q1"
1714   [(set_attr "type" "push")
1715    (set_attr "mode" "DI")])
1716
1717 (define_insn "*push<mode>2"
1718   [(set (match_operand:SWI12 0 "push_operand" "=X")
1719         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1720   "!TARGET_64BIT"
1721   "push{l}\t%k1"
1722   [(set_attr "type" "push")
1723    (set_attr "mode" "SI")])
1724
1725 (define_insn "*push<mode>2_prologue"
1726   [(set (match_operand:P 0 "push_operand" "=<")
1727         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1728    (clobber (mem:BLK (scratch)))]
1729   ""
1730   "push{<imodesuffix>}\t%1"
1731   [(set_attr "type" "push")
1732    (set_attr "mode" "<MODE>")])
1733
1734 (define_insn "*pop<mode>1"
1735   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1736         (match_operand:P 1 "pop_operand" ">"))]
1737   ""
1738   "pop{<imodesuffix>}\t%0"
1739   [(set_attr "type" "pop")
1740    (set_attr "mode" "<MODE>")])
1741
1742 (define_insn "*pop<mode>1_epilogue"
1743   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1744         (match_operand:P 1 "pop_operand" ">"))
1745    (clobber (mem:BLK (scratch)))]
1746   ""
1747   "pop{<imodesuffix>}\t%0"
1748   [(set_attr "type" "pop")
1749    (set_attr "mode" "<MODE>")])
1750 \f
1751 ;; Move instructions.
1752
1753 (define_expand "movoi"
1754   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1755         (match_operand:OI 1 "general_operand" ""))]
1756   "TARGET_AVX"
1757   "ix86_expand_move (OImode, operands); DONE;")
1758
1759 (define_expand "movti"
1760   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1761         (match_operand:TI 1 "nonimmediate_operand" ""))]
1762   "TARGET_64BIT || TARGET_SSE"
1763 {
1764   if (TARGET_64BIT)
1765     ix86_expand_move (TImode, operands);
1766   else if (push_operand (operands[0], TImode))
1767     ix86_expand_push (TImode, operands[1]);
1768   else
1769     ix86_expand_vector_move (TImode, operands);
1770   DONE;
1771 })
1772
1773 ;; This expands to what emit_move_complex would generate if we didn't
1774 ;; have a movti pattern.  Having this avoids problems with reload on
1775 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1776 ;; to have around all the time.
1777 (define_expand "movcdi"
1778   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1779         (match_operand:CDI 1 "general_operand" ""))]
1780   ""
1781 {
1782   if (push_operand (operands[0], CDImode))
1783     emit_move_complex_push (CDImode, operands[0], operands[1]);
1784   else
1785     emit_move_complex_parts (operands[0], operands[1]);
1786   DONE;
1787 })
1788
1789 (define_expand "mov<mode>"
1790   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1791         (match_operand:SWI1248x 1 "general_operand" ""))]
1792   ""
1793   "ix86_expand_move (<MODE>mode, operands); DONE;")
1794
1795 (define_insn "*mov<mode>_xor"
1796   [(set (match_operand:SWI48 0 "register_operand" "=r")
1797         (match_operand:SWI48 1 "const0_operand" ""))
1798    (clobber (reg:CC FLAGS_REG))]
1799   "reload_completed"
1800   "xor{l}\t%k0, %k0"
1801   [(set_attr "type" "alu1")
1802    (set_attr "mode" "SI")
1803    (set_attr "length_immediate" "0")])
1804
1805 (define_insn "*mov<mode>_or"
1806   [(set (match_operand:SWI48 0 "register_operand" "=r")
1807         (match_operand:SWI48 1 "const_int_operand" ""))
1808    (clobber (reg:CC FLAGS_REG))]
1809   "reload_completed
1810    && operands[1] == constm1_rtx"
1811   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1812   [(set_attr "type" "alu1")
1813    (set_attr "mode" "<MODE>")
1814    (set_attr "length_immediate" "1")])
1815
1816 (define_insn "*movoi_internal_avx"
1817   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1818         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1819   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1820 {
1821   switch (which_alternative)
1822     {
1823     case 0:
1824       return "vxorps\t%0, %0, %0";
1825     case 1:
1826     case 2:
1827       if (misaligned_operand (operands[0], OImode)
1828           || misaligned_operand (operands[1], OImode))
1829         return "vmovdqu\t{%1, %0|%0, %1}";
1830       else
1831         return "vmovdqa\t{%1, %0|%0, %1}";
1832     default:
1833       gcc_unreachable ();
1834     }
1835 }
1836   [(set_attr "type" "sselog1,ssemov,ssemov")
1837    (set_attr "prefix" "vex")
1838    (set_attr "mode" "OI")])
1839
1840 (define_insn "*movti_internal_rex64"
1841   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1842         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1843   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1844 {
1845   switch (which_alternative)
1846     {
1847     case 0:
1848     case 1:
1849       return "#";
1850     case 2:
1851       if (get_attr_mode (insn) == MODE_V4SF)
1852         return "%vxorps\t%0, %d0";
1853       else
1854         return "%vpxor\t%0, %d0";
1855     case 3:
1856     case 4:
1857       /* TDmode values are passed as TImode on the stack.  Moving them
1858          to stack may result in unaligned memory access.  */
1859       if (misaligned_operand (operands[0], TImode)
1860           || misaligned_operand (operands[1], TImode))
1861         {
1862           if (get_attr_mode (insn) == MODE_V4SF)
1863             return "%vmovups\t{%1, %0|%0, %1}";
1864          else
1865            return "%vmovdqu\t{%1, %0|%0, %1}";
1866         }
1867       else
1868         {
1869           if (get_attr_mode (insn) == MODE_V4SF)
1870             return "%vmovaps\t{%1, %0|%0, %1}";
1871          else
1872            return "%vmovdqa\t{%1, %0|%0, %1}";
1873         }
1874     default:
1875       gcc_unreachable ();
1876     }
1877 }
1878   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1879    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1880    (set (attr "mode")
1881         (cond [(eq_attr "alternative" "2,3")
1882                  (if_then_else
1883                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1884                        (const_int 0))
1885                    (const_string "V4SF")
1886                    (const_string "TI"))
1887                (eq_attr "alternative" "4")
1888                  (if_then_else
1889                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1890                             (const_int 0))
1891                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1892                             (const_int 0)))
1893                    (const_string "V4SF")
1894                    (const_string "TI"))]
1895                (const_string "DI")))])
1896
1897 (define_split
1898   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1899         (match_operand:TI 1 "general_operand" ""))]
1900   "reload_completed
1901    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1902   [(const_int 0)]
1903   "ix86_split_long_move (operands); DONE;")
1904
1905 (define_insn "*movti_internal_sse"
1906   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1907         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1908   "TARGET_SSE && !TARGET_64BIT
1909    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1910 {
1911   switch (which_alternative)
1912     {
1913     case 0:
1914       if (get_attr_mode (insn) == MODE_V4SF)
1915         return "%vxorps\t%0, %d0";
1916       else
1917         return "%vpxor\t%0, %d0";
1918     case 1:
1919     case 2:
1920       /* TDmode values are passed as TImode on the stack.  Moving them
1921          to stack may result in unaligned memory access.  */
1922       if (misaligned_operand (operands[0], TImode)
1923           || misaligned_operand (operands[1], TImode))
1924         {
1925           if (get_attr_mode (insn) == MODE_V4SF)
1926             return "%vmovups\t{%1, %0|%0, %1}";
1927          else
1928            return "%vmovdqu\t{%1, %0|%0, %1}";
1929         }
1930       else
1931         {
1932           if (get_attr_mode (insn) == MODE_V4SF)
1933             return "%vmovaps\t{%1, %0|%0, %1}";
1934          else
1935            return "%vmovdqa\t{%1, %0|%0, %1}";
1936         }
1937     default:
1938       gcc_unreachable ();
1939     }
1940 }
1941   [(set_attr "type" "sselog1,ssemov,ssemov")
1942    (set_attr "prefix" "maybe_vex")
1943    (set (attr "mode")
1944         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1945                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1946                         (const_int 0)))
1947                  (const_string "V4SF")
1948                (and (eq_attr "alternative" "2")
1949                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1950                         (const_int 0)))
1951                  (const_string "V4SF")]
1952               (const_string "TI")))])
1953
1954 (define_insn "*movdi_internal_rex64"
1955   [(set (match_operand:DI 0 "nonimmediate_operand"
1956           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1957         (match_operand:DI 1 "general_operand"
1958           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1959   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1960 {
1961   switch (get_attr_type (insn))
1962     {
1963     case TYPE_SSECVT:
1964       if (SSE_REG_P (operands[0]))
1965         return "movq2dq\t{%1, %0|%0, %1}";
1966       else
1967         return "movdq2q\t{%1, %0|%0, %1}";
1968
1969     case TYPE_SSEMOV:
1970       if (TARGET_AVX)
1971         {
1972           if (get_attr_mode (insn) == MODE_TI)
1973             return "vmovdqa\t{%1, %0|%0, %1}";
1974           else
1975             return "vmovq\t{%1, %0|%0, %1}";
1976         }
1977
1978       if (get_attr_mode (insn) == MODE_TI)
1979         return "movdqa\t{%1, %0|%0, %1}";
1980       /* FALLTHRU */
1981
1982     case TYPE_MMXMOV:
1983       /* Moves from and into integer register is done using movd
1984          opcode with REX prefix.  */
1985       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1986         return "movd\t{%1, %0|%0, %1}";
1987       return "movq\t{%1, %0|%0, %1}";
1988
1989     case TYPE_SSELOG1:
1990       return "%vpxor\t%0, %d0";
1991
1992     case TYPE_MMX:
1993       return "pxor\t%0, %0";
1994
1995     case TYPE_MULTI:
1996       return "#";
1997
1998     case TYPE_LEA:
1999       return "lea{q}\t{%a1, %0|%0, %a1}";
2000
2001     default:
2002       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2003       if (get_attr_mode (insn) == MODE_SI)
2004         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2005       else if (which_alternative == 2)
2006         return "movabs{q}\t{%1, %0|%0, %1}";
2007       else
2008         return "mov{q}\t{%1, %0|%0, %1}";
2009     }
2010 }
2011   [(set (attr "type")
2012      (cond [(eq_attr "alternative" "5")
2013               (const_string "mmx")
2014             (eq_attr "alternative" "6,7,8,9,10")
2015               (const_string "mmxmov")
2016             (eq_attr "alternative" "11")
2017               (const_string "sselog1")
2018             (eq_attr "alternative" "12,13,14,15,16")
2019               (const_string "ssemov")
2020             (eq_attr "alternative" "17,18")
2021               (const_string "ssecvt")
2022             (eq_attr "alternative" "4")
2023               (const_string "multi")
2024             (match_operand:DI 1 "pic_32bit_operand" "")
2025               (const_string "lea")
2026            ]
2027            (const_string "imov")))
2028    (set (attr "modrm")
2029      (if_then_else
2030        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2031          (const_string "0")
2032          (const_string "*")))
2033    (set (attr "length_immediate")
2034      (if_then_else
2035        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2036          (const_string "8")
2037          (const_string "*")))
2038    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2039    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2040    (set (attr "prefix")
2041      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2042        (const_string "maybe_vex")
2043        (const_string "orig")))
2044    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2045
2046 ;; Convert impossible stores of immediate to existing instructions.
2047 ;; First try to get scratch register and go through it.  In case this
2048 ;; fails, move by 32bit parts.
2049 (define_peephole2
2050   [(match_scratch:DI 2 "r")
2051    (set (match_operand:DI 0 "memory_operand" "")
2052         (match_operand:DI 1 "immediate_operand" ""))]
2053   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2054    && !x86_64_immediate_operand (operands[1], DImode)"
2055   [(set (match_dup 2) (match_dup 1))
2056    (set (match_dup 0) (match_dup 2))])
2057
2058 ;; We need to define this as both peepholer and splitter for case
2059 ;; peephole2 pass is not run.
2060 ;; "&& 1" is needed to keep it from matching the previous pattern.
2061 (define_peephole2
2062   [(set (match_operand:DI 0 "memory_operand" "")
2063         (match_operand:DI 1 "immediate_operand" ""))]
2064   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2065    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2066   [(set (match_dup 2) (match_dup 3))
2067    (set (match_dup 4) (match_dup 5))]
2068   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2069
2070 (define_split
2071   [(set (match_operand:DI 0 "memory_operand" "")
2072         (match_operand:DI 1 "immediate_operand" ""))]
2073   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2074                     ? epilogue_completed : reload_completed)
2075    && !symbolic_operand (operands[1], DImode)
2076    && !x86_64_immediate_operand (operands[1], DImode)"
2077   [(set (match_dup 2) (match_dup 3))
2078    (set (match_dup 4) (match_dup 5))]
2079   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2080
2081 (define_insn "*movdi_internal"
2082   [(set (match_operand:DI 0 "nonimmediate_operand"
2083                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2084         (match_operand:DI 1 "general_operand"
2085                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2086   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2087   "@
2088    #
2089    #
2090    pxor\t%0, %0
2091    movq\t{%1, %0|%0, %1}
2092    movq\t{%1, %0|%0, %1}
2093    %vpxor\t%0, %d0
2094    %vmovq\t{%1, %0|%0, %1}
2095    %vmovdqa\t{%1, %0|%0, %1}
2096    %vmovq\t{%1, %0|%0, %1}
2097    xorps\t%0, %0
2098    movlps\t{%1, %0|%0, %1}
2099    movaps\t{%1, %0|%0, %1}
2100    movlps\t{%1, %0|%0, %1}"
2101   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2102    (set (attr "prefix")
2103      (if_then_else (eq_attr "alternative" "5,6,7,8")
2104        (const_string "vex")
2105        (const_string "orig")))
2106    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2107
2108 (define_split
2109   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2110         (match_operand:DI 1 "general_operand" ""))]
2111   "!TARGET_64BIT && reload_completed
2112    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2113    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2114   [(const_int 0)]
2115   "ix86_split_long_move (operands); DONE;")
2116
2117 (define_insn "*movsi_internal"
2118   [(set (match_operand:SI 0 "nonimmediate_operand"
2119                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2120         (match_operand:SI 1 "general_operand"
2121                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2122   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2123 {
2124   switch (get_attr_type (insn))
2125     {
2126     case TYPE_SSELOG1:
2127       if (get_attr_mode (insn) == MODE_TI)
2128         return "%vpxor\t%0, %d0";
2129       return "%vxorps\t%0, %d0";
2130
2131     case TYPE_SSEMOV:
2132       switch (get_attr_mode (insn))
2133         {
2134         case MODE_TI:
2135           return "%vmovdqa\t{%1, %0|%0, %1}";
2136         case MODE_V4SF:
2137           return "%vmovaps\t{%1, %0|%0, %1}";
2138         case MODE_SI:
2139           return "%vmovd\t{%1, %0|%0, %1}";
2140         case MODE_SF:
2141           return "%vmovss\t{%1, %0|%0, %1}";
2142         default:
2143           gcc_unreachable ();
2144         }
2145
2146     case TYPE_MMX:
2147       return "pxor\t%0, %0";
2148
2149     case TYPE_MMXMOV:
2150       if (get_attr_mode (insn) == MODE_DI)
2151         return "movq\t{%1, %0|%0, %1}";
2152       return "movd\t{%1, %0|%0, %1}";
2153
2154     case TYPE_LEA:
2155       return "lea{l}\t{%a1, %0|%0, %a1}";
2156
2157     default:
2158       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2159       return "mov{l}\t{%1, %0|%0, %1}";
2160     }
2161 }
2162   [(set (attr "type")
2163      (cond [(eq_attr "alternative" "2")
2164               (const_string "mmx")
2165             (eq_attr "alternative" "3,4,5")
2166               (const_string "mmxmov")
2167             (eq_attr "alternative" "6")
2168               (const_string "sselog1")
2169             (eq_attr "alternative" "7,8,9,10,11")
2170               (const_string "ssemov")
2171             (match_operand:DI 1 "pic_32bit_operand" "")
2172               (const_string "lea")
2173            ]
2174            (const_string "imov")))
2175    (set (attr "prefix")
2176      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2177        (const_string "orig")
2178        (const_string "maybe_vex")))
2179    (set (attr "prefix_data16")
2180      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2181        (const_string "1")
2182        (const_string "*")))
2183    (set (attr "mode")
2184      (cond [(eq_attr "alternative" "2,3")
2185               (const_string "DI")
2186             (eq_attr "alternative" "6,7")
2187               (if_then_else
2188                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2189                 (const_string "V4SF")
2190                 (const_string "TI"))
2191             (and (eq_attr "alternative" "8,9,10,11")
2192                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2193               (const_string "SF")
2194            ]
2195            (const_string "SI")))])
2196
2197 (define_insn "*movhi_internal"
2198   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2199         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2200   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2201 {
2202   switch (get_attr_type (insn))
2203     {
2204     case TYPE_IMOVX:
2205       /* movzwl is faster than movw on p2 due to partial word stalls,
2206          though not as fast as an aligned movl.  */
2207       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2208     default:
2209       if (get_attr_mode (insn) == MODE_SI)
2210         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2211       else
2212         return "mov{w}\t{%1, %0|%0, %1}";
2213     }
2214 }
2215   [(set (attr "type")
2216      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2217                 (const_int 0))
2218               (const_string "imov")
2219             (and (eq_attr "alternative" "0")
2220                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2221                           (const_int 0))
2222                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2223                           (const_int 0))))
2224               (const_string "imov")
2225             (and (eq_attr "alternative" "1,2")
2226                  (match_operand:HI 1 "aligned_operand" ""))
2227               (const_string "imov")
2228             (and (ne (symbol_ref "TARGET_MOVX")
2229                      (const_int 0))
2230                  (eq_attr "alternative" "0,2"))
2231               (const_string "imovx")
2232            ]
2233            (const_string "imov")))
2234     (set (attr "mode")
2235       (cond [(eq_attr "type" "imovx")
2236                (const_string "SI")
2237              (and (eq_attr "alternative" "1,2")
2238                   (match_operand:HI 1 "aligned_operand" ""))
2239                (const_string "SI")
2240              (and (eq_attr "alternative" "0")
2241                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2242                            (const_int 0))
2243                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2244                            (const_int 0))))
2245                (const_string "SI")
2246             ]
2247             (const_string "HI")))])
2248
2249 ;; Situation is quite tricky about when to choose full sized (SImode) move
2250 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2251 ;; partial register dependency machines (such as AMD Athlon), where QImode
2252 ;; moves issue extra dependency and for partial register stalls machines
2253 ;; that don't use QImode patterns (and QImode move cause stall on the next
2254 ;; instruction).
2255 ;;
2256 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2257 ;; register stall machines with, where we use QImode instructions, since
2258 ;; partial register stall can be caused there.  Then we use movzx.
2259 (define_insn "*movqi_internal"
2260   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2261         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2262   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2263 {
2264   switch (get_attr_type (insn))
2265     {
2266     case TYPE_IMOVX:
2267       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2268       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2269     default:
2270       if (get_attr_mode (insn) == MODE_SI)
2271         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2272       else
2273         return "mov{b}\t{%1, %0|%0, %1}";
2274     }
2275 }
2276   [(set (attr "type")
2277      (cond [(and (eq_attr "alternative" "5")
2278                  (not (match_operand:QI 1 "aligned_operand" "")))
2279               (const_string "imovx")
2280             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2281                 (const_int 0))
2282               (const_string "imov")
2283             (and (eq_attr "alternative" "3")
2284                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2285                           (const_int 0))
2286                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2287                           (const_int 0))))
2288               (const_string "imov")
2289             (eq_attr "alternative" "3,5")
2290               (const_string "imovx")
2291             (and (ne (symbol_ref "TARGET_MOVX")
2292                      (const_int 0))
2293                  (eq_attr "alternative" "2"))
2294               (const_string "imovx")
2295            ]
2296            (const_string "imov")))
2297    (set (attr "mode")
2298       (cond [(eq_attr "alternative" "3,4,5")
2299                (const_string "SI")
2300              (eq_attr "alternative" "6")
2301                (const_string "QI")
2302              (eq_attr "type" "imovx")
2303                (const_string "SI")
2304              (and (eq_attr "type" "imov")
2305                   (and (eq_attr "alternative" "0,1")
2306                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2307                                 (const_int 0))
2308                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2309                                      (const_int 0))
2310                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2311                                      (const_int 0))))))
2312                (const_string "SI")
2313              ;; Avoid partial register stalls when not using QImode arithmetic
2314              (and (eq_attr "type" "imov")
2315                   (and (eq_attr "alternative" "0,1")
2316                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2317                                 (const_int 0))
2318                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2319                                 (const_int 0)))))
2320                (const_string "SI")
2321            ]
2322            (const_string "QI")))])
2323
2324 ;; Stores and loads of ax to arbitrary constant address.
2325 ;; We fake an second form of instruction to force reload to load address
2326 ;; into register when rax is not available
2327 (define_insn "*movabs<mode>_1"
2328   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2329         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2330   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2331   "@
2332    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2333    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2334   [(set_attr "type" "imov")
2335    (set_attr "modrm" "0,*")
2336    (set_attr "length_address" "8,0")
2337    (set_attr "length_immediate" "0,*")
2338    (set_attr "memory" "store")
2339    (set_attr "mode" "<MODE>")])
2340
2341 (define_insn "*movabs<mode>_2"
2342   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2343         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2344   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2345   "@
2346    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2347    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2348   [(set_attr "type" "imov")
2349    (set_attr "modrm" "0,*")
2350    (set_attr "length_address" "8,0")
2351    (set_attr "length_immediate" "0")
2352    (set_attr "memory" "load")
2353    (set_attr "mode" "<MODE>")])
2354
2355 (define_insn "*swap<mode>"
2356   [(set (match_operand:SWI48 0 "register_operand" "+r")
2357         (match_operand:SWI48 1 "register_operand" "+r"))
2358    (set (match_dup 1)
2359         (match_dup 0))]
2360   ""
2361   "xchg{<imodesuffix>}\t%1, %0"
2362   [(set_attr "type" "imov")
2363    (set_attr "mode" "<MODE>")
2364    (set_attr "pent_pair" "np")
2365    (set_attr "athlon_decode" "vector")
2366    (set_attr "amdfam10_decode" "double")
2367    (set_attr "bdver1_decode" "double")])
2368
2369 (define_insn "*swap<mode>_1"
2370   [(set (match_operand:SWI12 0 "register_operand" "+r")
2371         (match_operand:SWI12 1 "register_operand" "+r"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2375   "xchg{l}\t%k1, %k0"
2376   [(set_attr "type" "imov")
2377    (set_attr "mode" "SI")
2378    (set_attr "pent_pair" "np")
2379    (set_attr "athlon_decode" "vector")
2380    (set_attr "amdfam10_decode" "double")
2381    (set_attr "bdver1_decode" "double")])
2382
2383 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2384 ;; is disabled for AMDFAM10
2385 (define_insn "*swap<mode>_2"
2386   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2387         (match_operand:SWI12 1 "register_operand" "+<r>"))
2388    (set (match_dup 1)
2389         (match_dup 0))]
2390   "TARGET_PARTIAL_REG_STALL"
2391   "xchg{<imodesuffix>}\t%1, %0"
2392   [(set_attr "type" "imov")
2393    (set_attr "mode" "<MODE>")
2394    (set_attr "pent_pair" "np")
2395    (set_attr "athlon_decode" "vector")])
2396
2397 (define_expand "movstrict<mode>"
2398   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2399         (match_operand:SWI12 1 "general_operand" ""))]
2400   ""
2401 {
2402   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2403     FAIL;
2404   /* Don't generate memory->memory moves, go through a register */
2405   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2406     operands[1] = force_reg (<MODE>mode, operands[1]);
2407 })
2408
2409 (define_insn "*movstrict<mode>_1"
2410   [(set (strict_low_part
2411           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2412         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2413   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2414    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2416   [(set_attr "type" "imov")
2417    (set_attr "mode" "<MODE>")])
2418
2419 (define_insn "*movstrict<mode>_xor"
2420   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2421         (match_operand:SWI12 1 "const0_operand" ""))
2422    (clobber (reg:CC FLAGS_REG))]
2423   "reload_completed"
2424   "xor{<imodesuffix>}\t%0, %0"
2425   [(set_attr "type" "alu1")
2426    (set_attr "mode" "<MODE>")
2427    (set_attr "length_immediate" "0")])
2428
2429 (define_insn "*mov<mode>_extv_1"
2430   [(set (match_operand:SWI24 0 "register_operand" "=R")
2431         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2432                             (const_int 8)
2433                             (const_int 8)))]
2434   ""
2435   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2436   [(set_attr "type" "imovx")
2437    (set_attr "mode" "SI")])
2438
2439 (define_insn "*movqi_extv_1_rex64"
2440   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2441         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2442                          (const_int 8)
2443                          (const_int 8)))]
2444   "TARGET_64BIT"
2445 {
2446   switch (get_attr_type (insn))
2447     {
2448     case TYPE_IMOVX:
2449       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2450     default:
2451       return "mov{b}\t{%h1, %0|%0, %h1}";
2452     }
2453 }
2454   [(set (attr "type")
2455      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2456                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2457                              (ne (symbol_ref "TARGET_MOVX")
2458                                  (const_int 0))))
2459         (const_string "imovx")
2460         (const_string "imov")))
2461    (set (attr "mode")
2462      (if_then_else (eq_attr "type" "imovx")
2463         (const_string "SI")
2464         (const_string "QI")))])
2465
2466 (define_insn "*movqi_extv_1"
2467   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?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 "*mov<mode>_extzv_1"
2494   [(set (match_operand:SWI48 0 "register_operand" "=R")
2495         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2496                             (const_int 8)
2497                             (const_int 8)))]
2498   ""
2499   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2500   [(set_attr "type" "imovx")
2501    (set_attr "mode" "SI")])
2502
2503 (define_insn "*movqi_extzv_2_rex64"
2504   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2505         (subreg:QI
2506           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2507                            (const_int 8)
2508                            (const_int 8)) 0))]
2509   "TARGET_64BIT"
2510 {
2511   switch (get_attr_type (insn))
2512     {
2513     case TYPE_IMOVX:
2514       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2515     default:
2516       return "mov{b}\t{%h1, %0|%0, %h1}";
2517     }
2518 }
2519   [(set (attr "type")
2520      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2521                         (ne (symbol_ref "TARGET_MOVX")
2522                             (const_int 0)))
2523         (const_string "imovx")
2524         (const_string "imov")))
2525    (set (attr "mode")
2526      (if_then_else (eq_attr "type" "imovx")
2527         (const_string "SI")
2528         (const_string "QI")))])
2529
2530 (define_insn "*movqi_extzv_2"
2531   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?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 (and (match_operand:QI 0 "register_operand" "")
2548                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2549                              (ne (symbol_ref "TARGET_MOVX")
2550                                  (const_int 0))))
2551         (const_string "imovx")
2552         (const_string "imov")))
2553    (set (attr "mode")
2554      (if_then_else (eq_attr "type" "imovx")
2555         (const_string "SI")
2556         (const_string "QI")))])
2557
2558 (define_expand "mov<mode>_insv_1"
2559   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2560                             (const_int 8)
2561                             (const_int 8))
2562         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2563
2564 (define_insn "*mov<mode>_insv_1_rex64"
2565   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2566                              (const_int 8)
2567                              (const_int 8))
2568         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2569   "TARGET_64BIT"
2570   "mov{b}\t{%b1, %h0|%h0, %b1}"
2571   [(set_attr "type" "imov")
2572    (set_attr "mode" "QI")])
2573
2574 (define_insn "*movsi_insv_1"
2575   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2576                          (const_int 8)
2577                          (const_int 8))
2578         (match_operand:SI 1 "general_operand" "Qmn"))]
2579   "!TARGET_64BIT"
2580   "mov{b}\t{%b1, %h0|%h0, %b1}"
2581   [(set_attr "type" "imov")
2582    (set_attr "mode" "QI")])
2583
2584 (define_insn "*movqi_insv_2"
2585   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2586                          (const_int 8)
2587                          (const_int 8))
2588         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2589                      (const_int 8)))]
2590   ""
2591   "mov{b}\t{%h1, %h0|%h0, %h1}"
2592   [(set_attr "type" "imov")
2593    (set_attr "mode" "QI")])
2594 \f
2595 ;; Floating point push instructions.
2596
2597 (define_insn "*pushtf"
2598   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2599         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2600   "TARGET_SSE2"
2601 {
2602   /* This insn should be already split before reg-stack.  */
2603   gcc_unreachable ();
2604 }
2605   [(set_attr "type" "multi")
2606    (set_attr "unit" "sse,*,*")
2607    (set_attr "mode" "TF,SI,SI")])
2608
2609 (define_split
2610   [(set (match_operand:TF 0 "push_operand" "")
2611         (match_operand:TF 1 "sse_reg_operand" ""))]
2612   "TARGET_SSE2 && reload_completed"
2613   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2614    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2615
2616 (define_split
2617   [(set (match_operand:TF 0 "push_operand" "")
2618         (match_operand:TF 1 "general_operand" ""))]
2619   "TARGET_SSE2 && reload_completed
2620    && !SSE_REG_P (operands[1])"
2621   [(const_int 0)]
2622   "ix86_split_long_move (operands); DONE;")
2623
2624 (define_insn "*pushxf"
2625   [(set (match_operand:XF 0 "push_operand" "=<,<")
2626         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2627   "optimize_function_for_speed_p (cfun)"
2628 {
2629   /* This insn should be already split before reg-stack.  */
2630   gcc_unreachable ();
2631 }
2632   [(set_attr "type" "multi")
2633    (set_attr "unit" "i387,*")
2634    (set_attr "mode" "XF,SI")])
2635
2636 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2637 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2638 ;; Pushing using integer instructions is longer except for constants
2639 ;; and direct memory references (assuming that any given constant is pushed
2640 ;; only once, but this ought to be handled elsewhere).
2641
2642 (define_insn "*pushxf_nointeger"
2643   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2644         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2645   "optimize_function_for_size_p (cfun)"
2646 {
2647   /* This insn should be already split before reg-stack.  */
2648   gcc_unreachable ();
2649 }
2650   [(set_attr "type" "multi")
2651    (set_attr "unit" "i387,*,*")
2652    (set_attr "mode" "XF,SI,SI")])
2653
2654 (define_split
2655   [(set (match_operand:XF 0 "push_operand" "")
2656         (match_operand:XF 1 "fp_register_operand" ""))]
2657   "reload_completed"
2658   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2659    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2660   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2661
2662 (define_split
2663   [(set (match_operand:XF 0 "push_operand" "")
2664         (match_operand:XF 1 "general_operand" ""))]
2665   "reload_completed
2666    && !FP_REG_P (operands[1])"
2667   [(const_int 0)]
2668   "ix86_split_long_move (operands); DONE;")
2669
2670 (define_insn "*pushdf"
2671   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2672         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2673   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2674 {
2675   /* This insn should be already split before reg-stack.  */
2676   gcc_unreachable ();
2677 }
2678   [(set_attr "type" "multi")
2679    (set_attr "unit" "i387,*,*")
2680    (set_attr "mode" "DF,SI,DF")])
2681
2682 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2683 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2684 ;; On the average, pushdf using integers can be still shorter.  Allow this
2685 ;; pattern for optimize_size too.
2686
2687 (define_insn "*pushdf_nointeger"
2688   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2689         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2690   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2691 {
2692   /* This insn should be already split before reg-stack.  */
2693   gcc_unreachable ();
2694 }
2695   [(set_attr "type" "multi")
2696    (set_attr "unit" "i387,*,*,*")
2697    (set_attr "mode" "DF,SI,SI,DF")])
2698
2699 ;; %%% Kill this when call knows how to work this out.
2700 (define_split
2701   [(set (match_operand:DF 0 "push_operand" "")
2702         (match_operand:DF 1 "any_fp_register_operand" ""))]
2703   "reload_completed"
2704   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2705    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2706
2707 (define_split
2708   [(set (match_operand:DF 0 "push_operand" "")
2709         (match_operand:DF 1 "general_operand" ""))]
2710   "reload_completed
2711    && !ANY_FP_REG_P (operands[1])"
2712   [(const_int 0)]
2713   "ix86_split_long_move (operands); DONE;")
2714
2715 (define_insn "*pushsf_rex64"
2716   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2717         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2718   "TARGET_64BIT"
2719 {
2720   /* Anything else should be already split before reg-stack.  */
2721   gcc_assert (which_alternative == 1);
2722   return "push{q}\t%q1";
2723 }
2724   [(set_attr "type" "multi,push,multi")
2725    (set_attr "unit" "i387,*,*")
2726    (set_attr "mode" "SF,DI,SF")])
2727
2728 (define_insn "*pushsf"
2729   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2730         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2731   "!TARGET_64BIT"
2732 {
2733   /* Anything else should be already split before reg-stack.  */
2734   gcc_assert (which_alternative == 1);
2735   return "push{l}\t%1";
2736 }
2737   [(set_attr "type" "multi,push,multi")
2738    (set_attr "unit" "i387,*,*")
2739    (set_attr "mode" "SF,SI,SF")])
2740
2741 (define_split
2742   [(set (match_operand:SF 0 "push_operand" "")
2743         (match_operand:SF 1 "memory_operand" ""))]
2744   "reload_completed
2745    && MEM_P (operands[1])
2746    && (operands[2] = find_constant_src (insn))"
2747   [(set (match_dup 0)
2748         (match_dup 2))])
2749
2750 ;; %%% Kill this when call knows how to work this out.
2751 (define_split
2752   [(set (match_operand:SF 0 "push_operand" "")
2753         (match_operand:SF 1 "any_fp_register_operand" ""))]
2754   "reload_completed"
2755   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2756    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2757   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2758 \f
2759 ;; Floating point move instructions.
2760
2761 (define_expand "movtf"
2762   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2763         (match_operand:TF 1 "nonimmediate_operand" ""))]
2764   "TARGET_SSE2"
2765 {
2766   ix86_expand_move (TFmode, operands);
2767   DONE;
2768 })
2769
2770 (define_expand "mov<mode>"
2771   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2772         (match_operand:X87MODEF 1 "general_operand" ""))]
2773   ""
2774   "ix86_expand_move (<MODE>mode, operands); DONE;")
2775
2776 (define_insn "*movtf_internal"
2777   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2778         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2779   "TARGET_SSE2
2780    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2781 {
2782   switch (which_alternative)
2783     {
2784     case 0:
2785     case 1:
2786       if (get_attr_mode (insn) == MODE_V4SF)
2787         return "%vmovaps\t{%1, %0|%0, %1}";
2788       else
2789         return "%vmovdqa\t{%1, %0|%0, %1}";
2790     case 2:
2791       if (get_attr_mode (insn) == MODE_V4SF)
2792         return "%vxorps\t%0, %d0";
2793       else
2794         return "%vpxor\t%0, %d0";
2795     case 3:
2796     case 4:
2797         return "#";
2798     default:
2799       gcc_unreachable ();
2800     }
2801 }
2802   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2803    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2804    (set (attr "mode")
2805         (cond [(eq_attr "alternative" "0,2")
2806                  (if_then_else
2807                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2808                        (const_int 0))
2809                    (const_string "V4SF")
2810                    (const_string "TI"))
2811                (eq_attr "alternative" "1")
2812                  (if_then_else
2813                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2814                             (const_int 0))
2815                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2816                             (const_int 0)))
2817                    (const_string "V4SF")
2818                    (const_string "TI"))]
2819                (const_string "DI")))])
2820
2821 (define_split
2822   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2823         (match_operand:TF 1 "general_operand" ""))]
2824   "reload_completed
2825    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2826   [(const_int 0)]
2827   "ix86_split_long_move (operands); DONE;")
2828
2829 (define_insn "*movxf_internal"
2830   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2831         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2832   "optimize_function_for_speed_p (cfun)
2833    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2834    && (reload_in_progress || reload_completed
2835        || GET_CODE (operands[1]) != CONST_DOUBLE
2836        || memory_operand (operands[0], XFmode))"
2837 {
2838   switch (which_alternative)
2839     {
2840     case 0:
2841     case 1:
2842       return output_387_reg_move (insn, operands);
2843
2844     case 2:
2845       return standard_80387_constant_opcode (operands[1]);
2846
2847     case 3: case 4:
2848       return "#";
2849
2850     default:
2851       gcc_unreachable ();
2852     }
2853 }
2854   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2855    (set_attr "mode" "XF,XF,XF,SI,SI")])
2856
2857 ;; Do not use integer registers when optimizing for size
2858 (define_insn "*movxf_internal_nointeger"
2859   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2860         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2861   "optimize_function_for_size_p (cfun)
2862    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2863    && (reload_in_progress || reload_completed
2864        || standard_80387_constant_p (operands[1])
2865        || GET_CODE (operands[1]) != CONST_DOUBLE
2866        || memory_operand (operands[0], XFmode))"
2867 {
2868   switch (which_alternative)
2869     {
2870     case 0:
2871     case 1:
2872       return output_387_reg_move (insn, operands);
2873
2874     case 2:
2875       return standard_80387_constant_opcode (operands[1]);
2876
2877     case 3: case 4:
2878       return "#";
2879     default:
2880       gcc_unreachable ();
2881     }
2882 }
2883   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2884    (set_attr "mode" "XF,XF,XF,SI,SI")])
2885
2886 (define_split
2887   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2888         (match_operand:XF 1 "general_operand" ""))]
2889   "reload_completed
2890    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2891    && ! (FP_REG_P (operands[0]) ||
2892          (GET_CODE (operands[0]) == SUBREG
2893           && FP_REG_P (SUBREG_REG (operands[0]))))
2894    && ! (FP_REG_P (operands[1]) ||
2895          (GET_CODE (operands[1]) == SUBREG
2896           && FP_REG_P (SUBREG_REG (operands[1]))))"
2897   [(const_int 0)]
2898   "ix86_split_long_move (operands); DONE;")
2899
2900 (define_insn "*movdf_internal_rex64"
2901   [(set (match_operand:DF 0 "nonimmediate_operand"
2902                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2903         (match_operand:DF 1 "general_operand"
2904                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2905   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2906    && (reload_in_progress || reload_completed
2907        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2908        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2909            && optimize_function_for_size_p (cfun)
2910            && standard_80387_constant_p (operands[1]))
2911        || GET_CODE (operands[1]) != CONST_DOUBLE
2912        || memory_operand (operands[0], DFmode))"
2913 {
2914   switch (which_alternative)
2915     {
2916     case 0:
2917     case 1:
2918       return output_387_reg_move (insn, operands);
2919
2920     case 2:
2921       return standard_80387_constant_opcode (operands[1]);
2922
2923     case 3:
2924     case 4:
2925       return "#";
2926
2927     case 5:
2928       switch (get_attr_mode (insn))
2929         {
2930         case MODE_V4SF:
2931           return "%vxorps\t%0, %d0";
2932         case MODE_V2DF:
2933           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2934             return "%vxorps\t%0, %d0";
2935           else
2936             return "%vxorpd\t%0, %d0";
2937         case MODE_TI:
2938           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2939             return "%vxorps\t%0, %d0";
2940           else
2941             return "%vpxor\t%0, %d0";
2942         default:
2943           gcc_unreachable ();
2944         }
2945     case 6:
2946     case 7:
2947     case 8:
2948       switch (get_attr_mode (insn))
2949         {
2950         case MODE_V4SF:
2951           return "%vmovaps\t{%1, %0|%0, %1}";
2952         case MODE_V2DF:
2953           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2954             return "%vmovaps\t{%1, %0|%0, %1}";
2955           else
2956             return "%vmovapd\t{%1, %0|%0, %1}";
2957         case MODE_TI:
2958           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2959             return "%vmovaps\t{%1, %0|%0, %1}";
2960           else
2961             return "%vmovdqa\t{%1, %0|%0, %1}";
2962         case MODE_DI:
2963           return "%vmovq\t{%1, %0|%0, %1}";
2964         case MODE_DF:
2965           if (TARGET_AVX)
2966             {
2967               if (REG_P (operands[0]) && REG_P (operands[1]))
2968                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2969               else
2970                 return "vmovsd\t{%1, %0|%0, %1}";
2971             }
2972           else
2973             return "movsd\t{%1, %0|%0, %1}";
2974         case MODE_V1DF:
2975           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2976         case MODE_V2SF:
2977           return "%vmovlps\t{%1, %d0|%d0, %1}";
2978         default:
2979           gcc_unreachable ();
2980         }
2981
2982     case 9:
2983     case 10:
2984     return "%vmovd\t{%1, %0|%0, %1}";
2985
2986     default:
2987       gcc_unreachable();
2988     }
2989 }
2990   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2991    (set (attr "prefix")
2992      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2993        (const_string "orig")
2994        (const_string "maybe_vex")))
2995    (set (attr "prefix_data16")
2996      (if_then_else (eq_attr "mode" "V1DF")
2997        (const_string "1")
2998        (const_string "*")))
2999    (set (attr "mode")
3000         (cond [(eq_attr "alternative" "0,1,2")
3001                  (const_string "DF")
3002                (eq_attr "alternative" "3,4,9,10")
3003                  (const_string "DI")
3004
3005                /* For SSE1, we have many fewer alternatives.  */
3006                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3007                  (cond [(eq_attr "alternative" "5,6")
3008                           (const_string "V4SF")
3009                        ]
3010                    (const_string "V2SF"))
3011
3012                /* xorps is one byte shorter.  */
3013                (eq_attr "alternative" "5")
3014                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3015                             (const_int 0))
3016                           (const_string "V4SF")
3017                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3018                             (const_int 0))
3019                           (const_string "TI")
3020                        ]
3021                        (const_string "V2DF"))
3022
3023                /* For architectures resolving dependencies on
3024                   whole SSE registers use APD move to break dependency
3025                   chains, otherwise use short move to avoid extra work.
3026
3027                   movaps encodes one byte shorter.  */
3028                (eq_attr "alternative" "6")
3029                  (cond
3030                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3031                         (const_int 0))
3032                       (const_string "V4SF")
3033                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3034                         (const_int 0))
3035                       (const_string "V2DF")
3036                    ]
3037                    (const_string "DF"))
3038                /* For architectures resolving dependencies on register
3039                   parts we may avoid extra work to zero out upper part
3040                   of register.  */
3041                (eq_attr "alternative" "7")
3042                  (if_then_else
3043                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3044                        (const_int 0))
3045                    (const_string "V1DF")
3046                    (const_string "DF"))
3047               ]
3048               (const_string "DF")))])
3049
3050 (define_insn "*movdf_internal"
3051   [(set (match_operand:DF 0 "nonimmediate_operand"
3052                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3053         (match_operand:DF 1 "general_operand"
3054                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3055   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3056    && optimize_function_for_speed_p (cfun)
3057    && TARGET_INTEGER_DFMODE_MOVES
3058    && (reload_in_progress || reload_completed
3059        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3061            && optimize_function_for_size_p (cfun)
3062            && standard_80387_constant_p (operands[1]))
3063        || GET_CODE (operands[1]) != CONST_DOUBLE
3064        || memory_operand (operands[0], DFmode))"
3065 {
3066   switch (which_alternative)
3067     {
3068     case 0:
3069     case 1:
3070       return output_387_reg_move (insn, operands);
3071
3072     case 2:
3073       return standard_80387_constant_opcode (operands[1]);
3074
3075     case 3:
3076     case 4:
3077       return "#";
3078
3079     case 5:
3080       switch (get_attr_mode (insn))
3081         {
3082         case MODE_V4SF:
3083           return "xorps\t%0, %0";
3084         case MODE_V2DF:
3085           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3086             return "xorps\t%0, %0";
3087           else
3088             return "xorpd\t%0, %0";
3089         case MODE_TI:
3090           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3091             return "xorps\t%0, %0";
3092           else
3093             return "pxor\t%0, %0";
3094         default:
3095           gcc_unreachable ();
3096         }
3097     case 6:
3098     case 7:
3099     case 8:
3100       switch (get_attr_mode (insn))
3101         {
3102         case MODE_V4SF:
3103           return "movaps\t{%1, %0|%0, %1}";
3104         case MODE_V2DF:
3105           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3106             return "movaps\t{%1, %0|%0, %1}";
3107           else
3108             return "movapd\t{%1, %0|%0, %1}";
3109         case MODE_TI:
3110           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3111             return "movaps\t{%1, %0|%0, %1}";
3112           else
3113             return "movdqa\t{%1, %0|%0, %1}";
3114         case MODE_DI:
3115           return "movq\t{%1, %0|%0, %1}";
3116         case MODE_DF:
3117           return "movsd\t{%1, %0|%0, %1}";
3118         case MODE_V1DF:
3119           return "movlpd\t{%1, %0|%0, %1}";
3120         case MODE_V2SF:
3121           return "movlps\t{%1, %0|%0, %1}";
3122         default:
3123           gcc_unreachable ();
3124         }
3125
3126     default:
3127       gcc_unreachable();
3128     }
3129 }
3130   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3131    (set (attr "prefix_data16")
3132      (if_then_else (eq_attr "mode" "V1DF")
3133        (const_string "1")
3134        (const_string "*")))
3135    (set (attr "mode")
3136         (cond [(eq_attr "alternative" "0,1,2")
3137                  (const_string "DF")
3138                (eq_attr "alternative" "3,4")
3139                  (const_string "SI")
3140
3141                /* For SSE1, we have many fewer alternatives.  */
3142                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3143                  (cond [(eq_attr "alternative" "5,6")
3144                           (const_string "V4SF")
3145                        ]
3146                    (const_string "V2SF"))
3147
3148                /* xorps is one byte shorter.  */
3149                (eq_attr "alternative" "5")
3150                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3151                             (const_int 0))
3152                           (const_string "V4SF")
3153                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3154                             (const_int 0))
3155                           (const_string "TI")
3156                        ]
3157                        (const_string "V2DF"))
3158
3159                /* For architectures resolving dependencies on
3160                   whole SSE registers use APD move to break dependency
3161                   chains, otherwise use short move to avoid extra work.
3162
3163                   movaps encodes one byte shorter.  */
3164                (eq_attr "alternative" "6")
3165                  (cond
3166                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3167                         (const_int 0))
3168                       (const_string "V4SF")
3169                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3170                         (const_int 0))
3171                       (const_string "V2DF")
3172                    ]
3173                    (const_string "DF"))
3174                /* For architectures resolving dependencies on register
3175                   parts we may avoid extra work to zero out upper part
3176                   of register.  */
3177                (eq_attr "alternative" "7")
3178                  (if_then_else
3179                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3180                        (const_int 0))
3181                    (const_string "V1DF")
3182                    (const_string "DF"))
3183               ]
3184               (const_string "DF")))])
3185
3186 ;; Moving is usually shorter when only FP registers are used. This separate
3187 ;; movdf pattern avoids the use of integer registers for FP operations
3188 ;; when optimizing for size.
3189
3190 (define_insn "*movdf_internal_nointeger"
3191   [(set (match_operand:DF 0 "nonimmediate_operand"
3192                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3193         (match_operand:DF 1 "general_operand"
3194                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3195   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3196    && ((optimize_function_for_size_p (cfun)
3197        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3198    && (reload_in_progress || reload_completed
3199        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3200        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3201            && optimize_function_for_size_p (cfun)
3202            && !memory_operand (operands[0], DFmode)
3203            && standard_80387_constant_p (operands[1]))
3204        || GET_CODE (operands[1]) != CONST_DOUBLE
3205        || ((optimize_function_for_size_p (cfun)
3206             || !TARGET_MEMORY_MISMATCH_STALL
3207             || reload_in_progress || reload_completed)
3208            && memory_operand (operands[0], DFmode)))"
3209 {
3210   switch (which_alternative)
3211     {
3212     case 0:
3213     case 1:
3214       return output_387_reg_move (insn, operands);
3215
3216     case 2:
3217       return standard_80387_constant_opcode (operands[1]);
3218
3219     case 3:
3220     case 4:
3221       return "#";
3222
3223     case 5:
3224       switch (get_attr_mode (insn))
3225         {
3226         case MODE_V4SF:
3227           return "%vxorps\t%0, %d0";
3228         case MODE_V2DF:
3229           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3230             return "%vxorps\t%0, %d0";
3231           else
3232             return "%vxorpd\t%0, %d0";
3233         case MODE_TI:
3234           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3235             return "%vxorps\t%0, %d0";
3236           else
3237             return "%vpxor\t%0, %d0";
3238         default:
3239           gcc_unreachable ();
3240         }
3241     case 6:
3242     case 7:
3243     case 8:
3244       switch (get_attr_mode (insn))
3245         {
3246         case MODE_V4SF:
3247           return "%vmovaps\t{%1, %0|%0, %1}";
3248         case MODE_V2DF:
3249           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3250             return "%vmovaps\t{%1, %0|%0, %1}";
3251           else
3252             return "%vmovapd\t{%1, %0|%0, %1}";
3253         case MODE_TI:
3254           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3255             return "%vmovaps\t{%1, %0|%0, %1}";
3256           else
3257             return "%vmovdqa\t{%1, %0|%0, %1}";
3258         case MODE_DI:
3259           return "%vmovq\t{%1, %0|%0, %1}";
3260         case MODE_DF:
3261           if (TARGET_AVX)
3262             {
3263               if (REG_P (operands[0]) && REG_P (operands[1]))
3264                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3265               else
3266                 return "vmovsd\t{%1, %0|%0, %1}";
3267             }
3268           else
3269             return "movsd\t{%1, %0|%0, %1}";
3270         case MODE_V1DF:
3271           if (TARGET_AVX)
3272             {
3273               if (REG_P (operands[0]))
3274                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3275               else
3276                 return "vmovlpd\t{%1, %0|%0, %1}";
3277             }
3278           else
3279             return "movlpd\t{%1, %0|%0, %1}";
3280         case MODE_V2SF:
3281           if (TARGET_AVX)
3282             {
3283               if (REG_P (operands[0]))
3284                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3285               else
3286                 return "vmovlps\t{%1, %0|%0, %1}";
3287             }
3288           else
3289             return "movlps\t{%1, %0|%0, %1}";
3290         default:
3291           gcc_unreachable ();
3292         }
3293
3294     default:
3295       gcc_unreachable ();
3296     }
3297 }
3298   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3299    (set (attr "prefix")
3300      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3301        (const_string "orig")
3302        (const_string "maybe_vex")))
3303    (set (attr "prefix_data16")
3304      (if_then_else (eq_attr "mode" "V1DF")
3305        (const_string "1")
3306        (const_string "*")))
3307    (set (attr "mode")
3308         (cond [(eq_attr "alternative" "0,1,2")
3309                  (const_string "DF")
3310                (eq_attr "alternative" "3,4")
3311                  (const_string "SI")
3312
3313                /* For SSE1, we have many fewer alternatives.  */
3314                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3315                  (cond [(eq_attr "alternative" "5,6")
3316                           (const_string "V4SF")
3317                        ]
3318                    (const_string "V2SF"))
3319
3320                /* xorps is one byte shorter.  */
3321                (eq_attr "alternative" "5")
3322                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3323                             (const_int 0))
3324                           (const_string "V4SF")
3325                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3326                             (const_int 0))
3327                           (const_string "TI")
3328                        ]
3329                        (const_string "V2DF"))
3330
3331                /* For architectures resolving dependencies on
3332                   whole SSE registers use APD move to break dependency
3333                   chains, otherwise use short move to avoid extra work.
3334
3335                   movaps encodes one byte shorter.  */
3336                (eq_attr "alternative" "6")
3337                  (cond
3338                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3339                         (const_int 0))
3340                       (const_string "V4SF")
3341                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3342                         (const_int 0))
3343                       (const_string "V2DF")
3344                    ]
3345                    (const_string "DF"))
3346                /* For architectures resolving dependencies on register
3347                   parts we may avoid extra work to zero out upper part
3348                   of register.  */
3349                (eq_attr "alternative" "7")
3350                  (if_then_else
3351                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3352                        (const_int 0))
3353                    (const_string "V1DF")
3354                    (const_string "DF"))
3355               ]
3356               (const_string "DF")))])
3357
3358 (define_split
3359   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3360         (match_operand:DF 1 "general_operand" ""))]
3361   "reload_completed
3362    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3363    && ! (ANY_FP_REG_P (operands[0]) ||
3364          (GET_CODE (operands[0]) == SUBREG
3365           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3366    && ! (ANY_FP_REG_P (operands[1]) ||
3367          (GET_CODE (operands[1]) == SUBREG
3368           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3369   [(const_int 0)]
3370   "ix86_split_long_move (operands); DONE;")
3371
3372 (define_insn "*movsf_internal"
3373   [(set (match_operand:SF 0 "nonimmediate_operand"
3374           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3375         (match_operand:SF 1 "general_operand"
3376           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3377   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3378    && (reload_in_progress || reload_completed
3379        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3380        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3381            && standard_80387_constant_p (operands[1]))
3382        || GET_CODE (operands[1]) != CONST_DOUBLE
3383        || memory_operand (operands[0], SFmode))"
3384 {
3385   switch (which_alternative)
3386     {
3387     case 0:
3388     case 1:
3389       return output_387_reg_move (insn, operands);
3390
3391     case 2:
3392       return standard_80387_constant_opcode (operands[1]);
3393
3394     case 3:
3395     case 4:
3396       return "mov{l}\t{%1, %0|%0, %1}";
3397     case 5:
3398       if (get_attr_mode (insn) == MODE_TI)
3399         return "%vpxor\t%0, %d0";
3400       else
3401         return "%vxorps\t%0, %d0";
3402     case 6:
3403       if (get_attr_mode (insn) == MODE_V4SF)
3404         return "%vmovaps\t{%1, %0|%0, %1}";
3405       else
3406         return "%vmovss\t{%1, %d0|%d0, %1}";
3407     case 7:
3408       if (TARGET_AVX)
3409         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3410                                    : "vmovss\t{%1, %0|%0, %1}";
3411       else
3412         return "movss\t{%1, %0|%0, %1}";
3413     case 8:
3414       return "%vmovss\t{%1, %0|%0, %1}";
3415
3416     case 9: case 10: case 14: case 15:
3417       return "movd\t{%1, %0|%0, %1}";
3418     case 12: case 13:
3419       return "%vmovd\t{%1, %0|%0, %1}";
3420
3421     case 11:
3422       return "movq\t{%1, %0|%0, %1}";
3423
3424     default:
3425       gcc_unreachable ();
3426     }
3427 }
3428   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3429    (set (attr "prefix")
3430      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3431        (const_string "maybe_vex")
3432        (const_string "orig")))
3433    (set (attr "mode")
3434         (cond [(eq_attr "alternative" "3,4,9,10")
3435                  (const_string "SI")
3436                (eq_attr "alternative" "5")
3437                  (if_then_else
3438                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3439                                  (const_int 0))
3440                              (ne (symbol_ref "TARGET_SSE2")
3441                                  (const_int 0)))
3442                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3443                             (const_int 0)))
3444                    (const_string "TI")
3445                    (const_string "V4SF"))
3446                /* For architectures resolving dependencies on
3447                   whole SSE registers use APS move to break dependency
3448                   chains, otherwise use short move to avoid extra work.
3449
3450                   Do the same for architectures resolving dependencies on
3451                   the parts.  While in DF mode it is better to always handle
3452                   just register parts, the SF mode is different due to lack
3453                   of instructions to load just part of the register.  It is
3454                   better to maintain the whole registers in single format
3455                   to avoid problems on using packed logical operations.  */
3456                (eq_attr "alternative" "6")
3457                  (if_then_else
3458                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3459                             (const_int 0))
3460                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3461                             (const_int 0)))
3462                    (const_string "V4SF")
3463                    (const_string "SF"))
3464                (eq_attr "alternative" "11")
3465                  (const_string "DI")]
3466                (const_string "SF")))])
3467
3468 (define_split
3469   [(set (match_operand 0 "register_operand" "")
3470         (match_operand 1 "memory_operand" ""))]
3471   "reload_completed
3472    && MEM_P (operands[1])
3473    && (GET_MODE (operands[0]) == TFmode
3474        || GET_MODE (operands[0]) == XFmode
3475        || GET_MODE (operands[0]) == DFmode
3476        || GET_MODE (operands[0]) == SFmode)
3477    && (operands[2] = find_constant_src (insn))"
3478   [(set (match_dup 0) (match_dup 2))]
3479 {
3480   rtx c = operands[2];
3481   rtx r = operands[0];
3482
3483   if (GET_CODE (r) == SUBREG)
3484     r = SUBREG_REG (r);
3485
3486   if (SSE_REG_P (r))
3487     {
3488       if (!standard_sse_constant_p (c))
3489         FAIL;
3490     }
3491   else if (FP_REG_P (r))
3492     {
3493       if (!standard_80387_constant_p (c))
3494         FAIL;
3495     }
3496   else if (MMX_REG_P (r))
3497     FAIL;
3498 })
3499
3500 (define_split
3501   [(set (match_operand 0 "register_operand" "")
3502         (float_extend (match_operand 1 "memory_operand" "")))]
3503   "reload_completed
3504    && MEM_P (operands[1])
3505    && (GET_MODE (operands[0]) == TFmode
3506        || GET_MODE (operands[0]) == XFmode
3507        || GET_MODE (operands[0]) == DFmode
3508        || GET_MODE (operands[0]) == SFmode)
3509    && (operands[2] = find_constant_src (insn))"
3510   [(set (match_dup 0) (match_dup 2))]
3511 {
3512   rtx c = operands[2];
3513   rtx r = operands[0];
3514
3515   if (GET_CODE (r) == SUBREG)
3516     r = SUBREG_REG (r);
3517
3518   if (SSE_REG_P (r))
3519     {
3520       if (!standard_sse_constant_p (c))
3521         FAIL;
3522     }
3523   else if (FP_REG_P (r))
3524     {
3525       if (!standard_80387_constant_p (c))
3526         FAIL;
3527     }
3528   else if (MMX_REG_P (r))
3529     FAIL;
3530 })
3531
3532 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3533 (define_split
3534   [(set (match_operand:X87MODEF 0 "register_operand" "")
3535         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3536   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3537    && (standard_80387_constant_p (operands[1]) == 8
3538        || standard_80387_constant_p (operands[1]) == 9)"
3539   [(set (match_dup 0)(match_dup 1))
3540    (set (match_dup 0)
3541         (neg:X87MODEF (match_dup 0)))]
3542 {
3543   REAL_VALUE_TYPE r;
3544
3545   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3546   if (real_isnegzero (&r))
3547     operands[1] = CONST0_RTX (<MODE>mode);
3548   else
3549     operands[1] = CONST1_RTX (<MODE>mode);
3550 })
3551
3552 (define_insn "swapxf"
3553   [(set (match_operand:XF 0 "register_operand" "+f")
3554         (match_operand:XF 1 "register_operand" "+f"))
3555    (set (match_dup 1)
3556         (match_dup 0))]
3557   "TARGET_80387"
3558 {
3559   if (STACK_TOP_P (operands[0]))
3560     return "fxch\t%1";
3561   else
3562     return "fxch\t%0";
3563 }
3564   [(set_attr "type" "fxch")
3565    (set_attr "mode" "XF")])
3566
3567 (define_insn "*swap<mode>"
3568   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3569         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3570    (set (match_dup 1)
3571         (match_dup 0))]
3572   "TARGET_80387 || reload_completed"
3573 {
3574   if (STACK_TOP_P (operands[0]))
3575     return "fxch\t%1";
3576   else
3577     return "fxch\t%0";
3578 }
3579   [(set_attr "type" "fxch")
3580    (set_attr "mode" "<MODE>")])
3581 \f
3582 ;; Zero extension instructions
3583
3584 (define_expand "zero_extendsidi2"
3585   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3586         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3587   ""
3588 {
3589   if (!TARGET_64BIT)
3590     {
3591       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3592       DONE;
3593     }
3594 })
3595
3596 (define_insn "*zero_extendsidi2_rex64"
3597   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3598         (zero_extend:DI
3599          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3600   "TARGET_64BIT"
3601   "@
3602    mov\t{%k1, %k0|%k0, %k1}
3603    #
3604    movd\t{%1, %0|%0, %1}
3605    movd\t{%1, %0|%0, %1}
3606    %vmovd\t{%1, %0|%0, %1}
3607    %vmovd\t{%1, %0|%0, %1}"
3608   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3609    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3610    (set_attr "prefix_0f" "0,*,*,*,*,*")
3611    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3612
3613 (define_split
3614   [(set (match_operand:DI 0 "memory_operand" "")
3615         (zero_extend:DI (match_dup 0)))]
3616   "TARGET_64BIT"
3617   [(set (match_dup 4) (const_int 0))]
3618   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3619
3620 ;; %%% Kill me once multi-word ops are sane.
3621 (define_insn "zero_extendsidi2_1"
3622   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3623         (zero_extend:DI
3624          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3625    (clobber (reg:CC FLAGS_REG))]
3626   "!TARGET_64BIT"
3627   "@
3628    #
3629    #
3630    #
3631    movd\t{%1, %0|%0, %1}
3632    movd\t{%1, %0|%0, %1}
3633    %vmovd\t{%1, %0|%0, %1}
3634    %vmovd\t{%1, %0|%0, %1}"
3635   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3636    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3637    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3638
3639 (define_split
3640   [(set (match_operand:DI 0 "register_operand" "")
3641         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3642    (clobber (reg:CC FLAGS_REG))]
3643   "!TARGET_64BIT && reload_completed
3644    && true_regnum (operands[0]) == true_regnum (operands[1])"
3645   [(set (match_dup 4) (const_int 0))]
3646   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3647
3648 (define_split
3649   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3650         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3651    (clobber (reg:CC FLAGS_REG))]
3652   "!TARGET_64BIT && reload_completed
3653    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3654   [(set (match_dup 3) (match_dup 1))
3655    (set (match_dup 4) (const_int 0))]
3656   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3657
3658 (define_insn "zero_extend<mode>di2"
3659   [(set (match_operand:DI 0 "register_operand" "=r")
3660         (zero_extend:DI
3661          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3662   "TARGET_64BIT"
3663   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3664   [(set_attr "type" "imovx")
3665    (set_attr "mode" "SI")])
3666
3667 (define_expand "zero_extendhisi2"
3668   [(set (match_operand:SI 0 "register_operand" "")
3669         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3670   ""
3671 {
3672   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3673     {
3674       operands[1] = force_reg (HImode, operands[1]);
3675       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3676       DONE;
3677     }
3678 })
3679
3680 (define_insn_and_split "zero_extendhisi2_and"
3681   [(set (match_operand:SI 0 "register_operand" "=r")
3682         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3683    (clobber (reg:CC FLAGS_REG))]
3684   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3685   "#"
3686   "&& reload_completed"
3687   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3688               (clobber (reg:CC FLAGS_REG))])]
3689   ""
3690   [(set_attr "type" "alu1")
3691    (set_attr "mode" "SI")])
3692
3693 (define_insn "*zero_extendhisi2_movzwl"
3694   [(set (match_operand:SI 0 "register_operand" "=r")
3695         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3696   "!TARGET_ZERO_EXTEND_WITH_AND
3697    || optimize_function_for_size_p (cfun)"
3698   "movz{wl|x}\t{%1, %0|%0, %1}"
3699   [(set_attr "type" "imovx")
3700    (set_attr "mode" "SI")])
3701
3702 (define_expand "zero_extendqi<mode>2"
3703   [(parallel
3704     [(set (match_operand:SWI24 0 "register_operand" "")
3705           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3706      (clobber (reg:CC FLAGS_REG))])])
3707
3708 (define_insn "*zero_extendqi<mode>2_and"
3709   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3710         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3711    (clobber (reg:CC FLAGS_REG))]
3712   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3713   "#"
3714   [(set_attr "type" "alu1")
3715    (set_attr "mode" "<MODE>")])
3716
3717 ;; When source and destination does not overlap, clear destination
3718 ;; first and then do the movb
3719 (define_split
3720   [(set (match_operand:SWI24 0 "register_operand" "")
3721         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3722    (clobber (reg:CC FLAGS_REG))]
3723   "reload_completed
3724    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3725    && ANY_QI_REG_P (operands[0])
3726    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3727    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3728   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3729 {
3730   operands[2] = gen_lowpart (QImode, operands[0]);
3731   ix86_expand_clear (operands[0]);
3732 })
3733
3734 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3735   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3736         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3737    (clobber (reg:CC FLAGS_REG))]
3738   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3739   "#"
3740   [(set_attr "type" "imovx,alu1")
3741    (set_attr "mode" "<MODE>")])
3742
3743 ;; For the movzbl case strip only the clobber
3744 (define_split
3745   [(set (match_operand:SWI24 0 "register_operand" "")
3746         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3747    (clobber (reg:CC FLAGS_REG))]
3748   "reload_completed
3749    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3750    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3751   [(set (match_dup 0)
3752         (zero_extend:SWI24 (match_dup 1)))])
3753
3754 ; zero extend to SImode to avoid partial register stalls
3755 (define_insn "*zero_extendqi<mode>2_movzbl"
3756   [(set (match_operand:SWI24 0 "register_operand" "=r")
3757         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3758   "reload_completed
3759    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3760   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3761   [(set_attr "type" "imovx")
3762    (set_attr "mode" "SI")])
3763
3764 ;; Rest is handled by single and.
3765 (define_split
3766   [(set (match_operand:SWI24 0 "register_operand" "")
3767         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3768    (clobber (reg:CC FLAGS_REG))]
3769   "reload_completed
3770    && true_regnum (operands[0]) == true_regnum (operands[1])"
3771   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3772               (clobber (reg:CC FLAGS_REG))])])
3773 \f
3774 ;; Sign extension instructions
3775
3776 (define_expand "extendsidi2"
3777   [(set (match_operand:DI 0 "register_operand" "")
3778         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3779   ""
3780 {
3781   if (!TARGET_64BIT)
3782     {
3783       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3784       DONE;
3785     }
3786 })
3787
3788 (define_insn "*extendsidi2_rex64"
3789   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3790         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3791   "TARGET_64BIT"
3792   "@
3793    {cltq|cdqe}
3794    movs{lq|x}\t{%1, %0|%0, %1}"
3795   [(set_attr "type" "imovx")
3796    (set_attr "mode" "DI")
3797    (set_attr "prefix_0f" "0")
3798    (set_attr "modrm" "0,1")])
3799
3800 (define_insn "extendsidi2_1"
3801   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3802         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3803    (clobber (reg:CC FLAGS_REG))
3804    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3805   "!TARGET_64BIT"
3806   "#")
3807
3808 ;; Extend to memory case when source register does die.
3809 (define_split
3810   [(set (match_operand:DI 0 "memory_operand" "")
3811         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3812    (clobber (reg:CC FLAGS_REG))
3813    (clobber (match_operand:SI 2 "register_operand" ""))]
3814   "(reload_completed
3815     && dead_or_set_p (insn, operands[1])
3816     && !reg_mentioned_p (operands[1], operands[0]))"
3817   [(set (match_dup 3) (match_dup 1))
3818    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3819               (clobber (reg:CC FLAGS_REG))])
3820    (set (match_dup 4) (match_dup 1))]
3821   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3822
3823 ;; Extend to memory case when source register does not die.
3824 (define_split
3825   [(set (match_operand:DI 0 "memory_operand" "")
3826         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3827    (clobber (reg:CC FLAGS_REG))
3828    (clobber (match_operand:SI 2 "register_operand" ""))]
3829   "reload_completed"
3830   [(const_int 0)]
3831 {
3832   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3833
3834   emit_move_insn (operands[3], operands[1]);
3835
3836   /* Generate a cltd if possible and doing so it profitable.  */
3837   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3838       && true_regnum (operands[1]) == AX_REG
3839       && true_regnum (operands[2]) == DX_REG)
3840     {
3841       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3842     }
3843   else
3844     {
3845       emit_move_insn (operands[2], operands[1]);
3846       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3847     }
3848   emit_move_insn (operands[4], operands[2]);
3849   DONE;
3850 })
3851
3852 ;; Extend to register case.  Optimize case where source and destination
3853 ;; registers match and cases where we can use cltd.
3854 (define_split
3855   [(set (match_operand:DI 0 "register_operand" "")
3856         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3857    (clobber (reg:CC FLAGS_REG))
3858    (clobber (match_scratch:SI 2 ""))]
3859   "reload_completed"
3860   [(const_int 0)]
3861 {
3862   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3863
3864   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3865     emit_move_insn (operands[3], operands[1]);
3866
3867   /* Generate a cltd if possible and doing so it profitable.  */
3868   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3869       && true_regnum (operands[3]) == AX_REG
3870       && true_regnum (operands[4]) == DX_REG)
3871     {
3872       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3873       DONE;
3874     }
3875
3876   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3877     emit_move_insn (operands[4], operands[1]);
3878
3879   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3880   DONE;
3881 })
3882
3883 (define_insn "extend<mode>di2"
3884   [(set (match_operand:DI 0 "register_operand" "=r")
3885         (sign_extend:DI
3886          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3887   "TARGET_64BIT"
3888   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3889   [(set_attr "type" "imovx")
3890    (set_attr "mode" "DI")])
3891
3892 (define_insn "extendhisi2"
3893   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3894         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3895   ""
3896 {
3897   switch (get_attr_prefix_0f (insn))
3898     {
3899     case 0:
3900       return "{cwtl|cwde}";
3901     default:
3902       return "movs{wl|x}\t{%1, %0|%0, %1}";
3903     }
3904 }
3905   [(set_attr "type" "imovx")
3906    (set_attr "mode" "SI")
3907    (set (attr "prefix_0f")
3908      ;; movsx is short decodable while cwtl is vector decoded.
3909      (if_then_else (and (eq_attr "cpu" "!k6")
3910                         (eq_attr "alternative" "0"))
3911         (const_string "0")
3912         (const_string "1")))
3913    (set (attr "modrm")
3914      (if_then_else (eq_attr "prefix_0f" "0")
3915         (const_string "0")
3916         (const_string "1")))])
3917
3918 (define_insn "*extendhisi2_zext"
3919   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3920         (zero_extend:DI
3921          (sign_extend:SI
3922           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3923   "TARGET_64BIT"
3924 {
3925   switch (get_attr_prefix_0f (insn))
3926     {
3927     case 0:
3928       return "{cwtl|cwde}";
3929     default:
3930       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3931     }
3932 }
3933   [(set_attr "type" "imovx")
3934    (set_attr "mode" "SI")
3935    (set (attr "prefix_0f")
3936      ;; movsx is short decodable while cwtl is vector decoded.
3937      (if_then_else (and (eq_attr "cpu" "!k6")
3938                         (eq_attr "alternative" "0"))
3939         (const_string "0")
3940         (const_string "1")))
3941    (set (attr "modrm")
3942      (if_then_else (eq_attr "prefix_0f" "0")
3943         (const_string "0")
3944         (const_string "1")))])
3945
3946 (define_insn "extendqisi2"
3947   [(set (match_operand:SI 0 "register_operand" "=r")
3948         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3949   ""
3950   "movs{bl|x}\t{%1, %0|%0, %1}"
3951    [(set_attr "type" "imovx")
3952     (set_attr "mode" "SI")])
3953
3954 (define_insn "*extendqisi2_zext"
3955   [(set (match_operand:DI 0 "register_operand" "=r")
3956         (zero_extend:DI
3957           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3958   "TARGET_64BIT"
3959   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3960    [(set_attr "type" "imovx")
3961     (set_attr "mode" "SI")])
3962
3963 (define_insn "extendqihi2"
3964   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3965         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3966   ""
3967 {
3968   switch (get_attr_prefix_0f (insn))
3969     {
3970     case 0:
3971       return "{cbtw|cbw}";
3972     default:
3973       return "movs{bw|x}\t{%1, %0|%0, %1}";
3974     }
3975 }
3976   [(set_attr "type" "imovx")
3977    (set_attr "mode" "HI")
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 \f
3989 ;; Conversions between float and double.
3990
3991 ;; These are all no-ops in the model used for the 80387.
3992 ;; So just emit moves.
3993
3994 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3995 (define_split
3996   [(set (match_operand:DF 0 "push_operand" "")
3997         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3998   "reload_completed"
3999   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4000    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4001
4002 (define_split
4003   [(set (match_operand:XF 0 "push_operand" "")
4004         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4005   "reload_completed"
4006   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4007    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4008   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4009
4010 (define_expand "extendsfdf2"
4011   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4012         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4013   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4014 {
4015   /* ??? Needed for compress_float_constant since all fp constants
4016      are LEGITIMATE_CONSTANT_P.  */
4017   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4018     {
4019       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4020           && standard_80387_constant_p (operands[1]) > 0)
4021         {
4022           operands[1] = simplify_const_unary_operation
4023             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4024           emit_move_insn_1 (operands[0], operands[1]);
4025           DONE;
4026         }
4027       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4028     }
4029 })
4030
4031 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4032    cvtss2sd:
4033       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4034       cvtps2pd xmm2,xmm1
4035    We do the conversion post reload to avoid producing of 128bit spills
4036    that might lead to ICE on 32bit target.  The sequence unlikely combine
4037    anyway.  */
4038 (define_split
4039   [(set (match_operand:DF 0 "register_operand" "")
4040         (float_extend:DF
4041           (match_operand:SF 1 "nonimmediate_operand" "")))]
4042   "TARGET_USE_VECTOR_FP_CONVERTS
4043    && optimize_insn_for_speed_p ()
4044    && reload_completed && SSE_REG_P (operands[0])"
4045    [(set (match_dup 2)
4046          (float_extend:V2DF
4047            (vec_select:V2SF
4048              (match_dup 3)
4049              (parallel [(const_int 0) (const_int 1)]))))]
4050 {
4051   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4052   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4053   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4054      Try to avoid move when unpacking can be done in source.  */
4055   if (REG_P (operands[1]))
4056     {
4057       /* If it is unsafe to overwrite upper half of source, we need
4058          to move to destination and unpack there.  */
4059       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4060            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4061           && true_regnum (operands[0]) != true_regnum (operands[1]))
4062         {
4063           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4064           emit_move_insn (tmp, operands[1]);
4065         }
4066       else
4067         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4068       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4069                                              operands[3]));
4070     }
4071   else
4072     emit_insn (gen_vec_setv4sf_0 (operands[3],
4073                                   CONST0_RTX (V4SFmode), operands[1]));
4074 })
4075
4076 (define_insn "*extendsfdf2_mixed"
4077   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4078         (float_extend:DF
4079           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4080   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4081 {
4082   switch (which_alternative)
4083     {
4084     case 0:
4085     case 1:
4086       return output_387_reg_move (insn, operands);
4087
4088     case 2:
4089       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4090
4091     default:
4092       gcc_unreachable ();
4093     }
4094 }
4095   [(set_attr "type" "fmov,fmov,ssecvt")
4096    (set_attr "prefix" "orig,orig,maybe_vex")
4097    (set_attr "mode" "SF,XF,DF")])
4098
4099 (define_insn "*extendsfdf2_sse"
4100   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4101         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4102   "TARGET_SSE2 && TARGET_SSE_MATH"
4103   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4104   [(set_attr "type" "ssecvt")
4105    (set_attr "prefix" "maybe_vex")
4106    (set_attr "mode" "DF")])
4107
4108 (define_insn "*extendsfdf2_i387"
4109   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4110         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4111   "TARGET_80387"
4112   "* return output_387_reg_move (insn, operands);"
4113   [(set_attr "type" "fmov")
4114    (set_attr "mode" "SF,XF")])
4115
4116 (define_expand "extend<mode>xf2"
4117   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4118         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4119   "TARGET_80387"
4120 {
4121   /* ??? Needed for compress_float_constant since all fp constants
4122      are LEGITIMATE_CONSTANT_P.  */
4123   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4124     {
4125       if (standard_80387_constant_p (operands[1]) > 0)
4126         {
4127           operands[1] = simplify_const_unary_operation
4128             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4129           emit_move_insn_1 (operands[0], operands[1]);
4130           DONE;
4131         }
4132       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4133     }
4134 })
4135
4136 (define_insn "*extend<mode>xf2_i387"
4137   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4138         (float_extend:XF
4139           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4140   "TARGET_80387"
4141   "* return output_387_reg_move (insn, operands);"
4142   [(set_attr "type" "fmov")
4143    (set_attr "mode" "<MODE>,XF")])
4144
4145 ;; %%% This seems bad bad news.
4146 ;; This cannot output into an f-reg because there is no way to be sure
4147 ;; of truncating in that case.  Otherwise this is just like a simple move
4148 ;; insn.  So we pretend we can output to a reg in order to get better
4149 ;; register preferencing, but we really use a stack slot.
4150
4151 ;; Conversion from DFmode to SFmode.
4152
4153 (define_expand "truncdfsf2"
4154   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4155         (float_truncate:SF
4156           (match_operand:DF 1 "nonimmediate_operand" "")))]
4157   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4158 {
4159   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4160     ;
4161   else if (flag_unsafe_math_optimizations)
4162     ;
4163   else
4164     {
4165       enum ix86_stack_slot slot = (virtuals_instantiated
4166                                    ? SLOT_TEMP
4167                                    : SLOT_VIRTUAL);
4168       rtx temp = assign_386_stack_local (SFmode, slot);
4169       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4170       DONE;
4171     }
4172 })
4173
4174 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4175    cvtsd2ss:
4176       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4177       cvtpd2ps xmm2,xmm1
4178    We do the conversion post reload to avoid producing of 128bit spills
4179    that might lead to ICE on 32bit target.  The sequence unlikely combine
4180    anyway.  */
4181 (define_split
4182   [(set (match_operand:SF 0 "register_operand" "")
4183         (float_truncate:SF
4184           (match_operand:DF 1 "nonimmediate_operand" "")))]
4185   "TARGET_USE_VECTOR_FP_CONVERTS
4186    && optimize_insn_for_speed_p ()
4187    && reload_completed && SSE_REG_P (operands[0])"
4188    [(set (match_dup 2)
4189          (vec_concat:V4SF
4190            (float_truncate:V2SF
4191              (match_dup 4))
4192            (match_dup 3)))]
4193 {
4194   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4195   operands[3] = CONST0_RTX (V2SFmode);
4196   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4197   /* Use movsd for loading from memory, unpcklpd for registers.
4198      Try to avoid move when unpacking can be done in source, or SSE3
4199      movddup is available.  */
4200   if (REG_P (operands[1]))
4201     {
4202       if (!TARGET_SSE3
4203           && true_regnum (operands[0]) != true_regnum (operands[1])
4204           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4205               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4206         {
4207           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4208           emit_move_insn (tmp, operands[1]);
4209           operands[1] = tmp;
4210         }
4211       else if (!TARGET_SSE3)
4212         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4213       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4214     }
4215   else
4216     emit_insn (gen_sse2_loadlpd (operands[4],
4217                                  CONST0_RTX (V2DFmode), operands[1]));
4218 })
4219
4220 (define_expand "truncdfsf2_with_temp"
4221   [(parallel [(set (match_operand:SF 0 "" "")
4222                    (float_truncate:SF (match_operand:DF 1 "" "")))
4223               (clobber (match_operand:SF 2 "" ""))])])
4224
4225 (define_insn "*truncdfsf_fast_mixed"
4226   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4227         (float_truncate:SF
4228           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4229   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4230 {
4231   switch (which_alternative)
4232     {
4233     case 0:
4234       return output_387_reg_move (insn, operands);
4235     case 1:
4236       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4237     default:
4238       gcc_unreachable ();
4239     }
4240 }
4241   [(set_attr "type" "fmov,ssecvt")
4242    (set_attr "prefix" "orig,maybe_vex")
4243    (set_attr "mode" "SF")])
4244
4245 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4246 ;; because nothing we do here is unsafe.
4247 (define_insn "*truncdfsf_fast_sse"
4248   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4249         (float_truncate:SF
4250           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4251   "TARGET_SSE2 && TARGET_SSE_MATH"
4252   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4253   [(set_attr "type" "ssecvt")
4254    (set_attr "prefix" "maybe_vex")
4255    (set_attr "mode" "SF")])
4256
4257 (define_insn "*truncdfsf_fast_i387"
4258   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4259         (float_truncate:SF
4260           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4261   "TARGET_80387 && flag_unsafe_math_optimizations"
4262   "* return output_387_reg_move (insn, operands);"
4263   [(set_attr "type" "fmov")
4264    (set_attr "mode" "SF")])
4265
4266 (define_insn "*truncdfsf_mixed"
4267   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4268         (float_truncate:SF
4269           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4270    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4271   "TARGET_MIX_SSE_I387"
4272 {
4273   switch (which_alternative)
4274     {
4275     case 0:
4276       return output_387_reg_move (insn, operands);
4277     case 1:
4278       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4279
4280     default:
4281       return "#";
4282     }
4283 }
4284   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4285    (set_attr "unit" "*,*,i387,i387,i387")
4286    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4287    (set_attr "mode" "SF")])
4288
4289 (define_insn "*truncdfsf_i387"
4290   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4291         (float_truncate:SF
4292           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4293    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4294   "TARGET_80387"
4295 {
4296   switch (which_alternative)
4297     {
4298     case 0:
4299       return output_387_reg_move (insn, operands);
4300
4301     default:
4302       return "#";
4303     }
4304 }
4305   [(set_attr "type" "fmov,multi,multi,multi")
4306    (set_attr "unit" "*,i387,i387,i387")
4307    (set_attr "mode" "SF")])
4308
4309 (define_insn "*truncdfsf2_i387_1"
4310   [(set (match_operand:SF 0 "memory_operand" "=m")
4311         (float_truncate:SF
4312           (match_operand:DF 1 "register_operand" "f")))]
4313   "TARGET_80387
4314    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4315    && !TARGET_MIX_SSE_I387"
4316   "* return output_387_reg_move (insn, operands);"
4317   [(set_attr "type" "fmov")
4318    (set_attr "mode" "SF")])
4319
4320 (define_split
4321   [(set (match_operand:SF 0 "register_operand" "")
4322         (float_truncate:SF
4323          (match_operand:DF 1 "fp_register_operand" "")))
4324    (clobber (match_operand 2 "" ""))]
4325   "reload_completed"
4326   [(set (match_dup 2) (match_dup 1))
4327    (set (match_dup 0) (match_dup 2))]
4328   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4329
4330 ;; Conversion from XFmode to {SF,DF}mode
4331
4332 (define_expand "truncxf<mode>2"
4333   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4334                    (float_truncate:MODEF
4335                      (match_operand:XF 1 "register_operand" "")))
4336               (clobber (match_dup 2))])]
4337   "TARGET_80387"
4338 {
4339   if (flag_unsafe_math_optimizations)
4340     {
4341       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4342       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4343       if (reg != operands[0])
4344         emit_move_insn (operands[0], reg);
4345       DONE;
4346     }
4347   else
4348     {
4349       enum ix86_stack_slot slot = (virtuals_instantiated
4350                                    ? SLOT_TEMP
4351                                    : SLOT_VIRTUAL);
4352       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4353     }
4354 })
4355
4356 (define_insn "*truncxfsf2_mixed"
4357   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4358         (float_truncate:SF
4359           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4360    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4361   "TARGET_80387"
4362 {
4363   gcc_assert (!which_alternative);
4364   return output_387_reg_move (insn, operands);
4365 }
4366   [(set_attr "type" "fmov,multi,multi,multi")
4367    (set_attr "unit" "*,i387,i387,i387")
4368    (set_attr "mode" "SF")])
4369
4370 (define_insn "*truncxfdf2_mixed"
4371   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4372         (float_truncate:DF
4373           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4374    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4375   "TARGET_80387"
4376 {
4377   gcc_assert (!which_alternative);
4378   return output_387_reg_move (insn, operands);
4379 }
4380   [(set_attr "type" "fmov,multi,multi,multi")
4381    (set_attr "unit" "*,i387,i387,i387")
4382    (set_attr "mode" "DF")])
4383
4384 (define_insn "truncxf<mode>2_i387_noop"
4385   [(set (match_operand:MODEF 0 "register_operand" "=f")
4386         (float_truncate:MODEF
4387           (match_operand:XF 1 "register_operand" "f")))]
4388   "TARGET_80387 && flag_unsafe_math_optimizations"
4389   "* return output_387_reg_move (insn, operands);"
4390   [(set_attr "type" "fmov")
4391    (set_attr "mode" "<MODE>")])
4392
4393 (define_insn "*truncxf<mode>2_i387"
4394   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4395         (float_truncate:MODEF
4396           (match_operand:XF 1 "register_operand" "f")))]
4397   "TARGET_80387"
4398   "* return output_387_reg_move (insn, operands);"
4399   [(set_attr "type" "fmov")
4400    (set_attr "mode" "<MODE>")])
4401
4402 (define_split
4403   [(set (match_operand:MODEF 0 "register_operand" "")
4404         (float_truncate:MODEF
4405           (match_operand:XF 1 "register_operand" "")))
4406    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4407   "TARGET_80387 && reload_completed"
4408   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4409    (set (match_dup 0) (match_dup 2))])
4410
4411 (define_split
4412   [(set (match_operand:MODEF 0 "memory_operand" "")
4413         (float_truncate:MODEF
4414           (match_operand:XF 1 "register_operand" "")))
4415    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4416   "TARGET_80387"
4417   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4418 \f
4419 ;; Signed conversion to DImode.
4420
4421 (define_expand "fix_truncxfdi2"
4422   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4423                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4424               (clobber (reg:CC FLAGS_REG))])]
4425   "TARGET_80387"
4426 {
4427   if (TARGET_FISTTP)
4428    {
4429      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4430      DONE;
4431    }
4432 })
4433
4434 (define_expand "fix_trunc<mode>di2"
4435   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4436                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4437               (clobber (reg:CC FLAGS_REG))])]
4438   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4439 {
4440   if (TARGET_FISTTP
4441       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4442    {
4443      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4444      DONE;
4445    }
4446   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4447    {
4448      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4449      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4450      if (out != operands[0])
4451         emit_move_insn (operands[0], out);
4452      DONE;
4453    }
4454 })
4455
4456 ;; Signed conversion to SImode.
4457
4458 (define_expand "fix_truncxfsi2"
4459   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4460                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4461               (clobber (reg:CC FLAGS_REG))])]
4462   "TARGET_80387"
4463 {
4464   if (TARGET_FISTTP)
4465    {
4466      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4467      DONE;
4468    }
4469 })
4470
4471 (define_expand "fix_trunc<mode>si2"
4472   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4473                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4474               (clobber (reg:CC FLAGS_REG))])]
4475   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4476 {
4477   if (TARGET_FISTTP
4478       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4479    {
4480      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4481      DONE;
4482    }
4483   if (SSE_FLOAT_MODE_P (<MODE>mode))
4484    {
4485      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4486      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4487      if (out != operands[0])
4488         emit_move_insn (operands[0], out);
4489      DONE;
4490    }
4491 })
4492
4493 ;; Signed conversion to HImode.
4494
4495 (define_expand "fix_trunc<mode>hi2"
4496   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4497                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4498               (clobber (reg:CC FLAGS_REG))])]
4499   "TARGET_80387
4500    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4501 {
4502   if (TARGET_FISTTP)
4503    {
4504      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4505      DONE;
4506    }
4507 })
4508
4509 ;; Unsigned conversion to SImode.
4510
4511 (define_expand "fixuns_trunc<mode>si2"
4512   [(parallel
4513     [(set (match_operand:SI 0 "register_operand" "")
4514           (unsigned_fix:SI
4515             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4516      (use (match_dup 2))
4517      (clobber (match_scratch:<ssevecmode> 3 ""))
4518      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4519   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4520 {
4521   enum machine_mode mode = <MODE>mode;
4522   enum machine_mode vecmode = <ssevecmode>mode;
4523   REAL_VALUE_TYPE TWO31r;
4524   rtx two31;
4525
4526   if (optimize_insn_for_size_p ())
4527     FAIL;
4528
4529   real_ldexp (&TWO31r, &dconst1, 31);
4530   two31 = const_double_from_real_value (TWO31r, mode);
4531   two31 = ix86_build_const_vector (vecmode, true, two31);
4532   operands[2] = force_reg (vecmode, two31);
4533 })
4534
4535 (define_insn_and_split "*fixuns_trunc<mode>_1"
4536   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4537         (unsigned_fix:SI
4538           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4539    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4540    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4541    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4542   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4543    && optimize_function_for_speed_p (cfun)"
4544   "#"
4545   "&& reload_completed"
4546   [(const_int 0)]
4547 {
4548   ix86_split_convert_uns_si_sse (operands);
4549   DONE;
4550 })
4551
4552 ;; Unsigned conversion to HImode.
4553 ;; Without these patterns, we'll try the unsigned SI conversion which
4554 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4555
4556 (define_expand "fixuns_trunc<mode>hi2"
4557   [(set (match_dup 2)
4558         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4559    (set (match_operand:HI 0 "nonimmediate_operand" "")
4560         (subreg:HI (match_dup 2) 0))]
4561   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4562   "operands[2] = gen_reg_rtx (SImode);")
4563
4564 ;; When SSE is available, it is always faster to use it!
4565 (define_insn "fix_trunc<mode>di_sse"
4566   [(set (match_operand:DI 0 "register_operand" "=r,r")
4567         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4568   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4569    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4570   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4571   [(set_attr "type" "sseicvt")
4572    (set_attr "prefix" "maybe_vex")
4573    (set_attr "prefix_rex" "1")
4574    (set_attr "mode" "<MODE>")
4575    (set_attr "athlon_decode" "double,vector")
4576    (set_attr "amdfam10_decode" "double,double")
4577    (set_attr "bdver1_decode" "double,double")])
4578
4579 (define_insn "fix_trunc<mode>si_sse"
4580   [(set (match_operand:SI 0 "register_operand" "=r,r")
4581         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4582   "SSE_FLOAT_MODE_P (<MODE>mode)
4583    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4584   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4585   [(set_attr "type" "sseicvt")
4586    (set_attr "prefix" "maybe_vex")
4587    (set_attr "mode" "<MODE>")
4588    (set_attr "athlon_decode" "double,vector")
4589    (set_attr "amdfam10_decode" "double,double")
4590    (set_attr "bdver1_decode" "double,double")])
4591
4592 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4593 (define_peephole2
4594   [(set (match_operand:MODEF 0 "register_operand" "")
4595         (match_operand:MODEF 1 "memory_operand" ""))
4596    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4597         (fix:SSEMODEI24 (match_dup 0)))]
4598   "TARGET_SHORTEN_X87_SSE
4599    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4600    && peep2_reg_dead_p (2, operands[0])"
4601   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4602
4603 ;; Avoid vector decoded forms of the instruction.
4604 (define_peephole2
4605   [(match_scratch:DF 2 "Y2")
4606    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4607         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4608   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4609   [(set (match_dup 2) (match_dup 1))
4610    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4611
4612 (define_peephole2
4613   [(match_scratch:SF 2 "x")
4614    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4615         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4616   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4617   [(set (match_dup 2) (match_dup 1))
4618    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4619
4620 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4621   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4622         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4623   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4624    && TARGET_FISTTP
4625    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4626          && (TARGET_64BIT || <MODE>mode != DImode))
4627         && TARGET_SSE_MATH)
4628    && can_create_pseudo_p ()"
4629   "#"
4630   "&& 1"
4631   [(const_int 0)]
4632 {
4633   if (memory_operand (operands[0], VOIDmode))
4634     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4635   else
4636     {
4637       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4638       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4639                                                             operands[1],
4640                                                             operands[2]));
4641     }
4642   DONE;
4643 }
4644   [(set_attr "type" "fisttp")
4645    (set_attr "mode" "<MODE>")])
4646
4647 (define_insn "fix_trunc<mode>_i387_fisttp"
4648   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4649         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4650    (clobber (match_scratch:XF 2 "=&1f"))]
4651   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652    && TARGET_FISTTP
4653    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4654          && (TARGET_64BIT || <MODE>mode != DImode))
4655         && TARGET_SSE_MATH)"
4656   "* return output_fix_trunc (insn, operands, 1);"
4657   [(set_attr "type" "fisttp")
4658    (set_attr "mode" "<MODE>")])
4659
4660 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4661   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4662         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4663    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4664    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4665   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4666    && TARGET_FISTTP
4667    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4668         && (TARGET_64BIT || <MODE>mode != DImode))
4669         && TARGET_SSE_MATH)"
4670   "#"
4671   [(set_attr "type" "fisttp")
4672    (set_attr "mode" "<MODE>")])
4673
4674 (define_split
4675   [(set (match_operand:X87MODEI 0 "register_operand" "")
4676         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4677    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4678    (clobber (match_scratch 3 ""))]
4679   "reload_completed"
4680   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4681               (clobber (match_dup 3))])
4682    (set (match_dup 0) (match_dup 2))])
4683
4684 (define_split
4685   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4686         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4687    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4688    (clobber (match_scratch 3 ""))]
4689   "reload_completed"
4690   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4691               (clobber (match_dup 3))])])
4692
4693 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4694 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4695 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4696 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4697 ;; function in i386.c.
4698 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4699   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4700         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4701    (clobber (reg:CC FLAGS_REG))]
4702   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4703    && !TARGET_FISTTP
4704    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4705          && (TARGET_64BIT || <MODE>mode != DImode))
4706    && can_create_pseudo_p ()"
4707   "#"
4708   "&& 1"
4709   [(const_int 0)]
4710 {
4711   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4712
4713   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4714   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4715   if (memory_operand (operands[0], VOIDmode))
4716     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4717                                          operands[2], operands[3]));
4718   else
4719     {
4720       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4721       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4722                                                      operands[2], operands[3],
4723                                                      operands[4]));
4724     }
4725   DONE;
4726 }
4727   [(set_attr "type" "fistp")
4728    (set_attr "i387_cw" "trunc")
4729    (set_attr "mode" "<MODE>")])
4730
4731 (define_insn "fix_truncdi_i387"
4732   [(set (match_operand:DI 0 "memory_operand" "=m")
4733         (fix:DI (match_operand 1 "register_operand" "f")))
4734    (use (match_operand:HI 2 "memory_operand" "m"))
4735    (use (match_operand:HI 3 "memory_operand" "m"))
4736    (clobber (match_scratch:XF 4 "=&1f"))]
4737   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4738    && !TARGET_FISTTP
4739    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4740   "* return output_fix_trunc (insn, operands, 0);"
4741   [(set_attr "type" "fistp")
4742    (set_attr "i387_cw" "trunc")
4743    (set_attr "mode" "DI")])
4744
4745 (define_insn "fix_truncdi_i387_with_temp"
4746   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4747         (fix:DI (match_operand 1 "register_operand" "f,f")))
4748    (use (match_operand:HI 2 "memory_operand" "m,m"))
4749    (use (match_operand:HI 3 "memory_operand" "m,m"))
4750    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4751    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4752   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4753    && !TARGET_FISTTP
4754    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4755   "#"
4756   [(set_attr "type" "fistp")
4757    (set_attr "i387_cw" "trunc")
4758    (set_attr "mode" "DI")])
4759
4760 (define_split
4761   [(set (match_operand:DI 0 "register_operand" "")
4762         (fix:DI (match_operand 1 "register_operand" "")))
4763    (use (match_operand:HI 2 "memory_operand" ""))
4764    (use (match_operand:HI 3 "memory_operand" ""))
4765    (clobber (match_operand:DI 4 "memory_operand" ""))
4766    (clobber (match_scratch 5 ""))]
4767   "reload_completed"
4768   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4769               (use (match_dup 2))
4770               (use (match_dup 3))
4771               (clobber (match_dup 5))])
4772    (set (match_dup 0) (match_dup 4))])
4773
4774 (define_split
4775   [(set (match_operand:DI 0 "memory_operand" "")
4776         (fix:DI (match_operand 1 "register_operand" "")))
4777    (use (match_operand:HI 2 "memory_operand" ""))
4778    (use (match_operand:HI 3 "memory_operand" ""))
4779    (clobber (match_operand:DI 4 "memory_operand" ""))
4780    (clobber (match_scratch 5 ""))]
4781   "reload_completed"
4782   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4783               (use (match_dup 2))
4784               (use (match_dup 3))
4785               (clobber (match_dup 5))])])
4786
4787 (define_insn "fix_trunc<mode>_i387"
4788   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4789         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4790    (use (match_operand:HI 2 "memory_operand" "m"))
4791    (use (match_operand:HI 3 "memory_operand" "m"))]
4792   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4793    && !TARGET_FISTTP
4794    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4795   "* return output_fix_trunc (insn, operands, 0);"
4796   [(set_attr "type" "fistp")
4797    (set_attr "i387_cw" "trunc")
4798    (set_attr "mode" "<MODE>")])
4799
4800 (define_insn "fix_trunc<mode>_i387_with_temp"
4801   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4802         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4803    (use (match_operand:HI 2 "memory_operand" "m,m"))
4804    (use (match_operand:HI 3 "memory_operand" "m,m"))
4805    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4806   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4807    && !TARGET_FISTTP
4808    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4809   "#"
4810   [(set_attr "type" "fistp")
4811    (set_attr "i387_cw" "trunc")
4812    (set_attr "mode" "<MODE>")])
4813
4814 (define_split
4815   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4816         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4817    (use (match_operand:HI 2 "memory_operand" ""))
4818    (use (match_operand:HI 3 "memory_operand" ""))
4819    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4820   "reload_completed"
4821   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4822               (use (match_dup 2))
4823               (use (match_dup 3))])
4824    (set (match_dup 0) (match_dup 4))])
4825
4826 (define_split
4827   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4828         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4829    (use (match_operand:HI 2 "memory_operand" ""))
4830    (use (match_operand:HI 3 "memory_operand" ""))
4831    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4832   "reload_completed"
4833   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4834               (use (match_dup 2))
4835               (use (match_dup 3))])])
4836
4837 (define_insn "x86_fnstcw_1"
4838   [(set (match_operand:HI 0 "memory_operand" "=m")
4839         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4840   "TARGET_80387"
4841   "fnstcw\t%0"
4842   [(set (attr "length")
4843         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4844    (set_attr "mode" "HI")
4845    (set_attr "unit" "i387")
4846    (set_attr "bdver1_decode" "vector")])
4847
4848 (define_insn "x86_fldcw_1"
4849   [(set (reg:HI FPCR_REG)
4850         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4851   "TARGET_80387"
4852   "fldcw\t%0"
4853   [(set (attr "length")
4854         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4855    (set_attr "mode" "HI")
4856    (set_attr "unit" "i387")
4857    (set_attr "athlon_decode" "vector")
4858    (set_attr "amdfam10_decode" "vector")
4859    (set_attr "bdver1_decode" "vector")])
4860 \f
4861 ;; Conversion between fixed point and floating point.
4862
4863 ;; Even though we only accept memory inputs, the backend _really_
4864 ;; wants to be able to do this between registers.
4865
4866 (define_expand "floathi<mode>2"
4867   [(set (match_operand:X87MODEF 0 "register_operand" "")
4868         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4869   "TARGET_80387
4870    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4871        || TARGET_MIX_SSE_I387)")
4872
4873 ;; Pre-reload splitter to add memory clobber to the pattern.
4874 (define_insn_and_split "*floathi<mode>2_1"
4875   [(set (match_operand:X87MODEF 0 "register_operand" "")
4876         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4877   "TARGET_80387
4878    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4879        || TARGET_MIX_SSE_I387)
4880    && can_create_pseudo_p ()"
4881   "#"
4882   "&& 1"
4883   [(parallel [(set (match_dup 0)
4884               (float:X87MODEF (match_dup 1)))
4885    (clobber (match_dup 2))])]
4886   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4887
4888 (define_insn "*floathi<mode>2_i387_with_temp"
4889   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4890         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4891   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4892   "TARGET_80387
4893    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4894        || TARGET_MIX_SSE_I387)"
4895   "#"
4896   [(set_attr "type" "fmov,multi")
4897    (set_attr "mode" "<MODE>")
4898    (set_attr "unit" "*,i387")
4899    (set_attr "fp_int_src" "true")])
4900
4901 (define_insn "*floathi<mode>2_i387"
4902   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4903         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4904   "TARGET_80387
4905    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4906        || TARGET_MIX_SSE_I387)"
4907   "fild%Z1\t%1"
4908   [(set_attr "type" "fmov")
4909    (set_attr "mode" "<MODE>")
4910    (set_attr "fp_int_src" "true")])
4911
4912 (define_split
4913   [(set (match_operand:X87MODEF 0 "register_operand" "")
4914         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4915    (clobber (match_operand:HI 2 "memory_operand" ""))]
4916   "TARGET_80387
4917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4918        || TARGET_MIX_SSE_I387)
4919    && reload_completed"
4920   [(set (match_dup 2) (match_dup 1))
4921    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4922
4923 (define_split
4924   [(set (match_operand:X87MODEF 0 "register_operand" "")
4925         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4926    (clobber (match_operand:HI 2 "memory_operand" ""))]
4927    "TARGET_80387
4928     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4929         || TARGET_MIX_SSE_I387)
4930     && reload_completed"
4931   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4932
4933 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4934   [(set (match_operand:X87MODEF 0 "register_operand" "")
4935         (float:X87MODEF
4936           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4937   "TARGET_80387
4938    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4939        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4940 {
4941   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4942         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4943       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4944     {
4945       rtx reg = gen_reg_rtx (XFmode);
4946       rtx insn;
4947
4948       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4949
4950       if (<X87MODEF:MODE>mode == SFmode)
4951         insn = gen_truncxfsf2 (operands[0], reg);
4952       else if (<X87MODEF:MODE>mode == DFmode)
4953         insn = gen_truncxfdf2 (operands[0], reg);
4954       else
4955         gcc_unreachable ();
4956
4957       emit_insn (insn);
4958       DONE;
4959     }
4960 })
4961
4962 ;; Pre-reload splitter to add memory clobber to the pattern.
4963 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4964   [(set (match_operand:X87MODEF 0 "register_operand" "")
4965         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4966   "((TARGET_80387
4967      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4968      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4969            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4970          || TARGET_MIX_SSE_I387))
4971     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4972         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4973         && ((<SSEMODEI24:MODE>mode == SImode
4974              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4975              && optimize_function_for_speed_p (cfun)
4976              && flag_trapping_math)
4977             || !(TARGET_INTER_UNIT_CONVERSIONS
4978                  || optimize_function_for_size_p (cfun)))))
4979    && can_create_pseudo_p ()"
4980   "#"
4981   "&& 1"
4982   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4983               (clobber (match_dup 2))])]
4984 {
4985   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4986
4987   /* Avoid store forwarding (partial memory) stall penalty
4988      by passing DImode value through XMM registers.  */
4989   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4990       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4991       && optimize_function_for_speed_p (cfun))
4992     {
4993       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4994                                                             operands[1],
4995                                                             operands[2]));
4996       DONE;
4997     }
4998 })
4999
5000 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5001   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5002         (float:MODEF
5003           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5004    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5005   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5006    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5007   "#"
5008   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5009    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5010    (set_attr "unit" "*,i387,*,*,*")
5011    (set_attr "athlon_decode" "*,*,double,direct,double")
5012    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5013    (set_attr "bdver1_decode" "*,*,double,direct,double")
5014    (set_attr "fp_int_src" "true")])
5015
5016 (define_insn "*floatsi<mode>2_vector_mixed"
5017   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5018         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5019   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5020    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5021   "@
5022    fild%Z1\t%1
5023    #"
5024   [(set_attr "type" "fmov,sseicvt")
5025    (set_attr "mode" "<MODE>,<ssevecmode>")
5026    (set_attr "unit" "i387,*")
5027    (set_attr "athlon_decode" "*,direct")
5028    (set_attr "amdfam10_decode" "*,double")
5029    (set_attr "bdver1_decode" "*,direct")
5030    (set_attr "fp_int_src" "true")])
5031
5032 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5033   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5034         (float:MODEF
5035           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5036   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5037   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5038    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5039   "#"
5040   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5041    (set_attr "mode" "<MODEF:MODE>")
5042    (set_attr "unit" "*,i387,*,*")
5043    (set_attr "athlon_decode" "*,*,double,direct")
5044    (set_attr "amdfam10_decode" "*,*,vector,double")
5045    (set_attr "bdver1_decode" "*,*,double,direct")
5046    (set_attr "fp_int_src" "true")])
5047
5048 (define_split
5049   [(set (match_operand:MODEF 0 "register_operand" "")
5050         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5051    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5052   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5053    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5054    && TARGET_INTER_UNIT_CONVERSIONS
5055    && reload_completed
5056    && (SSE_REG_P (operands[0])
5057        || (GET_CODE (operands[0]) == SUBREG
5058            && SSE_REG_P (operands[0])))"
5059   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5060
5061 (define_split
5062   [(set (match_operand:MODEF 0 "register_operand" "")
5063         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5064    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5065   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5066    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5067    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5068    && reload_completed
5069    && (SSE_REG_P (operands[0])
5070        || (GET_CODE (operands[0]) == SUBREG
5071            && SSE_REG_P (operands[0])))"
5072   [(set (match_dup 2) (match_dup 1))
5073    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5074
5075 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5076   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5077         (float:MODEF
5078           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5079   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5080    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5081    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5082   "@
5083    fild%Z1\t%1
5084    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5085    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5086   [(set_attr "type" "fmov,sseicvt,sseicvt")
5087    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5088    (set_attr "mode" "<MODEF:MODE>")
5089    (set (attr "prefix_rex")
5090      (if_then_else
5091        (and (eq_attr "prefix" "maybe_vex")
5092             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5093        (const_string "1")
5094        (const_string "*")))
5095    (set_attr "unit" "i387,*,*")
5096    (set_attr "athlon_decode" "*,double,direct")
5097    (set_attr "amdfam10_decode" "*,vector,double")
5098    (set_attr "bdver1_decode" "*,double,direct")
5099    (set_attr "fp_int_src" "true")])
5100
5101 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5102   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5103         (float:MODEF
5104           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5105   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5106    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5107    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5108   "@
5109    fild%Z1\t%1
5110    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5111   [(set_attr "type" "fmov,sseicvt")
5112    (set_attr "prefix" "orig,maybe_vex")
5113    (set_attr "mode" "<MODEF:MODE>")
5114    (set (attr "prefix_rex")
5115      (if_then_else
5116        (and (eq_attr "prefix" "maybe_vex")
5117             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5118        (const_string "1")
5119        (const_string "*")))
5120    (set_attr "athlon_decode" "*,direct")
5121    (set_attr "amdfam10_decode" "*,double")
5122    (set_attr "bdver1_decode" "*,direct")
5123    (set_attr "fp_int_src" "true")])
5124
5125 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5126   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5127         (float:MODEF
5128           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5129    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5130   "TARGET_SSE2 && TARGET_SSE_MATH
5131    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5132   "#"
5133   [(set_attr "type" "sseicvt")
5134    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5135    (set_attr "athlon_decode" "double,direct,double")
5136    (set_attr "amdfam10_decode" "vector,double,double")
5137    (set_attr "bdver1_decode" "double,direct,double")
5138    (set_attr "fp_int_src" "true")])
5139
5140 (define_insn "*floatsi<mode>2_vector_sse"
5141   [(set (match_operand:MODEF 0 "register_operand" "=x")
5142         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5143   "TARGET_SSE2 && TARGET_SSE_MATH
5144    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5145   "#"
5146   [(set_attr "type" "sseicvt")
5147    (set_attr "mode" "<MODE>")
5148    (set_attr "athlon_decode" "direct")
5149    (set_attr "amdfam10_decode" "double")
5150    (set_attr "bdver1_decode" "direct")
5151    (set_attr "fp_int_src" "true")])
5152
5153 (define_split
5154   [(set (match_operand:MODEF 0 "register_operand" "")
5155         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5156    (clobber (match_operand:SI 2 "memory_operand" ""))]
5157   "TARGET_SSE2 && TARGET_SSE_MATH
5158    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5159    && reload_completed
5160    && (SSE_REG_P (operands[0])
5161        || (GET_CODE (operands[0]) == SUBREG
5162            && SSE_REG_P (operands[0])))"
5163   [(const_int 0)]
5164 {
5165   rtx op1 = operands[1];
5166
5167   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5168                                      <MODE>mode, 0);
5169   if (GET_CODE (op1) == SUBREG)
5170     op1 = SUBREG_REG (op1);
5171
5172   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5173     {
5174       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5175       emit_insn (gen_sse2_loadld (operands[4],
5176                                   CONST0_RTX (V4SImode), operands[1]));
5177     }
5178   /* We can ignore possible trapping value in the
5179      high part of SSE register for non-trapping math. */
5180   else if (SSE_REG_P (op1) && !flag_trapping_math)
5181     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5182   else
5183     {
5184       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5185       emit_move_insn (operands[2], operands[1]);
5186       emit_insn (gen_sse2_loadld (operands[4],
5187                                   CONST0_RTX (V4SImode), operands[2]));
5188     }
5189   emit_insn
5190     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5191   DONE;
5192 })
5193
5194 (define_split
5195   [(set (match_operand:MODEF 0 "register_operand" "")
5196         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5197    (clobber (match_operand:SI 2 "memory_operand" ""))]
5198   "TARGET_SSE2 && TARGET_SSE_MATH
5199    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5200    && reload_completed
5201    && (SSE_REG_P (operands[0])
5202        || (GET_CODE (operands[0]) == SUBREG
5203            && SSE_REG_P (operands[0])))"
5204   [(const_int 0)]
5205 {
5206   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5207                                      <MODE>mode, 0);
5208   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5209
5210   emit_insn (gen_sse2_loadld (operands[4],
5211                               CONST0_RTX (V4SImode), operands[1]));
5212   emit_insn
5213     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5214   DONE;
5215 })
5216
5217 (define_split
5218   [(set (match_operand:MODEF 0 "register_operand" "")
5219         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5220   "TARGET_SSE2 && TARGET_SSE_MATH
5221    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5222    && reload_completed
5223    && (SSE_REG_P (operands[0])
5224        || (GET_CODE (operands[0]) == SUBREG
5225            && SSE_REG_P (operands[0])))"
5226   [(const_int 0)]
5227 {
5228   rtx op1 = operands[1];
5229
5230   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5231                                      <MODE>mode, 0);
5232   if (GET_CODE (op1) == SUBREG)
5233     op1 = SUBREG_REG (op1);
5234
5235   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5236     {
5237       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5238       emit_insn (gen_sse2_loadld (operands[4],
5239                                   CONST0_RTX (V4SImode), operands[1]));
5240     }
5241   /* We can ignore possible trapping value in the
5242      high part of SSE register for non-trapping math. */
5243   else if (SSE_REG_P (op1) && !flag_trapping_math)
5244     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5245   else
5246     gcc_unreachable ();
5247   emit_insn
5248     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5249   DONE;
5250 })
5251
5252 (define_split
5253   [(set (match_operand:MODEF 0 "register_operand" "")
5254         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5255   "TARGET_SSE2 && TARGET_SSE_MATH
5256    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5257    && reload_completed
5258    && (SSE_REG_P (operands[0])
5259        || (GET_CODE (operands[0]) == SUBREG
5260            && SSE_REG_P (operands[0])))"
5261   [(const_int 0)]
5262 {
5263   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5264                                      <MODE>mode, 0);
5265   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5266
5267   emit_insn (gen_sse2_loadld (operands[4],
5268                               CONST0_RTX (V4SImode), operands[1]));
5269   emit_insn
5270     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5271   DONE;
5272 })
5273
5274 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5275   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5276         (float:MODEF
5277           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5278   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5279   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5280    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5281   "#"
5282   [(set_attr "type" "sseicvt")
5283    (set_attr "mode" "<MODEF:MODE>")
5284    (set_attr "athlon_decode" "double,direct")
5285    (set_attr "amdfam10_decode" "vector,double")
5286    (set_attr "bdver1_decode" "double,direct")
5287    (set_attr "fp_int_src" "true")])
5288
5289 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5290   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5291         (float:MODEF
5292           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5293   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5294    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5295    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5296   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5297   [(set_attr "type" "sseicvt")
5298    (set_attr "prefix" "maybe_vex")
5299    (set_attr "mode" "<MODEF:MODE>")
5300    (set (attr "prefix_rex")
5301      (if_then_else
5302        (and (eq_attr "prefix" "maybe_vex")
5303             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5304        (const_string "1")
5305        (const_string "*")))
5306    (set_attr "athlon_decode" "double,direct")
5307    (set_attr "amdfam10_decode" "vector,double")
5308    (set_attr "bdver1_decode" "double,direct")
5309    (set_attr "fp_int_src" "true")])
5310
5311 (define_split
5312   [(set (match_operand:MODEF 0 "register_operand" "")
5313         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5314    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5315   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5316    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5317    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5318    && reload_completed
5319    && (SSE_REG_P (operands[0])
5320        || (GET_CODE (operands[0]) == SUBREG
5321            && SSE_REG_P (operands[0])))"
5322   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5323
5324 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5325   [(set (match_operand:MODEF 0 "register_operand" "=x")
5326         (float:MODEF
5327           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5328   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5329    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5330    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5331   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5332   [(set_attr "type" "sseicvt")
5333    (set_attr "prefix" "maybe_vex")
5334    (set_attr "mode" "<MODEF:MODE>")
5335    (set (attr "prefix_rex")
5336      (if_then_else
5337        (and (eq_attr "prefix" "maybe_vex")
5338             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5339        (const_string "1")
5340        (const_string "*")))
5341    (set_attr "athlon_decode" "direct")
5342    (set_attr "amdfam10_decode" "double")
5343    (set_attr "bdver1_decode" "direct")
5344    (set_attr "fp_int_src" "true")])
5345
5346 (define_split
5347   [(set (match_operand:MODEF 0 "register_operand" "")
5348         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5349    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5350   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5351    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5352    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5353    && reload_completed
5354    && (SSE_REG_P (operands[0])
5355        || (GET_CODE (operands[0]) == SUBREG
5356            && SSE_REG_P (operands[0])))"
5357   [(set (match_dup 2) (match_dup 1))
5358    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5359
5360 (define_split
5361   [(set (match_operand:MODEF 0 "register_operand" "")
5362         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5363    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5364   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5366    && reload_completed
5367    && (SSE_REG_P (operands[0])
5368        || (GET_CODE (operands[0]) == SUBREG
5369            && SSE_REG_P (operands[0])))"
5370   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5371
5372 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5373   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5374         (float:X87MODEF
5375           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5376   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5377   "TARGET_80387
5378    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5379   "@
5380    fild%Z1\t%1
5381    #"
5382   [(set_attr "type" "fmov,multi")
5383    (set_attr "mode" "<X87MODEF:MODE>")
5384    (set_attr "unit" "*,i387")
5385    (set_attr "fp_int_src" "true")])
5386
5387 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5388   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5389         (float:X87MODEF
5390           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5391   "TARGET_80387
5392    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5393   "fild%Z1\t%1"
5394   [(set_attr "type" "fmov")
5395    (set_attr "mode" "<X87MODEF:MODE>")
5396    (set_attr "fp_int_src" "true")])
5397
5398 (define_split
5399   [(set (match_operand:X87MODEF 0 "register_operand" "")
5400         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5401    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5402   "TARGET_80387
5403    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5404    && reload_completed
5405    && FP_REG_P (operands[0])"
5406   [(set (match_dup 2) (match_dup 1))
5407    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5408
5409 (define_split
5410   [(set (match_operand:X87MODEF 0 "register_operand" "")
5411         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5412    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5413   "TARGET_80387
5414    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5415    && reload_completed
5416    && FP_REG_P (operands[0])"
5417   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5418
5419 ;; Avoid store forwarding (partial memory) stall penalty
5420 ;; by passing DImode value through XMM registers.  */
5421
5422 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5423   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5424         (float:X87MODEF
5425           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5426    (clobber (match_scratch:V4SI 3 "=X,x"))
5427    (clobber (match_scratch:V4SI 4 "=X,x"))
5428    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5429   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5430    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5431    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5432   "#"
5433   [(set_attr "type" "multi")
5434    (set_attr "mode" "<X87MODEF:MODE>")
5435    (set_attr "unit" "i387")
5436    (set_attr "fp_int_src" "true")])
5437
5438 (define_split
5439   [(set (match_operand:X87MODEF 0 "register_operand" "")
5440         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5441    (clobber (match_scratch:V4SI 3 ""))
5442    (clobber (match_scratch:V4SI 4 ""))
5443    (clobber (match_operand:DI 2 "memory_operand" ""))]
5444   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5445    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5446    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5447    && reload_completed
5448    && FP_REG_P (operands[0])"
5449   [(set (match_dup 2) (match_dup 3))
5450    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5451 {
5452   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5453      Assemble the 64-bit DImode value in an xmm register.  */
5454   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5455                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5456   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5457                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5458   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5459                                          operands[4]));
5460
5461   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5462 })
5463
5464 (define_split
5465   [(set (match_operand:X87MODEF 0 "register_operand" "")
5466         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5467    (clobber (match_scratch:V4SI 3 ""))
5468    (clobber (match_scratch:V4SI 4 ""))
5469    (clobber (match_operand:DI 2 "memory_operand" ""))]
5470   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5471    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5472    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5473    && reload_completed
5474    && FP_REG_P (operands[0])"
5475   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5476
5477 ;; Avoid store forwarding (partial memory) stall penalty by extending
5478 ;; SImode value to DImode through XMM register instead of pushing two
5479 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5480 ;; targets benefit from this optimization. Also note that fild
5481 ;; loads from memory only.
5482
5483 (define_insn "*floatunssi<mode>2_1"
5484   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5485         (unsigned_float:X87MODEF
5486           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5487    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5488    (clobber (match_scratch:SI 3 "=X,x"))]
5489   "!TARGET_64BIT
5490    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5491    && TARGET_SSE"
5492   "#"
5493   [(set_attr "type" "multi")
5494    (set_attr "mode" "<MODE>")])
5495
5496 (define_split
5497   [(set (match_operand:X87MODEF 0 "register_operand" "")
5498         (unsigned_float:X87MODEF
5499           (match_operand:SI 1 "register_operand" "")))
5500    (clobber (match_operand:DI 2 "memory_operand" ""))
5501    (clobber (match_scratch:SI 3 ""))]
5502   "!TARGET_64BIT
5503    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5504    && TARGET_SSE
5505    && reload_completed"
5506   [(set (match_dup 2) (match_dup 1))
5507    (set (match_dup 0)
5508         (float:X87MODEF (match_dup 2)))]
5509   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5510
5511 (define_split
5512   [(set (match_operand:X87MODEF 0 "register_operand" "")
5513         (unsigned_float:X87MODEF
5514           (match_operand:SI 1 "memory_operand" "")))
5515    (clobber (match_operand:DI 2 "memory_operand" ""))
5516    (clobber (match_scratch:SI 3 ""))]
5517   "!TARGET_64BIT
5518    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5519    && TARGET_SSE
5520    && reload_completed"
5521   [(set (match_dup 2) (match_dup 3))
5522    (set (match_dup 0)
5523         (float:X87MODEF (match_dup 2)))]
5524 {
5525   emit_move_insn (operands[3], operands[1]);
5526   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5527 })
5528
5529 (define_expand "floatunssi<mode>2"
5530   [(parallel
5531      [(set (match_operand:X87MODEF 0 "register_operand" "")
5532            (unsigned_float:X87MODEF
5533              (match_operand:SI 1 "nonimmediate_operand" "")))
5534       (clobber (match_dup 2))
5535       (clobber (match_scratch:SI 3 ""))])]
5536   "!TARGET_64BIT
5537    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5538         && TARGET_SSE)
5539        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5540 {
5541   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5542     {
5543       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5544       DONE;
5545     }
5546   else
5547     {
5548       enum ix86_stack_slot slot = (virtuals_instantiated
5549                                    ? SLOT_TEMP
5550                                    : SLOT_VIRTUAL);
5551       operands[2] = assign_386_stack_local (DImode, slot);
5552     }
5553 })
5554
5555 (define_expand "floatunsdisf2"
5556   [(use (match_operand:SF 0 "register_operand" ""))
5557    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5558   "TARGET_64BIT && TARGET_SSE_MATH"
5559   "x86_emit_floatuns (operands); DONE;")
5560
5561 (define_expand "floatunsdidf2"
5562   [(use (match_operand:DF 0 "register_operand" ""))
5563    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5564   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5565    && TARGET_SSE2 && TARGET_SSE_MATH"
5566 {
5567   if (TARGET_64BIT)
5568     x86_emit_floatuns (operands);
5569   else
5570     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5571   DONE;
5572 })
5573 \f
5574 ;; Add instructions
5575
5576 (define_expand "add<mode>3"
5577   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5578         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5579                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5580   ""
5581   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5582
5583 (define_insn_and_split "*add<dwi>3_doubleword"
5584   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5585         (plus:<DWI>
5586           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5587           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5588    (clobber (reg:CC FLAGS_REG))]
5589   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5590   "#"
5591   "reload_completed"
5592   [(parallel [(set (reg:CC FLAGS_REG)
5593                    (unspec:CC [(match_dup 1) (match_dup 2)]
5594                               UNSPEC_ADD_CARRY))
5595               (set (match_dup 0)
5596                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5597    (parallel [(set (match_dup 3)
5598                    (plus:DWIH
5599                      (match_dup 4)
5600                      (plus:DWIH
5601                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5602                        (match_dup 5))))
5603               (clobber (reg:CC FLAGS_REG))])]
5604   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5605
5606 (define_insn "*add<mode>3_cc"
5607   [(set (reg:CC FLAGS_REG)
5608         (unspec:CC
5609           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5610            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5611           UNSPEC_ADD_CARRY))
5612    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5613         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5614   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5615   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5616   [(set_attr "type" "alu")
5617    (set_attr "mode" "<MODE>")])
5618
5619 (define_insn "addqi3_cc"
5620   [(set (reg:CC FLAGS_REG)
5621         (unspec:CC
5622           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5623            (match_operand:QI 2 "general_operand" "qn,qm")]
5624           UNSPEC_ADD_CARRY))
5625    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5626         (plus:QI (match_dup 1) (match_dup 2)))]
5627   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5628   "add{b}\t{%2, %0|%0, %2}"
5629   [(set_attr "type" "alu")
5630    (set_attr "mode" "QI")])
5631
5632 (define_insn "*lea_1"
5633   [(set (match_operand:P 0 "register_operand" "=r")
5634         (match_operand:P 1 "no_seg_address_operand" "p"))]
5635   ""
5636   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5637   [(set_attr "type" "lea")
5638    (set_attr "mode" "<MODE>")])
5639
5640 (define_insn "*lea_2"
5641   [(set (match_operand:SI 0 "register_operand" "=r")
5642         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5643   "TARGET_64BIT"
5644   "lea{l}\t{%a1, %0|%0, %a1}"
5645   [(set_attr "type" "lea")
5646    (set_attr "mode" "SI")])
5647
5648 (define_insn "*lea_2_zext"
5649   [(set (match_operand:DI 0 "register_operand" "=r")
5650         (zero_extend:DI
5651           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5652   "TARGET_64BIT"
5653   "lea{l}\t{%a1, %k0|%k0, %a1}"
5654   [(set_attr "type" "lea")
5655    (set_attr "mode" "SI")])
5656
5657 (define_insn "*add<mode>_1"
5658   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5659         (plus:SWI48
5660           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5661           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5662    (clobber (reg:CC FLAGS_REG))]
5663   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5664 {
5665   switch (get_attr_type (insn))
5666     {
5667     case TYPE_LEA:
5668       return "#";
5669
5670     case TYPE_INCDEC:
5671       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5672       if (operands[2] == const1_rtx)
5673         return "inc{<imodesuffix>}\t%0";
5674       else
5675         {
5676           gcc_assert (operands[2] == constm1_rtx);
5677           return "dec{<imodesuffix>}\t%0";
5678         }
5679
5680     default:
5681       /* For most processors, ADD is faster than LEA.  This alternative
5682          was added to use ADD as much as possible.  */
5683       if (which_alternative == 2)
5684         {
5685           rtx tmp;
5686           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5687         }
5688         
5689       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5690       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5691         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5692
5693       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5694     }
5695 }
5696   [(set (attr "type")
5697      (cond [(eq_attr "alternative" "3")
5698               (const_string "lea")
5699             (match_operand:SWI48 2 "incdec_operand" "")
5700               (const_string "incdec")
5701            ]
5702            (const_string "alu")))
5703    (set (attr "length_immediate")
5704       (if_then_else
5705         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5706         (const_string "1")
5707         (const_string "*")))
5708    (set_attr "mode" "<MODE>")])
5709
5710 ;; It may seem that nonimmediate operand is proper one for operand 1.
5711 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5712 ;; we take care in ix86_binary_operator_ok to not allow two memory
5713 ;; operands so proper swapping will be done in reload.  This allow
5714 ;; patterns constructed from addsi_1 to match.
5715
5716 (define_insn "*addsi_1_zext"
5717   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5718         (zero_extend:DI
5719           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5720                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5721    (clobber (reg:CC FLAGS_REG))]
5722   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5723 {
5724   switch (get_attr_type (insn))
5725     {
5726     case TYPE_LEA:
5727       return "#";
5728
5729     case TYPE_INCDEC:
5730       if (operands[2] == const1_rtx)
5731         return "inc{l}\t%k0";
5732       else
5733         {
5734           gcc_assert (operands[2] == constm1_rtx);
5735           return "dec{l}\t%k0";
5736         }
5737
5738     default:
5739       /* For most processors, ADD is faster than LEA.  This alternative
5740          was added to use ADD as much as possible.  */
5741       if (which_alternative == 1)
5742         {
5743           rtx tmp;
5744           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5745         }
5746
5747       if (x86_maybe_negate_const_int (&operands[2], SImode))
5748         return "sub{l}\t{%2, %k0|%k0, %2}";
5749
5750       return "add{l}\t{%2, %k0|%k0, %2}";
5751     }
5752 }
5753   [(set (attr "type")
5754      (cond [(eq_attr "alternative" "2")
5755               (const_string "lea")
5756             (match_operand:SI 2 "incdec_operand" "")
5757               (const_string "incdec")
5758            ]
5759            (const_string "alu")))
5760    (set (attr "length_immediate")
5761       (if_then_else
5762         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5763         (const_string "1")
5764         (const_string "*")))
5765    (set_attr "mode" "SI")])
5766
5767 (define_insn "*addhi_1"
5768   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5769         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5770                  (match_operand:HI 2 "general_operand" "rn,rm")))
5771    (clobber (reg:CC FLAGS_REG))]
5772   "TARGET_PARTIAL_REG_STALL
5773    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5774 {
5775   switch (get_attr_type (insn))
5776     {
5777     case TYPE_INCDEC:
5778       if (operands[2] == const1_rtx)
5779         return "inc{w}\t%0";
5780       else
5781         {
5782           gcc_assert (operands[2] == constm1_rtx);
5783           return "dec{w}\t%0";
5784         }
5785
5786     default:
5787       if (x86_maybe_negate_const_int (&operands[2], HImode))
5788         return "sub{w}\t{%2, %0|%0, %2}";
5789
5790       return "add{w}\t{%2, %0|%0, %2}";
5791     }
5792 }
5793   [(set (attr "type")
5794      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5795         (const_string "incdec")
5796         (const_string "alu")))
5797    (set (attr "length_immediate")
5798       (if_then_else
5799         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5800         (const_string "1")
5801         (const_string "*")))
5802    (set_attr "mode" "HI")])
5803
5804 (define_insn "*addhi_1_lea"
5805   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5806         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5807                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5808    (clobber (reg:CC FLAGS_REG))]
5809   "!TARGET_PARTIAL_REG_STALL
5810    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5811 {
5812   switch (get_attr_type (insn))
5813     {
5814     case TYPE_LEA:
5815       return "#";
5816
5817     case TYPE_INCDEC:
5818       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5819       if (operands[2] == const1_rtx)
5820         return "inc{w}\t%0";
5821       else
5822         {
5823           gcc_assert (operands[2] == constm1_rtx);
5824           return "dec{w}\t%0";
5825         }
5826
5827     default:
5828       /* For most processors, ADD is faster than LEA.  This alternative
5829          was added to use ADD as much as possible.  */
5830       if (which_alternative == 2)
5831         {
5832           rtx tmp;
5833           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5834         }
5835
5836       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5837       if (x86_maybe_negate_const_int (&operands[2], HImode))
5838         return "sub{w}\t{%2, %0|%0, %2}";
5839
5840       return "add{w}\t{%2, %0|%0, %2}";
5841     }
5842 }
5843   [(set (attr "type")
5844      (cond [(eq_attr "alternative" "3")
5845               (const_string "lea")
5846             (match_operand:HI 2 "incdec_operand" "")
5847               (const_string "incdec")
5848            ]
5849            (const_string "alu")))
5850    (set (attr "length_immediate")
5851       (if_then_else
5852         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5853         (const_string "1")
5854         (const_string "*")))
5855    (set_attr "mode" "HI,HI,HI,SI")])
5856
5857 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5858 (define_insn "*addqi_1"
5859   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5860         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5861                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5862    (clobber (reg:CC FLAGS_REG))]
5863   "TARGET_PARTIAL_REG_STALL
5864    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5865 {
5866   int widen = (which_alternative == 2);
5867   switch (get_attr_type (insn))
5868     {
5869     case TYPE_INCDEC:
5870       if (operands[2] == const1_rtx)
5871         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5872       else
5873         {
5874           gcc_assert (operands[2] == constm1_rtx);
5875           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5876         }
5877
5878     default:
5879       if (x86_maybe_negate_const_int (&operands[2], QImode))
5880         {
5881           if (widen)
5882             return "sub{l}\t{%2, %k0|%k0, %2}";
5883           else
5884             return "sub{b}\t{%2, %0|%0, %2}";
5885         }
5886       if (widen)
5887         return "add{l}\t{%k2, %k0|%k0, %k2}";
5888       else
5889         return "add{b}\t{%2, %0|%0, %2}";
5890     }
5891 }
5892   [(set (attr "type")
5893      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5894         (const_string "incdec")
5895         (const_string "alu")))
5896    (set (attr "length_immediate")
5897       (if_then_else
5898         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5899         (const_string "1")
5900         (const_string "*")))
5901    (set_attr "mode" "QI,QI,SI")])
5902
5903 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5904 (define_insn "*addqi_1_lea"
5905   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5906         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5907                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5908    (clobber (reg:CC FLAGS_REG))]
5909   "!TARGET_PARTIAL_REG_STALL
5910    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5911 {
5912   int widen = (which_alternative == 3 || which_alternative == 4);
5913
5914   switch (get_attr_type (insn))
5915     {
5916     case TYPE_LEA:
5917       return "#";
5918
5919     case TYPE_INCDEC:
5920       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5921       if (operands[2] == const1_rtx)
5922         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5923       else
5924         {
5925           gcc_assert (operands[2] == constm1_rtx);
5926           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5927         }
5928
5929     default:
5930       /* For most processors, ADD is faster than LEA.  These alternatives
5931          were added to use ADD as much as possible.  */
5932       if (which_alternative == 2 || which_alternative == 4)
5933         {
5934           rtx tmp;
5935           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5936         }
5937
5938       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5939       if (x86_maybe_negate_const_int (&operands[2], QImode))
5940         {
5941           if (widen)
5942             return "sub{l}\t{%2, %k0|%k0, %2}";
5943           else
5944             return "sub{b}\t{%2, %0|%0, %2}";
5945         }
5946       if (widen)
5947         return "add{l}\t{%k2, %k0|%k0, %k2}";
5948       else
5949         return "add{b}\t{%2, %0|%0, %2}";
5950     }
5951 }
5952   [(set (attr "type")
5953      (cond [(eq_attr "alternative" "5")
5954               (const_string "lea")
5955             (match_operand:QI 2 "incdec_operand" "")
5956               (const_string "incdec")
5957            ]
5958            (const_string "alu")))
5959    (set (attr "length_immediate")
5960       (if_then_else
5961         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5962         (const_string "1")
5963         (const_string "*")))
5964    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5965
5966 (define_insn "*addqi_1_slp"
5967   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5968         (plus:QI (match_dup 0)
5969                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5970    (clobber (reg:CC FLAGS_REG))]
5971   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5972    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5973 {
5974   switch (get_attr_type (insn))
5975     {
5976     case TYPE_INCDEC:
5977       if (operands[1] == const1_rtx)
5978         return "inc{b}\t%0";
5979       else
5980         {
5981           gcc_assert (operands[1] == constm1_rtx);
5982           return "dec{b}\t%0";
5983         }
5984
5985     default:
5986       if (x86_maybe_negate_const_int (&operands[1], QImode))
5987         return "sub{b}\t{%1, %0|%0, %1}";
5988
5989       return "add{b}\t{%1, %0|%0, %1}";
5990     }
5991 }
5992   [(set (attr "type")
5993      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5994         (const_string "incdec")
5995         (const_string "alu1")))
5996    (set (attr "memory")
5997      (if_then_else (match_operand 1 "memory_operand" "")
5998         (const_string "load")
5999         (const_string "none")))
6000    (set_attr "mode" "QI")])
6001
6002 ;; Convert lea to the lea pattern to avoid flags dependency.
6003 (define_split
6004   [(set (match_operand 0 "register_operand" "")
6005         (plus (match_operand 1 "register_operand" "")
6006               (match_operand 2 "nonmemory_operand" "")))
6007    (clobber (reg:CC FLAGS_REG))]
6008   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6009   [(const_int 0)]
6010 {
6011   rtx pat;
6012   enum machine_mode mode = GET_MODE (operands[0]);
6013
6014   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6015      may confuse gen_lowpart.  */
6016   if (mode != Pmode)
6017     {
6018       operands[1] = gen_lowpart (Pmode, operands[1]);
6019       operands[2] = gen_lowpart (Pmode, operands[2]);
6020     }
6021
6022   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6023
6024   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6025     operands[0] = gen_lowpart (SImode, operands[0]);
6026
6027   if (TARGET_64BIT && mode != Pmode)
6028     pat = gen_rtx_SUBREG (SImode, pat, 0);
6029
6030   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6031   DONE;
6032 })
6033
6034 ;; Convert lea to the lea pattern to avoid flags dependency.
6035 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6036 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6037 (define_split
6038   [(set (match_operand:DI 0 "register_operand" "")
6039         (plus:DI (match_operand:DI 1 "register_operand" "")
6040                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6041    (clobber (reg:CC FLAGS_REG))]
6042   "TARGET_64BIT && reload_completed 
6043    && true_regnum (operands[0]) != true_regnum (operands[1])"
6044   [(set (match_dup 0)
6045         (plus:DI (match_dup 1) (match_dup 2)))])
6046
6047 ;; Convert lea to the lea pattern to avoid flags dependency.
6048 (define_split
6049   [(set (match_operand:DI 0 "register_operand" "")
6050         (zero_extend:DI
6051           (plus:SI (match_operand:SI 1 "register_operand" "")
6052                    (match_operand:SI 2 "nonmemory_operand" ""))))
6053    (clobber (reg:CC FLAGS_REG))]
6054   "TARGET_64BIT && reload_completed
6055    && ix86_lea_for_add_ok (insn, operands)"
6056   [(set (match_dup 0)
6057         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6058 {
6059   operands[1] = gen_lowpart (DImode, operands[1]);
6060   operands[2] = gen_lowpart (DImode, operands[2]);
6061 })
6062
6063 (define_insn "*add<mode>_2"
6064   [(set (reg FLAGS_REG)
6065         (compare
6066           (plus:SWI
6067             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6068             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6069           (const_int 0)))
6070    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6071         (plus:SWI (match_dup 1) (match_dup 2)))]
6072   "ix86_match_ccmode (insn, CCGOCmode)
6073    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6074 {
6075   switch (get_attr_type (insn))
6076     {
6077     case TYPE_INCDEC:
6078       if (operands[2] == const1_rtx)
6079         return "inc{<imodesuffix>}\t%0";
6080       else
6081         {
6082           gcc_assert (operands[2] == constm1_rtx);
6083           return "dec{<imodesuffix>}\t%0";
6084         }
6085
6086     default:
6087       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6088         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6089
6090       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6091     }
6092 }
6093   [(set (attr "type")
6094      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6095         (const_string "incdec")
6096         (const_string "alu")))
6097    (set (attr "length_immediate")
6098       (if_then_else
6099         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6100         (const_string "1")
6101         (const_string "*")))
6102    (set_attr "mode" "<MODE>")])
6103
6104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6105 (define_insn "*addsi_2_zext"
6106   [(set (reg FLAGS_REG)
6107         (compare
6108           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6109                    (match_operand:SI 2 "general_operand" "g"))
6110           (const_int 0)))
6111    (set (match_operand:DI 0 "register_operand" "=r")
6112         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6113   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6114    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6115 {
6116   switch (get_attr_type (insn))
6117     {
6118     case TYPE_INCDEC:
6119       if (operands[2] == const1_rtx)
6120         return "inc{l}\t%k0";
6121       else
6122         {
6123           gcc_assert (operands[2] == constm1_rtx);
6124           return "dec{l}\t%k0";
6125         }
6126
6127     default:
6128       if (x86_maybe_negate_const_int (&operands[2], SImode))
6129         return "sub{l}\t{%2, %k0|%k0, %2}";
6130
6131       return "add{l}\t{%2, %k0|%k0, %2}";
6132     }
6133 }
6134   [(set (attr "type")
6135      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6136         (const_string "incdec")
6137         (const_string "alu")))
6138    (set (attr "length_immediate")
6139       (if_then_else
6140         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6141         (const_string "1")
6142         (const_string "*")))
6143    (set_attr "mode" "SI")])
6144
6145 (define_insn "*add<mode>_3"
6146   [(set (reg FLAGS_REG)
6147         (compare
6148           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6149           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6150    (clobber (match_scratch:SWI 0 "=<r>"))]
6151   "ix86_match_ccmode (insn, CCZmode)
6152    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6153 {
6154   switch (get_attr_type (insn))
6155     {
6156     case TYPE_INCDEC:
6157       if (operands[2] == const1_rtx)
6158         return "inc{<imodesuffix>}\t%0";
6159       else
6160         {
6161           gcc_assert (operands[2] == constm1_rtx);
6162           return "dec{<imodesuffix>}\t%0";
6163         }
6164
6165     default:
6166       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6167         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6168
6169       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6170     }
6171 }
6172   [(set (attr "type")
6173      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6174         (const_string "incdec")
6175         (const_string "alu")))
6176    (set (attr "length_immediate")
6177       (if_then_else
6178         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6179         (const_string "1")
6180         (const_string "*")))
6181    (set_attr "mode" "<MODE>")])
6182
6183 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6184 (define_insn "*addsi_3_zext"
6185   [(set (reg FLAGS_REG)
6186         (compare
6187           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6188           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6189    (set (match_operand:DI 0 "register_operand" "=r")
6190         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6191   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6192    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6193 {
6194   switch (get_attr_type (insn))
6195     {
6196     case TYPE_INCDEC:
6197       if (operands[2] == const1_rtx)
6198         return "inc{l}\t%k0";
6199       else
6200         {
6201           gcc_assert (operands[2] == constm1_rtx);
6202           return "dec{l}\t%k0";
6203         }
6204
6205     default:
6206       if (x86_maybe_negate_const_int (&operands[2], SImode))
6207         return "sub{l}\t{%2, %k0|%k0, %2}";
6208
6209       return "add{l}\t{%2, %k0|%k0, %2}";
6210     }
6211 }
6212   [(set (attr "type")
6213      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6214         (const_string "incdec")
6215         (const_string "alu")))
6216    (set (attr "length_immediate")
6217       (if_then_else
6218         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6219         (const_string "1")
6220         (const_string "*")))
6221    (set_attr "mode" "SI")])
6222
6223 ; For comparisons against 1, -1 and 128, we may generate better code
6224 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6225 ; is matched then.  We can't accept general immediate, because for
6226 ; case of overflows,  the result is messed up.
6227 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6228 ; only for comparisons not depending on it.
6229
6230 (define_insn "*adddi_4"
6231   [(set (reg FLAGS_REG)
6232         (compare
6233           (match_operand:DI 1 "nonimmediate_operand" "0")
6234           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6235    (clobber (match_scratch:DI 0 "=rm"))]
6236   "TARGET_64BIT
6237    && ix86_match_ccmode (insn, CCGCmode)"
6238 {
6239   switch (get_attr_type (insn))
6240     {
6241     case TYPE_INCDEC:
6242       if (operands[2] == constm1_rtx)
6243         return "inc{q}\t%0";
6244       else
6245         {
6246           gcc_assert (operands[2] == const1_rtx);
6247           return "dec{q}\t%0";
6248         }
6249
6250     default:
6251       if (x86_maybe_negate_const_int (&operands[2], DImode))
6252         return "add{q}\t{%2, %0|%0, %2}";
6253
6254       return "sub{q}\t{%2, %0|%0, %2}";
6255     }
6256 }
6257   [(set (attr "type")
6258      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6259         (const_string "incdec")
6260         (const_string "alu")))
6261    (set (attr "length_immediate")
6262       (if_then_else
6263         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6264         (const_string "1")
6265         (const_string "*")))
6266    (set_attr "mode" "DI")])
6267
6268 ; For comparisons against 1, -1 and 128, we may generate better code
6269 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6270 ; is matched then.  We can't accept general immediate, because for
6271 ; case of overflows,  the result is messed up.
6272 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6273 ; only for comparisons not depending on it.
6274
6275 (define_insn "*add<mode>_4"
6276   [(set (reg FLAGS_REG)
6277         (compare
6278           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6279           (match_operand:SWI124 2 "const_int_operand" "n")))
6280    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6281   "ix86_match_ccmode (insn, CCGCmode)"
6282 {
6283   switch (get_attr_type (insn))
6284     {
6285     case TYPE_INCDEC:
6286       if (operands[2] == constm1_rtx)
6287         return "inc{<imodesuffix>}\t%0";
6288       else
6289         {
6290           gcc_assert (operands[2] == const1_rtx);
6291           return "dec{<imodesuffix>}\t%0";
6292         }
6293
6294     default:
6295       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6296         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6297
6298       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6299     }
6300 }
6301   [(set (attr "type")
6302      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6303         (const_string "incdec")
6304         (const_string "alu")))
6305    (set (attr "length_immediate")
6306       (if_then_else
6307         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6308         (const_string "1")
6309         (const_string "*")))
6310    (set_attr "mode" "<MODE>")])
6311
6312 (define_insn "*add<mode>_5"
6313   [(set (reg FLAGS_REG)
6314         (compare
6315           (plus:SWI
6316             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6317             (match_operand:SWI 2 "<general_operand>" "<g>"))
6318           (const_int 0)))
6319    (clobber (match_scratch:SWI 0 "=<r>"))]
6320   "ix86_match_ccmode (insn, CCGOCmode)
6321    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6322 {
6323   switch (get_attr_type (insn))
6324     {
6325     case TYPE_INCDEC:
6326       if (operands[2] == const1_rtx)
6327         return "inc{<imodesuffix>}\t%0";
6328       else
6329         {
6330           gcc_assert (operands[2] == constm1_rtx);
6331           return "dec{<imodesuffix>}\t%0";
6332         }
6333
6334     default:
6335       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6336         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6337
6338       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6339     }
6340 }
6341   [(set (attr "type")
6342      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6343         (const_string "incdec")
6344         (const_string "alu")))
6345    (set (attr "length_immediate")
6346       (if_then_else
6347         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6348         (const_string "1")
6349         (const_string "*")))
6350    (set_attr "mode" "<MODE>")])
6351
6352 (define_insn "*addqi_ext_1_rex64"
6353   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6354                          (const_int 8)
6355                          (const_int 8))
6356         (plus:SI
6357           (zero_extract:SI
6358             (match_operand 1 "ext_register_operand" "0")
6359             (const_int 8)
6360             (const_int 8))
6361           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6362    (clobber (reg:CC FLAGS_REG))]
6363   "TARGET_64BIT"
6364 {
6365   switch (get_attr_type (insn))
6366     {
6367     case TYPE_INCDEC:
6368       if (operands[2] == const1_rtx)
6369         return "inc{b}\t%h0";
6370       else
6371         {
6372           gcc_assert (operands[2] == constm1_rtx);
6373           return "dec{b}\t%h0";
6374         }
6375
6376     default:
6377       return "add{b}\t{%2, %h0|%h0, %2}";
6378     }
6379 }
6380   [(set (attr "type")
6381      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6382         (const_string "incdec")
6383         (const_string "alu")))
6384    (set_attr "modrm" "1")
6385    (set_attr "mode" "QI")])
6386
6387 (define_insn "addqi_ext_1"
6388   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6389                          (const_int 8)
6390                          (const_int 8))
6391         (plus:SI
6392           (zero_extract:SI
6393             (match_operand 1 "ext_register_operand" "0")
6394             (const_int 8)
6395             (const_int 8))
6396           (match_operand:QI 2 "general_operand" "Qmn")))
6397    (clobber (reg:CC FLAGS_REG))]
6398   "!TARGET_64BIT"
6399 {
6400   switch (get_attr_type (insn))
6401     {
6402     case TYPE_INCDEC:
6403       if (operands[2] == const1_rtx)
6404         return "inc{b}\t%h0";
6405       else
6406         {
6407           gcc_assert (operands[2] == constm1_rtx);
6408           return "dec{b}\t%h0";
6409         }
6410
6411     default:
6412       return "add{b}\t{%2, %h0|%h0, %2}";
6413     }
6414 }
6415   [(set (attr "type")
6416      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6417         (const_string "incdec")
6418         (const_string "alu")))
6419    (set_attr "modrm" "1")
6420    (set_attr "mode" "QI")])
6421
6422 (define_insn "*addqi_ext_2"
6423   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6424                          (const_int 8)
6425                          (const_int 8))
6426         (plus:SI
6427           (zero_extract:SI
6428             (match_operand 1 "ext_register_operand" "%0")
6429             (const_int 8)
6430             (const_int 8))
6431           (zero_extract:SI
6432             (match_operand 2 "ext_register_operand" "Q")
6433             (const_int 8)
6434             (const_int 8))))
6435    (clobber (reg:CC FLAGS_REG))]
6436   ""
6437   "add{b}\t{%h2, %h0|%h0, %h2}"
6438   [(set_attr "type" "alu")
6439    (set_attr "mode" "QI")])
6440
6441 ;; The lea patterns for non-Pmodes needs to be matched by
6442 ;; several insns converted to real lea by splitters.
6443
6444 (define_insn_and_split "*lea_general_1"
6445   [(set (match_operand 0 "register_operand" "=r")
6446         (plus (plus (match_operand 1 "index_register_operand" "l")
6447                     (match_operand 2 "register_operand" "r"))
6448               (match_operand 3 "immediate_operand" "i")))]
6449   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6450     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6451    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6452    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6453    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6454    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6455        || GET_MODE (operands[3]) == VOIDmode)"
6456   "#"
6457   "&& reload_completed"
6458   [(const_int 0)]
6459 {
6460   rtx pat;
6461   operands[0] = gen_lowpart (SImode, operands[0]);
6462   operands[1] = gen_lowpart (Pmode, operands[1]);
6463   operands[2] = gen_lowpart (Pmode, operands[2]);
6464   operands[3] = gen_lowpart (Pmode, operands[3]);
6465   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6466                       operands[3]);
6467   if (Pmode != SImode)
6468     pat = gen_rtx_SUBREG (SImode, pat, 0);
6469   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6470   DONE;
6471 }
6472   [(set_attr "type" "lea")
6473    (set_attr "mode" "SI")])
6474
6475 (define_insn_and_split "*lea_general_1_zext"
6476   [(set (match_operand:DI 0 "register_operand" "=r")
6477         (zero_extend:DI
6478           (plus:SI (plus:SI
6479                      (match_operand:SI 1 "index_register_operand" "l")
6480                      (match_operand:SI 2 "register_operand" "r"))
6481                    (match_operand:SI 3 "immediate_operand" "i"))))]
6482   "TARGET_64BIT"
6483   "#"
6484   "&& reload_completed"
6485   [(set (match_dup 0)
6486         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6487                                                      (match_dup 2))
6488                                             (match_dup 3)) 0)))]
6489 {
6490   operands[1] = gen_lowpart (Pmode, operands[1]);
6491   operands[2] = gen_lowpart (Pmode, operands[2]);
6492   operands[3] = gen_lowpart (Pmode, operands[3]);
6493 }
6494   [(set_attr "type" "lea")
6495    (set_attr "mode" "SI")])
6496
6497 (define_insn_and_split "*lea_general_2"
6498   [(set (match_operand 0 "register_operand" "=r")
6499         (plus (mult (match_operand 1 "index_register_operand" "l")
6500                     (match_operand 2 "const248_operand" "i"))
6501               (match_operand 3 "nonmemory_operand" "ri")))]
6502   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6503     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6504    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6505    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6506    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6507        || GET_MODE (operands[3]) == VOIDmode)"
6508   "#"
6509   "&& reload_completed"
6510   [(const_int 0)]
6511 {
6512   rtx pat;
6513   operands[0] = gen_lowpart (SImode, operands[0]);
6514   operands[1] = gen_lowpart (Pmode, operands[1]);
6515   operands[3] = gen_lowpart (Pmode, operands[3]);
6516   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6517                       operands[3]);
6518   if (Pmode != SImode)
6519     pat = gen_rtx_SUBREG (SImode, pat, 0);
6520   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6521   DONE;
6522 }
6523   [(set_attr "type" "lea")
6524    (set_attr "mode" "SI")])
6525
6526 (define_insn_and_split "*lea_general_2_zext"
6527   [(set (match_operand:DI 0 "register_operand" "=r")
6528         (zero_extend:DI
6529           (plus:SI (mult:SI
6530                      (match_operand:SI 1 "index_register_operand" "l")
6531                      (match_operand:SI 2 "const248_operand" "n"))
6532                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6533   "TARGET_64BIT"
6534   "#"
6535   "&& reload_completed"
6536   [(set (match_dup 0)
6537         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6538                                                      (match_dup 2))
6539                                             (match_dup 3)) 0)))]
6540 {
6541   operands[1] = gen_lowpart (Pmode, operands[1]);
6542   operands[3] = gen_lowpart (Pmode, operands[3]);
6543 }
6544   [(set_attr "type" "lea")
6545    (set_attr "mode" "SI")])
6546
6547 (define_insn_and_split "*lea_general_3"
6548   [(set (match_operand 0 "register_operand" "=r")
6549         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6550                           (match_operand 2 "const248_operand" "i"))
6551                     (match_operand 3 "register_operand" "r"))
6552               (match_operand 4 "immediate_operand" "i")))]
6553   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6554     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6555    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6556    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6557    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6558   "#"
6559   "&& reload_completed"
6560   [(const_int 0)]
6561 {
6562   rtx pat;
6563   operands[0] = gen_lowpart (SImode, operands[0]);
6564   operands[1] = gen_lowpart (Pmode, operands[1]);
6565   operands[3] = gen_lowpart (Pmode, operands[3]);
6566   operands[4] = gen_lowpart (Pmode, operands[4]);
6567   pat = gen_rtx_PLUS (Pmode,
6568                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6569                                                          operands[2]),
6570                                     operands[3]),
6571                       operands[4]);
6572   if (Pmode != SImode)
6573     pat = gen_rtx_SUBREG (SImode, pat, 0);
6574   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6575   DONE;
6576 }
6577   [(set_attr "type" "lea")
6578    (set_attr "mode" "SI")])
6579
6580 (define_insn_and_split "*lea_general_3_zext"
6581   [(set (match_operand:DI 0 "register_operand" "=r")
6582         (zero_extend:DI
6583           (plus:SI (plus:SI
6584                      (mult:SI
6585                        (match_operand:SI 1 "index_register_operand" "l")
6586                        (match_operand:SI 2 "const248_operand" "n"))
6587                      (match_operand:SI 3 "register_operand" "r"))
6588                    (match_operand:SI 4 "immediate_operand" "i"))))]
6589   "TARGET_64BIT"
6590   "#"
6591   "&& reload_completed"
6592   [(set (match_dup 0)
6593         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6594                                                               (match_dup 2))
6595                                                      (match_dup 3))
6596                                             (match_dup 4)) 0)))]
6597 {
6598   operands[1] = gen_lowpart (Pmode, operands[1]);
6599   operands[3] = gen_lowpart (Pmode, operands[3]);
6600   operands[4] = gen_lowpart (Pmode, operands[4]);
6601 }
6602   [(set_attr "type" "lea")
6603    (set_attr "mode" "SI")])
6604 \f
6605 ;; Subtract instructions
6606
6607 (define_expand "sub<mode>3"
6608   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6609         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6610                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6611   ""
6612   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6613
6614 (define_insn_and_split "*sub<dwi>3_doubleword"
6615   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6616         (minus:<DWI>
6617           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6618           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6621   "#"
6622   "reload_completed"
6623   [(parallel [(set (reg:CC FLAGS_REG)
6624                    (compare:CC (match_dup 1) (match_dup 2)))
6625               (set (match_dup 0)
6626                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6627    (parallel [(set (match_dup 3)
6628                    (minus:DWIH
6629                      (match_dup 4)
6630                      (plus:DWIH
6631                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6632                        (match_dup 5))))
6633               (clobber (reg:CC FLAGS_REG))])]
6634   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6635
6636 (define_insn "*sub<mode>_1"
6637   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6638         (minus:SWI
6639           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6640           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6641    (clobber (reg:CC FLAGS_REG))]
6642   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6643   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6644   [(set_attr "type" "alu")
6645    (set_attr "mode" "<MODE>")])
6646
6647 (define_insn "*subsi_1_zext"
6648   [(set (match_operand:DI 0 "register_operand" "=r")
6649         (zero_extend:DI
6650           (minus:SI (match_operand:SI 1 "register_operand" "0")
6651                     (match_operand:SI 2 "general_operand" "g"))))
6652    (clobber (reg:CC FLAGS_REG))]
6653   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6654   "sub{l}\t{%2, %k0|%k0, %2}"
6655   [(set_attr "type" "alu")
6656    (set_attr "mode" "SI")])
6657
6658 (define_insn "*subqi_1_slp"
6659   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6660         (minus:QI (match_dup 0)
6661                   (match_operand:QI 1 "general_operand" "qn,qm")))
6662    (clobber (reg:CC FLAGS_REG))]
6663   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6664    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6665   "sub{b}\t{%1, %0|%0, %1}"
6666   [(set_attr "type" "alu1")
6667    (set_attr "mode" "QI")])
6668
6669 (define_insn "*sub<mode>_2"
6670   [(set (reg FLAGS_REG)
6671         (compare
6672           (minus:SWI
6673             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6674             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6675           (const_int 0)))
6676    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6677         (minus:SWI (match_dup 1) (match_dup 2)))]
6678   "ix86_match_ccmode (insn, CCGOCmode)
6679    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6680   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6681   [(set_attr "type" "alu")
6682    (set_attr "mode" "<MODE>")])
6683
6684 (define_insn "*subsi_2_zext"
6685   [(set (reg FLAGS_REG)
6686         (compare
6687           (minus:SI (match_operand:SI 1 "register_operand" "0")
6688                     (match_operand:SI 2 "general_operand" "g"))
6689           (const_int 0)))
6690    (set (match_operand:DI 0 "register_operand" "=r")
6691         (zero_extend:DI
6692           (minus:SI (match_dup 1)
6693                     (match_dup 2))))]
6694   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6695    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6696   "sub{l}\t{%2, %k0|%k0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "mode" "SI")])
6699
6700 (define_insn "*sub<mode>_3"
6701   [(set (reg FLAGS_REG)
6702         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6703                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6704    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6705         (minus:SWI (match_dup 1) (match_dup 2)))]
6706   "ix86_match_ccmode (insn, CCmode)
6707    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6708   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6709   [(set_attr "type" "alu")
6710    (set_attr "mode" "<MODE>")])
6711
6712 (define_insn "*subsi_3_zext"
6713   [(set (reg FLAGS_REG)
6714         (compare (match_operand:SI 1 "register_operand" "0")
6715                  (match_operand:SI 2 "general_operand" "g")))
6716    (set (match_operand:DI 0 "register_operand" "=r")
6717         (zero_extend:DI
6718           (minus:SI (match_dup 1)
6719                     (match_dup 2))))]
6720   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6721    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6722   "sub{l}\t{%2, %1|%1, %2}"
6723   [(set_attr "type" "alu")
6724    (set_attr "mode" "SI")])
6725 \f
6726 ;; Add with carry and subtract with borrow
6727
6728 (define_expand "<plusminus_insn><mode>3_carry"
6729   [(parallel
6730     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6731           (plusminus:SWI
6732             (match_operand:SWI 1 "nonimmediate_operand" "")
6733             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6734                        [(match_operand 3 "flags_reg_operand" "")
6735                         (const_int 0)])
6736                       (match_operand:SWI 2 "<general_operand>" ""))))
6737      (clobber (reg:CC FLAGS_REG))])]
6738   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6739
6740 (define_insn "*<plusminus_insn><mode>3_carry"
6741   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6742         (plusminus:SWI
6743           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6744           (plus:SWI
6745             (match_operator 3 "ix86_carry_flag_operator"
6746              [(reg FLAGS_REG) (const_int 0)])
6747             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6748    (clobber (reg:CC FLAGS_REG))]
6749   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6750   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "use_carry" "1")
6753    (set_attr "pent_pair" "pu")
6754    (set_attr "mode" "<MODE>")])
6755
6756 (define_insn "*addsi3_carry_zext"
6757   [(set (match_operand:DI 0 "register_operand" "=r")
6758         (zero_extend:DI
6759           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6760                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6761                              [(reg FLAGS_REG) (const_int 0)])
6762                             (match_operand:SI 2 "general_operand" "g")))))
6763    (clobber (reg:CC FLAGS_REG))]
6764   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6765   "adc{l}\t{%2, %k0|%k0, %2}"
6766   [(set_attr "type" "alu")
6767    (set_attr "use_carry" "1")
6768    (set_attr "pent_pair" "pu")
6769    (set_attr "mode" "SI")])
6770
6771 (define_insn "*subsi3_carry_zext"
6772   [(set (match_operand:DI 0 "register_operand" "=r")
6773         (zero_extend:DI
6774           (minus:SI (match_operand:SI 1 "register_operand" "0")
6775                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6776                               [(reg FLAGS_REG) (const_int 0)])
6777                              (match_operand:SI 2 "general_operand" "g")))))
6778    (clobber (reg:CC FLAGS_REG))]
6779   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6780   "sbb{l}\t{%2, %k0|%k0, %2}"
6781   [(set_attr "type" "alu")
6782    (set_attr "pent_pair" "pu")
6783    (set_attr "mode" "SI")])
6784 \f
6785 ;; Overflow setting add and subtract instructions
6786
6787 (define_insn "*add<mode>3_cconly_overflow"
6788   [(set (reg:CCC FLAGS_REG)
6789         (compare:CCC
6790           (plus:SWI
6791             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6792             (match_operand:SWI 2 "<general_operand>" "<g>"))
6793           (match_dup 1)))
6794    (clobber (match_scratch:SWI 0 "=<r>"))]
6795   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6797   [(set_attr "type" "alu")
6798    (set_attr "mode" "<MODE>")])
6799
6800 (define_insn "*sub<mode>3_cconly_overflow"
6801   [(set (reg:CCC FLAGS_REG)
6802         (compare:CCC
6803           (minus:SWI
6804             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6805             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6806           (match_dup 0)))]
6807   ""
6808   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6809   [(set_attr "type" "icmp")
6810    (set_attr "mode" "<MODE>")])
6811
6812 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6813   [(set (reg:CCC FLAGS_REG)
6814         (compare:CCC
6815             (plusminus:SWI
6816                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6817                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6818             (match_dup 1)))
6819    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6820         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6821   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6822   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6823   [(set_attr "type" "alu")
6824    (set_attr "mode" "<MODE>")])
6825
6826 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6827   [(set (reg:CCC FLAGS_REG)
6828         (compare:CCC
6829           (plusminus:SI
6830             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6831             (match_operand:SI 2 "general_operand" "g"))
6832           (match_dup 1)))
6833    (set (match_operand:DI 0 "register_operand" "=r")
6834         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6835   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6836   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6837   [(set_attr "type" "alu")
6838    (set_attr "mode" "SI")])
6839
6840 ;; The patterns that match these are at the end of this file.
6841
6842 (define_expand "<plusminus_insn>xf3"
6843   [(set (match_operand:XF 0 "register_operand" "")
6844         (plusminus:XF
6845           (match_operand:XF 1 "register_operand" "")
6846           (match_operand:XF 2 "register_operand" "")))]
6847   "TARGET_80387")
6848
6849 (define_expand "<plusminus_insn><mode>3"
6850   [(set (match_operand:MODEF 0 "register_operand" "")
6851         (plusminus:MODEF
6852           (match_operand:MODEF 1 "register_operand" "")
6853           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6854   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6855     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6856 \f
6857 ;; Multiply instructions
6858
6859 (define_expand "mul<mode>3"
6860   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6861                    (mult:SWIM248
6862                      (match_operand:SWIM248 1 "register_operand" "")
6863                      (match_operand:SWIM248 2 "<general_operand>" "")))
6864               (clobber (reg:CC FLAGS_REG))])])
6865
6866 (define_expand "mulqi3"
6867   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6868                    (mult:QI
6869                      (match_operand:QI 1 "register_operand" "")
6870                      (match_operand:QI 2 "nonimmediate_operand" "")))
6871               (clobber (reg:CC FLAGS_REG))])]
6872   "TARGET_QIMODE_MATH")
6873
6874 ;; On AMDFAM10
6875 ;; IMUL reg32/64, reg32/64, imm8        Direct
6876 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6877 ;; IMUL reg32/64, reg32/64, imm32       Direct
6878 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6879 ;; IMUL reg32/64, reg32/64              Direct
6880 ;; IMUL reg32/64, mem32/64              Direct
6881 ;;
6882 ;; On BDVER1, all above IMULs use DirectPath
6883
6884 (define_insn "*mul<mode>3_1"
6885   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6886         (mult:SWI48
6887           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6888           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6889    (clobber (reg:CC FLAGS_REG))]
6890   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6891   "@
6892    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6893    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6894    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6895   [(set_attr "type" "imul")
6896    (set_attr "prefix_0f" "0,0,1")
6897    (set (attr "athlon_decode")
6898         (cond [(eq_attr "cpu" "athlon")
6899                   (const_string "vector")
6900                (eq_attr "alternative" "1")
6901                   (const_string "vector")
6902                (and (eq_attr "alternative" "2")
6903                     (match_operand 1 "memory_operand" ""))
6904                   (const_string "vector")]
6905               (const_string "direct")))
6906    (set (attr "amdfam10_decode")
6907         (cond [(and (eq_attr "alternative" "0,1")
6908                     (match_operand 1 "memory_operand" ""))
6909                   (const_string "vector")]
6910               (const_string "direct")))
6911    (set_attr "bdver1_decode" "direct")
6912    (set_attr "mode" "<MODE>")])
6913
6914 (define_insn "*mulsi3_1_zext"
6915   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6916         (zero_extend:DI
6917           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6918                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6919    (clobber (reg:CC FLAGS_REG))]
6920   "TARGET_64BIT
6921    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6922   "@
6923    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6924    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6925    imul{l}\t{%2, %k0|%k0, %2}"
6926   [(set_attr "type" "imul")
6927    (set_attr "prefix_0f" "0,0,1")
6928    (set (attr "athlon_decode")
6929         (cond [(eq_attr "cpu" "athlon")
6930                   (const_string "vector")
6931                (eq_attr "alternative" "1")
6932                   (const_string "vector")
6933                (and (eq_attr "alternative" "2")
6934                     (match_operand 1 "memory_operand" ""))
6935                   (const_string "vector")]
6936               (const_string "direct")))
6937    (set (attr "amdfam10_decode")
6938         (cond [(and (eq_attr "alternative" "0,1")
6939                     (match_operand 1 "memory_operand" ""))
6940                   (const_string "vector")]
6941               (const_string "direct")))
6942    (set_attr "bdver1_decode" "direct")
6943    (set_attr "mode" "SI")])
6944
6945 ;; On AMDFAM10
6946 ;; IMUL reg16, reg16, imm8      VectorPath
6947 ;; IMUL reg16, mem16, imm8      VectorPath
6948 ;; IMUL reg16, reg16, imm16     VectorPath
6949 ;; IMUL reg16, mem16, imm16     VectorPath
6950 ;; IMUL reg16, reg16            Direct
6951 ;; IMUL reg16, mem16            Direct
6952 ;;
6953 ;; On BDVER1, all HI MULs use DoublePath
6954
6955 (define_insn "*mulhi3_1"
6956   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6957         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6958                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "TARGET_HIMODE_MATH
6961    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6962   "@
6963    imul{w}\t{%2, %1, %0|%0, %1, %2}
6964    imul{w}\t{%2, %1, %0|%0, %1, %2}
6965    imul{w}\t{%2, %0|%0, %2}"
6966   [(set_attr "type" "imul")
6967    (set_attr "prefix_0f" "0,0,1")
6968    (set (attr "athlon_decode")
6969         (cond [(eq_attr "cpu" "athlon")
6970                   (const_string "vector")
6971                (eq_attr "alternative" "1,2")
6972                   (const_string "vector")]
6973               (const_string "direct")))
6974    (set (attr "amdfam10_decode")
6975         (cond [(eq_attr "alternative" "0,1")
6976                   (const_string "vector")]
6977               (const_string "direct")))
6978    (set_attr "bdver1_decode" "double")
6979    (set_attr "mode" "HI")])
6980
6981 ;;On AMDFAM10 and BDVER1
6982 ;; MUL reg8     Direct
6983 ;; MUL mem8     Direct
6984
6985 (define_insn "*mulqi3_1"
6986   [(set (match_operand:QI 0 "register_operand" "=a")
6987         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6988                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6989    (clobber (reg:CC FLAGS_REG))]
6990   "TARGET_QIMODE_MATH
6991    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6992   "mul{b}\t%2"
6993   [(set_attr "type" "imul")
6994    (set_attr "length_immediate" "0")
6995    (set (attr "athlon_decode")
6996      (if_then_else (eq_attr "cpu" "athlon")
6997         (const_string "vector")
6998         (const_string "direct")))
6999    (set_attr "amdfam10_decode" "direct")
7000    (set_attr "bdver1_decode" "direct")
7001    (set_attr "mode" "QI")])
7002
7003 (define_expand "<u>mul<mode><dwi>3"
7004   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7005                    (mult:<DWI>
7006                      (any_extend:<DWI>
7007                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7008                      (any_extend:<DWI>
7009                        (match_operand:DWIH 2 "register_operand" ""))))
7010               (clobber (reg:CC FLAGS_REG))])])
7011
7012 (define_expand "<u>mulqihi3"
7013   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7014                    (mult:HI
7015                      (any_extend:HI
7016                        (match_operand:QI 1 "nonimmediate_operand" ""))
7017                      (any_extend:HI
7018                        (match_operand:QI 2 "register_operand" ""))))
7019               (clobber (reg:CC FLAGS_REG))])]
7020   "TARGET_QIMODE_MATH")
7021
7022 (define_insn "*<u>mul<mode><dwi>3_1"
7023   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7024         (mult:<DWI>
7025           (any_extend:<DWI>
7026             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7027           (any_extend:<DWI>
7028             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7029    (clobber (reg:CC FLAGS_REG))]
7030   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7031   "<sgnprefix>mul{<imodesuffix>}\t%2"
7032   [(set_attr "type" "imul")
7033    (set_attr "length_immediate" "0")
7034    (set (attr "athlon_decode")
7035      (if_then_else (eq_attr "cpu" "athlon")
7036         (const_string "vector")
7037         (const_string "double")))
7038    (set_attr "amdfam10_decode" "double")
7039    (set_attr "bdver1_decode" "direct")
7040    (set_attr "mode" "<MODE>")])
7041
7042 (define_insn "*<u>mulqihi3_1"
7043   [(set (match_operand:HI 0 "register_operand" "=a")
7044         (mult:HI
7045           (any_extend:HI
7046             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7047           (any_extend:HI
7048             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7049    (clobber (reg:CC FLAGS_REG))]
7050   "TARGET_QIMODE_MATH
7051    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7052   "<sgnprefix>mul{b}\t%2"
7053   [(set_attr "type" "imul")
7054    (set_attr "length_immediate" "0")
7055    (set (attr "athlon_decode")
7056      (if_then_else (eq_attr "cpu" "athlon")
7057         (const_string "vector")
7058         (const_string "direct")))
7059    (set_attr "amdfam10_decode" "direct")
7060    (set_attr "bdver1_decode" "direct")
7061    (set_attr "mode" "QI")])
7062
7063 (define_expand "<s>mul<mode>3_highpart"
7064   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7065                    (truncate:SWI48
7066                      (lshiftrt:<DWI>
7067                        (mult:<DWI>
7068                          (any_extend:<DWI>
7069                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7070                          (any_extend:<DWI>
7071                            (match_operand:SWI48 2 "register_operand" "")))
7072                        (match_dup 4))))
7073               (clobber (match_scratch:SWI48 3 ""))
7074               (clobber (reg:CC FLAGS_REG))])]
7075   ""
7076   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7077
7078 (define_insn "*<s>muldi3_highpart_1"
7079   [(set (match_operand:DI 0 "register_operand" "=d")
7080         (truncate:DI
7081           (lshiftrt:TI
7082             (mult:TI
7083               (any_extend:TI
7084                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7085               (any_extend:TI
7086                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7087             (const_int 64))))
7088    (clobber (match_scratch:DI 3 "=1"))
7089    (clobber (reg:CC FLAGS_REG))]
7090   "TARGET_64BIT
7091    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7092   "<sgnprefix>mul{q}\t%2"
7093   [(set_attr "type" "imul")
7094    (set_attr "length_immediate" "0")
7095    (set (attr "athlon_decode")
7096      (if_then_else (eq_attr "cpu" "athlon")
7097         (const_string "vector")
7098         (const_string "double")))
7099    (set_attr "amdfam10_decode" "double")
7100    (set_attr "bdver1_decode" "direct")
7101    (set_attr "mode" "DI")])
7102
7103 (define_insn "*<s>mulsi3_highpart_1"
7104   [(set (match_operand:SI 0 "register_operand" "=d")
7105         (truncate:SI
7106           (lshiftrt:DI
7107             (mult:DI
7108               (any_extend:DI
7109                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7110               (any_extend:DI
7111                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7112             (const_int 32))))
7113    (clobber (match_scratch:SI 3 "=1"))
7114    (clobber (reg:CC FLAGS_REG))]
7115   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7116   "<sgnprefix>mul{l}\t%2"
7117   [(set_attr "type" "imul")
7118    (set_attr "length_immediate" "0")
7119    (set (attr "athlon_decode")
7120      (if_then_else (eq_attr "cpu" "athlon")
7121         (const_string "vector")
7122         (const_string "double")))
7123    (set_attr "amdfam10_decode" "double")
7124    (set_attr "bdver1_decode" "direct")
7125    (set_attr "mode" "SI")])
7126
7127 (define_insn "*<s>mulsi3_highpart_zext"
7128   [(set (match_operand:DI 0 "register_operand" "=d")
7129         (zero_extend:DI (truncate:SI
7130           (lshiftrt:DI
7131             (mult:DI (any_extend:DI
7132                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7133                      (any_extend:DI
7134                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7135             (const_int 32)))))
7136    (clobber (match_scratch:SI 3 "=1"))
7137    (clobber (reg:CC FLAGS_REG))]
7138   "TARGET_64BIT
7139    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7140   "<sgnprefix>mul{l}\t%2"
7141   [(set_attr "type" "imul")
7142    (set_attr "length_immediate" "0")
7143    (set (attr "athlon_decode")
7144      (if_then_else (eq_attr "cpu" "athlon")
7145         (const_string "vector")
7146         (const_string "double")))
7147    (set_attr "amdfam10_decode" "double")
7148    (set_attr "bdver1_decode" "direct")
7149    (set_attr "mode" "SI")])
7150
7151 ;; The patterns that match these are at the end of this file.
7152
7153 (define_expand "mulxf3"
7154   [(set (match_operand:XF 0 "register_operand" "")
7155         (mult:XF (match_operand:XF 1 "register_operand" "")
7156                  (match_operand:XF 2 "register_operand" "")))]
7157   "TARGET_80387")
7158
7159 (define_expand "mul<mode>3"
7160   [(set (match_operand:MODEF 0 "register_operand" "")
7161         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7162                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7163   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7164     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7165 \f
7166 ;; Divide instructions
7167
7168 ;; The patterns that match these are at the end of this file.
7169
7170 (define_expand "divxf3"
7171   [(set (match_operand:XF 0 "register_operand" "")
7172         (div:XF (match_operand:XF 1 "register_operand" "")
7173                 (match_operand:XF 2 "register_operand" "")))]
7174   "TARGET_80387")
7175
7176 (define_expand "divdf3"
7177   [(set (match_operand:DF 0 "register_operand" "")
7178         (div:DF (match_operand:DF 1 "register_operand" "")
7179                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7180    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7181     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7182
7183 (define_expand "divsf3"
7184   [(set (match_operand:SF 0 "register_operand" "")
7185         (div:SF (match_operand:SF 1 "register_operand" "")
7186                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7187   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7188     || TARGET_SSE_MATH"
7189 {
7190   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7191       && flag_finite_math_only && !flag_trapping_math
7192       && flag_unsafe_math_optimizations)
7193     {
7194       ix86_emit_swdivsf (operands[0], operands[1],
7195                          operands[2], SFmode);
7196       DONE;
7197     }
7198 })
7199 \f
7200 ;; Divmod instructions.
7201
7202 (define_expand "divmod<mode>4"
7203   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7204                    (div:SWIM248
7205                      (match_operand:SWIM248 1 "register_operand" "")
7206                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7207               (set (match_operand:SWIM248 3 "register_operand" "")
7208                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7209               (clobber (reg:CC FLAGS_REG))])])
7210
7211 ;; Split with 8bit unsigned divide:
7212 ;;      if (dividend an divisor are in [0-255])
7213 ;;         use 8bit unsigned integer divide
7214 ;;       else
7215 ;;         use original integer divide
7216 (define_split
7217   [(set (match_operand:SWI48 0 "register_operand" "")
7218         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7219                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7220    (set (match_operand:SWI48 1 "register_operand" "")
7221         (mod:SWI48 (match_dup 2) (match_dup 3)))
7222    (clobber (reg:CC FLAGS_REG))]
7223   "TARGET_USE_8BIT_IDIV
7224    && TARGET_QIMODE_MATH
7225    && can_create_pseudo_p ()
7226    && !optimize_insn_for_size_p ()"
7227   [(const_int 0)]
7228   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7229
7230 (define_insn_and_split "divmod<mode>4_1"
7231   [(set (match_operand:SWI48 0 "register_operand" "=a")
7232         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7233                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7234    (set (match_operand:SWI48 1 "register_operand" "=&d")
7235         (mod:SWI48 (match_dup 2) (match_dup 3)))
7236    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7237    (clobber (reg:CC FLAGS_REG))]
7238   ""
7239   "#"
7240   "reload_completed"
7241   [(parallel [(set (match_dup 1)
7242                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7243               (clobber (reg:CC FLAGS_REG))])
7244    (parallel [(set (match_dup 0)
7245                    (div:SWI48 (match_dup 2) (match_dup 3)))
7246               (set (match_dup 1)
7247                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7248               (use (match_dup 1))
7249               (clobber (reg:CC FLAGS_REG))])]
7250 {
7251   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7252
7253   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7254     operands[4] = operands[2];
7255   else
7256     {
7257       /* Avoid use of cltd in favor of a mov+shift.  */
7258       emit_move_insn (operands[1], operands[2]);
7259       operands[4] = operands[1];
7260     }
7261 }
7262   [(set_attr "type" "multi")
7263    (set_attr "mode" "<MODE>")])
7264
7265 (define_insn_and_split "*divmod<mode>4"
7266   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7267         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7268                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7269    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7270         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7271    (clobber (reg:CC FLAGS_REG))]
7272   ""
7273   "#"
7274   "reload_completed"
7275   [(parallel [(set (match_dup 1)
7276                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7277               (clobber (reg:CC FLAGS_REG))])
7278    (parallel [(set (match_dup 0)
7279                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7280               (set (match_dup 1)
7281                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7282               (use (match_dup 1))
7283               (clobber (reg:CC FLAGS_REG))])]
7284 {
7285   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7286
7287   if (<MODE>mode != HImode
7288       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7289     operands[4] = operands[2];
7290   else
7291     {
7292       /* Avoid use of cltd in favor of a mov+shift.  */
7293       emit_move_insn (operands[1], operands[2]);
7294       operands[4] = operands[1];
7295     }
7296 }
7297   [(set_attr "type" "multi")
7298    (set_attr "mode" "<MODE>")])
7299
7300 (define_insn "*divmod<mode>4_noext"
7301   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7302         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7303                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7304    (set (match_operand:SWIM248 1 "register_operand" "=d")
7305         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7306    (use (match_operand:SWIM248 4 "register_operand" "1"))
7307    (clobber (reg:CC FLAGS_REG))]
7308   ""
7309   "idiv{<imodesuffix>}\t%3"
7310   [(set_attr "type" "idiv")
7311    (set_attr "mode" "<MODE>")])
7312
7313 (define_expand "divmodqi4"
7314   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7315                    (div:QI
7316                      (match_operand:QI 1 "register_operand" "")
7317                      (match_operand:QI 2 "nonimmediate_operand" "")))
7318               (set (match_operand:QI 3 "register_operand" "")
7319                    (mod:QI (match_dup 1) (match_dup 2)))
7320               (clobber (reg:CC FLAGS_REG))])]
7321   "TARGET_QIMODE_MATH"
7322 {
7323   rtx div, mod, insn;
7324   rtx tmp0, tmp1;
7325   
7326   tmp0 = gen_reg_rtx (HImode);
7327   tmp1 = gen_reg_rtx (HImode);
7328
7329   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7330      in AX.  */
7331   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7332   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7333
7334   /* Extract remainder from AH.  */
7335   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7336   insn = emit_move_insn (operands[3], tmp1);
7337
7338   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7339   set_unique_reg_note (insn, REG_EQUAL, mod);
7340
7341   /* Extract quotient from AL.  */
7342   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7343
7344   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7345   set_unique_reg_note (insn, REG_EQUAL, div);
7346
7347   DONE;
7348 })
7349
7350 ;; Divide AX by r/m8, with result stored in
7351 ;; AL <- Quotient
7352 ;; AH <- Remainder
7353 ;; Change div/mod to HImode and extend the second argument to HImode
7354 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7355 ;; combine may fail.
7356 (define_insn "divmodhiqi3"
7357   [(set (match_operand:HI 0 "register_operand" "=a")
7358         (ior:HI
7359           (ashift:HI
7360             (zero_extend:HI
7361               (truncate:QI
7362                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7363                         (sign_extend:HI
7364                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7365             (const_int 8))
7366           (zero_extend:HI
7367             (truncate:QI
7368               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7369    (clobber (reg:CC FLAGS_REG))]
7370   "TARGET_QIMODE_MATH"
7371   "idiv{b}\t%2"
7372   [(set_attr "type" "idiv")
7373    (set_attr "mode" "QI")])
7374
7375 (define_expand "udivmod<mode>4"
7376   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7377                    (udiv:SWIM248
7378                      (match_operand:SWIM248 1 "register_operand" "")
7379                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7380               (set (match_operand:SWIM248 3 "register_operand" "")
7381                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7382               (clobber (reg:CC FLAGS_REG))])])
7383
7384 ;; Split with 8bit unsigned divide:
7385 ;;      if (dividend an divisor are in [0-255])
7386 ;;         use 8bit unsigned integer divide
7387 ;;       else
7388 ;;         use original integer divide
7389 (define_split
7390   [(set (match_operand:SWI48 0 "register_operand" "")
7391         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7392                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7393    (set (match_operand:SWI48 1 "register_operand" "")
7394         (umod:SWI48 (match_dup 2) (match_dup 3)))
7395    (clobber (reg:CC FLAGS_REG))]
7396   "TARGET_USE_8BIT_IDIV
7397    && TARGET_QIMODE_MATH
7398    && can_create_pseudo_p ()
7399    && !optimize_insn_for_size_p ()"
7400   [(const_int 0)]
7401   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7402
7403 (define_insn_and_split "udivmod<mode>4_1"
7404   [(set (match_operand:SWI48 0 "register_operand" "=a")
7405         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7406                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7407    (set (match_operand:SWI48 1 "register_operand" "=&d")
7408         (umod:SWI48 (match_dup 2) (match_dup 3)))
7409    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7410    (clobber (reg:CC FLAGS_REG))]
7411   ""
7412   "#"
7413   "reload_completed"
7414   [(set (match_dup 1) (const_int 0))
7415    (parallel [(set (match_dup 0)
7416                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7417               (set (match_dup 1)
7418                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7419               (use (match_dup 1))
7420               (clobber (reg:CC FLAGS_REG))])]
7421   ""
7422   [(set_attr "type" "multi")
7423    (set_attr "mode" "<MODE>")])
7424
7425 (define_insn_and_split "*udivmod<mode>4"
7426   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7427         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7428                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7429    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7430         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7431    (clobber (reg:CC FLAGS_REG))]
7432   ""
7433   "#"
7434   "reload_completed"
7435   [(set (match_dup 1) (const_int 0))
7436    (parallel [(set (match_dup 0)
7437                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7438               (set (match_dup 1)
7439                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7440               (use (match_dup 1))
7441               (clobber (reg:CC FLAGS_REG))])]
7442   ""
7443   [(set_attr "type" "multi")
7444    (set_attr "mode" "<MODE>")])
7445
7446 (define_insn "*udivmod<mode>4_noext"
7447   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7448         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7449                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7450    (set (match_operand:SWIM248 1 "register_operand" "=d")
7451         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7452    (use (match_operand:SWIM248 4 "register_operand" "1"))
7453    (clobber (reg:CC FLAGS_REG))]
7454   ""
7455   "div{<imodesuffix>}\t%3"
7456   [(set_attr "type" "idiv")
7457    (set_attr "mode" "<MODE>")])
7458
7459 (define_expand "udivmodqi4"
7460   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7461                    (udiv:QI
7462                      (match_operand:QI 1 "register_operand" "")
7463                      (match_operand:QI 2 "nonimmediate_operand" "")))
7464               (set (match_operand:QI 3 "register_operand" "")
7465                    (umod:QI (match_dup 1) (match_dup 2)))
7466               (clobber (reg:CC FLAGS_REG))])]
7467   "TARGET_QIMODE_MATH"
7468 {
7469   rtx div, mod, insn;
7470   rtx tmp0, tmp1;
7471   
7472   tmp0 = gen_reg_rtx (HImode);
7473   tmp1 = gen_reg_rtx (HImode);
7474
7475   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7476      in AX.  */
7477   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7478   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7479
7480   /* Extract remainder from AH.  */
7481   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7482   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7483   insn = emit_move_insn (operands[3], tmp1);
7484
7485   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7486   set_unique_reg_note (insn, REG_EQUAL, mod);
7487
7488   /* Extract quotient from AL.  */
7489   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7490
7491   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7492   set_unique_reg_note (insn, REG_EQUAL, div);
7493
7494   DONE;
7495 })
7496
7497 (define_insn "udivmodhiqi3"
7498   [(set (match_operand:HI 0 "register_operand" "=a")
7499         (ior:HI
7500           (ashift:HI
7501             (zero_extend:HI
7502               (truncate:QI
7503                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7504                         (zero_extend:HI
7505                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7506             (const_int 8))
7507           (zero_extend:HI
7508             (truncate:QI
7509               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7510    (clobber (reg:CC FLAGS_REG))]
7511   "TARGET_QIMODE_MATH"
7512   "div{b}\t%2"
7513   [(set_attr "type" "idiv")
7514    (set_attr "mode" "QI")])
7515
7516 ;; We cannot use div/idiv for double division, because it causes
7517 ;; "division by zero" on the overflow and that's not what we expect
7518 ;; from truncate.  Because true (non truncating) double division is
7519 ;; never generated, we can't create this insn anyway.
7520 ;
7521 ;(define_insn ""
7522 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7523 ;       (truncate:SI
7524 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7525 ;                  (zero_extend:DI
7526 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7527 ;   (set (match_operand:SI 3 "register_operand" "=d")
7528 ;       (truncate:SI
7529 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7530 ;   (clobber (reg:CC FLAGS_REG))]
7531 ;  ""
7532 ;  "div{l}\t{%2, %0|%0, %2}"
7533 ;  [(set_attr "type" "idiv")])
7534 \f
7535 ;;- Logical AND instructions
7536
7537 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7538 ;; Note that this excludes ah.
7539
7540 (define_expand "testsi_ccno_1"
7541   [(set (reg:CCNO FLAGS_REG)
7542         (compare:CCNO
7543           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7544                   (match_operand:SI 1 "nonmemory_operand" ""))
7545           (const_int 0)))])
7546
7547 (define_expand "testqi_ccz_1"
7548   [(set (reg:CCZ FLAGS_REG)
7549         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7550                              (match_operand:QI 1 "nonmemory_operand" ""))
7551                  (const_int 0)))])
7552
7553 (define_expand "testdi_ccno_1"
7554   [(set (reg:CCNO FLAGS_REG)
7555         (compare:CCNO
7556           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7557                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7558           (const_int 0)))]
7559   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7560
7561 (define_insn "*testdi_1"
7562   [(set (reg FLAGS_REG)
7563         (compare
7564          (and:DI
7565           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7566           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7567          (const_int 0)))]
7568   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7569    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7570   "@
7571    test{l}\t{%k1, %k0|%k0, %k1}
7572    test{l}\t{%k1, %k0|%k0, %k1}
7573    test{q}\t{%1, %0|%0, %1}
7574    test{q}\t{%1, %0|%0, %1}
7575    test{q}\t{%1, %0|%0, %1}"
7576   [(set_attr "type" "test")
7577    (set_attr "modrm" "0,1,0,1,1")
7578    (set_attr "mode" "SI,SI,DI,DI,DI")])
7579
7580 (define_insn "*testqi_1_maybe_si"
7581   [(set (reg FLAGS_REG)
7582         (compare
7583           (and:QI
7584             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7585             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7586           (const_int 0)))]
7587    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7588     && ix86_match_ccmode (insn,
7589                          CONST_INT_P (operands[1])
7590                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7591 {
7592   if (which_alternative == 3)
7593     {
7594       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7595         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7596       return "test{l}\t{%1, %k0|%k0, %1}";
7597     }
7598   return "test{b}\t{%1, %0|%0, %1}";
7599 }
7600   [(set_attr "type" "test")
7601    (set_attr "modrm" "0,1,1,1")
7602    (set_attr "mode" "QI,QI,QI,SI")
7603    (set_attr "pent_pair" "uv,np,uv,np")])
7604
7605 (define_insn "*test<mode>_1"
7606   [(set (reg FLAGS_REG)
7607         (compare
7608          (and:SWI124
7609           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7610           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7611          (const_int 0)))]
7612   "ix86_match_ccmode (insn, CCNOmode)
7613    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7614   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7615   [(set_attr "type" "test")
7616    (set_attr "modrm" "0,1,1")
7617    (set_attr "mode" "<MODE>")
7618    (set_attr "pent_pair" "uv,np,uv")])
7619
7620 (define_expand "testqi_ext_ccno_0"
7621   [(set (reg:CCNO FLAGS_REG)
7622         (compare:CCNO
7623           (and:SI
7624             (zero_extract:SI
7625               (match_operand 0 "ext_register_operand" "")
7626               (const_int 8)
7627               (const_int 8))
7628             (match_operand 1 "const_int_operand" ""))
7629           (const_int 0)))])
7630
7631 (define_insn "*testqi_ext_0"
7632   [(set (reg FLAGS_REG)
7633         (compare
7634           (and:SI
7635             (zero_extract:SI
7636               (match_operand 0 "ext_register_operand" "Q")
7637               (const_int 8)
7638               (const_int 8))
7639             (match_operand 1 "const_int_operand" "n"))
7640           (const_int 0)))]
7641   "ix86_match_ccmode (insn, CCNOmode)"
7642   "test{b}\t{%1, %h0|%h0, %1}"
7643   [(set_attr "type" "test")
7644    (set_attr "mode" "QI")
7645    (set_attr "length_immediate" "1")
7646    (set_attr "modrm" "1")
7647    (set_attr "pent_pair" "np")])
7648
7649 (define_insn "*testqi_ext_1_rex64"
7650   [(set (reg FLAGS_REG)
7651         (compare
7652           (and:SI
7653             (zero_extract:SI
7654               (match_operand 0 "ext_register_operand" "Q")
7655               (const_int 8)
7656               (const_int 8))
7657             (zero_extend:SI
7658               (match_operand:QI 1 "register_operand" "Q")))
7659           (const_int 0)))]
7660   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7661   "test{b}\t{%1, %h0|%h0, %1}"
7662   [(set_attr "type" "test")
7663    (set_attr "mode" "QI")])
7664
7665 (define_insn "*testqi_ext_1"
7666   [(set (reg FLAGS_REG)
7667         (compare
7668           (and:SI
7669             (zero_extract:SI
7670               (match_operand 0 "ext_register_operand" "Q")
7671               (const_int 8)
7672               (const_int 8))
7673             (zero_extend:SI
7674               (match_operand:QI 1 "general_operand" "Qm")))
7675           (const_int 0)))]
7676   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7677   "test{b}\t{%1, %h0|%h0, %1}"
7678   [(set_attr "type" "test")
7679    (set_attr "mode" "QI")])
7680
7681 (define_insn "*testqi_ext_2"
7682   [(set (reg FLAGS_REG)
7683         (compare
7684           (and:SI
7685             (zero_extract:SI
7686               (match_operand 0 "ext_register_operand" "Q")
7687               (const_int 8)
7688               (const_int 8))
7689             (zero_extract:SI
7690               (match_operand 1 "ext_register_operand" "Q")
7691               (const_int 8)
7692               (const_int 8)))
7693           (const_int 0)))]
7694   "ix86_match_ccmode (insn, CCNOmode)"
7695   "test{b}\t{%h1, %h0|%h0, %h1}"
7696   [(set_attr "type" "test")
7697    (set_attr "mode" "QI")])
7698
7699 (define_insn "*testqi_ext_3_rex64"
7700   [(set (reg FLAGS_REG)
7701         (compare (zero_extract:DI
7702                    (match_operand 0 "nonimmediate_operand" "rm")
7703                    (match_operand:DI 1 "const_int_operand" "")
7704                    (match_operand:DI 2 "const_int_operand" ""))
7705                  (const_int 0)))]
7706   "TARGET_64BIT
7707    && ix86_match_ccmode (insn, CCNOmode)
7708    && INTVAL (operands[1]) > 0
7709    && INTVAL (operands[2]) >= 0
7710    /* Ensure that resulting mask is zero or sign extended operand.  */
7711    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7712        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7713            && INTVAL (operands[1]) > 32))
7714    && (GET_MODE (operands[0]) == SImode
7715        || GET_MODE (operands[0]) == DImode
7716        || GET_MODE (operands[0]) == HImode
7717        || GET_MODE (operands[0]) == QImode)"
7718   "#")
7719
7720 ;; Combine likes to form bit extractions for some tests.  Humor it.
7721 (define_insn "*testqi_ext_3"
7722   [(set (reg FLAGS_REG)
7723         (compare (zero_extract:SI
7724                    (match_operand 0 "nonimmediate_operand" "rm")
7725                    (match_operand:SI 1 "const_int_operand" "")
7726                    (match_operand:SI 2 "const_int_operand" ""))
7727                  (const_int 0)))]
7728   "ix86_match_ccmode (insn, CCNOmode)
7729    && INTVAL (operands[1]) > 0
7730    && INTVAL (operands[2]) >= 0
7731    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7732    && (GET_MODE (operands[0]) == SImode
7733        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7734        || GET_MODE (operands[0]) == HImode
7735        || GET_MODE (operands[0]) == QImode)"
7736   "#")
7737
7738 (define_split
7739   [(set (match_operand 0 "flags_reg_operand" "")
7740         (match_operator 1 "compare_operator"
7741           [(zero_extract
7742              (match_operand 2 "nonimmediate_operand" "")
7743              (match_operand 3 "const_int_operand" "")
7744              (match_operand 4 "const_int_operand" ""))
7745            (const_int 0)]))]
7746   "ix86_match_ccmode (insn, CCNOmode)"
7747   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7748 {
7749   rtx val = operands[2];
7750   HOST_WIDE_INT len = INTVAL (operands[3]);
7751   HOST_WIDE_INT pos = INTVAL (operands[4]);
7752   HOST_WIDE_INT mask;
7753   enum machine_mode mode, submode;
7754
7755   mode = GET_MODE (val);
7756   if (MEM_P (val))
7757     {
7758       /* ??? Combine likes to put non-volatile mem extractions in QImode
7759          no matter the size of the test.  So find a mode that works.  */
7760       if (! MEM_VOLATILE_P (val))
7761         {
7762           mode = smallest_mode_for_size (pos + len, MODE_INT);
7763           val = adjust_address (val, mode, 0);
7764         }
7765     }
7766   else if (GET_CODE (val) == SUBREG
7767            && (submode = GET_MODE (SUBREG_REG (val)),
7768                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7769            && pos + len <= GET_MODE_BITSIZE (submode)
7770            && GET_MODE_CLASS (submode) == MODE_INT)
7771     {
7772       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7773       mode = submode;
7774       val = SUBREG_REG (val);
7775     }
7776   else if (mode == HImode && pos + len <= 8)
7777     {
7778       /* Small HImode tests can be converted to QImode.  */
7779       mode = QImode;
7780       val = gen_lowpart (QImode, val);
7781     }
7782
7783   if (len == HOST_BITS_PER_WIDE_INT)
7784     mask = -1;
7785   else
7786     mask = ((HOST_WIDE_INT)1 << len) - 1;
7787   mask <<= pos;
7788
7789   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7790 })
7791
7792 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7793 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7794 ;; this is relatively important trick.
7795 ;; Do the conversion only post-reload to avoid limiting of the register class
7796 ;; to QI regs.
7797 (define_split
7798   [(set (match_operand 0 "flags_reg_operand" "")
7799         (match_operator 1 "compare_operator"
7800           [(and (match_operand 2 "register_operand" "")
7801                 (match_operand 3 "const_int_operand" ""))
7802            (const_int 0)]))]
7803    "reload_completed
7804     && QI_REG_P (operands[2])
7805     && GET_MODE (operands[2]) != QImode
7806     && ((ix86_match_ccmode (insn, CCZmode)
7807          && !(INTVAL (operands[3]) & ~(255 << 8)))
7808         || (ix86_match_ccmode (insn, CCNOmode)
7809             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7810   [(set (match_dup 0)
7811         (match_op_dup 1
7812           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7813                    (match_dup 3))
7814            (const_int 0)]))]
7815   "operands[2] = gen_lowpart (SImode, operands[2]);
7816    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7817
7818 (define_split
7819   [(set (match_operand 0 "flags_reg_operand" "")
7820         (match_operator 1 "compare_operator"
7821           [(and (match_operand 2 "nonimmediate_operand" "")
7822                 (match_operand 3 "const_int_operand" ""))
7823            (const_int 0)]))]
7824    "reload_completed
7825     && GET_MODE (operands[2]) != QImode
7826     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7827     && ((ix86_match_ccmode (insn, CCZmode)
7828          && !(INTVAL (operands[3]) & ~255))
7829         || (ix86_match_ccmode (insn, CCNOmode)
7830             && !(INTVAL (operands[3]) & ~127)))"
7831   [(set (match_dup 0)
7832         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7833                          (const_int 0)]))]
7834   "operands[2] = gen_lowpart (QImode, operands[2]);
7835    operands[3] = gen_lowpart (QImode, operands[3]);")
7836
7837 ;; %%% This used to optimize known byte-wide and operations to memory,
7838 ;; and sometimes to QImode registers.  If this is considered useful,
7839 ;; it should be done with splitters.
7840
7841 (define_expand "and<mode>3"
7842   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7843         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7844                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7845   ""
7846   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7847
7848 (define_insn "*anddi_1"
7849   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7850         (and:DI
7851          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7852          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7853    (clobber (reg:CC FLAGS_REG))]
7854   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7855 {
7856   switch (get_attr_type (insn))
7857     {
7858     case TYPE_IMOVX:
7859       {
7860         enum machine_mode mode;
7861
7862         gcc_assert (CONST_INT_P (operands[2]));
7863         if (INTVAL (operands[2]) == 0xff)
7864           mode = QImode;
7865         else
7866           {
7867             gcc_assert (INTVAL (operands[2]) == 0xffff);
7868             mode = HImode;
7869           }
7870
7871         operands[1] = gen_lowpart (mode, operands[1]);
7872         if (mode == QImode)
7873           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7874         else
7875           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7876       }
7877
7878     default:
7879       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7880       if (get_attr_mode (insn) == MODE_SI)
7881         return "and{l}\t{%k2, %k0|%k0, %k2}";
7882       else
7883         return "and{q}\t{%2, %0|%0, %2}";
7884     }
7885 }
7886   [(set_attr "type" "alu,alu,alu,imovx")
7887    (set_attr "length_immediate" "*,*,*,0")
7888    (set (attr "prefix_rex")
7889      (if_then_else
7890        (and (eq_attr "type" "imovx")
7891             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7892                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7893        (const_string "1")
7894        (const_string "*")))
7895    (set_attr "mode" "SI,DI,DI,SI")])
7896
7897 (define_insn "*andsi_1"
7898   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7899         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7900                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7901    (clobber (reg:CC FLAGS_REG))]
7902   "ix86_binary_operator_ok (AND, SImode, operands)"
7903 {
7904   switch (get_attr_type (insn))
7905     {
7906     case TYPE_IMOVX:
7907       {
7908         enum machine_mode mode;
7909
7910         gcc_assert (CONST_INT_P (operands[2]));
7911         if (INTVAL (operands[2]) == 0xff)
7912           mode = QImode;
7913         else
7914           {
7915             gcc_assert (INTVAL (operands[2]) == 0xffff);
7916             mode = HImode;
7917           }
7918
7919         operands[1] = gen_lowpart (mode, operands[1]);
7920         if (mode == QImode)
7921           return "movz{bl|x}\t{%1, %0|%0, %1}";
7922         else
7923           return "movz{wl|x}\t{%1, %0|%0, %1}";
7924       }
7925
7926     default:
7927       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7928       return "and{l}\t{%2, %0|%0, %2}";
7929     }
7930 }
7931   [(set_attr "type" "alu,alu,imovx")
7932    (set (attr "prefix_rex")
7933      (if_then_else
7934        (and (eq_attr "type" "imovx")
7935             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7936                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7937        (const_string "1")
7938        (const_string "*")))
7939    (set_attr "length_immediate" "*,*,0")
7940    (set_attr "mode" "SI")])
7941
7942 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7943 (define_insn "*andsi_1_zext"
7944   [(set (match_operand:DI 0 "register_operand" "=r")
7945         (zero_extend:DI
7946           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7947                   (match_operand:SI 2 "general_operand" "g"))))
7948    (clobber (reg:CC FLAGS_REG))]
7949   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7950   "and{l}\t{%2, %k0|%k0, %2}"
7951   [(set_attr "type" "alu")
7952    (set_attr "mode" "SI")])
7953
7954 (define_insn "*andhi_1"
7955   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7956         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7957                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7958    (clobber (reg:CC FLAGS_REG))]
7959   "ix86_binary_operator_ok (AND, HImode, operands)"
7960 {
7961   switch (get_attr_type (insn))
7962     {
7963     case TYPE_IMOVX:
7964       gcc_assert (CONST_INT_P (operands[2]));
7965       gcc_assert (INTVAL (operands[2]) == 0xff);
7966       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7967
7968     default:
7969       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7970
7971       return "and{w}\t{%2, %0|%0, %2}";
7972     }
7973 }
7974   [(set_attr "type" "alu,alu,imovx")
7975    (set_attr "length_immediate" "*,*,0")
7976    (set (attr "prefix_rex")
7977      (if_then_else
7978        (and (eq_attr "type" "imovx")
7979             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7980        (const_string "1")
7981        (const_string "*")))
7982    (set_attr "mode" "HI,HI,SI")])
7983
7984 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7985 (define_insn "*andqi_1"
7986   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7987         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7988                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7989    (clobber (reg:CC FLAGS_REG))]
7990   "ix86_binary_operator_ok (AND, QImode, operands)"
7991   "@
7992    and{b}\t{%2, %0|%0, %2}
7993    and{b}\t{%2, %0|%0, %2}
7994    and{l}\t{%k2, %k0|%k0, %k2}"
7995   [(set_attr "type" "alu")
7996    (set_attr "mode" "QI,QI,SI")])
7997
7998 (define_insn "*andqi_1_slp"
7999   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8000         (and:QI (match_dup 0)
8001                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8002    (clobber (reg:CC FLAGS_REG))]
8003   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8004    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8005   "and{b}\t{%1, %0|%0, %1}"
8006   [(set_attr "type" "alu1")
8007    (set_attr "mode" "QI")])
8008
8009 (define_split
8010   [(set (match_operand 0 "register_operand" "")
8011         (and (match_dup 0)
8012              (const_int -65536)))
8013    (clobber (reg:CC FLAGS_REG))]
8014   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8015     || optimize_function_for_size_p (cfun)"
8016   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8017   "operands[1] = gen_lowpart (HImode, operands[0]);")
8018
8019 (define_split
8020   [(set (match_operand 0 "ext_register_operand" "")
8021         (and (match_dup 0)
8022              (const_int -256)))
8023    (clobber (reg:CC FLAGS_REG))]
8024   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8025    && reload_completed"
8026   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8027   "operands[1] = gen_lowpart (QImode, operands[0]);")
8028
8029 (define_split
8030   [(set (match_operand 0 "ext_register_operand" "")
8031         (and (match_dup 0)
8032              (const_int -65281)))
8033    (clobber (reg:CC FLAGS_REG))]
8034   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8035    && reload_completed"
8036   [(parallel [(set (zero_extract:SI (match_dup 0)
8037                                     (const_int 8)
8038                                     (const_int 8))
8039                    (xor:SI
8040                      (zero_extract:SI (match_dup 0)
8041                                       (const_int 8)
8042                                       (const_int 8))
8043                      (zero_extract:SI (match_dup 0)
8044                                       (const_int 8)
8045                                       (const_int 8))))
8046               (clobber (reg:CC FLAGS_REG))])]
8047   "operands[0] = gen_lowpart (SImode, operands[0]);")
8048
8049 (define_insn "*anddi_2"
8050   [(set (reg FLAGS_REG)
8051         (compare
8052          (and:DI
8053           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8054           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8055          (const_int 0)))
8056    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8057         (and:DI (match_dup 1) (match_dup 2)))]
8058   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8059    && ix86_binary_operator_ok (AND, DImode, operands)"
8060   "@
8061    and{l}\t{%k2, %k0|%k0, %k2}
8062    and{q}\t{%2, %0|%0, %2}
8063    and{q}\t{%2, %0|%0, %2}"
8064   [(set_attr "type" "alu")
8065    (set_attr "mode" "SI,DI,DI")])
8066
8067 (define_insn "*andqi_2_maybe_si"
8068   [(set (reg FLAGS_REG)
8069         (compare (and:QI
8070                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8071                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8072                  (const_int 0)))
8073    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8074         (and:QI (match_dup 1) (match_dup 2)))]
8075   "ix86_binary_operator_ok (AND, QImode, operands)
8076    && ix86_match_ccmode (insn,
8077                          CONST_INT_P (operands[2])
8078                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8079 {
8080   if (which_alternative == 2)
8081     {
8082       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8083         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8084       return "and{l}\t{%2, %k0|%k0, %2}";
8085     }
8086   return "and{b}\t{%2, %0|%0, %2}";
8087 }
8088   [(set_attr "type" "alu")
8089    (set_attr "mode" "QI,QI,SI")])
8090
8091 (define_insn "*and<mode>_2"
8092   [(set (reg FLAGS_REG)
8093         (compare (and:SWI124
8094                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8095                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8096                  (const_int 0)))
8097    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8098         (and:SWI124 (match_dup 1) (match_dup 2)))]
8099   "ix86_match_ccmode (insn, CCNOmode)
8100    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8101   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8102   [(set_attr "type" "alu")
8103    (set_attr "mode" "<MODE>")])
8104
8105 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8106 (define_insn "*andsi_2_zext"
8107   [(set (reg FLAGS_REG)
8108         (compare (and:SI
8109                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8110                   (match_operand:SI 2 "general_operand" "g"))
8111                  (const_int 0)))
8112    (set (match_operand:DI 0 "register_operand" "=r")
8113         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8114   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8115    && ix86_binary_operator_ok (AND, SImode, operands)"
8116   "and{l}\t{%2, %k0|%k0, %2}"
8117   [(set_attr "type" "alu")
8118    (set_attr "mode" "SI")])
8119
8120 (define_insn "*andqi_2_slp"
8121   [(set (reg FLAGS_REG)
8122         (compare (and:QI
8123                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8124                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8125                  (const_int 0)))
8126    (set (strict_low_part (match_dup 0))
8127         (and:QI (match_dup 0) (match_dup 1)))]
8128   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8129    && ix86_match_ccmode (insn, CCNOmode)
8130    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8131   "and{b}\t{%1, %0|%0, %1}"
8132   [(set_attr "type" "alu1")
8133    (set_attr "mode" "QI")])
8134
8135 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8136 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8137 ;; for a QImode operand, which of course failed.
8138 (define_insn "andqi_ext_0"
8139   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8140                          (const_int 8)
8141                          (const_int 8))
8142         (and:SI
8143           (zero_extract:SI
8144             (match_operand 1 "ext_register_operand" "0")
8145             (const_int 8)
8146             (const_int 8))
8147           (match_operand 2 "const_int_operand" "n")))
8148    (clobber (reg:CC FLAGS_REG))]
8149   ""
8150   "and{b}\t{%2, %h0|%h0, %2}"
8151   [(set_attr "type" "alu")
8152    (set_attr "length_immediate" "1")
8153    (set_attr "modrm" "1")
8154    (set_attr "mode" "QI")])
8155
8156 ;; Generated by peephole translating test to and.  This shows up
8157 ;; often in fp comparisons.
8158 (define_insn "*andqi_ext_0_cc"
8159   [(set (reg FLAGS_REG)
8160         (compare
8161           (and:SI
8162             (zero_extract:SI
8163               (match_operand 1 "ext_register_operand" "0")
8164               (const_int 8)
8165               (const_int 8))
8166             (match_operand 2 "const_int_operand" "n"))
8167           (const_int 0)))
8168    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8169                          (const_int 8)
8170                          (const_int 8))
8171         (and:SI
8172           (zero_extract:SI
8173             (match_dup 1)
8174             (const_int 8)
8175             (const_int 8))
8176           (match_dup 2)))]
8177   "ix86_match_ccmode (insn, CCNOmode)"
8178   "and{b}\t{%2, %h0|%h0, %2}"
8179   [(set_attr "type" "alu")
8180    (set_attr "length_immediate" "1")
8181    (set_attr "modrm" "1")
8182    (set_attr "mode" "QI")])
8183
8184 (define_insn "*andqi_ext_1_rex64"
8185   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8186                          (const_int 8)
8187                          (const_int 8))
8188         (and:SI
8189           (zero_extract:SI
8190             (match_operand 1 "ext_register_operand" "0")
8191             (const_int 8)
8192             (const_int 8))
8193           (zero_extend:SI
8194             (match_operand 2 "ext_register_operand" "Q"))))
8195    (clobber (reg:CC FLAGS_REG))]
8196   "TARGET_64BIT"
8197   "and{b}\t{%2, %h0|%h0, %2}"
8198   [(set_attr "type" "alu")
8199    (set_attr "length_immediate" "0")
8200    (set_attr "mode" "QI")])
8201
8202 (define_insn "*andqi_ext_1"
8203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8204                          (const_int 8)
8205                          (const_int 8))
8206         (and:SI
8207           (zero_extract:SI
8208             (match_operand 1 "ext_register_operand" "0")
8209             (const_int 8)
8210             (const_int 8))
8211           (zero_extend:SI
8212             (match_operand:QI 2 "general_operand" "Qm"))))
8213    (clobber (reg:CC FLAGS_REG))]
8214   "!TARGET_64BIT"
8215   "and{b}\t{%2, %h0|%h0, %2}"
8216   [(set_attr "type" "alu")
8217    (set_attr "length_immediate" "0")
8218    (set_attr "mode" "QI")])
8219
8220 (define_insn "*andqi_ext_2"
8221   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8222                          (const_int 8)
8223                          (const_int 8))
8224         (and:SI
8225           (zero_extract:SI
8226             (match_operand 1 "ext_register_operand" "%0")
8227             (const_int 8)
8228             (const_int 8))
8229           (zero_extract:SI
8230             (match_operand 2 "ext_register_operand" "Q")
8231             (const_int 8)
8232             (const_int 8))))
8233    (clobber (reg:CC FLAGS_REG))]
8234   ""
8235   "and{b}\t{%h2, %h0|%h0, %h2}"
8236   [(set_attr "type" "alu")
8237    (set_attr "length_immediate" "0")
8238    (set_attr "mode" "QI")])
8239
8240 ;; Convert wide AND instructions with immediate operand to shorter QImode
8241 ;; equivalents when possible.
8242 ;; Don't do the splitting with memory operands, since it introduces risk
8243 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8244 ;; for size, but that can (should?) be handled by generic code instead.
8245 (define_split
8246   [(set (match_operand 0 "register_operand" "")
8247         (and (match_operand 1 "register_operand" "")
8248              (match_operand 2 "const_int_operand" "")))
8249    (clobber (reg:CC FLAGS_REG))]
8250    "reload_completed
8251     && QI_REG_P (operands[0])
8252     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8253     && !(~INTVAL (operands[2]) & ~(255 << 8))
8254     && GET_MODE (operands[0]) != QImode"
8255   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8256                    (and:SI (zero_extract:SI (match_dup 1)
8257                                             (const_int 8) (const_int 8))
8258                            (match_dup 2)))
8259               (clobber (reg:CC FLAGS_REG))])]
8260   "operands[0] = gen_lowpart (SImode, operands[0]);
8261    operands[1] = gen_lowpart (SImode, operands[1]);
8262    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8263
8264 ;; Since AND can be encoded with sign extended immediate, this is only
8265 ;; profitable when 7th bit is not set.
8266 (define_split
8267   [(set (match_operand 0 "register_operand" "")
8268         (and (match_operand 1 "general_operand" "")
8269              (match_operand 2 "const_int_operand" "")))
8270    (clobber (reg:CC FLAGS_REG))]
8271    "reload_completed
8272     && ANY_QI_REG_P (operands[0])
8273     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8274     && !(~INTVAL (operands[2]) & ~255)
8275     && !(INTVAL (operands[2]) & 128)
8276     && GET_MODE (operands[0]) != QImode"
8277   [(parallel [(set (strict_low_part (match_dup 0))
8278                    (and:QI (match_dup 1)
8279                            (match_dup 2)))
8280               (clobber (reg:CC FLAGS_REG))])]
8281   "operands[0] = gen_lowpart (QImode, operands[0]);
8282    operands[1] = gen_lowpart (QImode, operands[1]);
8283    operands[2] = gen_lowpart (QImode, operands[2]);")
8284 \f
8285 ;; Logical inclusive and exclusive OR instructions
8286
8287 ;; %%% This used to optimize known byte-wide and operations to memory.
8288 ;; If this is considered useful, it should be done with splitters.
8289
8290 (define_expand "<code><mode>3"
8291   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8292         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8293                      (match_operand:SWIM 2 "<general_operand>" "")))]
8294   ""
8295   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8296
8297 (define_insn "*<code><mode>_1"
8298   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8299         (any_or:SWI248
8300          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8301          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8302    (clobber (reg:CC FLAGS_REG))]
8303   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8304   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "<MODE>")])
8307
8308 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8309 (define_insn "*<code>qi_1"
8310   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8311         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8312                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8315   "@
8316    <logic>{b}\t{%2, %0|%0, %2}
8317    <logic>{b}\t{%2, %0|%0, %2}
8318    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8319   [(set_attr "type" "alu")
8320    (set_attr "mode" "QI,QI,SI")])
8321
8322 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8323 (define_insn "*<code>si_1_zext"
8324   [(set (match_operand:DI 0 "register_operand" "=r")
8325         (zero_extend:DI
8326          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8327                     (match_operand:SI 2 "general_operand" "g"))))
8328    (clobber (reg:CC FLAGS_REG))]
8329   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8330   "<logic>{l}\t{%2, %k0|%k0, %2}"
8331   [(set_attr "type" "alu")
8332    (set_attr "mode" "SI")])
8333
8334 (define_insn "*<code>si_1_zext_imm"
8335   [(set (match_operand:DI 0 "register_operand" "=r")
8336         (any_or:DI
8337          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8338          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8339    (clobber (reg:CC FLAGS_REG))]
8340   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8341   "<logic>{l}\t{%2, %k0|%k0, %2}"
8342   [(set_attr "type" "alu")
8343    (set_attr "mode" "SI")])
8344
8345 (define_insn "*<code>qi_1_slp"
8346   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8347         (any_or:QI (match_dup 0)
8348                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8349    (clobber (reg:CC FLAGS_REG))]
8350   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8351    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8352   "<logic>{b}\t{%1, %0|%0, %1}"
8353   [(set_attr "type" "alu1")
8354    (set_attr "mode" "QI")])
8355
8356 (define_insn "*<code><mode>_2"
8357   [(set (reg FLAGS_REG)
8358         (compare (any_or:SWI
8359                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8360                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8361                  (const_int 0)))
8362    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8363         (any_or:SWI (match_dup 1) (match_dup 2)))]
8364   "ix86_match_ccmode (insn, CCNOmode)
8365    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8366   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8367   [(set_attr "type" "alu")
8368    (set_attr "mode" "<MODE>")])
8369
8370 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8371 ;; ??? Special case for immediate operand is missing - it is tricky.
8372 (define_insn "*<code>si_2_zext"
8373   [(set (reg FLAGS_REG)
8374         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8375                             (match_operand:SI 2 "general_operand" "g"))
8376                  (const_int 0)))
8377    (set (match_operand:DI 0 "register_operand" "=r")
8378         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8379   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8380    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381   "<logic>{l}\t{%2, %k0|%k0, %2}"
8382   [(set_attr "type" "alu")
8383    (set_attr "mode" "SI")])
8384
8385 (define_insn "*<code>si_2_zext_imm"
8386   [(set (reg FLAGS_REG)
8387         (compare (any_or:SI
8388                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8389                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8390                  (const_int 0)))
8391    (set (match_operand:DI 0 "register_operand" "=r")
8392         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8393   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8394    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8395   "<logic>{l}\t{%2, %k0|%k0, %2}"
8396   [(set_attr "type" "alu")
8397    (set_attr "mode" "SI")])
8398
8399 (define_insn "*<code>qi_2_slp"
8400   [(set (reg FLAGS_REG)
8401         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8402                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8403                  (const_int 0)))
8404    (set (strict_low_part (match_dup 0))
8405         (any_or:QI (match_dup 0) (match_dup 1)))]
8406   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8407    && ix86_match_ccmode (insn, CCNOmode)
8408    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8409   "<logic>{b}\t{%1, %0|%0, %1}"
8410   [(set_attr "type" "alu1")
8411    (set_attr "mode" "QI")])
8412
8413 (define_insn "*<code><mode>_3"
8414   [(set (reg FLAGS_REG)
8415         (compare (any_or:SWI
8416                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8417                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8418                  (const_int 0)))
8419    (clobber (match_scratch:SWI 0 "=<r>"))]
8420   "ix86_match_ccmode (insn, CCNOmode)
8421    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8422   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8423   [(set_attr "type" "alu")
8424    (set_attr "mode" "<MODE>")])
8425
8426 (define_insn "*<code>qi_ext_0"
8427   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8428                          (const_int 8)
8429                          (const_int 8))
8430         (any_or:SI
8431           (zero_extract:SI
8432             (match_operand 1 "ext_register_operand" "0")
8433             (const_int 8)
8434             (const_int 8))
8435           (match_operand 2 "const_int_operand" "n")))
8436    (clobber (reg:CC FLAGS_REG))]
8437   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8438   "<logic>{b}\t{%2, %h0|%h0, %2}"
8439   [(set_attr "type" "alu")
8440    (set_attr "length_immediate" "1")
8441    (set_attr "modrm" "1")
8442    (set_attr "mode" "QI")])
8443
8444 (define_insn "*<code>qi_ext_1_rex64"
8445   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8446                          (const_int 8)
8447                          (const_int 8))
8448         (any_or:SI
8449           (zero_extract:SI
8450             (match_operand 1 "ext_register_operand" "0")
8451             (const_int 8)
8452             (const_int 8))
8453           (zero_extend:SI
8454             (match_operand 2 "ext_register_operand" "Q"))))
8455    (clobber (reg:CC FLAGS_REG))]
8456   "TARGET_64BIT
8457    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8458   "<logic>{b}\t{%2, %h0|%h0, %2}"
8459   [(set_attr "type" "alu")
8460    (set_attr "length_immediate" "0")
8461    (set_attr "mode" "QI")])
8462
8463 (define_insn "*<code>qi_ext_1"
8464   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8465                          (const_int 8)
8466                          (const_int 8))
8467         (any_or:SI
8468           (zero_extract:SI
8469             (match_operand 1 "ext_register_operand" "0")
8470             (const_int 8)
8471             (const_int 8))
8472           (zero_extend:SI
8473             (match_operand:QI 2 "general_operand" "Qm"))))
8474    (clobber (reg:CC FLAGS_REG))]
8475   "!TARGET_64BIT
8476    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8477   "<logic>{b}\t{%2, %h0|%h0, %2}"
8478   [(set_attr "type" "alu")
8479    (set_attr "length_immediate" "0")
8480    (set_attr "mode" "QI")])
8481
8482 (define_insn "*<code>qi_ext_2"
8483   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8484                          (const_int 8)
8485                          (const_int 8))
8486         (any_or:SI
8487           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8488                            (const_int 8)
8489                            (const_int 8))
8490           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8491                            (const_int 8)
8492                            (const_int 8))))
8493    (clobber (reg:CC FLAGS_REG))]
8494   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8495   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8496   [(set_attr "type" "alu")
8497    (set_attr "length_immediate" "0")
8498    (set_attr "mode" "QI")])
8499
8500 (define_split
8501   [(set (match_operand 0 "register_operand" "")
8502         (any_or (match_operand 1 "register_operand" "")
8503                 (match_operand 2 "const_int_operand" "")))
8504    (clobber (reg:CC FLAGS_REG))]
8505    "reload_completed
8506     && QI_REG_P (operands[0])
8507     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8508     && !(INTVAL (operands[2]) & ~(255 << 8))
8509     && GET_MODE (operands[0]) != QImode"
8510   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8511                    (any_or:SI (zero_extract:SI (match_dup 1)
8512                                                (const_int 8) (const_int 8))
8513                               (match_dup 2)))
8514               (clobber (reg:CC FLAGS_REG))])]
8515   "operands[0] = gen_lowpart (SImode, operands[0]);
8516    operands[1] = gen_lowpart (SImode, operands[1]);
8517    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8518
8519 ;; Since OR can be encoded with sign extended immediate, this is only
8520 ;; profitable when 7th bit is set.
8521 (define_split
8522   [(set (match_operand 0 "register_operand" "")
8523         (any_or (match_operand 1 "general_operand" "")
8524                 (match_operand 2 "const_int_operand" "")))
8525    (clobber (reg:CC FLAGS_REG))]
8526    "reload_completed
8527     && ANY_QI_REG_P (operands[0])
8528     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8529     && !(INTVAL (operands[2]) & ~255)
8530     && (INTVAL (operands[2]) & 128)
8531     && GET_MODE (operands[0]) != QImode"
8532   [(parallel [(set (strict_low_part (match_dup 0))
8533                    (any_or:QI (match_dup 1)
8534                               (match_dup 2)))
8535               (clobber (reg:CC FLAGS_REG))])]
8536   "operands[0] = gen_lowpart (QImode, operands[0]);
8537    operands[1] = gen_lowpart (QImode, operands[1]);
8538    operands[2] = gen_lowpart (QImode, operands[2]);")
8539
8540 (define_expand "xorqi_cc_ext_1"
8541   [(parallel [
8542      (set (reg:CCNO FLAGS_REG)
8543           (compare:CCNO
8544             (xor:SI
8545               (zero_extract:SI
8546                 (match_operand 1 "ext_register_operand" "")
8547                 (const_int 8)
8548                 (const_int 8))
8549               (match_operand:QI 2 "general_operand" ""))
8550             (const_int 0)))
8551      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8552                            (const_int 8)
8553                            (const_int 8))
8554           (xor:SI
8555             (zero_extract:SI
8556              (match_dup 1)
8557              (const_int 8)
8558              (const_int 8))
8559             (match_dup 2)))])])
8560
8561 (define_insn "*xorqi_cc_ext_1_rex64"
8562   [(set (reg FLAGS_REG)
8563         (compare
8564           (xor:SI
8565             (zero_extract:SI
8566               (match_operand 1 "ext_register_operand" "0")
8567               (const_int 8)
8568               (const_int 8))
8569             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8570           (const_int 0)))
8571    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8572                          (const_int 8)
8573                          (const_int 8))
8574         (xor:SI
8575           (zero_extract:SI
8576            (match_dup 1)
8577            (const_int 8)
8578            (const_int 8))
8579           (match_dup 2)))]
8580   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8581   "xor{b}\t{%2, %h0|%h0, %2}"
8582   [(set_attr "type" "alu")
8583    (set_attr "modrm" "1")
8584    (set_attr "mode" "QI")])
8585
8586 (define_insn "*xorqi_cc_ext_1"
8587   [(set (reg FLAGS_REG)
8588         (compare
8589           (xor:SI
8590             (zero_extract:SI
8591               (match_operand 1 "ext_register_operand" "0")
8592               (const_int 8)
8593               (const_int 8))
8594             (match_operand:QI 2 "general_operand" "qmn"))
8595           (const_int 0)))
8596    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8597                          (const_int 8)
8598                          (const_int 8))
8599         (xor:SI
8600           (zero_extract:SI
8601            (match_dup 1)
8602            (const_int 8)
8603            (const_int 8))
8604           (match_dup 2)))]
8605   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8606   "xor{b}\t{%2, %h0|%h0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "modrm" "1")
8609    (set_attr "mode" "QI")])
8610 \f
8611 ;; Negation instructions
8612
8613 (define_expand "neg<mode>2"
8614   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8615         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8616   ""
8617   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8618
8619 (define_insn_and_split "*neg<dwi>2_doubleword"
8620   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8621         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8622    (clobber (reg:CC FLAGS_REG))]
8623   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8624   "#"
8625   "reload_completed"
8626   [(parallel
8627     [(set (reg:CCZ FLAGS_REG)
8628           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8629      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8630    (parallel
8631     [(set (match_dup 2)
8632           (plus:DWIH (match_dup 3)
8633                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8634                                 (const_int 0))))
8635      (clobber (reg:CC FLAGS_REG))])
8636    (parallel
8637     [(set (match_dup 2)
8638           (neg:DWIH (match_dup 2)))
8639      (clobber (reg:CC FLAGS_REG))])]
8640   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8641
8642 (define_insn "*neg<mode>2_1"
8643   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8644         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8645    (clobber (reg:CC FLAGS_REG))]
8646   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8647   "neg{<imodesuffix>}\t%0"
8648   [(set_attr "type" "negnot")
8649    (set_attr "mode" "<MODE>")])
8650
8651 ;; Combine is quite creative about this pattern.
8652 (define_insn "*negsi2_1_zext"
8653   [(set (match_operand:DI 0 "register_operand" "=r")
8654         (lshiftrt:DI
8655           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8656                              (const_int 32)))
8657         (const_int 32)))
8658    (clobber (reg:CC FLAGS_REG))]
8659   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8660   "neg{l}\t%k0"
8661   [(set_attr "type" "negnot")
8662    (set_attr "mode" "SI")])
8663
8664 ;; The problem with neg is that it does not perform (compare x 0),
8665 ;; it really performs (compare 0 x), which leaves us with the zero
8666 ;; flag being the only useful item.
8667
8668 (define_insn "*neg<mode>2_cmpz"
8669   [(set (reg:CCZ FLAGS_REG)
8670         (compare:CCZ
8671           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8672                    (const_int 0)))
8673    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8674         (neg:SWI (match_dup 1)))]
8675   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8676   "neg{<imodesuffix>}\t%0"
8677   [(set_attr "type" "negnot")
8678    (set_attr "mode" "<MODE>")])
8679
8680 (define_insn "*negsi2_cmpz_zext"
8681   [(set (reg:CCZ FLAGS_REG)
8682         (compare:CCZ
8683           (lshiftrt:DI
8684             (neg:DI (ashift:DI
8685                       (match_operand:DI 1 "register_operand" "0")
8686                       (const_int 32)))
8687             (const_int 32))
8688           (const_int 0)))
8689    (set (match_operand:DI 0 "register_operand" "=r")
8690         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8691                                         (const_int 32)))
8692                      (const_int 32)))]
8693   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8694   "neg{l}\t%k0"
8695   [(set_attr "type" "negnot")
8696    (set_attr "mode" "SI")])
8697
8698 ;; Changing of sign for FP values is doable using integer unit too.
8699
8700 (define_expand "<code><mode>2"
8701   [(set (match_operand:X87MODEF 0 "register_operand" "")
8702         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8703   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8704   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8705
8706 (define_insn "*absneg<mode>2_mixed"
8707   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8708         (match_operator:MODEF 3 "absneg_operator"
8709           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8710    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8711    (clobber (reg:CC FLAGS_REG))]
8712   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8713   "#")
8714
8715 (define_insn "*absneg<mode>2_sse"
8716   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8717         (match_operator:MODEF 3 "absneg_operator"
8718           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8719    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8720    (clobber (reg:CC FLAGS_REG))]
8721   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8722   "#")
8723
8724 (define_insn "*absneg<mode>2_i387"
8725   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8726         (match_operator:X87MODEF 3 "absneg_operator"
8727           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8728    (use (match_operand 2 "" ""))
8729    (clobber (reg:CC FLAGS_REG))]
8730   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8731   "#")
8732
8733 (define_expand "<code>tf2"
8734   [(set (match_operand:TF 0 "register_operand" "")
8735         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8736   "TARGET_SSE2"
8737   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8738
8739 (define_insn "*absnegtf2_sse"
8740   [(set (match_operand:TF 0 "register_operand" "=x,x")
8741         (match_operator:TF 3 "absneg_operator"
8742           [(match_operand:TF 1 "register_operand" "0,x")]))
8743    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8744    (clobber (reg:CC FLAGS_REG))]
8745   "TARGET_SSE2"
8746   "#")
8747
8748 ;; Splitters for fp abs and neg.
8749
8750 (define_split
8751   [(set (match_operand 0 "fp_register_operand" "")
8752         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8753    (use (match_operand 2 "" ""))
8754    (clobber (reg:CC FLAGS_REG))]
8755   "reload_completed"
8756   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8757
8758 (define_split
8759   [(set (match_operand 0 "register_operand" "")
8760         (match_operator 3 "absneg_operator"
8761           [(match_operand 1 "register_operand" "")]))
8762    (use (match_operand 2 "nonimmediate_operand" ""))
8763    (clobber (reg:CC FLAGS_REG))]
8764   "reload_completed && SSE_REG_P (operands[0])"
8765   [(set (match_dup 0) (match_dup 3))]
8766 {
8767   enum machine_mode mode = GET_MODE (operands[0]);
8768   enum machine_mode vmode = GET_MODE (operands[2]);
8769   rtx tmp;
8770
8771   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8772   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8773   if (operands_match_p (operands[0], operands[2]))
8774     {
8775       tmp = operands[1];
8776       operands[1] = operands[2];
8777       operands[2] = tmp;
8778     }
8779   if (GET_CODE (operands[3]) == ABS)
8780     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8781   else
8782     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8783   operands[3] = tmp;
8784 })
8785
8786 (define_split
8787   [(set (match_operand:SF 0 "register_operand" "")
8788         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8789    (use (match_operand:V4SF 2 "" ""))
8790    (clobber (reg:CC FLAGS_REG))]
8791   "reload_completed"
8792   [(parallel [(set (match_dup 0) (match_dup 1))
8793               (clobber (reg:CC FLAGS_REG))])]
8794 {
8795   rtx tmp;
8796   operands[0] = gen_lowpart (SImode, operands[0]);
8797   if (GET_CODE (operands[1]) == ABS)
8798     {
8799       tmp = gen_int_mode (0x7fffffff, SImode);
8800       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8801     }
8802   else
8803     {
8804       tmp = gen_int_mode (0x80000000, SImode);
8805       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8806     }
8807   operands[1] = tmp;
8808 })
8809
8810 (define_split
8811   [(set (match_operand:DF 0 "register_operand" "")
8812         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8813    (use (match_operand 2 "" ""))
8814    (clobber (reg:CC FLAGS_REG))]
8815   "reload_completed"
8816   [(parallel [(set (match_dup 0) (match_dup 1))
8817               (clobber (reg:CC FLAGS_REG))])]
8818 {
8819   rtx tmp;
8820   if (TARGET_64BIT)
8821     {
8822       tmp = gen_lowpart (DImode, operands[0]);
8823       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8824       operands[0] = tmp;
8825
8826       if (GET_CODE (operands[1]) == ABS)
8827         tmp = const0_rtx;
8828       else
8829         tmp = gen_rtx_NOT (DImode, tmp);
8830     }
8831   else
8832     {
8833       operands[0] = gen_highpart (SImode, operands[0]);
8834       if (GET_CODE (operands[1]) == ABS)
8835         {
8836           tmp = gen_int_mode (0x7fffffff, SImode);
8837           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8838         }
8839       else
8840         {
8841           tmp = gen_int_mode (0x80000000, SImode);
8842           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8843         }
8844     }
8845   operands[1] = tmp;
8846 })
8847
8848 (define_split
8849   [(set (match_operand:XF 0 "register_operand" "")
8850         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8851    (use (match_operand 2 "" ""))
8852    (clobber (reg:CC FLAGS_REG))]
8853   "reload_completed"
8854   [(parallel [(set (match_dup 0) (match_dup 1))
8855               (clobber (reg:CC FLAGS_REG))])]
8856 {
8857   rtx tmp;
8858   operands[0] = gen_rtx_REG (SImode,
8859                              true_regnum (operands[0])
8860                              + (TARGET_64BIT ? 1 : 2));
8861   if (GET_CODE (operands[1]) == ABS)
8862     {
8863       tmp = GEN_INT (0x7fff);
8864       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8865     }
8866   else
8867     {
8868       tmp = GEN_INT (0x8000);
8869       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8870     }
8871   operands[1] = tmp;
8872 })
8873
8874 ;; Conditionalize these after reload. If they match before reload, we
8875 ;; lose the clobber and ability to use integer instructions.
8876
8877 (define_insn "*<code><mode>2_1"
8878   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8879         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8880   "TARGET_80387
8881    && (reload_completed
8882        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8883   "f<absneg_mnemonic>"
8884   [(set_attr "type" "fsgn")
8885    (set_attr "mode" "<MODE>")])
8886
8887 (define_insn "*<code>extendsfdf2"
8888   [(set (match_operand:DF 0 "register_operand" "=f")
8889         (absneg:DF (float_extend:DF
8890                      (match_operand:SF 1 "register_operand" "0"))))]
8891   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8892   "f<absneg_mnemonic>"
8893   [(set_attr "type" "fsgn")
8894    (set_attr "mode" "DF")])
8895
8896 (define_insn "*<code>extendsfxf2"
8897   [(set (match_operand:XF 0 "register_operand" "=f")
8898         (absneg:XF (float_extend:XF
8899                      (match_operand:SF 1 "register_operand" "0"))))]
8900   "TARGET_80387"
8901   "f<absneg_mnemonic>"
8902   [(set_attr "type" "fsgn")
8903    (set_attr "mode" "XF")])
8904
8905 (define_insn "*<code>extenddfxf2"
8906   [(set (match_operand:XF 0 "register_operand" "=f")
8907         (absneg:XF (float_extend:XF
8908                      (match_operand:DF 1 "register_operand" "0"))))]
8909   "TARGET_80387"
8910   "f<absneg_mnemonic>"
8911   [(set_attr "type" "fsgn")
8912    (set_attr "mode" "XF")])
8913
8914 ;; Copysign instructions
8915
8916 (define_mode_iterator CSGNMODE [SF DF TF])
8917 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8918
8919 (define_expand "copysign<mode>3"
8920   [(match_operand:CSGNMODE 0 "register_operand" "")
8921    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8922    (match_operand:CSGNMODE 2 "register_operand" "")]
8923   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8924    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8925   "ix86_expand_copysign (operands); DONE;")
8926
8927 (define_insn_and_split "copysign<mode>3_const"
8928   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8929         (unspec:CSGNMODE
8930           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8931            (match_operand:CSGNMODE 2 "register_operand" "0")
8932            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8933           UNSPEC_COPYSIGN))]
8934   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8935    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8936   "#"
8937   "&& reload_completed"
8938   [(const_int 0)]
8939   "ix86_split_copysign_const (operands); DONE;")
8940
8941 (define_insn "copysign<mode>3_var"
8942   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8943         (unspec:CSGNMODE
8944           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8945            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8946            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8947            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8948           UNSPEC_COPYSIGN))
8949    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8950   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8951    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8952   "#")
8953
8954 (define_split
8955   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8956         (unspec:CSGNMODE
8957           [(match_operand:CSGNMODE 2 "register_operand" "")
8958            (match_operand:CSGNMODE 3 "register_operand" "")
8959            (match_operand:<CSGNVMODE> 4 "" "")
8960            (match_operand:<CSGNVMODE> 5 "" "")]
8961           UNSPEC_COPYSIGN))
8962    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8963   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8964     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8965    && reload_completed"
8966   [(const_int 0)]
8967   "ix86_split_copysign_var (operands); DONE;")
8968 \f
8969 ;; One complement instructions
8970
8971 (define_expand "one_cmpl<mode>2"
8972   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8973         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8974   ""
8975   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8976
8977 (define_insn "*one_cmpl<mode>2_1"
8978   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8979         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8980   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8981   "not{<imodesuffix>}\t%0"
8982   [(set_attr "type" "negnot")
8983    (set_attr "mode" "<MODE>")])
8984
8985 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8986 (define_insn "*one_cmplqi2_1"
8987   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8988         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8989   "ix86_unary_operator_ok (NOT, QImode, operands)"
8990   "@
8991    not{b}\t%0
8992    not{l}\t%k0"
8993   [(set_attr "type" "negnot")
8994    (set_attr "mode" "QI,SI")])
8995
8996 ;; ??? Currently never generated - xor is used instead.
8997 (define_insn "*one_cmplsi2_1_zext"
8998   [(set (match_operand:DI 0 "register_operand" "=r")
8999         (zero_extend:DI
9000           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9001   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9002   "not{l}\t%k0"
9003   [(set_attr "type" "negnot")
9004    (set_attr "mode" "SI")])
9005
9006 (define_insn "*one_cmpl<mode>2_2"
9007   [(set (reg FLAGS_REG)
9008         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9009                  (const_int 0)))
9010    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9011         (not:SWI (match_dup 1)))]
9012   "ix86_match_ccmode (insn, CCNOmode)
9013    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9014   "#"
9015   [(set_attr "type" "alu1")
9016    (set_attr "mode" "<MODE>")])
9017
9018 (define_split
9019   [(set (match_operand 0 "flags_reg_operand" "")
9020         (match_operator 2 "compare_operator"
9021           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9022            (const_int 0)]))
9023    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9024         (not:SWI (match_dup 3)))]
9025   "ix86_match_ccmode (insn, CCNOmode)"
9026   [(parallel [(set (match_dup 0)
9027                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9028                                     (const_int 0)]))
9029               (set (match_dup 1)
9030                    (xor:SWI (match_dup 3) (const_int -1)))])])
9031
9032 ;; ??? Currently never generated - xor is used instead.
9033 (define_insn "*one_cmplsi2_2_zext"
9034   [(set (reg FLAGS_REG)
9035         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9036                  (const_int 0)))
9037    (set (match_operand:DI 0 "register_operand" "=r")
9038         (zero_extend:DI (not:SI (match_dup 1))))]
9039   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9040    && ix86_unary_operator_ok (NOT, SImode, operands)"
9041   "#"
9042   [(set_attr "type" "alu1")
9043    (set_attr "mode" "SI")])
9044
9045 (define_split
9046   [(set (match_operand 0 "flags_reg_operand" "")
9047         (match_operator 2 "compare_operator"
9048           [(not:SI (match_operand:SI 3 "register_operand" ""))
9049            (const_int 0)]))
9050    (set (match_operand:DI 1 "register_operand" "")
9051         (zero_extend:DI (not:SI (match_dup 3))))]
9052   "ix86_match_ccmode (insn, CCNOmode)"
9053   [(parallel [(set (match_dup 0)
9054                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9055                                     (const_int 0)]))
9056               (set (match_dup 1)
9057                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9058 \f
9059 ;; Shift instructions
9060
9061 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9062 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9063 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9064 ;; from the assembler input.
9065 ;;
9066 ;; This instruction shifts the target reg/mem as usual, but instead of
9067 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9068 ;; is a left shift double, bits are taken from the high order bits of
9069 ;; reg, else if the insn is a shift right double, bits are taken from the
9070 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9071 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9072 ;;
9073 ;; Since sh[lr]d does not change the `reg' operand, that is done
9074 ;; separately, making all shifts emit pairs of shift double and normal
9075 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9076 ;; support a 63 bit shift, each shift where the count is in a reg expands
9077 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9078 ;;
9079 ;; If the shift count is a constant, we need never emit more than one
9080 ;; shift pair, instead using moves and sign extension for counts greater
9081 ;; than 31.
9082
9083 (define_expand "ashl<mode>3"
9084   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9085         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9086                       (match_operand:QI 2 "nonmemory_operand" "")))]
9087   ""
9088   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9089
9090 (define_insn "*ashl<mode>3_doubleword"
9091   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9092         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9093                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9094    (clobber (reg:CC FLAGS_REG))]
9095   ""
9096   "#"
9097   [(set_attr "type" "multi")])
9098
9099 (define_split
9100   [(set (match_operand:DWI 0 "register_operand" "")
9101         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9102                     (match_operand:QI 2 "nonmemory_operand" "")))
9103    (clobber (reg:CC FLAGS_REG))]
9104   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9105   [(const_int 0)]
9106   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9107
9108 ;; By default we don't ask for a scratch register, because when DWImode
9109 ;; values are manipulated, registers are already at a premium.  But if
9110 ;; we have one handy, we won't turn it away.
9111
9112 (define_peephole2
9113   [(match_scratch:DWIH 3 "r")
9114    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9115                    (ashift:<DWI>
9116                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9117                      (match_operand:QI 2 "nonmemory_operand" "")))
9118               (clobber (reg:CC FLAGS_REG))])
9119    (match_dup 3)]
9120   "TARGET_CMOVE"
9121   [(const_int 0)]
9122   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9123
9124 (define_insn "x86_64_shld"
9125   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9126         (ior:DI (ashift:DI (match_dup 0)
9127                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9128                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9129                   (minus:QI (const_int 64) (match_dup 2)))))
9130    (clobber (reg:CC FLAGS_REG))]
9131   "TARGET_64BIT"
9132   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9133   [(set_attr "type" "ishift")
9134    (set_attr "prefix_0f" "1")
9135    (set_attr "mode" "DI")
9136    (set_attr "athlon_decode" "vector")
9137    (set_attr "amdfam10_decode" "vector")
9138    (set_attr "bdver1_decode" "vector")])
9139
9140 (define_insn "x86_shld"
9141   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9142         (ior:SI (ashift:SI (match_dup 0)
9143                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9144                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9145                   (minus:QI (const_int 32) (match_dup 2)))))
9146    (clobber (reg:CC FLAGS_REG))]
9147   ""
9148   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9149   [(set_attr "type" "ishift")
9150    (set_attr "prefix_0f" "1")
9151    (set_attr "mode" "SI")
9152    (set_attr "pent_pair" "np")
9153    (set_attr "athlon_decode" "vector")
9154    (set_attr "amdfam10_decode" "vector")
9155    (set_attr "bdver1_decode" "vector")])
9156
9157 (define_expand "x86_shift<mode>_adj_1"
9158   [(set (reg:CCZ FLAGS_REG)
9159         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9160                              (match_dup 4))
9161                      (const_int 0)))
9162    (set (match_operand:SWI48 0 "register_operand" "")
9163         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9164                             (match_operand:SWI48 1 "register_operand" "")
9165                             (match_dup 0)))
9166    (set (match_dup 1)
9167         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9168                             (match_operand:SWI48 3 "register_operand" "r")
9169                             (match_dup 1)))]
9170   "TARGET_CMOVE"
9171   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9172
9173 (define_expand "x86_shift<mode>_adj_2"
9174   [(use (match_operand:SWI48 0 "register_operand" ""))
9175    (use (match_operand:SWI48 1 "register_operand" ""))
9176    (use (match_operand:QI 2 "register_operand" ""))]
9177   ""
9178 {
9179   rtx label = gen_label_rtx ();
9180   rtx tmp;
9181
9182   emit_insn (gen_testqi_ccz_1 (operands[2],
9183                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9184
9185   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9186   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9187   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9188                               gen_rtx_LABEL_REF (VOIDmode, label),
9189                               pc_rtx);
9190   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9191   JUMP_LABEL (tmp) = label;
9192
9193   emit_move_insn (operands[0], operands[1]);
9194   ix86_expand_clear (operands[1]);
9195
9196   emit_label (label);
9197   LABEL_NUSES (label) = 1;
9198
9199   DONE;
9200 })
9201
9202 ;; Avoid useless masking of count operand.
9203 (define_insn_and_split "*ashl<mode>3_mask"
9204   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9205         (ashift:SWI48
9206           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9207           (subreg:QI
9208             (and:SI
9209               (match_operand:SI 2 "nonimmediate_operand" "c")
9210               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9211    (clobber (reg:CC FLAGS_REG))]
9212   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9213    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9214       == GET_MODE_BITSIZE (<MODE>mode)-1"
9215   "#"
9216   "&& 1"
9217   [(parallel [(set (match_dup 0)
9218                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9219               (clobber (reg:CC FLAGS_REG))])]
9220 {
9221   if (can_create_pseudo_p ())
9222     operands [2] = force_reg (SImode, operands[2]);
9223
9224   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9225 }
9226   [(set_attr "type" "ishift")
9227    (set_attr "mode" "<MODE>")])
9228
9229 (define_insn "*ashl<mode>3_1"
9230   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9231         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9232                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9233    (clobber (reg:CC FLAGS_REG))]
9234   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9235 {
9236   switch (get_attr_type (insn))
9237     {
9238     case TYPE_LEA:
9239       return "#";
9240
9241     case TYPE_ALU:
9242       gcc_assert (operands[2] == const1_rtx);
9243       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9244       return "add{<imodesuffix>}\t%0, %0";
9245
9246     default:
9247       if (operands[2] == const1_rtx
9248           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9249         return "sal{<imodesuffix>}\t%0";
9250       else
9251         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9252     }
9253 }
9254   [(set (attr "type")
9255      (cond [(eq_attr "alternative" "1")
9256               (const_string "lea")
9257             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9258                           (const_int 0))
9259                       (match_operand 0 "register_operand" ""))
9260                  (match_operand 2 "const1_operand" ""))
9261               (const_string "alu")
9262            ]
9263            (const_string "ishift")))
9264    (set (attr "length_immediate")
9265      (if_then_else
9266        (ior (eq_attr "type" "alu")
9267             (and (eq_attr "type" "ishift")
9268                  (and (match_operand 2 "const1_operand" "")
9269                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9270                           (const_int 0)))))
9271        (const_string "0")
9272        (const_string "*")))
9273    (set_attr "mode" "<MODE>")])
9274
9275 (define_insn "*ashlsi3_1_zext"
9276   [(set (match_operand:DI 0 "register_operand" "=r,r")
9277         (zero_extend:DI
9278           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9279                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9280    (clobber (reg:CC FLAGS_REG))]
9281   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9282 {
9283   switch (get_attr_type (insn))
9284     {
9285     case TYPE_LEA:
9286       return "#";
9287
9288     case TYPE_ALU:
9289       gcc_assert (operands[2] == const1_rtx);
9290       return "add{l}\t%k0, %k0";
9291
9292     default:
9293       if (operands[2] == const1_rtx
9294           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9295         return "sal{l}\t%k0";
9296       else
9297         return "sal{l}\t{%2, %k0|%k0, %2}";
9298     }
9299 }
9300   [(set (attr "type")
9301      (cond [(eq_attr "alternative" "1")
9302               (const_string "lea")
9303             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9304                      (const_int 0))
9305                  (match_operand 2 "const1_operand" ""))
9306               (const_string "alu")
9307            ]
9308            (const_string "ishift")))
9309    (set (attr "length_immediate")
9310      (if_then_else
9311        (ior (eq_attr "type" "alu")
9312             (and (eq_attr "type" "ishift")
9313                  (and (match_operand 2 "const1_operand" "")
9314                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9315                           (const_int 0)))))
9316        (const_string "0")
9317        (const_string "*")))
9318    (set_attr "mode" "SI")])
9319
9320 (define_insn "*ashlhi3_1"
9321   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9322         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9323                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9324    (clobber (reg:CC FLAGS_REG))]
9325   "TARGET_PARTIAL_REG_STALL
9326    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9327 {
9328   switch (get_attr_type (insn))
9329     {
9330     case TYPE_ALU:
9331       gcc_assert (operands[2] == const1_rtx);
9332       return "add{w}\t%0, %0";
9333
9334     default:
9335       if (operands[2] == const1_rtx
9336           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9337         return "sal{w}\t%0";
9338       else
9339         return "sal{w}\t{%2, %0|%0, %2}";
9340     }
9341 }
9342   [(set (attr "type")
9343      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9344                           (const_int 0))
9345                       (match_operand 0 "register_operand" ""))
9346                  (match_operand 2 "const1_operand" ""))
9347               (const_string "alu")
9348            ]
9349            (const_string "ishift")))
9350    (set (attr "length_immediate")
9351      (if_then_else
9352        (ior (eq_attr "type" "alu")
9353             (and (eq_attr "type" "ishift")
9354                  (and (match_operand 2 "const1_operand" "")
9355                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9356                           (const_int 0)))))
9357        (const_string "0")
9358        (const_string "*")))
9359    (set_attr "mode" "HI")])
9360
9361 (define_insn "*ashlhi3_1_lea"
9362   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9363         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9364                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9365    (clobber (reg:CC FLAGS_REG))]
9366   "!TARGET_PARTIAL_REG_STALL
9367    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9368 {
9369   switch (get_attr_type (insn))
9370     {
9371     case TYPE_LEA:
9372       return "#";
9373
9374     case TYPE_ALU:
9375       gcc_assert (operands[2] == const1_rtx);
9376       return "add{w}\t%0, %0";
9377
9378     default:
9379       if (operands[2] == const1_rtx
9380           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9381         return "sal{w}\t%0";
9382       else
9383         return "sal{w}\t{%2, %0|%0, %2}";
9384     }
9385 }
9386   [(set (attr "type")
9387      (cond [(eq_attr "alternative" "1")
9388               (const_string "lea")
9389             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9390                           (const_int 0))
9391                       (match_operand 0 "register_operand" ""))
9392                  (match_operand 2 "const1_operand" ""))
9393               (const_string "alu")
9394            ]
9395            (const_string "ishift")))
9396    (set (attr "length_immediate")
9397      (if_then_else
9398        (ior (eq_attr "type" "alu")
9399             (and (eq_attr "type" "ishift")
9400                  (and (match_operand 2 "const1_operand" "")
9401                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9402                           (const_int 0)))))
9403        (const_string "0")
9404        (const_string "*")))
9405    (set_attr "mode" "HI,SI")])
9406
9407 (define_insn "*ashlqi3_1"
9408   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9409         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9410                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9411    (clobber (reg:CC FLAGS_REG))]
9412   "TARGET_PARTIAL_REG_STALL
9413    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9414 {
9415   switch (get_attr_type (insn))
9416     {
9417     case TYPE_ALU:
9418       gcc_assert (operands[2] == const1_rtx);
9419       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9420         return "add{l}\t%k0, %k0";
9421       else
9422         return "add{b}\t%0, %0";
9423
9424     default:
9425       if (operands[2] == const1_rtx
9426           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9427         {
9428           if (get_attr_mode (insn) == MODE_SI)
9429             return "sal{l}\t%k0";
9430           else
9431             return "sal{b}\t%0";
9432         }
9433       else
9434         {
9435           if (get_attr_mode (insn) == MODE_SI)
9436             return "sal{l}\t{%2, %k0|%k0, %2}";
9437           else
9438             return "sal{b}\t{%2, %0|%0, %2}";
9439         }
9440     }
9441 }
9442   [(set (attr "type")
9443      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9444                           (const_int 0))
9445                       (match_operand 0 "register_operand" ""))
9446                  (match_operand 2 "const1_operand" ""))
9447               (const_string "alu")
9448            ]
9449            (const_string "ishift")))
9450    (set (attr "length_immediate")
9451      (if_then_else
9452        (ior (eq_attr "type" "alu")
9453             (and (eq_attr "type" "ishift")
9454                  (and (match_operand 2 "const1_operand" "")
9455                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9456                           (const_int 0)))))
9457        (const_string "0")
9458        (const_string "*")))
9459    (set_attr "mode" "QI,SI")])
9460
9461 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9462 (define_insn "*ashlqi3_1_lea"
9463   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9464         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9465                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9466    (clobber (reg:CC FLAGS_REG))]
9467   "!TARGET_PARTIAL_REG_STALL
9468    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9469 {
9470   switch (get_attr_type (insn))
9471     {
9472     case TYPE_LEA:
9473       return "#";
9474
9475     case TYPE_ALU:
9476       gcc_assert (operands[2] == const1_rtx);
9477       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9478         return "add{l}\t%k0, %k0";
9479       else
9480         return "add{b}\t%0, %0";
9481
9482     default:
9483       if (operands[2] == const1_rtx
9484           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9485         {
9486           if (get_attr_mode (insn) == MODE_SI)
9487             return "sal{l}\t%k0";
9488           else
9489             return "sal{b}\t%0";
9490         }
9491       else
9492         {
9493           if (get_attr_mode (insn) == MODE_SI)
9494             return "sal{l}\t{%2, %k0|%k0, %2}";
9495           else
9496             return "sal{b}\t{%2, %0|%0, %2}";
9497         }
9498     }
9499 }
9500   [(set (attr "type")
9501      (cond [(eq_attr "alternative" "2")
9502               (const_string "lea")
9503             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9504                           (const_int 0))
9505                       (match_operand 0 "register_operand" ""))
9506                  (match_operand 2 "const1_operand" ""))
9507               (const_string "alu")
9508            ]
9509            (const_string "ishift")))
9510    (set (attr "length_immediate")
9511      (if_then_else
9512        (ior (eq_attr "type" "alu")
9513             (and (eq_attr "type" "ishift")
9514                  (and (match_operand 2 "const1_operand" "")
9515                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9516                           (const_int 0)))))
9517        (const_string "0")
9518        (const_string "*")))
9519    (set_attr "mode" "QI,SI,SI")])
9520
9521 (define_insn "*ashlqi3_1_slp"
9522   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9523         (ashift:QI (match_dup 0)
9524                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9525    (clobber (reg:CC FLAGS_REG))]
9526   "(optimize_function_for_size_p (cfun)
9527     || !TARGET_PARTIAL_FLAG_REG_STALL
9528     || (operands[1] == const1_rtx
9529         && (TARGET_SHIFT1
9530             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9531 {
9532   switch (get_attr_type (insn))
9533     {
9534     case TYPE_ALU:
9535       gcc_assert (operands[1] == const1_rtx);
9536       return "add{b}\t%0, %0";
9537
9538     default:
9539       if (operands[1] == const1_rtx
9540           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9541         return "sal{b}\t%0";
9542       else
9543         return "sal{b}\t{%1, %0|%0, %1}";
9544     }
9545 }
9546   [(set (attr "type")
9547      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9548                           (const_int 0))
9549                       (match_operand 0 "register_operand" ""))
9550                  (match_operand 1 "const1_operand" ""))
9551               (const_string "alu")
9552            ]
9553            (const_string "ishift1")))
9554    (set (attr "length_immediate")
9555      (if_then_else
9556        (ior (eq_attr "type" "alu")
9557             (and (eq_attr "type" "ishift1")
9558                  (and (match_operand 1 "const1_operand" "")
9559                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9560                           (const_int 0)))))
9561        (const_string "0")
9562        (const_string "*")))
9563    (set_attr "mode" "QI")])
9564
9565 ;; Convert lea to the lea pattern to avoid flags dependency.
9566 (define_split
9567   [(set (match_operand 0 "register_operand" "")
9568         (ashift (match_operand 1 "index_register_operand" "")
9569                 (match_operand:QI 2 "const_int_operand" "")))
9570    (clobber (reg:CC FLAGS_REG))]
9571   "reload_completed
9572    && true_regnum (operands[0]) != true_regnum (operands[1])"
9573   [(const_int 0)]
9574 {
9575   rtx pat;
9576   enum machine_mode mode = GET_MODE (operands[0]);
9577
9578   if (mode != Pmode)
9579     operands[1] = gen_lowpart (Pmode, operands[1]);
9580   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9581
9582   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9583
9584   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9585     operands[0] = gen_lowpart (SImode, operands[0]);
9586
9587   if (TARGET_64BIT && mode != Pmode)
9588     pat = gen_rtx_SUBREG (SImode, pat, 0);
9589
9590   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9591   DONE;
9592 })
9593
9594 ;; Convert lea to the lea pattern to avoid flags dependency.
9595 (define_split
9596   [(set (match_operand:DI 0 "register_operand" "")
9597         (zero_extend:DI
9598           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9599                      (match_operand:QI 2 "const_int_operand" ""))))
9600    (clobber (reg:CC FLAGS_REG))]
9601   "TARGET_64BIT && reload_completed
9602    && true_regnum (operands[0]) != true_regnum (operands[1])"
9603   [(set (match_dup 0)
9604         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9605 {
9606   operands[1] = gen_lowpart (DImode, operands[1]);
9607   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9608 })
9609
9610 ;; This pattern can't accept a variable shift count, since shifts by
9611 ;; zero don't affect the flags.  We assume that shifts by constant
9612 ;; zero are optimized away.
9613 (define_insn "*ashl<mode>3_cmp"
9614   [(set (reg FLAGS_REG)
9615         (compare
9616           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9617                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9618           (const_int 0)))
9619    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9620         (ashift:SWI (match_dup 1) (match_dup 2)))]
9621   "(optimize_function_for_size_p (cfun)
9622     || !TARGET_PARTIAL_FLAG_REG_STALL
9623     || (operands[2] == const1_rtx
9624         && (TARGET_SHIFT1
9625             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9626    && ix86_match_ccmode (insn, CCGOCmode)
9627    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9628 {
9629   switch (get_attr_type (insn))
9630     {
9631     case TYPE_ALU:
9632       gcc_assert (operands[2] == const1_rtx);
9633       return "add{<imodesuffix>}\t%0, %0";
9634
9635     default:
9636       if (operands[2] == const1_rtx
9637           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9638         return "sal{<imodesuffix>}\t%0";
9639       else
9640         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9641     }
9642 }
9643   [(set (attr "type")
9644      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9645                           (const_int 0))
9646                       (match_operand 0 "register_operand" ""))
9647                  (match_operand 2 "const1_operand" ""))
9648               (const_string "alu")
9649            ]
9650            (const_string "ishift")))
9651    (set (attr "length_immediate")
9652      (if_then_else
9653        (ior (eq_attr "type" "alu")
9654             (and (eq_attr "type" "ishift")
9655                  (and (match_operand 2 "const1_operand" "")
9656                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9657                           (const_int 0)))))
9658        (const_string "0")
9659        (const_string "*")))
9660    (set_attr "mode" "<MODE>")])
9661
9662 (define_insn "*ashlsi3_cmp_zext"
9663   [(set (reg FLAGS_REG)
9664         (compare
9665           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9666                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9667           (const_int 0)))
9668    (set (match_operand:DI 0 "register_operand" "=r")
9669         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9670   "TARGET_64BIT
9671    && (optimize_function_for_size_p (cfun)
9672        || !TARGET_PARTIAL_FLAG_REG_STALL
9673        || (operands[2] == const1_rtx
9674            && (TARGET_SHIFT1
9675                || TARGET_DOUBLE_WITH_ADD)))
9676    && ix86_match_ccmode (insn, CCGOCmode)
9677    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9678 {
9679   switch (get_attr_type (insn))
9680     {
9681     case TYPE_ALU:
9682       gcc_assert (operands[2] == const1_rtx);
9683       return "add{l}\t%k0, %k0";
9684
9685     default:
9686       if (operands[2] == const1_rtx
9687           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9688         return "sal{l}\t%k0";
9689       else
9690         return "sal{l}\t{%2, %k0|%k0, %2}";
9691     }
9692 }
9693   [(set (attr "type")
9694      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9695                      (const_int 0))
9696                  (match_operand 2 "const1_operand" ""))
9697               (const_string "alu")
9698            ]
9699            (const_string "ishift")))
9700    (set (attr "length_immediate")
9701      (if_then_else
9702        (ior (eq_attr "type" "alu")
9703             (and (eq_attr "type" "ishift")
9704                  (and (match_operand 2 "const1_operand" "")
9705                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9706                           (const_int 0)))))
9707        (const_string "0")
9708        (const_string "*")))
9709    (set_attr "mode" "SI")])
9710
9711 (define_insn "*ashl<mode>3_cconly"
9712   [(set (reg FLAGS_REG)
9713         (compare
9714           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9715                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9716           (const_int 0)))
9717    (clobber (match_scratch:SWI 0 "=<r>"))]
9718   "(optimize_function_for_size_p (cfun)
9719     || !TARGET_PARTIAL_FLAG_REG_STALL
9720     || (operands[2] == const1_rtx
9721         && (TARGET_SHIFT1
9722             || TARGET_DOUBLE_WITH_ADD)))
9723    && ix86_match_ccmode (insn, CCGOCmode)
9724    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9725 {
9726   switch (get_attr_type (insn))
9727     {
9728     case TYPE_ALU:
9729       gcc_assert (operands[2] == const1_rtx);
9730       return "add{<imodesuffix>}\t%0, %0";
9731
9732     default:
9733       if (operands[2] == const1_rtx
9734           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9735         return "sal{<imodesuffix>}\t%0";
9736       else
9737         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9738     }
9739 }
9740   [(set (attr "type")
9741      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9742                           (const_int 0))
9743                       (match_operand 0 "register_operand" ""))
9744                  (match_operand 2 "const1_operand" ""))
9745               (const_string "alu")
9746            ]
9747            (const_string "ishift")))
9748    (set (attr "length_immediate")
9749      (if_then_else
9750        (ior (eq_attr "type" "alu")
9751             (and (eq_attr "type" "ishift")
9752                  (and (match_operand 2 "const1_operand" "")
9753                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9754                           (const_int 0)))))
9755        (const_string "0")
9756        (const_string "*")))
9757    (set_attr "mode" "<MODE>")])
9758
9759 ;; See comment above `ashl<mode>3' about how this works.
9760
9761 (define_expand "<shiftrt_insn><mode>3"
9762   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9763         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9764                            (match_operand:QI 2 "nonmemory_operand" "")))]
9765   ""
9766   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9767
9768 ;; Avoid useless masking of count operand.
9769 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9770   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9771         (any_shiftrt:SWI48
9772           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9773           (subreg:QI
9774             (and:SI
9775               (match_operand:SI 2 "nonimmediate_operand" "c")
9776               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9777    (clobber (reg:CC FLAGS_REG))]
9778   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9779    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9780       == GET_MODE_BITSIZE (<MODE>mode)-1"
9781   "#"
9782   "&& 1"
9783   [(parallel [(set (match_dup 0)
9784                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9785               (clobber (reg:CC FLAGS_REG))])]
9786 {
9787   if (can_create_pseudo_p ())
9788     operands [2] = force_reg (SImode, operands[2]);
9789
9790   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9791 }
9792   [(set_attr "type" "ishift")
9793    (set_attr "mode" "<MODE>")])
9794
9795 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9796   [(set (match_operand:DWI 0 "register_operand" "=r")
9797         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9798                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9799    (clobber (reg:CC FLAGS_REG))]
9800   ""
9801   "#"
9802   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9803   [(const_int 0)]
9804   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9805   [(set_attr "type" "multi")])
9806
9807 ;; By default we don't ask for a scratch register, because when DWImode
9808 ;; values are manipulated, registers are already at a premium.  But if
9809 ;; we have one handy, we won't turn it away.
9810
9811 (define_peephole2
9812   [(match_scratch:DWIH 3 "r")
9813    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9814                    (any_shiftrt:<DWI>
9815                      (match_operand:<DWI> 1 "register_operand" "")
9816                      (match_operand:QI 2 "nonmemory_operand" "")))
9817               (clobber (reg:CC FLAGS_REG))])
9818    (match_dup 3)]
9819   "TARGET_CMOVE"
9820   [(const_int 0)]
9821   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9822
9823 (define_insn "x86_64_shrd"
9824   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9825         (ior:DI (ashiftrt:DI (match_dup 0)
9826                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9827                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9828                   (minus:QI (const_int 64) (match_dup 2)))))
9829    (clobber (reg:CC FLAGS_REG))]
9830   "TARGET_64BIT"
9831   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9832   [(set_attr "type" "ishift")
9833    (set_attr "prefix_0f" "1")
9834    (set_attr "mode" "DI")
9835    (set_attr "athlon_decode" "vector")
9836    (set_attr "amdfam10_decode" "vector")
9837    (set_attr "bdver1_decode" "vector")])
9838
9839 (define_insn "x86_shrd"
9840   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9841         (ior:SI (ashiftrt:SI (match_dup 0)
9842                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9843                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9844                   (minus:QI (const_int 32) (match_dup 2)))))
9845    (clobber (reg:CC FLAGS_REG))]
9846   ""
9847   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9848   [(set_attr "type" "ishift")
9849    (set_attr "prefix_0f" "1")
9850    (set_attr "mode" "SI")
9851    (set_attr "pent_pair" "np")
9852    (set_attr "athlon_decode" "vector")
9853    (set_attr "amdfam10_decode" "vector")
9854    (set_attr "bdver1_decode" "vector")])
9855
9856 (define_insn "ashrdi3_cvt"
9857   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9858         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9859                      (match_operand:QI 2 "const_int_operand" "")))
9860    (clobber (reg:CC FLAGS_REG))]
9861   "TARGET_64BIT && INTVAL (operands[2]) == 63
9862    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9863    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9864   "@
9865    {cqto|cqo}
9866    sar{q}\t{%2, %0|%0, %2}"
9867   [(set_attr "type" "imovx,ishift")
9868    (set_attr "prefix_0f" "0,*")
9869    (set_attr "length_immediate" "0,*")
9870    (set_attr "modrm" "0,1")
9871    (set_attr "mode" "DI")])
9872
9873 (define_insn "ashrsi3_cvt"
9874   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9875         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9876                      (match_operand:QI 2 "const_int_operand" "")))
9877    (clobber (reg:CC FLAGS_REG))]
9878   "INTVAL (operands[2]) == 31
9879    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9880    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9881   "@
9882    {cltd|cdq}
9883    sar{l}\t{%2, %0|%0, %2}"
9884   [(set_attr "type" "imovx,ishift")
9885    (set_attr "prefix_0f" "0,*")
9886    (set_attr "length_immediate" "0,*")
9887    (set_attr "modrm" "0,1")
9888    (set_attr "mode" "SI")])
9889
9890 (define_insn "*ashrsi3_cvt_zext"
9891   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9892         (zero_extend:DI
9893           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9894                        (match_operand:QI 2 "const_int_operand" ""))))
9895    (clobber (reg:CC FLAGS_REG))]
9896   "TARGET_64BIT && INTVAL (operands[2]) == 31
9897    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9898    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9899   "@
9900    {cltd|cdq}
9901    sar{l}\t{%2, %k0|%k0, %2}"
9902   [(set_attr "type" "imovx,ishift")
9903    (set_attr "prefix_0f" "0,*")
9904    (set_attr "length_immediate" "0,*")
9905    (set_attr "modrm" "0,1")
9906    (set_attr "mode" "SI")])
9907
9908 (define_expand "x86_shift<mode>_adj_3"
9909   [(use (match_operand:SWI48 0 "register_operand" ""))
9910    (use (match_operand:SWI48 1 "register_operand" ""))
9911    (use (match_operand:QI 2 "register_operand" ""))]
9912   ""
9913 {
9914   rtx label = gen_label_rtx ();
9915   rtx tmp;
9916
9917   emit_insn (gen_testqi_ccz_1 (operands[2],
9918                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9919
9920   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9921   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9922   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9923                               gen_rtx_LABEL_REF (VOIDmode, label),
9924                               pc_rtx);
9925   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9926   JUMP_LABEL (tmp) = label;
9927
9928   emit_move_insn (operands[0], operands[1]);
9929   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9930                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9931   emit_label (label);
9932   LABEL_NUSES (label) = 1;
9933
9934   DONE;
9935 })
9936
9937 (define_insn "*<shiftrt_insn><mode>3_1"
9938   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9939         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9940                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9941    (clobber (reg:CC FLAGS_REG))]
9942   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9943 {
9944   if (operands[2] == const1_rtx
9945       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9946     return "<shiftrt>{<imodesuffix>}\t%0";
9947   else
9948     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9949 }
9950   [(set_attr "type" "ishift")
9951    (set (attr "length_immediate")
9952      (if_then_else
9953        (and (match_operand 2 "const1_operand" "")
9954             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9955                 (const_int 0)))
9956        (const_string "0")
9957        (const_string "*")))
9958    (set_attr "mode" "<MODE>")])
9959
9960 (define_insn "*<shiftrt_insn>si3_1_zext"
9961   [(set (match_operand:DI 0 "register_operand" "=r")
9962         (zero_extend:DI
9963           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9964                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9965    (clobber (reg:CC FLAGS_REG))]
9966   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9967 {
9968   if (operands[2] == const1_rtx
9969       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9970     return "<shiftrt>{l}\t%k0";
9971   else
9972     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9973 }
9974   [(set_attr "type" "ishift")
9975    (set (attr "length_immediate")
9976      (if_then_else
9977        (and (match_operand 2 "const1_operand" "")
9978             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9979                 (const_int 0)))
9980        (const_string "0")
9981        (const_string "*")))
9982    (set_attr "mode" "SI")])
9983
9984 (define_insn "*<shiftrt_insn>qi3_1_slp"
9985   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9986         (any_shiftrt:QI (match_dup 0)
9987                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9988    (clobber (reg:CC FLAGS_REG))]
9989   "(optimize_function_for_size_p (cfun)
9990     || !TARGET_PARTIAL_REG_STALL
9991     || (operands[1] == const1_rtx
9992         && TARGET_SHIFT1))"
9993 {
9994   if (operands[1] == const1_rtx
9995       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9996     return "<shiftrt>{b}\t%0";
9997   else
9998     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9999 }
10000   [(set_attr "type" "ishift1")
10001    (set (attr "length_immediate")
10002      (if_then_else
10003        (and (match_operand 1 "const1_operand" "")
10004             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10005                 (const_int 0)))
10006        (const_string "0")
10007        (const_string "*")))
10008    (set_attr "mode" "QI")])
10009
10010 ;; This pattern can't accept a variable shift count, since shifts by
10011 ;; zero don't affect the flags.  We assume that shifts by constant
10012 ;; zero are optimized away.
10013 (define_insn "*<shiftrt_insn><mode>3_cmp"
10014   [(set (reg FLAGS_REG)
10015         (compare
10016           (any_shiftrt:SWI
10017             (match_operand:SWI 1 "nonimmediate_operand" "0")
10018             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10019           (const_int 0)))
10020    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10021         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10022   "(optimize_function_for_size_p (cfun)
10023     || !TARGET_PARTIAL_FLAG_REG_STALL
10024     || (operands[2] == const1_rtx
10025         && TARGET_SHIFT1))
10026    && ix86_match_ccmode (insn, CCGOCmode)
10027    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10028 {
10029   if (operands[2] == const1_rtx
10030       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10031     return "<shiftrt>{<imodesuffix>}\t%0";
10032   else
10033     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10034 }
10035   [(set_attr "type" "ishift")
10036    (set (attr "length_immediate")
10037      (if_then_else
10038        (and (match_operand 2 "const1_operand" "")
10039             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10040                 (const_int 0)))
10041        (const_string "0")
10042        (const_string "*")))
10043    (set_attr "mode" "<MODE>")])
10044
10045 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10046   [(set (reg FLAGS_REG)
10047         (compare
10048           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10049                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10050           (const_int 0)))
10051    (set (match_operand:DI 0 "register_operand" "=r")
10052         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10053   "TARGET_64BIT
10054    && (optimize_function_for_size_p (cfun)
10055        || !TARGET_PARTIAL_FLAG_REG_STALL
10056        || (operands[2] == const1_rtx
10057            && TARGET_SHIFT1))
10058    && ix86_match_ccmode (insn, CCGOCmode)
10059    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10060 {
10061   if (operands[2] == const1_rtx
10062       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10063     return "<shiftrt>{l}\t%k0";
10064   else
10065     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10066 }
10067   [(set_attr "type" "ishift")
10068    (set (attr "length_immediate")
10069      (if_then_else
10070        (and (match_operand 2 "const1_operand" "")
10071             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10072                 (const_int 0)))
10073        (const_string "0")
10074        (const_string "*")))
10075    (set_attr "mode" "SI")])
10076
10077 (define_insn "*<shiftrt_insn><mode>3_cconly"
10078   [(set (reg FLAGS_REG)
10079         (compare
10080           (any_shiftrt:SWI
10081             (match_operand:SWI 1 "nonimmediate_operand" "0")
10082             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10083           (const_int 0)))
10084    (clobber (match_scratch:SWI 0 "=<r>"))]
10085   "(optimize_function_for_size_p (cfun)
10086     || !TARGET_PARTIAL_FLAG_REG_STALL
10087     || (operands[2] == const1_rtx
10088         && TARGET_SHIFT1))
10089    && ix86_match_ccmode (insn, CCGOCmode)
10090    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10091 {
10092   if (operands[2] == const1_rtx
10093       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10094     return "<shiftrt>{<imodesuffix>}\t%0";
10095   else
10096     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10097 }
10098   [(set_attr "type" "ishift")
10099    (set (attr "length_immediate")
10100      (if_then_else
10101        (and (match_operand 2 "const1_operand" "")
10102             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10103                 (const_int 0)))
10104        (const_string "0")
10105        (const_string "*")))
10106    (set_attr "mode" "<MODE>")])
10107 \f
10108 ;; Rotate instructions
10109
10110 (define_expand "<rotate_insn>ti3"
10111   [(set (match_operand:TI 0 "register_operand" "")
10112         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10113                        (match_operand:QI 2 "nonmemory_operand" "")))]
10114   "TARGET_64BIT"
10115 {
10116   if (const_1_to_63_operand (operands[2], VOIDmode))
10117     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10118                 (operands[0], operands[1], operands[2]));
10119   else
10120     FAIL;
10121
10122   DONE;
10123 })
10124
10125 (define_expand "<rotate_insn>di3"
10126   [(set (match_operand:DI 0 "shiftdi_operand" "")
10127         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10128                        (match_operand:QI 2 "nonmemory_operand" "")))]
10129  ""
10130 {
10131   if (TARGET_64BIT)
10132     ix86_expand_binary_operator (<CODE>, DImode, operands);
10133   else if (const_1_to_31_operand (operands[2], VOIDmode))
10134     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10135                 (operands[0], operands[1], operands[2]));
10136   else
10137     FAIL;
10138
10139   DONE;
10140 })
10141
10142 (define_expand "<rotate_insn><mode>3"
10143   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10144         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10145                             (match_operand:QI 2 "nonmemory_operand" "")))]
10146   ""
10147   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10148
10149 ;; Avoid useless masking of count operand.
10150 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10151   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10152         (any_rotate:SWI48
10153           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10154           (subreg:QI
10155             (and:SI
10156               (match_operand:SI 2 "nonimmediate_operand" "c")
10157               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10158    (clobber (reg:CC FLAGS_REG))]
10159   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10160    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10161       == GET_MODE_BITSIZE (<MODE>mode)-1"
10162   "#"
10163   "&& 1"
10164   [(parallel [(set (match_dup 0)
10165                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10166               (clobber (reg:CC FLAGS_REG))])]
10167 {
10168   if (can_create_pseudo_p ())
10169     operands [2] = force_reg (SImode, operands[2]);
10170
10171   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10172 }
10173   [(set_attr "type" "rotate")
10174    (set_attr "mode" "<MODE>")])
10175
10176 ;; Implement rotation using two double-precision
10177 ;; shift instructions and a scratch register.
10178
10179 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10180  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10181        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10182                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10183   (clobber (reg:CC FLAGS_REG))
10184   (clobber (match_scratch:DWIH 3 "=&r"))]
10185  ""
10186  "#"
10187  "reload_completed"
10188  [(set (match_dup 3) (match_dup 4))
10189   (parallel
10190    [(set (match_dup 4)
10191          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10192                    (lshiftrt:DWIH (match_dup 5)
10193                                   (minus:QI (match_dup 6) (match_dup 2)))))
10194     (clobber (reg:CC FLAGS_REG))])
10195   (parallel
10196    [(set (match_dup 5)
10197          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10198                    (lshiftrt:DWIH (match_dup 3)
10199                                   (minus:QI (match_dup 6) (match_dup 2)))))
10200     (clobber (reg:CC FLAGS_REG))])]
10201 {
10202   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10203
10204   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10205 })
10206
10207 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10208  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10209        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10210                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10211   (clobber (reg:CC FLAGS_REG))
10212   (clobber (match_scratch:DWIH 3 "=&r"))]
10213  ""
10214  "#"
10215  "reload_completed"
10216  [(set (match_dup 3) (match_dup 4))
10217   (parallel
10218    [(set (match_dup 4)
10219          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10220                    (ashift:DWIH (match_dup 5)
10221                                 (minus:QI (match_dup 6) (match_dup 2)))))
10222     (clobber (reg:CC FLAGS_REG))])
10223   (parallel
10224    [(set (match_dup 5)
10225          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10226                    (ashift:DWIH (match_dup 3)
10227                                 (minus:QI (match_dup 6) (match_dup 2)))))
10228     (clobber (reg:CC FLAGS_REG))])]
10229 {
10230   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10231
10232   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10233 })
10234
10235 (define_insn "*<rotate_insn><mode>3_1"
10236   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10237         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10238                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10239    (clobber (reg:CC FLAGS_REG))]
10240   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10241 {
10242   if (operands[2] == const1_rtx
10243       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10244     return "<rotate>{<imodesuffix>}\t%0";
10245   else
10246     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10247 }
10248   [(set_attr "type" "rotate")
10249    (set (attr "length_immediate")
10250      (if_then_else
10251        (and (match_operand 2 "const1_operand" "")
10252             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10253                 (const_int 0)))
10254        (const_string "0")
10255        (const_string "*")))
10256    (set_attr "mode" "<MODE>")])
10257
10258 (define_insn "*<rotate_insn>si3_1_zext"
10259   [(set (match_operand:DI 0 "register_operand" "=r")
10260         (zero_extend:DI
10261           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10262                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10263    (clobber (reg:CC FLAGS_REG))]
10264   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10265 {
10266     if (operands[2] == const1_rtx
10267         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10268     return "<rotate>{l}\t%k0";
10269   else
10270     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10271 }
10272   [(set_attr "type" "rotate")
10273    (set (attr "length_immediate")
10274      (if_then_else
10275        (and (match_operand 2 "const1_operand" "")
10276             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10277                 (const_int 0)))
10278        (const_string "0")
10279        (const_string "*")))
10280    (set_attr "mode" "SI")])
10281
10282 (define_insn "*<rotate_insn>qi3_1_slp"
10283   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10284         (any_rotate:QI (match_dup 0)
10285                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10286    (clobber (reg:CC FLAGS_REG))]
10287   "(optimize_function_for_size_p (cfun)
10288     || !TARGET_PARTIAL_REG_STALL
10289     || (operands[1] == const1_rtx
10290         && TARGET_SHIFT1))"
10291 {
10292   if (operands[1] == const1_rtx
10293       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10294     return "<rotate>{b}\t%0";
10295   else
10296     return "<rotate>{b}\t{%1, %0|%0, %1}";
10297 }
10298   [(set_attr "type" "rotate1")
10299    (set (attr "length_immediate")
10300      (if_then_else
10301        (and (match_operand 1 "const1_operand" "")
10302             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10303                 (const_int 0)))
10304        (const_string "0")
10305        (const_string "*")))
10306    (set_attr "mode" "QI")])
10307
10308 (define_split
10309  [(set (match_operand:HI 0 "register_operand" "")
10310        (any_rotate:HI (match_dup 0) (const_int 8)))
10311   (clobber (reg:CC FLAGS_REG))]
10312  "reload_completed
10313   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10314  [(parallel [(set (strict_low_part (match_dup 0))
10315                   (bswap:HI (match_dup 0)))
10316              (clobber (reg:CC FLAGS_REG))])])
10317 \f
10318 ;; Bit set / bit test instructions
10319
10320 (define_expand "extv"
10321   [(set (match_operand:SI 0 "register_operand" "")
10322         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10323                          (match_operand:SI 2 "const8_operand" "")
10324                          (match_operand:SI 3 "const8_operand" "")))]
10325   ""
10326 {
10327   /* Handle extractions from %ah et al.  */
10328   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10329     FAIL;
10330
10331   /* From mips.md: extract_bit_field doesn't verify that our source
10332      matches the predicate, so check it again here.  */
10333   if (! ext_register_operand (operands[1], VOIDmode))
10334     FAIL;
10335 })
10336
10337 (define_expand "extzv"
10338   [(set (match_operand:SI 0 "register_operand" "")
10339         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10340                          (match_operand:SI 2 "const8_operand" "")
10341                          (match_operand:SI 3 "const8_operand" "")))]
10342   ""
10343 {
10344   /* Handle extractions from %ah et al.  */
10345   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10346     FAIL;
10347
10348   /* From mips.md: extract_bit_field doesn't verify that our source
10349      matches the predicate, so check it again here.  */
10350   if (! ext_register_operand (operands[1], VOIDmode))
10351     FAIL;
10352 })
10353
10354 (define_expand "insv"
10355   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10356                       (match_operand 1 "const8_operand" "")
10357                       (match_operand 2 "const8_operand" ""))
10358         (match_operand 3 "register_operand" ""))]
10359   ""
10360 {
10361   rtx (*gen_mov_insv_1) (rtx, rtx);
10362
10363   /* Handle insertions to %ah et al.  */
10364   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10365     FAIL;
10366
10367   /* From mips.md: insert_bit_field doesn't verify that our source
10368      matches the predicate, so check it again here.  */
10369   if (! ext_register_operand (operands[0], VOIDmode))
10370     FAIL;
10371
10372   gen_mov_insv_1 = (TARGET_64BIT
10373                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10374
10375   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10376   DONE;
10377 })
10378
10379 ;; %%% bts, btr, btc, bt.
10380 ;; In general these instructions are *slow* when applied to memory,
10381 ;; since they enforce atomic operation.  When applied to registers,
10382 ;; it depends on the cpu implementation.  They're never faster than
10383 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10384 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10385 ;; within the instruction itself, so operating on bits in the high
10386 ;; 32-bits of a register becomes easier.
10387 ;;
10388 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10389 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10390 ;; negdf respectively, so they can never be disabled entirely.
10391
10392 (define_insn "*btsq"
10393   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10394                          (const_int 1)
10395                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10396         (const_int 1))
10397    (clobber (reg:CC FLAGS_REG))]
10398   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10399   "bts{q}\t{%1, %0|%0, %1}"
10400   [(set_attr "type" "alu1")
10401    (set_attr "prefix_0f" "1")
10402    (set_attr "mode" "DI")])
10403
10404 (define_insn "*btrq"
10405   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10406                          (const_int 1)
10407                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10408         (const_int 0))
10409    (clobber (reg:CC FLAGS_REG))]
10410   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10411   "btr{q}\t{%1, %0|%0, %1}"
10412   [(set_attr "type" "alu1")
10413    (set_attr "prefix_0f" "1")
10414    (set_attr "mode" "DI")])
10415
10416 (define_insn "*btcq"
10417   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10418                          (const_int 1)
10419                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10420         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10421    (clobber (reg:CC FLAGS_REG))]
10422   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10423   "btc{q}\t{%1, %0|%0, %1}"
10424   [(set_attr "type" "alu1")
10425    (set_attr "prefix_0f" "1")
10426    (set_attr "mode" "DI")])
10427
10428 ;; Allow Nocona to avoid these instructions if a register is available.
10429
10430 (define_peephole2
10431   [(match_scratch:DI 2 "r")
10432    (parallel [(set (zero_extract:DI
10433                      (match_operand:DI 0 "register_operand" "")
10434                      (const_int 1)
10435                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10436                    (const_int 1))
10437               (clobber (reg:CC FLAGS_REG))])]
10438   "TARGET_64BIT && !TARGET_USE_BT"
10439   [(const_int 0)]
10440 {
10441   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10442   rtx op1;
10443
10444   if (HOST_BITS_PER_WIDE_INT >= 64)
10445     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446   else if (i < HOST_BITS_PER_WIDE_INT)
10447     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10448   else
10449     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10450
10451   op1 = immed_double_const (lo, hi, DImode);
10452   if (i >= 31)
10453     {
10454       emit_move_insn (operands[2], op1);
10455       op1 = operands[2];
10456     }
10457
10458   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10459   DONE;
10460 })
10461
10462 (define_peephole2
10463   [(match_scratch:DI 2 "r")
10464    (parallel [(set (zero_extract:DI
10465                      (match_operand:DI 0 "register_operand" "")
10466                      (const_int 1)
10467                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10468                    (const_int 0))
10469               (clobber (reg:CC FLAGS_REG))])]
10470   "TARGET_64BIT && !TARGET_USE_BT"
10471   [(const_int 0)]
10472 {
10473   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10474   rtx op1;
10475
10476   if (HOST_BITS_PER_WIDE_INT >= 64)
10477     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10478   else if (i < HOST_BITS_PER_WIDE_INT)
10479     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10480   else
10481     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10482
10483   op1 = immed_double_const (~lo, ~hi, DImode);
10484   if (i >= 32)
10485     {
10486       emit_move_insn (operands[2], op1);
10487       op1 = operands[2];
10488     }
10489
10490   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10491   DONE;
10492 })
10493
10494 (define_peephole2
10495   [(match_scratch:DI 2 "r")
10496    (parallel [(set (zero_extract:DI
10497                      (match_operand:DI 0 "register_operand" "")
10498                      (const_int 1)
10499                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10500               (not:DI (zero_extract:DI
10501                         (match_dup 0) (const_int 1) (match_dup 1))))
10502               (clobber (reg:CC FLAGS_REG))])]
10503   "TARGET_64BIT && !TARGET_USE_BT"
10504   [(const_int 0)]
10505 {
10506   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10507   rtx op1;
10508
10509   if (HOST_BITS_PER_WIDE_INT >= 64)
10510     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10511   else if (i < HOST_BITS_PER_WIDE_INT)
10512     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10513   else
10514     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10515
10516   op1 = immed_double_const (lo, hi, DImode);
10517   if (i >= 31)
10518     {
10519       emit_move_insn (operands[2], op1);
10520       op1 = operands[2];
10521     }
10522
10523   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10524   DONE;
10525 })
10526
10527 (define_insn "*bt<mode>"
10528   [(set (reg:CCC FLAGS_REG)
10529         (compare:CCC
10530           (zero_extract:SWI48
10531             (match_operand:SWI48 0 "register_operand" "r")
10532             (const_int 1)
10533             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10534           (const_int 0)))]
10535   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10536   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10537   [(set_attr "type" "alu1")
10538    (set_attr "prefix_0f" "1")
10539    (set_attr "mode" "<MODE>")])
10540 \f
10541 ;; Store-flag instructions.
10542
10543 ;; For all sCOND expanders, also expand the compare or test insn that
10544 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10545
10546 (define_insn_and_split "*setcc_di_1"
10547   [(set (match_operand:DI 0 "register_operand" "=q")
10548         (match_operator:DI 1 "ix86_comparison_operator"
10549           [(reg FLAGS_REG) (const_int 0)]))]
10550   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10551   "#"
10552   "&& reload_completed"
10553   [(set (match_dup 2) (match_dup 1))
10554    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10555 {
10556   PUT_MODE (operands[1], QImode);
10557   operands[2] = gen_lowpart (QImode, operands[0]);
10558 })
10559
10560 (define_insn_and_split "*setcc_si_1_and"
10561   [(set (match_operand:SI 0 "register_operand" "=q")
10562         (match_operator:SI 1 "ix86_comparison_operator"
10563           [(reg FLAGS_REG) (const_int 0)]))
10564    (clobber (reg:CC FLAGS_REG))]
10565   "!TARGET_PARTIAL_REG_STALL
10566    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10567   "#"
10568   "&& reload_completed"
10569   [(set (match_dup 2) (match_dup 1))
10570    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10571               (clobber (reg:CC FLAGS_REG))])]
10572 {
10573   PUT_MODE (operands[1], QImode);
10574   operands[2] = gen_lowpart (QImode, operands[0]);
10575 })
10576
10577 (define_insn_and_split "*setcc_si_1_movzbl"
10578   [(set (match_operand:SI 0 "register_operand" "=q")
10579         (match_operator:SI 1 "ix86_comparison_operator"
10580           [(reg FLAGS_REG) (const_int 0)]))]
10581   "!TARGET_PARTIAL_REG_STALL
10582    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10583   "#"
10584   "&& reload_completed"
10585   [(set (match_dup 2) (match_dup 1))
10586    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10587 {
10588   PUT_MODE (operands[1], QImode);
10589   operands[2] = gen_lowpart (QImode, operands[0]);
10590 })
10591
10592 (define_insn "*setcc_qi"
10593   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10594         (match_operator:QI 1 "ix86_comparison_operator"
10595           [(reg FLAGS_REG) (const_int 0)]))]
10596   ""
10597   "set%C1\t%0"
10598   [(set_attr "type" "setcc")
10599    (set_attr "mode" "QI")])
10600
10601 (define_insn "*setcc_qi_slp"
10602   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10603         (match_operator:QI 1 "ix86_comparison_operator"
10604           [(reg FLAGS_REG) (const_int 0)]))]
10605   ""
10606   "set%C1\t%0"
10607   [(set_attr "type" "setcc")
10608    (set_attr "mode" "QI")])
10609
10610 ;; In general it is not safe to assume too much about CCmode registers,
10611 ;; so simplify-rtx stops when it sees a second one.  Under certain
10612 ;; conditions this is safe on x86, so help combine not create
10613 ;;
10614 ;;      seta    %al
10615 ;;      testb   %al, %al
10616 ;;      sete    %al
10617
10618 (define_split
10619   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10620         (ne:QI (match_operator 1 "ix86_comparison_operator"
10621                  [(reg FLAGS_REG) (const_int 0)])
10622             (const_int 0)))]
10623   ""
10624   [(set (match_dup 0) (match_dup 1))]
10625   "PUT_MODE (operands[1], QImode);")
10626
10627 (define_split
10628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10629         (ne:QI (match_operator 1 "ix86_comparison_operator"
10630                  [(reg FLAGS_REG) (const_int 0)])
10631             (const_int 0)))]
10632   ""
10633   [(set (match_dup 0) (match_dup 1))]
10634   "PUT_MODE (operands[1], QImode);")
10635
10636 (define_split
10637   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10638         (eq:QI (match_operator 1 "ix86_comparison_operator"
10639                  [(reg FLAGS_REG) (const_int 0)])
10640             (const_int 0)))]
10641   ""
10642   [(set (match_dup 0) (match_dup 1))]
10643 {
10644   rtx new_op1 = copy_rtx (operands[1]);
10645   operands[1] = new_op1;
10646   PUT_MODE (new_op1, QImode);
10647   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10648                                              GET_MODE (XEXP (new_op1, 0))));
10649
10650   /* Make sure that (a) the CCmode we have for the flags is strong
10651      enough for the reversed compare or (b) we have a valid FP compare.  */
10652   if (! ix86_comparison_operator (new_op1, VOIDmode))
10653     FAIL;
10654 })
10655
10656 (define_split
10657   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10658         (eq:QI (match_operator 1 "ix86_comparison_operator"
10659                  [(reg FLAGS_REG) (const_int 0)])
10660             (const_int 0)))]
10661   ""
10662   [(set (match_dup 0) (match_dup 1))]
10663 {
10664   rtx new_op1 = copy_rtx (operands[1]);
10665   operands[1] = new_op1;
10666   PUT_MODE (new_op1, QImode);
10667   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10668                                              GET_MODE (XEXP (new_op1, 0))));
10669
10670   /* Make sure that (a) the CCmode we have for the flags is strong
10671      enough for the reversed compare or (b) we have a valid FP compare.  */
10672   if (! ix86_comparison_operator (new_op1, VOIDmode))
10673     FAIL;
10674 })
10675
10676 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10677 ;; subsequent logical operations are used to imitate conditional moves.
10678 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10679 ;; it directly.
10680
10681 (define_insn "*avx_setcc<mode>"
10682   [(set (match_operand:MODEF 0 "register_operand" "=x")
10683         (match_operator:MODEF 1 "avx_comparison_float_operator"
10684           [(match_operand:MODEF 2 "register_operand" "x")
10685            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10686   "TARGET_AVX"
10687   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10688   [(set_attr "type" "ssecmp")
10689    (set_attr "prefix" "vex")
10690    (set_attr "length_immediate" "1")
10691    (set_attr "mode" "<MODE>")])
10692
10693 (define_insn "*sse_setcc<mode>"
10694   [(set (match_operand:MODEF 0 "register_operand" "=x")
10695         (match_operator:MODEF 1 "sse_comparison_operator"
10696           [(match_operand:MODEF 2 "register_operand" "0")
10697            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10698   "SSE_FLOAT_MODE_P (<MODE>mode)"
10699   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10700   [(set_attr "type" "ssecmp")
10701    (set_attr "length_immediate" "1")
10702    (set_attr "mode" "<MODE>")])
10703 \f
10704 ;; Basic conditional jump instructions.
10705 ;; We ignore the overflow flag for signed branch instructions.
10706
10707 (define_insn "*jcc_1"
10708   [(set (pc)
10709         (if_then_else (match_operator 1 "ix86_comparison_operator"
10710                                       [(reg FLAGS_REG) (const_int 0)])
10711                       (label_ref (match_operand 0 "" ""))
10712                       (pc)))]
10713   ""
10714   "%+j%C1\t%l0"
10715   [(set_attr "type" "ibr")
10716    (set_attr "modrm" "0")
10717    (set (attr "length")
10718            (if_then_else (and (ge (minus (match_dup 0) (pc))
10719                                   (const_int -126))
10720                               (lt (minus (match_dup 0) (pc))
10721                                   (const_int 128)))
10722              (const_int 2)
10723              (const_int 6)))])
10724
10725 (define_insn "*jcc_2"
10726   [(set (pc)
10727         (if_then_else (match_operator 1 "ix86_comparison_operator"
10728                                       [(reg FLAGS_REG) (const_int 0)])
10729                       (pc)
10730                       (label_ref (match_operand 0 "" ""))))]
10731   ""
10732   "%+j%c1\t%l0"
10733   [(set_attr "type" "ibr")
10734    (set_attr "modrm" "0")
10735    (set (attr "length")
10736            (if_then_else (and (ge (minus (match_dup 0) (pc))
10737                                   (const_int -126))
10738                               (lt (minus (match_dup 0) (pc))
10739                                   (const_int 128)))
10740              (const_int 2)
10741              (const_int 6)))])
10742
10743 ;; In general it is not safe to assume too much about CCmode registers,
10744 ;; so simplify-rtx stops when it sees a second one.  Under certain
10745 ;; conditions this is safe on x86, so help combine not create
10746 ;;
10747 ;;      seta    %al
10748 ;;      testb   %al, %al
10749 ;;      je      Lfoo
10750
10751 (define_split
10752   [(set (pc)
10753         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10754                                       [(reg FLAGS_REG) (const_int 0)])
10755                           (const_int 0))
10756                       (label_ref (match_operand 1 "" ""))
10757                       (pc)))]
10758   ""
10759   [(set (pc)
10760         (if_then_else (match_dup 0)
10761                       (label_ref (match_dup 1))
10762                       (pc)))]
10763   "PUT_MODE (operands[0], VOIDmode);")
10764
10765 (define_split
10766   [(set (pc)
10767         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10768                                       [(reg FLAGS_REG) (const_int 0)])
10769                           (const_int 0))
10770                       (label_ref (match_operand 1 "" ""))
10771                       (pc)))]
10772   ""
10773   [(set (pc)
10774         (if_then_else (match_dup 0)
10775                       (label_ref (match_dup 1))
10776                       (pc)))]
10777 {
10778   rtx new_op0 = copy_rtx (operands[0]);
10779   operands[0] = new_op0;
10780   PUT_MODE (new_op0, VOIDmode);
10781   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10782                                              GET_MODE (XEXP (new_op0, 0))));
10783
10784   /* Make sure that (a) the CCmode we have for the flags is strong
10785      enough for the reversed compare or (b) we have a valid FP compare.  */
10786   if (! ix86_comparison_operator (new_op0, VOIDmode))
10787     FAIL;
10788 })
10789
10790 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10791 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10792 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10793 ;; appropriate modulo of the bit offset value.
10794
10795 (define_insn_and_split "*jcc_bt<mode>"
10796   [(set (pc)
10797         (if_then_else (match_operator 0 "bt_comparison_operator"
10798                         [(zero_extract:SWI48
10799                            (match_operand:SWI48 1 "register_operand" "r")
10800                            (const_int 1)
10801                            (zero_extend:SI
10802                              (match_operand:QI 2 "register_operand" "r")))
10803                          (const_int 0)])
10804                       (label_ref (match_operand 3 "" ""))
10805                       (pc)))
10806    (clobber (reg:CC FLAGS_REG))]
10807   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10808   "#"
10809   "&& 1"
10810   [(set (reg:CCC FLAGS_REG)
10811         (compare:CCC
10812           (zero_extract:SWI48
10813             (match_dup 1)
10814             (const_int 1)
10815             (match_dup 2))
10816           (const_int 0)))
10817    (set (pc)
10818         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10819                       (label_ref (match_dup 3))
10820                       (pc)))]
10821 {
10822   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10823
10824   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10825 })
10826
10827 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10828 ;; also for DImode, this is what combine produces.
10829 (define_insn_and_split "*jcc_bt<mode>_mask"
10830   [(set (pc)
10831         (if_then_else (match_operator 0 "bt_comparison_operator"
10832                         [(zero_extract:SWI48
10833                            (match_operand:SWI48 1 "register_operand" "r")
10834                            (const_int 1)
10835                            (and:SI
10836                              (match_operand:SI 2 "register_operand" "r")
10837                              (match_operand:SI 3 "const_int_operand" "n")))])
10838                       (label_ref (match_operand 4 "" ""))
10839                       (pc)))
10840    (clobber (reg:CC FLAGS_REG))]
10841   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10842    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10843       == GET_MODE_BITSIZE (<MODE>mode)-1"
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 4))
10856                       (pc)))]
10857 {
10858   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10859
10860   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10861 })
10862
10863 (define_insn_and_split "*jcc_btsi_1"
10864   [(set (pc)
10865         (if_then_else (match_operator 0 "bt_comparison_operator"
10866                         [(and:SI
10867                            (lshiftrt:SI
10868                              (match_operand:SI 1 "register_operand" "r")
10869                              (match_operand:QI 2 "register_operand" "r"))
10870                            (const_int 1))
10871                          (const_int 0)])
10872                       (label_ref (match_operand 3 "" ""))
10873                       (pc)))
10874    (clobber (reg:CC FLAGS_REG))]
10875   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10876   "#"
10877   "&& 1"
10878   [(set (reg:CCC FLAGS_REG)
10879         (compare:CCC
10880           (zero_extract:SI
10881             (match_dup 1)
10882             (const_int 1)
10883             (match_dup 2))
10884           (const_int 0)))
10885    (set (pc)
10886         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10887                       (label_ref (match_dup 3))
10888                       (pc)))]
10889 {
10890   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10891
10892   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10893 })
10894
10895 ;; avoid useless masking of bit offset operand
10896 (define_insn_and_split "*jcc_btsi_mask_1"
10897   [(set (pc)
10898         (if_then_else
10899           (match_operator 0 "bt_comparison_operator"
10900             [(and:SI
10901                (lshiftrt:SI
10902                  (match_operand:SI 1 "register_operand" "r")
10903                  (subreg:QI
10904                    (and:SI
10905                      (match_operand:SI 2 "register_operand" "r")
10906                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10907                (const_int 1))
10908              (const_int 0)])
10909           (label_ref (match_operand 4 "" ""))
10910           (pc)))
10911    (clobber (reg:CC FLAGS_REG))]
10912   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10913    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10914   "#"
10915   "&& 1"
10916   [(set (reg:CCC FLAGS_REG)
10917         (compare:CCC
10918           (zero_extract:SI
10919             (match_dup 1)
10920             (const_int 1)
10921             (match_dup 2))
10922           (const_int 0)))
10923    (set (pc)
10924         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10925                       (label_ref (match_dup 4))
10926                       (pc)))]
10927   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10928
10929 ;; Define combination compare-and-branch fp compare instructions to help
10930 ;; combine.
10931
10932 (define_insn "*fp_jcc_1_387"
10933   [(set (pc)
10934         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10935                         [(match_operand 1 "register_operand" "f")
10936                          (match_operand 2 "nonimmediate_operand" "fm")])
10937           (label_ref (match_operand 3 "" ""))
10938           (pc)))
10939    (clobber (reg:CCFP FPSR_REG))
10940    (clobber (reg:CCFP FLAGS_REG))
10941    (clobber (match_scratch:HI 4 "=a"))]
10942   "TARGET_80387
10943    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10944    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10945    && SELECT_CC_MODE (GET_CODE (operands[0]),
10946                       operands[1], operands[2]) == CCFPmode
10947    && !TARGET_CMOVE"
10948   "#")
10949
10950 (define_insn "*fp_jcc_1r_387"
10951   [(set (pc)
10952         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10953                         [(match_operand 1 "register_operand" "f")
10954                          (match_operand 2 "nonimmediate_operand" "fm")])
10955           (pc)
10956           (label_ref (match_operand 3 "" ""))))
10957    (clobber (reg:CCFP FPSR_REG))
10958    (clobber (reg:CCFP FLAGS_REG))
10959    (clobber (match_scratch:HI 4 "=a"))]
10960   "TARGET_80387
10961    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10962    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10963    && SELECT_CC_MODE (GET_CODE (operands[0]),
10964                       operands[1], operands[2]) == CCFPmode
10965    && !TARGET_CMOVE"
10966   "#")
10967
10968 (define_insn "*fp_jcc_2_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 "register_operand" "f")])
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   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10979    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10980    && !TARGET_CMOVE"
10981   "#")
10982
10983 (define_insn "*fp_jcc_2r_387"
10984   [(set (pc)
10985         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10986                         [(match_operand 1 "register_operand" "f")
10987                          (match_operand 2 "register_operand" "f")])
10988           (pc)
10989           (label_ref (match_operand 3 "" ""))))
10990    (clobber (reg:CCFP FPSR_REG))
10991    (clobber (reg:CCFP FLAGS_REG))
10992    (clobber (match_scratch:HI 4 "=a"))]
10993   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10994    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10995    && !TARGET_CMOVE"
10996   "#")
10997
10998 (define_insn "*fp_jcc_3_387"
10999   [(set (pc)
11000         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11001                         [(match_operand 1 "register_operand" "f")
11002                          (match_operand 2 "const0_operand" "")])
11003           (label_ref (match_operand 3 "" ""))
11004           (pc)))
11005    (clobber (reg:CCFP FPSR_REG))
11006    (clobber (reg:CCFP FLAGS_REG))
11007    (clobber (match_scratch:HI 4 "=a"))]
11008   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11009    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11010    && SELECT_CC_MODE (GET_CODE (operands[0]),
11011                       operands[1], operands[2]) == CCFPmode
11012    && !TARGET_CMOVE"
11013   "#")
11014
11015 (define_split
11016   [(set (pc)
11017         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11018                         [(match_operand 1 "register_operand" "")
11019                          (match_operand 2 "nonimmediate_operand" "")])
11020           (match_operand 3 "" "")
11021           (match_operand 4 "" "")))
11022    (clobber (reg:CCFP FPSR_REG))
11023    (clobber (reg:CCFP FLAGS_REG))]
11024   "reload_completed"
11025   [(const_int 0)]
11026 {
11027   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11028                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11029   DONE;
11030 })
11031
11032 (define_split
11033   [(set (pc)
11034         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11035                         [(match_operand 1 "register_operand" "")
11036                          (match_operand 2 "general_operand" "")])
11037           (match_operand 3 "" "")
11038           (match_operand 4 "" "")))
11039    (clobber (reg:CCFP FPSR_REG))
11040    (clobber (reg:CCFP FLAGS_REG))
11041    (clobber (match_scratch:HI 5 "=a"))]
11042   "reload_completed"
11043   [(const_int 0)]
11044 {
11045   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11046                         operands[3], operands[4], operands[5], NULL_RTX);
11047   DONE;
11048 })
11049
11050 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11051 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11052 ;; with a precedence over other operators and is always put in the first
11053 ;; place. Swap condition and operands to match ficom instruction.
11054
11055 (define_insn "*fp_jcc_4_<mode>_387"
11056   [(set (pc)
11057         (if_then_else
11058           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11059             [(match_operator 1 "float_operator"
11060               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11061              (match_operand 3 "register_operand" "f,f")])
11062           (label_ref (match_operand 4 "" ""))
11063           (pc)))
11064    (clobber (reg:CCFP FPSR_REG))
11065    (clobber (reg:CCFP FLAGS_REG))
11066    (clobber (match_scratch:HI 5 "=a,a"))]
11067   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11068    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11069    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11070    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11071    && !TARGET_CMOVE"
11072   "#")
11073
11074 (define_split
11075   [(set (pc)
11076         (if_then_else
11077           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11078             [(match_operator 1 "float_operator"
11079               [(match_operand:X87MODEI12 2 "memory_operand" "")])
11080              (match_operand 3 "register_operand" "")])
11081           (match_operand 4 "" "")
11082           (match_operand 5 "" "")))
11083    (clobber (reg:CCFP FPSR_REG))
11084    (clobber (reg:CCFP FLAGS_REG))
11085    (clobber (match_scratch:HI 6 "=a"))]
11086   "reload_completed"
11087   [(const_int 0)]
11088 {
11089   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11090
11091   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11092                         operands[3], operands[7],
11093                         operands[4], operands[5], operands[6], NULL_RTX);
11094   DONE;
11095 })
11096
11097 ;; %%% Kill this when reload knows how to do it.
11098 (define_split
11099   [(set (pc)
11100         (if_then_else
11101           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11102             [(match_operator 1 "float_operator"
11103               [(match_operand:X87MODEI12 2 "register_operand" "")])
11104              (match_operand 3 "register_operand" "")])
11105           (match_operand 4 "" "")
11106           (match_operand 5 "" "")))
11107    (clobber (reg:CCFP FPSR_REG))
11108    (clobber (reg:CCFP FLAGS_REG))
11109    (clobber (match_scratch:HI 6 "=a"))]
11110   "reload_completed"
11111   [(const_int 0)]
11112 {
11113   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11114   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11115
11116   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11117                         operands[3], operands[7],
11118                         operands[4], operands[5], operands[6], operands[2]);
11119   DONE;
11120 })
11121 \f
11122 ;; Unconditional and other jump instructions
11123
11124 (define_insn "jump"
11125   [(set (pc)
11126         (label_ref (match_operand 0 "" "")))]
11127   ""
11128   "jmp\t%l0"
11129   [(set_attr "type" "ibr")
11130    (set (attr "length")
11131            (if_then_else (and (ge (minus (match_dup 0) (pc))
11132                                   (const_int -126))
11133                               (lt (minus (match_dup 0) (pc))
11134                                   (const_int 128)))
11135              (const_int 2)
11136              (const_int 5)))
11137    (set_attr "modrm" "0")])
11138
11139 (define_expand "indirect_jump"
11140   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11141   ""
11142   "")
11143
11144 (define_insn "*indirect_jump"
11145   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11146   ""
11147   "jmp\t%A0"
11148   [(set_attr "type" "ibr")
11149    (set_attr "length_immediate" "0")])
11150
11151 (define_expand "tablejump"
11152   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11153               (use (label_ref (match_operand 1 "" "")))])]
11154   ""
11155 {
11156   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11157      relative.  Convert the relative address to an absolute address.  */
11158   if (flag_pic)
11159     {
11160       rtx op0, op1;
11161       enum rtx_code code;
11162
11163       /* We can't use @GOTOFF for text labels on VxWorks;
11164          see gotoff_operand.  */
11165       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11166         {
11167           code = PLUS;
11168           op0 = operands[0];
11169           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11170         }
11171       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11172         {
11173           code = PLUS;
11174           op0 = operands[0];
11175           op1 = pic_offset_table_rtx;
11176         }
11177       else
11178         {
11179           code = MINUS;
11180           op0 = pic_offset_table_rtx;
11181           op1 = operands[0];
11182         }
11183
11184       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11185                                          OPTAB_DIRECT);
11186     }
11187 })
11188
11189 (define_insn "*tablejump_1"
11190   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11191    (use (label_ref (match_operand 1 "" "")))]
11192   ""
11193   "jmp\t%A0"
11194   [(set_attr "type" "ibr")
11195    (set_attr "length_immediate" "0")])
11196 \f
11197 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11198
11199 (define_peephole2
11200   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11201    (set (match_operand:QI 1 "register_operand" "")
11202         (match_operator:QI 2 "ix86_comparison_operator"
11203           [(reg FLAGS_REG) (const_int 0)]))
11204    (set (match_operand 3 "q_regs_operand" "")
11205         (zero_extend (match_dup 1)))]
11206   "(peep2_reg_dead_p (3, operands[1])
11207     || operands_match_p (operands[1], operands[3]))
11208    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11209   [(set (match_dup 4) (match_dup 0))
11210    (set (strict_low_part (match_dup 5))
11211         (match_dup 2))]
11212 {
11213   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11214   operands[5] = gen_lowpart (QImode, operands[3]);
11215   ix86_expand_clear (operands[3]);
11216 })
11217
11218 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11219
11220 (define_peephole2
11221   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11222    (set (match_operand:QI 1 "register_operand" "")
11223         (match_operator:QI 2 "ix86_comparison_operator"
11224           [(reg FLAGS_REG) (const_int 0)]))
11225    (parallel [(set (match_operand 3 "q_regs_operand" "")
11226                    (zero_extend (match_dup 1)))
11227               (clobber (reg:CC FLAGS_REG))])]
11228   "(peep2_reg_dead_p (3, operands[1])
11229     || operands_match_p (operands[1], operands[3]))
11230    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11231   [(set (match_dup 4) (match_dup 0))
11232    (set (strict_low_part (match_dup 5))
11233         (match_dup 2))]
11234 {
11235   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11236   operands[5] = gen_lowpart (QImode, operands[3]);
11237   ix86_expand_clear (operands[3]);
11238 })
11239 \f
11240 ;; Call instructions.
11241
11242 ;; The predicates normally associated with named expanders are not properly
11243 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11244 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11245
11246 ;; P6 processors will jump to the address after the decrement when %esp
11247 ;; is used as a call operand, so they will execute return address as a code.
11248 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11249  
11250 ;; Call subroutine returning no value.
11251
11252 (define_expand "call_pop"
11253   [(parallel [(call (match_operand:QI 0 "" "")
11254                     (match_operand:SI 1 "" ""))
11255               (set (reg:SI SP_REG)
11256                    (plus:SI (reg:SI SP_REG)
11257                             (match_operand:SI 3 "" "")))])]
11258   "!TARGET_64BIT"
11259 {
11260   ix86_expand_call (NULL, operands[0], operands[1],
11261                     operands[2], operands[3], 0);
11262   DONE;
11263 })
11264
11265 (define_insn_and_split "*call_pop_0_vzeroupper"
11266   [(parallel
11267     [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11268            (match_operand:SI 1 "" ""))
11269      (set (reg:SI SP_REG)
11270           (plus:SI (reg:SI SP_REG)
11271                    (match_operand:SI 2 "immediate_operand" "")))])
11272    (unspec [(match_operand 3 "const_int_operand" "")]
11273            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11274   "TARGET_VZEROUPPER && !TARGET_64BIT"
11275   "#"
11276   "&& reload_completed"
11277   [(const_int 0)]
11278   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11279   [(set_attr "type" "call")])
11280
11281 (define_insn "*call_pop_0"
11282   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11283          (match_operand:SI 1 "" ""))
11284    (set (reg:SI SP_REG)
11285         (plus:SI (reg:SI SP_REG)
11286                  (match_operand:SI 2 "immediate_operand" "")))]
11287   "!TARGET_64BIT"
11288 {
11289   if (SIBLING_CALL_P (insn))
11290     return "jmp\t%P0";
11291   else
11292     return "call\t%P0";
11293 }
11294   [(set_attr "type" "call")])
11295
11296 (define_insn_and_split "*call_pop_1_vzeroupper"
11297   [(parallel
11298     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11299            (match_operand:SI 1 "" ""))
11300      (set (reg:SI SP_REG)
11301           (plus:SI (reg:SI SP_REG)
11302                    (match_operand:SI 2 "immediate_operand" "i")))])
11303    (unspec [(match_operand 3 "const_int_operand" "")]
11304            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11305   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11306   "#"
11307   "&& reload_completed"
11308   [(const_int 0)]
11309   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11310   [(set_attr "type" "call")])
11311
11312 (define_insn "*call_pop_1"
11313   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11314          (match_operand:SI 1 "" ""))
11315    (set (reg:SI SP_REG)
11316         (plus:SI (reg:SI SP_REG)
11317                  (match_operand:SI 2 "immediate_operand" "i")))]
11318   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11319 {
11320   if (constant_call_address_operand (operands[0], Pmode))
11321     return "call\t%P0";
11322   return "call\t%A0";
11323 }
11324   [(set_attr "type" "call")])
11325
11326 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11327  [(parallel
11328    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11329            (match_operand:SI 1 "" ""))
11330      (set (reg:SI SP_REG)
11331           (plus:SI (reg:SI SP_REG)
11332                    (match_operand:SI 2 "immediate_operand" "i,i")))])
11333    (unspec [(match_operand 3 "const_int_operand" "")]
11334            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11335   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11336   "#"
11337   "&& reload_completed"
11338   [(const_int 0)]
11339   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11340   [(set_attr "type" "call")])
11341
11342 (define_insn "*sibcall_pop_1"
11343   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11344          (match_operand:SI 1 "" ""))
11345    (set (reg:SI SP_REG)
11346         (plus:SI (reg:SI SP_REG)
11347                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11348   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11349   "@
11350    jmp\t%P0
11351    jmp\t%A0"
11352   [(set_attr "type" "call")])
11353
11354 (define_expand "call"
11355   [(call (match_operand:QI 0 "" "")
11356          (match_operand 1 "" ""))
11357    (use (match_operand 2 "" ""))]
11358   ""
11359 {
11360   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11361   DONE;
11362 })
11363
11364 (define_expand "sibcall"
11365   [(call (match_operand:QI 0 "" "")
11366          (match_operand 1 "" ""))
11367    (use (match_operand 2 "" ""))]
11368   ""
11369 {
11370   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11371   DONE;
11372 })
11373
11374 (define_insn_and_split "*call_0_vzeroupper"
11375   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11376          (match_operand 1 "" ""))
11377    (unspec [(match_operand 2 "const_int_operand" "")]
11378            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11379   "TARGET_VZEROUPPER"
11380   "#"
11381   "&& reload_completed"
11382   [(const_int 0)]
11383   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11384   [(set_attr "type" "call")])
11385
11386 (define_insn "*call_0"
11387   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11388          (match_operand 1 "" ""))]
11389   ""
11390   { return ix86_output_call_insn (insn, operands[0], 0); }
11391   [(set_attr "type" "call")])
11392
11393 (define_insn_and_split "*call_1_vzeroupper"
11394   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11395          (match_operand 1 "" ""))
11396    (unspec [(match_operand 2 "const_int_operand" "")]
11397            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11398   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11399   "#"
11400   "&& reload_completed"
11401   [(const_int 0)]
11402   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11403   [(set_attr "type" "call")])
11404
11405 (define_insn "*call_1"
11406   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11407          (match_operand 1 "" ""))]
11408   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11409   { return ix86_output_call_insn (insn, operands[0], 0); }
11410   [(set_attr "type" "call")])
11411
11412 (define_insn_and_split "*sibcall_1_vzeroupper"
11413   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11414          (match_operand 1 "" ""))
11415    (unspec [(match_operand 2 "const_int_operand" "")]
11416            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11417   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11418   "#"
11419   "&& reload_completed"
11420   [(const_int 0)]
11421   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11422   [(set_attr "type" "call")])
11423
11424 (define_insn "*sibcall_1"
11425   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11426          (match_operand 1 "" ""))]
11427   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11428   { return ix86_output_call_insn (insn, operands[0], 0); }
11429   [(set_attr "type" "call")])
11430
11431 (define_insn_and_split "*call_1_rex64_vzeroupper"
11432   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11433          (match_operand 1 "" ""))
11434    (unspec [(match_operand 2 "const_int_operand" "")]
11435            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11436   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11437    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11438   "#"
11439   "&& reload_completed"
11440   [(const_int 0)]
11441   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11442   [(set_attr "type" "call")])
11443
11444 (define_insn "*call_1_rex64"
11445   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11446          (match_operand 1 "" ""))]
11447   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11448    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11449   { return ix86_output_call_insn (insn, operands[0], 0); }
11450   [(set_attr "type" "call")])
11451
11452 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11453   [(parallel
11454     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11455            (match_operand 1 "" ""))
11456      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11457      (clobber (reg:TI XMM6_REG))
11458      (clobber (reg:TI XMM7_REG))
11459      (clobber (reg:TI XMM8_REG))
11460      (clobber (reg:TI XMM9_REG))
11461      (clobber (reg:TI XMM10_REG))
11462      (clobber (reg:TI XMM11_REG))
11463      (clobber (reg:TI XMM12_REG))
11464      (clobber (reg:TI XMM13_REG))
11465      (clobber (reg:TI XMM14_REG))
11466      (clobber (reg:TI XMM15_REG))
11467      (clobber (reg:DI SI_REG))
11468      (clobber (reg:DI DI_REG))])
11469    (unspec [(match_operand 2 "const_int_operand" "")]
11470            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11471   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11472   "#"
11473   "&& reload_completed"
11474   [(const_int 0)]
11475   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11476   [(set_attr "type" "call")])
11477
11478 (define_insn "*call_1_rex64_ms_sysv"
11479   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11480          (match_operand 1 "" ""))
11481    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11482    (clobber (reg:TI XMM6_REG))
11483    (clobber (reg:TI XMM7_REG))
11484    (clobber (reg:TI XMM8_REG))
11485    (clobber (reg:TI XMM9_REG))
11486    (clobber (reg:TI XMM10_REG))
11487    (clobber (reg:TI XMM11_REG))
11488    (clobber (reg:TI XMM12_REG))
11489    (clobber (reg:TI XMM13_REG))
11490    (clobber (reg:TI XMM14_REG))
11491    (clobber (reg:TI XMM15_REG))
11492    (clobber (reg:DI SI_REG))
11493    (clobber (reg:DI DI_REG))]
11494   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11495   { return ix86_output_call_insn (insn, operands[0], 0); }
11496   [(set_attr "type" "call")])
11497
11498 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11499   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11500          (match_operand 1 "" ""))
11501    (unspec [(match_operand 2 "const_int_operand" "")]
11502            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11503   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11504   "#"
11505   "&& reload_completed"
11506   [(const_int 0)]
11507   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11508   [(set_attr "type" "call")])
11509
11510 (define_insn "*call_1_rex64_large"
11511   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11512          (match_operand 1 "" ""))]
11513   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11514   { return ix86_output_call_insn (insn, operands[0], 0); }
11515   [(set_attr "type" "call")])
11516
11517 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11518   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11519          (match_operand 1 "" ""))
11520    (unspec [(match_operand 2 "const_int_operand" "")]
11521            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11522   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11523   "#"
11524   "&& reload_completed"
11525   [(const_int 0)]
11526   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11527   [(set_attr "type" "call")])
11528
11529 (define_insn "*sibcall_1_rex64"
11530   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11531          (match_operand 1 "" ""))]
11532   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11533   { return ix86_output_call_insn (insn, operands[0], 0); }
11534   [(set_attr "type" "call")])
11535
11536 ;; Call subroutine, returning value in operand 0
11537 (define_expand "call_value_pop"
11538   [(parallel [(set (match_operand 0 "" "")
11539                    (call (match_operand:QI 1 "" "")
11540                          (match_operand:SI 2 "" "")))
11541               (set (reg:SI SP_REG)
11542                    (plus:SI (reg:SI SP_REG)
11543                             (match_operand:SI 4 "" "")))])]
11544   "!TARGET_64BIT"
11545 {
11546   ix86_expand_call (operands[0], operands[1], operands[2],
11547                     operands[3], operands[4], 0);
11548   DONE;
11549 })
11550
11551 (define_expand "call_value"
11552   [(set (match_operand 0 "" "")
11553         (call (match_operand:QI 1 "" "")
11554               (match_operand:SI 2 "" "")))
11555    (use (match_operand:SI 3 "" ""))]
11556   ;; Operand 3 is not used on the i386.
11557   ""
11558 {
11559   ix86_expand_call (operands[0], operands[1], operands[2],
11560                     operands[3], NULL, 0);
11561   DONE;
11562 })
11563
11564 (define_expand "sibcall_value"
11565   [(set (match_operand 0 "" "")
11566         (call (match_operand:QI 1 "" "")
11567               (match_operand:SI 2 "" "")))
11568    (use (match_operand:SI 3 "" ""))]
11569   ;; Operand 3 is not used on the i386.
11570   ""
11571 {
11572   ix86_expand_call (operands[0], operands[1], operands[2],
11573                     operands[3], NULL, 1);
11574   DONE;
11575 })
11576
11577 ;; Call subroutine returning any type.
11578
11579 (define_expand "untyped_call"
11580   [(parallel [(call (match_operand 0 "" "")
11581                     (const_int 0))
11582               (match_operand 1 "" "")
11583               (match_operand 2 "" "")])]
11584   ""
11585 {
11586   int i;
11587
11588   /* In order to give reg-stack an easier job in validating two
11589      coprocessor registers as containing a possible return value,
11590      simply pretend the untyped call returns a complex long double
11591      value. 
11592
11593      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11594      and should have the default ABI.  */
11595
11596   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11597                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11598                     operands[0], const0_rtx,
11599                     GEN_INT ((TARGET_64BIT
11600                               ? (ix86_abi == SYSV_ABI
11601                                  ? X86_64_SSE_REGPARM_MAX
11602                                  : X86_64_MS_SSE_REGPARM_MAX)
11603                               : X86_32_SSE_REGPARM_MAX)
11604                              - 1),
11605                     NULL, 0);
11606
11607   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11608     {
11609       rtx set = XVECEXP (operands[2], 0, i);
11610       emit_move_insn (SET_DEST (set), SET_SRC (set));
11611     }
11612
11613   /* The optimizer does not know that the call sets the function value
11614      registers we stored in the result block.  We avoid problems by
11615      claiming that all hard registers are used and clobbered at this
11616      point.  */
11617   emit_insn (gen_blockage ());
11618
11619   DONE;
11620 })
11621 \f
11622 ;; Prologue and epilogue instructions
11623
11624 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11625 ;; all of memory.  This blocks insns from being moved across this point.
11626
11627 (define_insn "blockage"
11628   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11629   ""
11630   ""
11631   [(set_attr "length" "0")])
11632
11633 ;; Do not schedule instructions accessing memory across this point.
11634
11635 (define_expand "memory_blockage"
11636   [(set (match_dup 0)
11637         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11638   ""
11639 {
11640   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11641   MEM_VOLATILE_P (operands[0]) = 1;
11642 })
11643
11644 (define_insn "*memory_blockage"
11645   [(set (match_operand:BLK 0 "" "")
11646         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11647   ""
11648   ""
11649   [(set_attr "length" "0")])
11650
11651 ;; As USE insns aren't meaningful after reload, this is used instead
11652 ;; to prevent deleting instructions setting registers for PIC code
11653 (define_insn "prologue_use"
11654   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11655   ""
11656   ""
11657   [(set_attr "length" "0")])
11658
11659 ;; Insn emitted into the body of a function to return from a function.
11660 ;; This is only done if the function's epilogue is known to be simple.
11661 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11662
11663 (define_expand "return"
11664   [(return)]
11665   "ix86_can_use_return_insn_p ()"
11666 {
11667   if (crtl->args.pops_args)
11668     {
11669       rtx popc = GEN_INT (crtl->args.pops_args);
11670       emit_jump_insn (gen_return_pop_internal (popc));
11671       DONE;
11672     }
11673 })
11674
11675 (define_insn "return_internal"
11676   [(return)]
11677   "reload_completed"
11678   "ret"
11679   [(set_attr "length" "1")
11680    (set_attr "atom_unit" "jeu")
11681    (set_attr "length_immediate" "0")
11682    (set_attr "modrm" "0")])
11683
11684 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11685 ;; instruction Athlon and K8 have.
11686
11687 (define_insn "return_internal_long"
11688   [(return)
11689    (unspec [(const_int 0)] UNSPEC_REP)]
11690   "reload_completed"
11691   "rep\;ret"
11692   [(set_attr "length" "2")
11693    (set_attr "atom_unit" "jeu")
11694    (set_attr "length_immediate" "0")
11695    (set_attr "prefix_rep" "1")
11696    (set_attr "modrm" "0")])
11697
11698 (define_insn "return_pop_internal"
11699   [(return)
11700    (use (match_operand:SI 0 "const_int_operand" ""))]
11701   "reload_completed"
11702   "ret\t%0"
11703   [(set_attr "length" "3")
11704    (set_attr "atom_unit" "jeu")
11705    (set_attr "length_immediate" "2")
11706    (set_attr "modrm" "0")])
11707
11708 (define_insn "return_indirect_internal"
11709   [(return)
11710    (use (match_operand:SI 0 "register_operand" "r"))]
11711   "reload_completed"
11712   "jmp\t%A0"
11713   [(set_attr "type" "ibr")
11714    (set_attr "length_immediate" "0")])
11715
11716 (define_insn "nop"
11717   [(const_int 0)]
11718   ""
11719   "nop"
11720   [(set_attr "length" "1")
11721    (set_attr "length_immediate" "0")
11722    (set_attr "modrm" "0")])
11723
11724 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11725 (define_insn "nops"
11726   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11727                     UNSPECV_NOPS)]
11728   "reload_completed"
11729 {
11730   int num = INTVAL (operands[0]);
11731
11732   gcc_assert (num >= 1 && num <= 8);
11733
11734   while (num--)
11735     fputs ("\tnop\n", asm_out_file);
11736
11737   return "";
11738 }
11739   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11740    (set_attr "length_immediate" "0")
11741    (set_attr "modrm" "0")])
11742
11743 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11744 ;; branch prediction penalty for the third jump in a 16-byte
11745 ;; block on K8.
11746
11747 (define_insn "pad"
11748   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11749   ""
11750 {
11751 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11752   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11753 #else
11754   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11755      The align insn is used to avoid 3 jump instructions in the row to improve
11756      branch prediction and the benefits hardly outweigh the cost of extra 8
11757      nops on the average inserted by full alignment pseudo operation.  */
11758 #endif
11759   return "";
11760 }
11761   [(set_attr "length" "16")])
11762
11763 (define_expand "prologue"
11764   [(const_int 0)]
11765   ""
11766   "ix86_expand_prologue (); DONE;")
11767
11768 (define_insn "set_got"
11769   [(set (match_operand:SI 0 "register_operand" "=r")
11770         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11771    (clobber (reg:CC FLAGS_REG))]
11772   "!TARGET_64BIT"
11773   "* return output_set_got (operands[0], NULL_RTX);"
11774   [(set_attr "type" "multi")
11775    (set_attr "length" "12")])
11776
11777 (define_insn "set_got_labelled"
11778   [(set (match_operand:SI 0 "register_operand" "=r")
11779         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11780          UNSPEC_SET_GOT))
11781    (clobber (reg:CC FLAGS_REG))]
11782   "!TARGET_64BIT"
11783   "* return output_set_got (operands[0], operands[1]);"
11784   [(set_attr "type" "multi")
11785    (set_attr "length" "12")])
11786
11787 (define_insn "set_got_rex64"
11788   [(set (match_operand:DI 0 "register_operand" "=r")
11789         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11790   "TARGET_64BIT"
11791   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11792   [(set_attr "type" "lea")
11793    (set_attr "length_address" "4")
11794    (set_attr "mode" "DI")])
11795
11796 (define_insn "set_rip_rex64"
11797   [(set (match_operand:DI 0 "register_operand" "=r")
11798         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11799   "TARGET_64BIT"
11800   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11801   [(set_attr "type" "lea")
11802    (set_attr "length_address" "4")
11803    (set_attr "mode" "DI")])
11804
11805 (define_insn "set_got_offset_rex64"
11806   [(set (match_operand:DI 0 "register_operand" "=r")
11807         (unspec:DI
11808           [(label_ref (match_operand 1 "" ""))]
11809           UNSPEC_SET_GOT_OFFSET))]
11810   "TARGET_64BIT"
11811   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11812   [(set_attr "type" "imov")
11813    (set_attr "length_immediate" "0")
11814    (set_attr "length_address" "8")
11815    (set_attr "mode" "DI")])
11816
11817 (define_expand "epilogue"
11818   [(const_int 0)]
11819   ""
11820   "ix86_expand_epilogue (1); DONE;")
11821
11822 (define_expand "sibcall_epilogue"
11823   [(const_int 0)]
11824   ""
11825   "ix86_expand_epilogue (0); DONE;")
11826
11827 (define_expand "eh_return"
11828   [(use (match_operand 0 "register_operand" ""))]
11829   ""
11830 {
11831   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11832
11833   /* Tricky bit: we write the address of the handler to which we will
11834      be returning into someone else's stack frame, one word below the
11835      stack address we wish to restore.  */
11836   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11837   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11838   tmp = gen_rtx_MEM (Pmode, tmp);
11839   emit_move_insn (tmp, ra);
11840
11841   emit_jump_insn (gen_eh_return_internal ());
11842   emit_barrier ();
11843   DONE;
11844 })
11845
11846 (define_insn_and_split "eh_return_internal"
11847   [(eh_return)]
11848   ""
11849   "#"
11850   "epilogue_completed"
11851   [(const_int 0)]
11852   "ix86_expand_epilogue (2); DONE;")
11853
11854 (define_insn "leave"
11855   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11856    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11857    (clobber (mem:BLK (scratch)))]
11858   "!TARGET_64BIT"
11859   "leave"
11860   [(set_attr "type" "leave")])
11861
11862 (define_insn "leave_rex64"
11863   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11864    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11865    (clobber (mem:BLK (scratch)))]
11866   "TARGET_64BIT"
11867   "leave"
11868   [(set_attr "type" "leave")])
11869 \f
11870 ;; Handle -fsplit-stack.
11871
11872 (define_expand "split_stack_prologue"
11873   [(const_int 0)]
11874   ""
11875 {
11876   ix86_expand_split_stack_prologue ();
11877   DONE;
11878 })
11879
11880 ;; In order to support the call/return predictor, we use a return
11881 ;; instruction which the middle-end doesn't see.
11882 (define_insn "split_stack_return"
11883   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11884                      UNSPECV_SPLIT_STACK_RETURN)]
11885   ""
11886 {
11887   if (operands[0] == const0_rtx)
11888     return "ret";
11889   else
11890     return "ret\t%0";
11891 }
11892   [(set_attr "atom_unit" "jeu")
11893    (set_attr "modrm" "0")
11894    (set (attr "length")
11895         (if_then_else (match_operand:SI 0 "const0_operand" "")
11896                       (const_int 1)
11897                       (const_int 3)))
11898    (set (attr "length_immediate")
11899         (if_then_else (match_operand:SI 0 "const0_operand" "")
11900                       (const_int 0)
11901                       (const_int 2)))])
11902
11903 ;; If there are operand 0 bytes available on the stack, jump to
11904 ;; operand 1.
11905
11906 (define_expand "split_stack_space_check"
11907   [(set (pc) (if_then_else
11908               (ltu (minus (reg SP_REG)
11909                           (match_operand 0 "register_operand" ""))
11910                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11911               (label_ref (match_operand 1 "" ""))
11912               (pc)))]
11913   ""
11914 {
11915   rtx reg, size, limit;
11916
11917   reg = gen_reg_rtx (Pmode);
11918   size = force_reg (Pmode, operands[0]);
11919   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11920   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11921                           UNSPEC_STACK_CHECK);
11922   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11923   ix86_expand_branch (GEU, reg, limit, operands[1]);
11924
11925   DONE;
11926 })
11927 \f
11928 ;; Bit manipulation instructions.
11929
11930 (define_expand "ffs<mode>2"
11931   [(set (match_dup 2) (const_int -1))
11932    (parallel [(set (reg:CCZ FLAGS_REG)
11933                    (compare:CCZ
11934                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11935                      (const_int 0)))
11936               (set (match_operand:SWI48 0 "register_operand" "")
11937                    (ctz:SWI48 (match_dup 1)))])
11938    (set (match_dup 0) (if_then_else:SWI48
11939                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11940                         (match_dup 2)
11941                         (match_dup 0)))
11942    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11943               (clobber (reg:CC FLAGS_REG))])]
11944   ""
11945 {
11946   if (<MODE>mode == SImode && !TARGET_CMOVE)
11947     {
11948       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11949       DONE;
11950     }
11951   operands[2] = gen_reg_rtx (<MODE>mode);
11952 })
11953
11954 (define_insn_and_split "ffssi2_no_cmove"
11955   [(set (match_operand:SI 0 "register_operand" "=r")
11956         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11957    (clobber (match_scratch:SI 2 "=&q"))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "!TARGET_CMOVE"
11960   "#"
11961   "&& reload_completed"
11962   [(parallel [(set (reg:CCZ FLAGS_REG)
11963                    (compare:CCZ (match_dup 1) (const_int 0)))
11964               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11965    (set (strict_low_part (match_dup 3))
11966         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11967    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11968               (clobber (reg:CC FLAGS_REG))])
11969    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11970               (clobber (reg:CC FLAGS_REG))])
11971    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11972               (clobber (reg:CC FLAGS_REG))])]
11973 {
11974   operands[3] = gen_lowpart (QImode, operands[2]);
11975   ix86_expand_clear (operands[2]);
11976 })
11977
11978 (define_insn "*ffs<mode>_1"
11979   [(set (reg:CCZ FLAGS_REG)
11980         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11981                      (const_int 0)))
11982    (set (match_operand:SWI48 0 "register_operand" "=r")
11983         (ctz:SWI48 (match_dup 1)))]
11984   ""
11985   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11986   [(set_attr "type" "alu1")
11987    (set_attr "prefix_0f" "1")
11988    (set_attr "mode" "<MODE>")])
11989
11990 (define_insn "ctz<mode>2"
11991   [(set (match_operand:SWI48 0 "register_operand" "=r")
11992         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11993    (clobber (reg:CC FLAGS_REG))]
11994   ""
11995   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11996   [(set_attr "type" "alu1")
11997    (set_attr "prefix_0f" "1")
11998    (set_attr "mode" "<MODE>")])
11999
12000 (define_expand "clz<mode>2"
12001   [(parallel
12002      [(set (match_operand:SWI248 0 "register_operand" "")
12003            (minus:SWI248
12004              (match_dup 2)
12005              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12006       (clobber (reg:CC FLAGS_REG))])
12007    (parallel
12008      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12009       (clobber (reg:CC FLAGS_REG))])]
12010   ""
12011 {
12012   if (TARGET_ABM)
12013     {
12014       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12015       DONE;
12016     }
12017   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12018 })
12019
12020 (define_insn "clz<mode>2_abm"
12021   [(set (match_operand:SWI248 0 "register_operand" "=r")
12022         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12023    (clobber (reg:CC FLAGS_REG))]
12024   "TARGET_ABM"
12025   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12026   [(set_attr "prefix_rep" "1")
12027    (set_attr "type" "bitmanip")
12028    (set_attr "mode" "<MODE>")])
12029
12030 (define_insn "bsr_rex64"
12031   [(set (match_operand:DI 0 "register_operand" "=r")
12032         (minus:DI (const_int 63)
12033                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12034    (clobber (reg:CC FLAGS_REG))]
12035   "TARGET_64BIT"
12036   "bsr{q}\t{%1, %0|%0, %1}"
12037   [(set_attr "type" "alu1")
12038    (set_attr "prefix_0f" "1")
12039    (set_attr "mode" "DI")])
12040
12041 (define_insn "bsr"
12042   [(set (match_operand:SI 0 "register_operand" "=r")
12043         (minus:SI (const_int 31)
12044                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12045    (clobber (reg:CC FLAGS_REG))]
12046   ""
12047   "bsr{l}\t{%1, %0|%0, %1}"
12048   [(set_attr "type" "alu1")
12049    (set_attr "prefix_0f" "1")
12050    (set_attr "mode" "SI")])
12051
12052 (define_insn "*bsrhi"
12053   [(set (match_operand:HI 0 "register_operand" "=r")
12054         (minus:HI (const_int 15)
12055                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12056    (clobber (reg:CC FLAGS_REG))]
12057   ""
12058   "bsr{w}\t{%1, %0|%0, %1}"
12059   [(set_attr "type" "alu1")
12060    (set_attr "prefix_0f" "1")
12061    (set_attr "mode" "HI")])
12062
12063 (define_insn "popcount<mode>2"
12064   [(set (match_operand:SWI248 0 "register_operand" "=r")
12065         (popcount:SWI248
12066           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "TARGET_POPCNT"
12069 {
12070 #if TARGET_MACHO
12071   return "popcnt\t{%1, %0|%0, %1}";
12072 #else
12073   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12074 #endif
12075 }
12076   [(set_attr "prefix_rep" "1")
12077    (set_attr "type" "bitmanip")
12078    (set_attr "mode" "<MODE>")])
12079
12080 (define_insn "*popcount<mode>2_cmp"
12081   [(set (reg FLAGS_REG)
12082         (compare
12083           (popcount:SWI248
12084             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12085           (const_int 0)))
12086    (set (match_operand:SWI248 0 "register_operand" "=r")
12087         (popcount:SWI248 (match_dup 1)))]
12088   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12089 {
12090 #if TARGET_MACHO
12091   return "popcnt\t{%1, %0|%0, %1}";
12092 #else
12093   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12094 #endif
12095 }
12096   [(set_attr "prefix_rep" "1")
12097    (set_attr "type" "bitmanip")
12098    (set_attr "mode" "<MODE>")])
12099
12100 (define_insn "*popcountsi2_cmp_zext"
12101   [(set (reg FLAGS_REG)
12102         (compare
12103           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12104           (const_int 0)))
12105    (set (match_operand:DI 0 "register_operand" "=r")
12106         (zero_extend:DI(popcount:SI (match_dup 1))))]
12107   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12108 {
12109 #if TARGET_MACHO
12110   return "popcnt\t{%1, %0|%0, %1}";
12111 #else
12112   return "popcnt{l}\t{%1, %0|%0, %1}";
12113 #endif
12114 }
12115   [(set_attr "prefix_rep" "1")
12116    (set_attr "type" "bitmanip")
12117    (set_attr "mode" "SI")])
12118
12119 (define_expand "bswap<mode>2"
12120   [(set (match_operand:SWI48 0 "register_operand" "")
12121         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12122   ""
12123 {
12124   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12125     {
12126       rtx x = operands[0];
12127
12128       emit_move_insn (x, operands[1]);
12129       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12130       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12131       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12132       DONE;
12133     }
12134 })
12135
12136 (define_insn "*bswap<mode>2_movbe"
12137   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12138         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12139   "TARGET_MOVBE
12140    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12141   "@
12142     bswap\t%0
12143     movbe\t{%1, %0|%0, %1}
12144     movbe\t{%1, %0|%0, %1}"
12145   [(set_attr "type" "bitmanip,imov,imov")
12146    (set_attr "modrm" "0,1,1")
12147    (set_attr "prefix_0f" "*,1,1")
12148    (set_attr "prefix_extra" "*,1,1")
12149    (set_attr "mode" "<MODE>")])
12150
12151 (define_insn "*bswap<mode>2_1"
12152   [(set (match_operand:SWI48 0 "register_operand" "=r")
12153         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12154   "TARGET_BSWAP"
12155   "bswap\t%0"
12156   [(set_attr "type" "bitmanip")
12157    (set_attr "modrm" "0")
12158    (set_attr "mode" "<MODE>")])
12159
12160 (define_insn "*bswaphi_lowpart_1"
12161   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12162         (bswap:HI (match_dup 0)))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12165   "@
12166     xchg{b}\t{%h0, %b0|%b0, %h0}
12167     rol{w}\t{$8, %0|%0, 8}"
12168   [(set_attr "length" "2,4")
12169    (set_attr "mode" "QI,HI")])
12170
12171 (define_insn "bswaphi_lowpart"
12172   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12173         (bswap:HI (match_dup 0)))
12174    (clobber (reg:CC FLAGS_REG))]
12175   ""
12176   "rol{w}\t{$8, %0|%0, 8}"
12177   [(set_attr "length" "4")
12178    (set_attr "mode" "HI")])
12179
12180 (define_expand "paritydi2"
12181   [(set (match_operand:DI 0 "register_operand" "")
12182         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12183   "! TARGET_POPCNT"
12184 {
12185   rtx scratch = gen_reg_rtx (QImode);
12186   rtx cond;
12187
12188   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12189                                 NULL_RTX, operands[1]));
12190
12191   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12192                          gen_rtx_REG (CCmode, FLAGS_REG),
12193                          const0_rtx);
12194   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12195
12196   if (TARGET_64BIT)
12197     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12198   else
12199     {
12200       rtx tmp = gen_reg_rtx (SImode);
12201
12202       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12203       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12204     }
12205   DONE;
12206 })
12207
12208 (define_expand "paritysi2"
12209   [(set (match_operand:SI 0 "register_operand" "")
12210         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12211   "! TARGET_POPCNT"
12212 {
12213   rtx scratch = gen_reg_rtx (QImode);
12214   rtx cond;
12215
12216   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12217
12218   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12219                          gen_rtx_REG (CCmode, FLAGS_REG),
12220                          const0_rtx);
12221   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12222
12223   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12224   DONE;
12225 })
12226
12227 (define_insn_and_split "paritydi2_cmp"
12228   [(set (reg:CC FLAGS_REG)
12229         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12230                    UNSPEC_PARITY))
12231    (clobber (match_scratch:DI 0 "=r"))
12232    (clobber (match_scratch:SI 1 "=&r"))
12233    (clobber (match_scratch:HI 2 "=Q"))]
12234   "! TARGET_POPCNT"
12235   "#"
12236   "&& reload_completed"
12237   [(parallel
12238      [(set (match_dup 1)
12239            (xor:SI (match_dup 1) (match_dup 4)))
12240       (clobber (reg:CC FLAGS_REG))])
12241    (parallel
12242      [(set (reg:CC FLAGS_REG)
12243            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12244       (clobber (match_dup 1))
12245       (clobber (match_dup 2))])]
12246 {
12247   operands[4] = gen_lowpart (SImode, operands[3]);
12248
12249   if (TARGET_64BIT)
12250     {
12251       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12252       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12253     }
12254   else
12255     operands[1] = gen_highpart (SImode, operands[3]);
12256 })
12257
12258 (define_insn_and_split "paritysi2_cmp"
12259   [(set (reg:CC FLAGS_REG)
12260         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12261                    UNSPEC_PARITY))
12262    (clobber (match_scratch:SI 0 "=r"))
12263    (clobber (match_scratch:HI 1 "=&Q"))]
12264   "! TARGET_POPCNT"
12265   "#"
12266   "&& reload_completed"
12267   [(parallel
12268      [(set (match_dup 1)
12269            (xor:HI (match_dup 1) (match_dup 3)))
12270       (clobber (reg:CC FLAGS_REG))])
12271    (parallel
12272      [(set (reg:CC FLAGS_REG)
12273            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12274       (clobber (match_dup 1))])]
12275 {
12276   operands[3] = gen_lowpart (HImode, operands[2]);
12277
12278   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12279   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12280 })
12281
12282 (define_insn "*parityhi2_cmp"
12283   [(set (reg:CC FLAGS_REG)
12284         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12285                    UNSPEC_PARITY))
12286    (clobber (match_scratch:HI 0 "=Q"))]
12287   "! TARGET_POPCNT"
12288   "xor{b}\t{%h0, %b0|%b0, %h0}"
12289   [(set_attr "length" "2")
12290    (set_attr "mode" "HI")])
12291 \f
12292 ;; Thread-local storage patterns for ELF.
12293 ;;
12294 ;; Note that these code sequences must appear exactly as shown
12295 ;; in order to allow linker relaxation.
12296
12297 (define_insn "*tls_global_dynamic_32_gnu"
12298   [(set (match_operand:SI 0 "register_operand" "=a")
12299         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12300                     (match_operand:SI 2 "tls_symbolic_operand" "")
12301                     (match_operand:SI 3 "call_insn_operand" "")]
12302                     UNSPEC_TLS_GD))
12303    (clobber (match_scratch:SI 4 "=d"))
12304    (clobber (match_scratch:SI 5 "=c"))
12305    (clobber (reg:CC FLAGS_REG))]
12306   "!TARGET_64BIT && TARGET_GNU_TLS"
12307   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12308   [(set_attr "type" "multi")
12309    (set_attr "length" "12")])
12310
12311 (define_expand "tls_global_dynamic_32"
12312   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12313                    (unspec:SI
12314                     [(match_dup 2)
12315                      (match_operand:SI 1 "tls_symbolic_operand" "")
12316                      (match_dup 3)]
12317                     UNSPEC_TLS_GD))
12318               (clobber (match_scratch:SI 4 ""))
12319               (clobber (match_scratch:SI 5 ""))
12320               (clobber (reg:CC FLAGS_REG))])]
12321   ""
12322 {
12323   if (flag_pic)
12324     operands[2] = pic_offset_table_rtx;
12325   else
12326     {
12327       operands[2] = gen_reg_rtx (Pmode);
12328       emit_insn (gen_set_got (operands[2]));
12329     }
12330   if (TARGET_GNU2_TLS)
12331     {
12332        emit_insn (gen_tls_dynamic_gnu2_32
12333                   (operands[0], operands[1], operands[2]));
12334        DONE;
12335     }
12336   operands[3] = ix86_tls_get_addr ();
12337 })
12338
12339 (define_insn "*tls_global_dynamic_64"
12340   [(set (match_operand:DI 0 "register_operand" "=a")
12341         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12342                  (match_operand:DI 3 "" "")))
12343    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12344               UNSPEC_TLS_GD)]
12345   "TARGET_64BIT"
12346   { 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"; }
12347   [(set_attr "type" "multi")
12348    (set_attr "length" "16")])
12349
12350 (define_expand "tls_global_dynamic_64"
12351   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12352                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12353               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12354                          UNSPEC_TLS_GD)])]
12355   ""
12356 {
12357   if (TARGET_GNU2_TLS)
12358     {
12359        emit_insn (gen_tls_dynamic_gnu2_64
12360                   (operands[0], operands[1]));
12361        DONE;
12362     }
12363   operands[2] = ix86_tls_get_addr ();
12364 })
12365
12366 (define_insn "*tls_local_dynamic_base_32_gnu"
12367   [(set (match_operand:SI 0 "register_operand" "=a")
12368         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12369                     (match_operand:SI 2 "call_insn_operand" "")]
12370                    UNSPEC_TLS_LD_BASE))
12371    (clobber (match_scratch:SI 3 "=d"))
12372    (clobber (match_scratch:SI 4 "=c"))
12373    (clobber (reg:CC FLAGS_REG))]
12374   "!TARGET_64BIT && TARGET_GNU_TLS"
12375   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12376   [(set_attr "type" "multi")
12377    (set_attr "length" "11")])
12378
12379 (define_expand "tls_local_dynamic_base_32"
12380   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12381                    (unspec:SI [(match_dup 1) (match_dup 2)]
12382                               UNSPEC_TLS_LD_BASE))
12383               (clobber (match_scratch:SI 3 ""))
12384               (clobber (match_scratch:SI 4 ""))
12385               (clobber (reg:CC FLAGS_REG))])]
12386   ""
12387 {
12388   if (flag_pic)
12389     operands[1] = pic_offset_table_rtx;
12390   else
12391     {
12392       operands[1] = gen_reg_rtx (Pmode);
12393       emit_insn (gen_set_got (operands[1]));
12394     }
12395   if (TARGET_GNU2_TLS)
12396     {
12397        emit_insn (gen_tls_dynamic_gnu2_32
12398                   (operands[0], ix86_tls_module_base (), operands[1]));
12399        DONE;
12400     }
12401   operands[2] = ix86_tls_get_addr ();
12402 })
12403
12404 (define_insn "*tls_local_dynamic_base_64"
12405   [(set (match_operand:DI 0 "register_operand" "=a")
12406         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12407                  (match_operand:DI 2 "" "")))
12408    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12409   "TARGET_64BIT"
12410   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12411   [(set_attr "type" "multi")
12412    (set_attr "length" "12")])
12413
12414 (define_expand "tls_local_dynamic_base_64"
12415   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12416                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12417               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12418   ""
12419 {
12420   if (TARGET_GNU2_TLS)
12421     {
12422        emit_insn (gen_tls_dynamic_gnu2_64
12423                   (operands[0], ix86_tls_module_base ()));
12424        DONE;
12425     }
12426   operands[1] = ix86_tls_get_addr ();
12427 })
12428
12429 ;; Local dynamic of a single variable is a lose.  Show combine how
12430 ;; to convert that back to global dynamic.
12431
12432 (define_insn_and_split "*tls_local_dynamic_32_once"
12433   [(set (match_operand:SI 0 "register_operand" "=a")
12434         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12435                              (match_operand:SI 2 "call_insn_operand" "")]
12436                             UNSPEC_TLS_LD_BASE)
12437                  (const:SI (unspec:SI
12438                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12439                             UNSPEC_DTPOFF))))
12440    (clobber (match_scratch:SI 4 "=d"))
12441    (clobber (match_scratch:SI 5 "=c"))
12442    (clobber (reg:CC FLAGS_REG))]
12443   ""
12444   "#"
12445   ""
12446   [(parallel [(set (match_dup 0)
12447                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12448                               UNSPEC_TLS_GD))
12449               (clobber (match_dup 4))
12450               (clobber (match_dup 5))
12451               (clobber (reg:CC FLAGS_REG))])])
12452
12453 ;; Segment register for the thread base ptr load
12454 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12455
12456 ;; Load and add the thread base pointer from %gs:0.
12457 (define_insn "*load_tp_<mode>"
12458   [(set (match_operand:P 0 "register_operand" "=r")
12459         (unspec:P [(const_int 0)] UNSPEC_TP))]
12460   ""
12461   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12462   [(set_attr "type" "imov")
12463    (set_attr "modrm" "0")
12464    (set_attr "length" "7")
12465    (set_attr "memory" "load")
12466    (set_attr "imm_disp" "false")])
12467
12468 (define_insn "*add_tp_<mode>"
12469   [(set (match_operand:P 0 "register_operand" "=r")
12470         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12471                 (match_operand:P 1 "register_operand" "0")))
12472    (clobber (reg:CC FLAGS_REG))]
12473   ""
12474   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12475   [(set_attr "type" "alu")
12476    (set_attr "modrm" "0")
12477    (set_attr "length" "7")
12478    (set_attr "memory" "load")
12479    (set_attr "imm_disp" "false")])
12480
12481 ;; GNU2 TLS patterns can be split.
12482
12483 (define_expand "tls_dynamic_gnu2_32"
12484   [(set (match_dup 3)
12485         (plus:SI (match_operand:SI 2 "register_operand" "")
12486                  (const:SI
12487                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12488                              UNSPEC_TLSDESC))))
12489    (parallel
12490     [(set (match_operand:SI 0 "register_operand" "")
12491           (unspec:SI [(match_dup 1) (match_dup 3)
12492                       (match_dup 2) (reg:SI SP_REG)]
12493                       UNSPEC_TLSDESC))
12494      (clobber (reg:CC FLAGS_REG))])]
12495   "!TARGET_64BIT && TARGET_GNU2_TLS"
12496 {
12497   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12498   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12499 })
12500
12501 (define_insn "*tls_dynamic_lea_32"
12502   [(set (match_operand:SI 0 "register_operand" "=r")
12503         (plus:SI (match_operand:SI 1 "register_operand" "b")
12504                  (const:SI
12505                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12506                               UNSPEC_TLSDESC))))]
12507   "!TARGET_64BIT && TARGET_GNU2_TLS"
12508   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12509   [(set_attr "type" "lea")
12510    (set_attr "mode" "SI")
12511    (set_attr "length" "6")
12512    (set_attr "length_address" "4")])
12513
12514 (define_insn "*tls_dynamic_call_32"
12515   [(set (match_operand:SI 0 "register_operand" "=a")
12516         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12517                     (match_operand:SI 2 "register_operand" "0")
12518                     ;; we have to make sure %ebx still points to the GOT
12519                     (match_operand:SI 3 "register_operand" "b")
12520                     (reg:SI SP_REG)]
12521                    UNSPEC_TLSDESC))
12522    (clobber (reg:CC FLAGS_REG))]
12523   "!TARGET_64BIT && TARGET_GNU2_TLS"
12524   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12525   [(set_attr "type" "call")
12526    (set_attr "length" "2")
12527    (set_attr "length_address" "0")])
12528
12529 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12530   [(set (match_operand:SI 0 "register_operand" "=&a")
12531         (plus:SI
12532          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12533                      (match_operand:SI 4 "" "")
12534                      (match_operand:SI 2 "register_operand" "b")
12535                      (reg:SI SP_REG)]
12536                     UNSPEC_TLSDESC)
12537          (const:SI (unspec:SI
12538                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12539                     UNSPEC_DTPOFF))))
12540    (clobber (reg:CC FLAGS_REG))]
12541   "!TARGET_64BIT && TARGET_GNU2_TLS"
12542   "#"
12543   ""
12544   [(set (match_dup 0) (match_dup 5))]
12545 {
12546   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12547   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12548 })
12549
12550 (define_expand "tls_dynamic_gnu2_64"
12551   [(set (match_dup 2)
12552         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12553                    UNSPEC_TLSDESC))
12554    (parallel
12555     [(set (match_operand:DI 0 "register_operand" "")
12556           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12557                      UNSPEC_TLSDESC))
12558      (clobber (reg:CC FLAGS_REG))])]
12559   "TARGET_64BIT && TARGET_GNU2_TLS"
12560 {
12561   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12562   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12563 })
12564
12565 (define_insn "*tls_dynamic_lea_64"
12566   [(set (match_operand:DI 0 "register_operand" "=r")
12567         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12568                    UNSPEC_TLSDESC))]
12569   "TARGET_64BIT && TARGET_GNU2_TLS"
12570   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12571   [(set_attr "type" "lea")
12572    (set_attr "mode" "DI")
12573    (set_attr "length" "7")
12574    (set_attr "length_address" "4")])
12575
12576 (define_insn "*tls_dynamic_call_64"
12577   [(set (match_operand:DI 0 "register_operand" "=a")
12578         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12579                     (match_operand:DI 2 "register_operand" "0")
12580                     (reg:DI SP_REG)]
12581                    UNSPEC_TLSDESC))
12582    (clobber (reg:CC FLAGS_REG))]
12583   "TARGET_64BIT && TARGET_GNU2_TLS"
12584   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12585   [(set_attr "type" "call")
12586    (set_attr "length" "2")
12587    (set_attr "length_address" "0")])
12588
12589 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12590   [(set (match_operand:DI 0 "register_operand" "=&a")
12591         (plus:DI
12592          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12593                      (match_operand:DI 3 "" "")
12594                      (reg:DI SP_REG)]
12595                     UNSPEC_TLSDESC)
12596          (const:DI (unspec:DI
12597                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12598                     UNSPEC_DTPOFF))))
12599    (clobber (reg:CC FLAGS_REG))]
12600   "TARGET_64BIT && TARGET_GNU2_TLS"
12601   "#"
12602   ""
12603   [(set (match_dup 0) (match_dup 4))]
12604 {
12605   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12606   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12607 })
12608 \f
12609 ;; These patterns match the binary 387 instructions for addM3, subM3,
12610 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12611 ;; SFmode.  The first is the normal insn, the second the same insn but
12612 ;; with one operand a conversion, and the third the same insn but with
12613 ;; the other operand a conversion.  The conversion may be SFmode or
12614 ;; SImode if the target mode DFmode, but only SImode if the target mode
12615 ;; is SFmode.
12616
12617 ;; Gcc is slightly more smart about handling normal two address instructions
12618 ;; so use special patterns for add and mull.
12619
12620 (define_insn "*fop_<mode>_comm_mixed_avx"
12621   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12622         (match_operator:MODEF 3 "binary_fp_operator"
12623           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12624            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12625   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12626    && COMMUTATIVE_ARITH_P (operands[3])
12627    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12628   "* return output_387_binary_op (insn, operands);"
12629   [(set (attr "type")
12630         (if_then_else (eq_attr "alternative" "1")
12631            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12632               (const_string "ssemul")
12633               (const_string "sseadd"))
12634            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12635               (const_string "fmul")
12636               (const_string "fop"))))
12637    (set_attr "prefix" "orig,maybe_vex")
12638    (set_attr "mode" "<MODE>")])
12639
12640 (define_insn "*fop_<mode>_comm_mixed"
12641   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12642         (match_operator:MODEF 3 "binary_fp_operator"
12643           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12644            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12645   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12646    && COMMUTATIVE_ARITH_P (operands[3])
12647    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12648   "* return output_387_binary_op (insn, operands);"
12649   [(set (attr "type")
12650         (if_then_else (eq_attr "alternative" "1")
12651            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12652               (const_string "ssemul")
12653               (const_string "sseadd"))
12654            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12655               (const_string "fmul")
12656               (const_string "fop"))))
12657    (set_attr "mode" "<MODE>")])
12658
12659 (define_insn "*fop_<mode>_comm_avx"
12660   [(set (match_operand:MODEF 0 "register_operand" "=x")
12661         (match_operator:MODEF 3 "binary_fp_operator"
12662           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12663            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12664   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12665    && COMMUTATIVE_ARITH_P (operands[3])
12666    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12667   "* return output_387_binary_op (insn, operands);"
12668   [(set (attr "type")
12669         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12670            (const_string "ssemul")
12671            (const_string "sseadd")))
12672    (set_attr "prefix" "vex")
12673    (set_attr "mode" "<MODE>")])
12674
12675 (define_insn "*fop_<mode>_comm_sse"
12676   [(set (match_operand:MODEF 0 "register_operand" "=x")
12677         (match_operator:MODEF 3 "binary_fp_operator"
12678           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12679            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12680   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12681    && COMMUTATIVE_ARITH_P (operands[3])
12682    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12683   "* return output_387_binary_op (insn, operands);"
12684   [(set (attr "type")
12685         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12686            (const_string "ssemul")
12687            (const_string "sseadd")))
12688    (set_attr "mode" "<MODE>")])
12689
12690 (define_insn "*fop_<mode>_comm_i387"
12691   [(set (match_operand:MODEF 0 "register_operand" "=f")
12692         (match_operator:MODEF 3 "binary_fp_operator"
12693           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12694            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12695   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12696    && COMMUTATIVE_ARITH_P (operands[3])
12697    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12698   "* return output_387_binary_op (insn, operands);"
12699   [(set (attr "type")
12700         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12701            (const_string "fmul")
12702            (const_string "fop")))
12703    (set_attr "mode" "<MODE>")])
12704
12705 (define_insn "*fop_<mode>_1_mixed_avx"
12706   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12707         (match_operator:MODEF 3 "binary_fp_operator"
12708           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12709            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12710   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12711    && !COMMUTATIVE_ARITH_P (operands[3])
12712    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12713   "* return output_387_binary_op (insn, operands);"
12714   [(set (attr "type")
12715         (cond [(and (eq_attr "alternative" "2")
12716                     (match_operand:MODEF 3 "mult_operator" ""))
12717                  (const_string "ssemul")
12718                (and (eq_attr "alternative" "2")
12719                     (match_operand:MODEF 3 "div_operator" ""))
12720                  (const_string "ssediv")
12721                (eq_attr "alternative" "2")
12722                  (const_string "sseadd")
12723                (match_operand:MODEF 3 "mult_operator" "")
12724                  (const_string "fmul")
12725                (match_operand:MODEF 3 "div_operator" "")
12726                  (const_string "fdiv")
12727               ]
12728               (const_string "fop")))
12729    (set_attr "prefix" "orig,orig,maybe_vex")
12730    (set_attr "mode" "<MODE>")])
12731
12732 (define_insn "*fop_<mode>_1_mixed"
12733   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12734         (match_operator:MODEF 3 "binary_fp_operator"
12735           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12736            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12737   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12738    && !COMMUTATIVE_ARITH_P (operands[3])
12739    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12740   "* return output_387_binary_op (insn, operands);"
12741   [(set (attr "type")
12742         (cond [(and (eq_attr "alternative" "2")
12743                     (match_operand:MODEF 3 "mult_operator" ""))
12744                  (const_string "ssemul")
12745                (and (eq_attr "alternative" "2")
12746                     (match_operand:MODEF 3 "div_operator" ""))
12747                  (const_string "ssediv")
12748                (eq_attr "alternative" "2")
12749                  (const_string "sseadd")
12750                (match_operand:MODEF 3 "mult_operator" "")
12751                  (const_string "fmul")
12752                (match_operand:MODEF 3 "div_operator" "")
12753                  (const_string "fdiv")
12754               ]
12755               (const_string "fop")))
12756    (set_attr "mode" "<MODE>")])
12757
12758 (define_insn "*rcpsf2_sse"
12759   [(set (match_operand:SF 0 "register_operand" "=x")
12760         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12761                    UNSPEC_RCP))]
12762   "TARGET_SSE_MATH"
12763   "%vrcpss\t{%1, %d0|%d0, %1}"
12764   [(set_attr "type" "sse")
12765    (set_attr "atom_sse_attr" "rcp")
12766    (set_attr "prefix" "maybe_vex")
12767    (set_attr "mode" "SF")])
12768
12769 (define_insn "*fop_<mode>_1_avx"
12770   [(set (match_operand:MODEF 0 "register_operand" "=x")
12771         (match_operator:MODEF 3 "binary_fp_operator"
12772           [(match_operand:MODEF 1 "register_operand" "x")
12773            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12774   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12775    && !COMMUTATIVE_ARITH_P (operands[3])"
12776   "* return output_387_binary_op (insn, operands);"
12777   [(set (attr "type")
12778         (cond [(match_operand:MODEF 3 "mult_operator" "")
12779                  (const_string "ssemul")
12780                (match_operand:MODEF 3 "div_operator" "")
12781                  (const_string "ssediv")
12782               ]
12783               (const_string "sseadd")))
12784    (set_attr "prefix" "vex")
12785    (set_attr "mode" "<MODE>")])
12786
12787 (define_insn "*fop_<mode>_1_sse"
12788   [(set (match_operand:MODEF 0 "register_operand" "=x")
12789         (match_operator:MODEF 3 "binary_fp_operator"
12790           [(match_operand:MODEF 1 "register_operand" "0")
12791            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12792   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12793    && !COMMUTATIVE_ARITH_P (operands[3])"
12794   "* return output_387_binary_op (insn, operands);"
12795   [(set (attr "type")
12796         (cond [(match_operand:MODEF 3 "mult_operator" "")
12797                  (const_string "ssemul")
12798                (match_operand:MODEF 3 "div_operator" "")
12799                  (const_string "ssediv")
12800               ]
12801               (const_string "sseadd")))
12802    (set_attr "mode" "<MODE>")])
12803
12804 ;; This pattern is not fully shadowed by the pattern above.
12805 (define_insn "*fop_<mode>_1_i387"
12806   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12807         (match_operator:MODEF 3 "binary_fp_operator"
12808           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12809            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12810   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12811    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12812    && !COMMUTATIVE_ARITH_P (operands[3])
12813    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12814   "* return output_387_binary_op (insn, operands);"
12815   [(set (attr "type")
12816         (cond [(match_operand:MODEF 3 "mult_operator" "")
12817                  (const_string "fmul")
12818                (match_operand:MODEF 3 "div_operator" "")
12819                  (const_string "fdiv")
12820               ]
12821               (const_string "fop")))
12822    (set_attr "mode" "<MODE>")])
12823
12824 ;; ??? Add SSE splitters for these!
12825 (define_insn "*fop_<MODEF:mode>_2_i387"
12826   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12827         (match_operator:MODEF 3 "binary_fp_operator"
12828           [(float:MODEF
12829              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12830            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12831   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12832    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12833    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12834   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12835   [(set (attr "type")
12836         (cond [(match_operand:MODEF 3 "mult_operator" "")
12837                  (const_string "fmul")
12838                (match_operand:MODEF 3 "div_operator" "")
12839                  (const_string "fdiv")
12840               ]
12841               (const_string "fop")))
12842    (set_attr "fp_int_src" "true")
12843    (set_attr "mode" "<X87MODEI12:MODE>")])
12844
12845 (define_insn "*fop_<MODEF:mode>_3_i387"
12846   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12847         (match_operator:MODEF 3 "binary_fp_operator"
12848           [(match_operand:MODEF 1 "register_operand" "0,0")
12849            (float:MODEF
12850              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12851   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12852    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12853    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12854   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12855   [(set (attr "type")
12856         (cond [(match_operand:MODEF 3 "mult_operator" "")
12857                  (const_string "fmul")
12858                (match_operand:MODEF 3 "div_operator" "")
12859                  (const_string "fdiv")
12860               ]
12861               (const_string "fop")))
12862    (set_attr "fp_int_src" "true")
12863    (set_attr "mode" "<MODE>")])
12864
12865 (define_insn "*fop_df_4_i387"
12866   [(set (match_operand:DF 0 "register_operand" "=f,f")
12867         (match_operator:DF 3 "binary_fp_operator"
12868            [(float_extend:DF
12869              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12870             (match_operand:DF 2 "register_operand" "0,f")]))]
12871   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12872    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12873    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12874   "* return output_387_binary_op (insn, operands);"
12875   [(set (attr "type")
12876         (cond [(match_operand:DF 3 "mult_operator" "")
12877                  (const_string "fmul")
12878                (match_operand:DF 3 "div_operator" "")
12879                  (const_string "fdiv")
12880               ]
12881               (const_string "fop")))
12882    (set_attr "mode" "SF")])
12883
12884 (define_insn "*fop_df_5_i387"
12885   [(set (match_operand:DF 0 "register_operand" "=f,f")
12886         (match_operator:DF 3 "binary_fp_operator"
12887           [(match_operand:DF 1 "register_operand" "0,f")
12888            (float_extend:DF
12889             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12890   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12891    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12892   "* return output_387_binary_op (insn, operands);"
12893   [(set (attr "type")
12894         (cond [(match_operand:DF 3 "mult_operator" "")
12895                  (const_string "fmul")
12896                (match_operand:DF 3 "div_operator" "")
12897                  (const_string "fdiv")
12898               ]
12899               (const_string "fop")))
12900    (set_attr "mode" "SF")])
12901
12902 (define_insn "*fop_df_6_i387"
12903   [(set (match_operand:DF 0 "register_operand" "=f,f")
12904         (match_operator:DF 3 "binary_fp_operator"
12905           [(float_extend:DF
12906             (match_operand:SF 1 "register_operand" "0,f"))
12907            (float_extend:DF
12908             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12909   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12910    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12911   "* return output_387_binary_op (insn, operands);"
12912   [(set (attr "type")
12913         (cond [(match_operand:DF 3 "mult_operator" "")
12914                  (const_string "fmul")
12915                (match_operand:DF 3 "div_operator" "")
12916                  (const_string "fdiv")
12917               ]
12918               (const_string "fop")))
12919    (set_attr "mode" "SF")])
12920
12921 (define_insn "*fop_xf_comm_i387"
12922   [(set (match_operand:XF 0 "register_operand" "=f")
12923         (match_operator:XF 3 "binary_fp_operator"
12924                         [(match_operand:XF 1 "register_operand" "%0")
12925                          (match_operand:XF 2 "register_operand" "f")]))]
12926   "TARGET_80387
12927    && COMMUTATIVE_ARITH_P (operands[3])"
12928   "* return output_387_binary_op (insn, operands);"
12929   [(set (attr "type")
12930         (if_then_else (match_operand:XF 3 "mult_operator" "")
12931            (const_string "fmul")
12932            (const_string "fop")))
12933    (set_attr "mode" "XF")])
12934
12935 (define_insn "*fop_xf_1_i387"
12936   [(set (match_operand:XF 0 "register_operand" "=f,f")
12937         (match_operator:XF 3 "binary_fp_operator"
12938                         [(match_operand:XF 1 "register_operand" "0,f")
12939                          (match_operand:XF 2 "register_operand" "f,0")]))]
12940   "TARGET_80387
12941    && !COMMUTATIVE_ARITH_P (operands[3])"
12942   "* return output_387_binary_op (insn, operands);"
12943   [(set (attr "type")
12944         (cond [(match_operand:XF 3 "mult_operator" "")
12945                  (const_string "fmul")
12946                (match_operand:XF 3 "div_operator" "")
12947                  (const_string "fdiv")
12948               ]
12949               (const_string "fop")))
12950    (set_attr "mode" "XF")])
12951
12952 (define_insn "*fop_xf_2_i387"
12953   [(set (match_operand:XF 0 "register_operand" "=f,f")
12954         (match_operator:XF 3 "binary_fp_operator"
12955           [(float:XF
12956              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12957            (match_operand:XF 2 "register_operand" "0,0")]))]
12958   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12959   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12960   [(set (attr "type")
12961         (cond [(match_operand:XF 3 "mult_operator" "")
12962                  (const_string "fmul")
12963                (match_operand:XF 3 "div_operator" "")
12964                  (const_string "fdiv")
12965               ]
12966               (const_string "fop")))
12967    (set_attr "fp_int_src" "true")
12968    (set_attr "mode" "<MODE>")])
12969
12970 (define_insn "*fop_xf_3_i387"
12971   [(set (match_operand:XF 0 "register_operand" "=f,f")
12972         (match_operator:XF 3 "binary_fp_operator"
12973           [(match_operand:XF 1 "register_operand" "0,0")
12974            (float:XF
12975              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12976   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12977   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12978   [(set (attr "type")
12979         (cond [(match_operand:XF 3 "mult_operator" "")
12980                  (const_string "fmul")
12981                (match_operand:XF 3 "div_operator" "")
12982                  (const_string "fdiv")
12983               ]
12984               (const_string "fop")))
12985    (set_attr "fp_int_src" "true")
12986    (set_attr "mode" "<MODE>")])
12987
12988 (define_insn "*fop_xf_4_i387"
12989   [(set (match_operand:XF 0 "register_operand" "=f,f")
12990         (match_operator:XF 3 "binary_fp_operator"
12991            [(float_extend:XF
12992               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12993             (match_operand:XF 2 "register_operand" "0,f")]))]
12994   "TARGET_80387"
12995   "* return output_387_binary_op (insn, operands);"
12996   [(set (attr "type")
12997         (cond [(match_operand:XF 3 "mult_operator" "")
12998                  (const_string "fmul")
12999                (match_operand:XF 3 "div_operator" "")
13000                  (const_string "fdiv")
13001               ]
13002               (const_string "fop")))
13003    (set_attr "mode" "<MODE>")])
13004
13005 (define_insn "*fop_xf_5_i387"
13006   [(set (match_operand:XF 0 "register_operand" "=f,f")
13007         (match_operator:XF 3 "binary_fp_operator"
13008           [(match_operand:XF 1 "register_operand" "0,f")
13009            (float_extend:XF
13010              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13011   "TARGET_80387"
13012   "* return output_387_binary_op (insn, operands);"
13013   [(set (attr "type")
13014         (cond [(match_operand:XF 3 "mult_operator" "")
13015                  (const_string "fmul")
13016                (match_operand:XF 3 "div_operator" "")
13017                  (const_string "fdiv")
13018               ]
13019               (const_string "fop")))
13020    (set_attr "mode" "<MODE>")])
13021
13022 (define_insn "*fop_xf_6_i387"
13023   [(set (match_operand:XF 0 "register_operand" "=f,f")
13024         (match_operator:XF 3 "binary_fp_operator"
13025           [(float_extend:XF
13026              (match_operand:MODEF 1 "register_operand" "0,f"))
13027            (float_extend:XF
13028              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13029   "TARGET_80387"
13030   "* return output_387_binary_op (insn, operands);"
13031   [(set (attr "type")
13032         (cond [(match_operand:XF 3 "mult_operator" "")
13033                  (const_string "fmul")
13034                (match_operand:XF 3 "div_operator" "")
13035                  (const_string "fdiv")
13036               ]
13037               (const_string "fop")))
13038    (set_attr "mode" "<MODE>")])
13039
13040 (define_split
13041   [(set (match_operand 0 "register_operand" "")
13042         (match_operator 3 "binary_fp_operator"
13043            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13044             (match_operand 2 "register_operand" "")]))]
13045   "reload_completed
13046    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13047    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13048   [(const_int 0)]
13049 {
13050   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13051   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13052   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13053                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13054                                           GET_MODE (operands[3]),
13055                                           operands[4],
13056                                           operands[2])));
13057   ix86_free_from_memory (GET_MODE (operands[1]));
13058   DONE;
13059 })
13060
13061 (define_split
13062   [(set (match_operand 0 "register_operand" "")
13063         (match_operator 3 "binary_fp_operator"
13064            [(match_operand 1 "register_operand" "")
13065             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13066   "reload_completed
13067    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13068    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13069   [(const_int 0)]
13070 {
13071   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13072   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13073   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13074                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13075                                           GET_MODE (operands[3]),
13076                                           operands[1],
13077                                           operands[4])));
13078   ix86_free_from_memory (GET_MODE (operands[2]));
13079   DONE;
13080 })
13081 \f
13082 ;; FPU special functions.
13083
13084 ;; This pattern implements a no-op XFmode truncation for
13085 ;; all fancy i386 XFmode math functions.
13086
13087 (define_insn "truncxf<mode>2_i387_noop_unspec"
13088   [(set (match_operand:MODEF 0 "register_operand" "=f")
13089         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13090         UNSPEC_TRUNC_NOOP))]
13091   "TARGET_USE_FANCY_MATH_387"
13092   "* return output_387_reg_move (insn, operands);"
13093   [(set_attr "type" "fmov")
13094    (set_attr "mode" "<MODE>")])
13095
13096 (define_insn "sqrtxf2"
13097   [(set (match_operand:XF 0 "register_operand" "=f")
13098         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13099   "TARGET_USE_FANCY_MATH_387"
13100   "fsqrt"
13101   [(set_attr "type" "fpspc")
13102    (set_attr "mode" "XF")
13103    (set_attr "athlon_decode" "direct")
13104    (set_attr "amdfam10_decode" "direct")
13105    (set_attr "bdver1_decode" "direct")])
13106
13107 (define_insn "sqrt_extend<mode>xf2_i387"
13108   [(set (match_operand:XF 0 "register_operand" "=f")
13109         (sqrt:XF
13110           (float_extend:XF
13111             (match_operand:MODEF 1 "register_operand" "0"))))]
13112   "TARGET_USE_FANCY_MATH_387"
13113   "fsqrt"
13114   [(set_attr "type" "fpspc")
13115    (set_attr "mode" "XF")
13116    (set_attr "athlon_decode" "direct")
13117    (set_attr "amdfam10_decode" "direct")
13118    (set_attr "bdver1_decode" "direct")])
13119
13120 (define_insn "*rsqrtsf2_sse"
13121   [(set (match_operand:SF 0 "register_operand" "=x")
13122         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13123                    UNSPEC_RSQRT))]
13124   "TARGET_SSE_MATH"
13125   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13126   [(set_attr "type" "sse")
13127    (set_attr "atom_sse_attr" "rcp")
13128    (set_attr "prefix" "maybe_vex")
13129    (set_attr "mode" "SF")])
13130
13131 (define_expand "rsqrtsf2"
13132   [(set (match_operand:SF 0 "register_operand" "")
13133         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13134                    UNSPEC_RSQRT))]
13135   "TARGET_SSE_MATH"
13136 {
13137   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13138   DONE;
13139 })
13140
13141 (define_insn "*sqrt<mode>2_sse"
13142   [(set (match_operand:MODEF 0 "register_operand" "=x")
13143         (sqrt:MODEF
13144           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13145   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13146   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13147   [(set_attr "type" "sse")
13148    (set_attr "atom_sse_attr" "sqrt")
13149    (set_attr "prefix" "maybe_vex")
13150    (set_attr "mode" "<MODE>")
13151    (set_attr "athlon_decode" "*")
13152    (set_attr "amdfam10_decode" "*")
13153    (set_attr "bdver1_decode" "*")])
13154
13155 (define_expand "sqrt<mode>2"
13156   [(set (match_operand:MODEF 0 "register_operand" "")
13157         (sqrt:MODEF
13158           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13159   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13160    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13161 {
13162   if (<MODE>mode == SFmode
13163       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13164       && flag_finite_math_only && !flag_trapping_math
13165       && flag_unsafe_math_optimizations)
13166     {
13167       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13168       DONE;
13169     }
13170
13171   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13172     {
13173       rtx op0 = gen_reg_rtx (XFmode);
13174       rtx op1 = force_reg (<MODE>mode, operands[1]);
13175
13176       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13177       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13178       DONE;
13179    }
13180 })
13181
13182 (define_insn "fpremxf4_i387"
13183   [(set (match_operand:XF 0 "register_operand" "=f")
13184         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13185                     (match_operand:XF 3 "register_operand" "1")]
13186                    UNSPEC_FPREM_F))
13187    (set (match_operand:XF 1 "register_operand" "=u")
13188         (unspec:XF [(match_dup 2) (match_dup 3)]
13189                    UNSPEC_FPREM_U))
13190    (set (reg:CCFP FPSR_REG)
13191         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13192                      UNSPEC_C2_FLAG))]
13193   "TARGET_USE_FANCY_MATH_387"
13194   "fprem"
13195   [(set_attr "type" "fpspc")
13196    (set_attr "mode" "XF")])
13197
13198 (define_expand "fmodxf3"
13199   [(use (match_operand:XF 0 "register_operand" ""))
13200    (use (match_operand:XF 1 "general_operand" ""))
13201    (use (match_operand:XF 2 "general_operand" ""))]
13202   "TARGET_USE_FANCY_MATH_387"
13203 {
13204   rtx label = gen_label_rtx ();
13205
13206   rtx op1 = gen_reg_rtx (XFmode);
13207   rtx op2 = gen_reg_rtx (XFmode);
13208
13209   emit_move_insn (op2, operands[2]);
13210   emit_move_insn (op1, operands[1]);
13211
13212   emit_label (label);
13213   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13214   ix86_emit_fp_unordered_jump (label);
13215   LABEL_NUSES (label) = 1;
13216
13217   emit_move_insn (operands[0], op1);
13218   DONE;
13219 })
13220
13221 (define_expand "fmod<mode>3"
13222   [(use (match_operand:MODEF 0 "register_operand" ""))
13223    (use (match_operand:MODEF 1 "general_operand" ""))
13224    (use (match_operand:MODEF 2 "general_operand" ""))]
13225   "TARGET_USE_FANCY_MATH_387"
13226 {
13227   rtx (*gen_truncxf) (rtx, rtx);
13228
13229   rtx label = gen_label_rtx ();
13230
13231   rtx op1 = gen_reg_rtx (XFmode);
13232   rtx op2 = gen_reg_rtx (XFmode);
13233
13234   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13235   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13236
13237   emit_label (label);
13238   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13239   ix86_emit_fp_unordered_jump (label);
13240   LABEL_NUSES (label) = 1;
13241
13242   /* Truncate the result properly for strict SSE math.  */
13243   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13244       && !TARGET_MIX_SSE_I387)
13245     gen_truncxf = gen_truncxf<mode>2;
13246   else
13247     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13248
13249   emit_insn (gen_truncxf (operands[0], op1));
13250   DONE;
13251 })
13252
13253 (define_insn "fprem1xf4_i387"
13254   [(set (match_operand:XF 0 "register_operand" "=f")
13255         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13256                     (match_operand:XF 3 "register_operand" "1")]
13257                    UNSPEC_FPREM1_F))
13258    (set (match_operand:XF 1 "register_operand" "=u")
13259         (unspec:XF [(match_dup 2) (match_dup 3)]
13260                    UNSPEC_FPREM1_U))
13261    (set (reg:CCFP FPSR_REG)
13262         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13263                      UNSPEC_C2_FLAG))]
13264   "TARGET_USE_FANCY_MATH_387"
13265   "fprem1"
13266   [(set_attr "type" "fpspc")
13267    (set_attr "mode" "XF")])
13268
13269 (define_expand "remainderxf3"
13270   [(use (match_operand:XF 0 "register_operand" ""))
13271    (use (match_operand:XF 1 "general_operand" ""))
13272    (use (match_operand:XF 2 "general_operand" ""))]
13273   "TARGET_USE_FANCY_MATH_387"
13274 {
13275   rtx label = gen_label_rtx ();
13276
13277   rtx op1 = gen_reg_rtx (XFmode);
13278   rtx op2 = gen_reg_rtx (XFmode);
13279
13280   emit_move_insn (op2, operands[2]);
13281   emit_move_insn (op1, operands[1]);
13282
13283   emit_label (label);
13284   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13285   ix86_emit_fp_unordered_jump (label);
13286   LABEL_NUSES (label) = 1;
13287
13288   emit_move_insn (operands[0], op1);
13289   DONE;
13290 })
13291
13292 (define_expand "remainder<mode>3"
13293   [(use (match_operand:MODEF 0 "register_operand" ""))
13294    (use (match_operand:MODEF 1 "general_operand" ""))
13295    (use (match_operand:MODEF 2 "general_operand" ""))]
13296   "TARGET_USE_FANCY_MATH_387"
13297 {
13298   rtx (*gen_truncxf) (rtx, rtx);
13299
13300   rtx label = gen_label_rtx ();
13301
13302   rtx op1 = gen_reg_rtx (XFmode);
13303   rtx op2 = gen_reg_rtx (XFmode);
13304
13305   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13306   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13307
13308   emit_label (label);
13309
13310   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13311   ix86_emit_fp_unordered_jump (label);
13312   LABEL_NUSES (label) = 1;
13313
13314   /* Truncate the result properly for strict SSE math.  */
13315   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13316       && !TARGET_MIX_SSE_I387)
13317     gen_truncxf = gen_truncxf<mode>2;
13318   else
13319     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13320
13321   emit_insn (gen_truncxf (operands[0], op1));
13322   DONE;
13323 })
13324
13325 (define_insn "*sinxf2_i387"
13326   [(set (match_operand:XF 0 "register_operand" "=f")
13327         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13328   "TARGET_USE_FANCY_MATH_387
13329    && flag_unsafe_math_optimizations"
13330   "fsin"
13331   [(set_attr "type" "fpspc")
13332    (set_attr "mode" "XF")])
13333
13334 (define_insn "*sin_extend<mode>xf2_i387"
13335   [(set (match_operand:XF 0 "register_operand" "=f")
13336         (unspec:XF [(float_extend:XF
13337                       (match_operand:MODEF 1 "register_operand" "0"))]
13338                    UNSPEC_SIN))]
13339   "TARGET_USE_FANCY_MATH_387
13340    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13341        || TARGET_MIX_SSE_I387)
13342    && flag_unsafe_math_optimizations"
13343   "fsin"
13344   [(set_attr "type" "fpspc")
13345    (set_attr "mode" "XF")])
13346
13347 (define_insn "*cosxf2_i387"
13348   [(set (match_operand:XF 0 "register_operand" "=f")
13349         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13350   "TARGET_USE_FANCY_MATH_387
13351    && flag_unsafe_math_optimizations"
13352   "fcos"
13353   [(set_attr "type" "fpspc")
13354    (set_attr "mode" "XF")])
13355
13356 (define_insn "*cos_extend<mode>xf2_i387"
13357   [(set (match_operand:XF 0 "register_operand" "=f")
13358         (unspec:XF [(float_extend:XF
13359                       (match_operand:MODEF 1 "register_operand" "0"))]
13360                    UNSPEC_COS))]
13361   "TARGET_USE_FANCY_MATH_387
13362    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13363        || TARGET_MIX_SSE_I387)
13364    && flag_unsafe_math_optimizations"
13365   "fcos"
13366   [(set_attr "type" "fpspc")
13367    (set_attr "mode" "XF")])
13368
13369 ;; When sincos pattern is defined, sin and cos builtin functions will be
13370 ;; expanded to sincos pattern with one of its outputs left unused.
13371 ;; CSE pass will figure out if two sincos patterns can be combined,
13372 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13373 ;; depending on the unused output.
13374
13375 (define_insn "sincosxf3"
13376   [(set (match_operand:XF 0 "register_operand" "=f")
13377         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13378                    UNSPEC_SINCOS_COS))
13379    (set (match_operand:XF 1 "register_operand" "=u")
13380         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13381   "TARGET_USE_FANCY_MATH_387
13382    && flag_unsafe_math_optimizations"
13383   "fsincos"
13384   [(set_attr "type" "fpspc")
13385    (set_attr "mode" "XF")])
13386
13387 (define_split
13388   [(set (match_operand:XF 0 "register_operand" "")
13389         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13390                    UNSPEC_SINCOS_COS))
13391    (set (match_operand:XF 1 "register_operand" "")
13392         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13393   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13394    && !(reload_completed || reload_in_progress)"
13395   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13396
13397 (define_split
13398   [(set (match_operand:XF 0 "register_operand" "")
13399         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13400                    UNSPEC_SINCOS_COS))
13401    (set (match_operand:XF 1 "register_operand" "")
13402         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13403   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13404    && !(reload_completed || reload_in_progress)"
13405   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13406
13407 (define_insn "sincos_extend<mode>xf3_i387"
13408   [(set (match_operand:XF 0 "register_operand" "=f")
13409         (unspec:XF [(float_extend:XF
13410                       (match_operand:MODEF 2 "register_operand" "0"))]
13411                    UNSPEC_SINCOS_COS))
13412    (set (match_operand:XF 1 "register_operand" "=u")
13413         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13414   "TARGET_USE_FANCY_MATH_387
13415    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13416        || TARGET_MIX_SSE_I387)
13417    && flag_unsafe_math_optimizations"
13418   "fsincos"
13419   [(set_attr "type" "fpspc")
13420    (set_attr "mode" "XF")])
13421
13422 (define_split
13423   [(set (match_operand:XF 0 "register_operand" "")
13424         (unspec:XF [(float_extend:XF
13425                       (match_operand:MODEF 2 "register_operand" ""))]
13426                    UNSPEC_SINCOS_COS))
13427    (set (match_operand:XF 1 "register_operand" "")
13428         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13429   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13430    && !(reload_completed || reload_in_progress)"
13431   [(set (match_dup 1)
13432         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13433
13434 (define_split
13435   [(set (match_operand:XF 0 "register_operand" "")
13436         (unspec:XF [(float_extend:XF
13437                       (match_operand:MODEF 2 "register_operand" ""))]
13438                    UNSPEC_SINCOS_COS))
13439    (set (match_operand:XF 1 "register_operand" "")
13440         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13441   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13442    && !(reload_completed || reload_in_progress)"
13443   [(set (match_dup 0)
13444         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13445
13446 (define_expand "sincos<mode>3"
13447   [(use (match_operand:MODEF 0 "register_operand" ""))
13448    (use (match_operand:MODEF 1 "register_operand" ""))
13449    (use (match_operand:MODEF 2 "register_operand" ""))]
13450   "TARGET_USE_FANCY_MATH_387
13451    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13452        || TARGET_MIX_SSE_I387)
13453    && flag_unsafe_math_optimizations"
13454 {
13455   rtx op0 = gen_reg_rtx (XFmode);
13456   rtx op1 = gen_reg_rtx (XFmode);
13457
13458   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13459   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13460   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13461   DONE;
13462 })
13463
13464 (define_insn "fptanxf4_i387"
13465   [(set (match_operand:XF 0 "register_operand" "=f")
13466         (match_operand:XF 3 "const_double_operand" "F"))
13467    (set (match_operand:XF 1 "register_operand" "=u")
13468         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13469                    UNSPEC_TAN))]
13470   "TARGET_USE_FANCY_MATH_387
13471    && flag_unsafe_math_optimizations
13472    && standard_80387_constant_p (operands[3]) == 2"
13473   "fptan"
13474   [(set_attr "type" "fpspc")
13475    (set_attr "mode" "XF")])
13476
13477 (define_insn "fptan_extend<mode>xf4_i387"
13478   [(set (match_operand:MODEF 0 "register_operand" "=f")
13479         (match_operand:MODEF 3 "const_double_operand" "F"))
13480    (set (match_operand:XF 1 "register_operand" "=u")
13481         (unspec:XF [(float_extend:XF
13482                       (match_operand:MODEF 2 "register_operand" "0"))]
13483                    UNSPEC_TAN))]
13484   "TARGET_USE_FANCY_MATH_387
13485    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13486        || TARGET_MIX_SSE_I387)
13487    && flag_unsafe_math_optimizations
13488    && standard_80387_constant_p (operands[3]) == 2"
13489   "fptan"
13490   [(set_attr "type" "fpspc")
13491    (set_attr "mode" "XF")])
13492
13493 (define_expand "tanxf2"
13494   [(use (match_operand:XF 0 "register_operand" ""))
13495    (use (match_operand:XF 1 "register_operand" ""))]
13496   "TARGET_USE_FANCY_MATH_387
13497    && flag_unsafe_math_optimizations"
13498 {
13499   rtx one = gen_reg_rtx (XFmode);
13500   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13501
13502   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13503   DONE;
13504 })
13505
13506 (define_expand "tan<mode>2"
13507   [(use (match_operand:MODEF 0 "register_operand" ""))
13508    (use (match_operand:MODEF 1 "register_operand" ""))]
13509   "TARGET_USE_FANCY_MATH_387
13510    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13511        || TARGET_MIX_SSE_I387)
13512    && flag_unsafe_math_optimizations"
13513 {
13514   rtx op0 = gen_reg_rtx (XFmode);
13515
13516   rtx one = gen_reg_rtx (<MODE>mode);
13517   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13518
13519   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13520                                              operands[1], op2));
13521   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13522   DONE;
13523 })
13524
13525 (define_insn "*fpatanxf3_i387"
13526   [(set (match_operand:XF 0 "register_operand" "=f")
13527         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13528                     (match_operand:XF 2 "register_operand" "u")]
13529                    UNSPEC_FPATAN))
13530    (clobber (match_scratch:XF 3 "=2"))]
13531   "TARGET_USE_FANCY_MATH_387
13532    && flag_unsafe_math_optimizations"
13533   "fpatan"
13534   [(set_attr "type" "fpspc")
13535    (set_attr "mode" "XF")])
13536
13537 (define_insn "fpatan_extend<mode>xf3_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                     (float_extend:XF
13542                       (match_operand:MODEF 2 "register_operand" "u"))]
13543                    UNSPEC_FPATAN))
13544    (clobber (match_scratch:XF 3 "=2"))]
13545   "TARGET_USE_FANCY_MATH_387
13546    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13547        || TARGET_MIX_SSE_I387)
13548    && flag_unsafe_math_optimizations"
13549   "fpatan"
13550   [(set_attr "type" "fpspc")
13551    (set_attr "mode" "XF")])
13552
13553 (define_expand "atan2xf3"
13554   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13555                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13556                                (match_operand:XF 1 "register_operand" "")]
13557                               UNSPEC_FPATAN))
13558               (clobber (match_scratch:XF 3 ""))])]
13559   "TARGET_USE_FANCY_MATH_387
13560    && flag_unsafe_math_optimizations")
13561
13562 (define_expand "atan2<mode>3"
13563   [(use (match_operand:MODEF 0 "register_operand" ""))
13564    (use (match_operand:MODEF 1 "register_operand" ""))
13565    (use (match_operand:MODEF 2 "register_operand" ""))]
13566   "TARGET_USE_FANCY_MATH_387
13567    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13568        || TARGET_MIX_SSE_I387)
13569    && flag_unsafe_math_optimizations"
13570 {
13571   rtx op0 = gen_reg_rtx (XFmode);
13572
13573   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13574   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13575   DONE;
13576 })
13577
13578 (define_expand "atanxf2"
13579   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13580                    (unspec:XF [(match_dup 2)
13581                                (match_operand:XF 1 "register_operand" "")]
13582                               UNSPEC_FPATAN))
13583               (clobber (match_scratch:XF 3 ""))])]
13584   "TARGET_USE_FANCY_MATH_387
13585    && flag_unsafe_math_optimizations"
13586 {
13587   operands[2] = gen_reg_rtx (XFmode);
13588   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13589 })
13590
13591 (define_expand "atan<mode>2"
13592   [(use (match_operand:MODEF 0 "register_operand" ""))
13593    (use (match_operand:MODEF 1 "register_operand" ""))]
13594   "TARGET_USE_FANCY_MATH_387
13595    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13596        || TARGET_MIX_SSE_I387)
13597    && flag_unsafe_math_optimizations"
13598 {
13599   rtx op0 = gen_reg_rtx (XFmode);
13600
13601   rtx op2 = gen_reg_rtx (<MODE>mode);
13602   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13603
13604   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13605   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13606   DONE;
13607 })
13608
13609 (define_expand "asinxf2"
13610   [(set (match_dup 2)
13611         (mult:XF (match_operand:XF 1 "register_operand" "")
13612                  (match_dup 1)))
13613    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13614    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13615    (parallel [(set (match_operand:XF 0 "register_operand" "")
13616                    (unspec:XF [(match_dup 5) (match_dup 1)]
13617                               UNSPEC_FPATAN))
13618               (clobber (match_scratch:XF 6 ""))])]
13619   "TARGET_USE_FANCY_MATH_387
13620    && flag_unsafe_math_optimizations"
13621 {
13622   int i;
13623
13624   if (optimize_insn_for_size_p ())
13625     FAIL;
13626
13627   for (i = 2; i < 6; i++)
13628     operands[i] = gen_reg_rtx (XFmode);
13629
13630   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13631 })
13632
13633 (define_expand "asin<mode>2"
13634   [(use (match_operand:MODEF 0 "register_operand" ""))
13635    (use (match_operand:MODEF 1 "general_operand" ""))]
13636  "TARGET_USE_FANCY_MATH_387
13637    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13638        || TARGET_MIX_SSE_I387)
13639    && flag_unsafe_math_optimizations"
13640 {
13641   rtx op0 = gen_reg_rtx (XFmode);
13642   rtx op1 = gen_reg_rtx (XFmode);
13643
13644   if (optimize_insn_for_size_p ())
13645     FAIL;
13646
13647   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13648   emit_insn (gen_asinxf2 (op0, op1));
13649   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13650   DONE;
13651 })
13652
13653 (define_expand "acosxf2"
13654   [(set (match_dup 2)
13655         (mult:XF (match_operand:XF 1 "register_operand" "")
13656                  (match_dup 1)))
13657    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13658    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13659    (parallel [(set (match_operand:XF 0 "register_operand" "")
13660                    (unspec:XF [(match_dup 1) (match_dup 5)]
13661                               UNSPEC_FPATAN))
13662               (clobber (match_scratch:XF 6 ""))])]
13663   "TARGET_USE_FANCY_MATH_387
13664    && flag_unsafe_math_optimizations"
13665 {
13666   int i;
13667
13668   if (optimize_insn_for_size_p ())
13669     FAIL;
13670
13671   for (i = 2; i < 6; i++)
13672     operands[i] = gen_reg_rtx (XFmode);
13673
13674   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13675 })
13676
13677 (define_expand "acos<mode>2"
13678   [(use (match_operand:MODEF 0 "register_operand" ""))
13679    (use (match_operand:MODEF 1 "general_operand" ""))]
13680  "TARGET_USE_FANCY_MATH_387
13681    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13682        || TARGET_MIX_SSE_I387)
13683    && flag_unsafe_math_optimizations"
13684 {
13685   rtx op0 = gen_reg_rtx (XFmode);
13686   rtx op1 = gen_reg_rtx (XFmode);
13687
13688   if (optimize_insn_for_size_p ())
13689     FAIL;
13690
13691   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13692   emit_insn (gen_acosxf2 (op0, op1));
13693   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13694   DONE;
13695 })
13696
13697 (define_insn "fyl2xxf3_i387"
13698   [(set (match_operand:XF 0 "register_operand" "=f")
13699         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13700                     (match_operand:XF 2 "register_operand" "u")]
13701                    UNSPEC_FYL2X))
13702    (clobber (match_scratch:XF 3 "=2"))]
13703   "TARGET_USE_FANCY_MATH_387
13704    && flag_unsafe_math_optimizations"
13705   "fyl2x"
13706   [(set_attr "type" "fpspc")
13707    (set_attr "mode" "XF")])
13708
13709 (define_insn "fyl2x_extend<mode>xf3_i387"
13710   [(set (match_operand:XF 0 "register_operand" "=f")
13711         (unspec:XF [(float_extend:XF
13712                       (match_operand:MODEF 1 "register_operand" "0"))
13713                     (match_operand:XF 2 "register_operand" "u")]
13714                    UNSPEC_FYL2X))
13715    (clobber (match_scratch:XF 3 "=2"))]
13716   "TARGET_USE_FANCY_MATH_387
13717    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13718        || TARGET_MIX_SSE_I387)
13719    && flag_unsafe_math_optimizations"
13720   "fyl2x"
13721   [(set_attr "type" "fpspc")
13722    (set_attr "mode" "XF")])
13723
13724 (define_expand "logxf2"
13725   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13726                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13727                                (match_dup 2)] UNSPEC_FYL2X))
13728               (clobber (match_scratch:XF 3 ""))])]
13729   "TARGET_USE_FANCY_MATH_387
13730    && flag_unsafe_math_optimizations"
13731 {
13732   operands[2] = gen_reg_rtx (XFmode);
13733   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13734 })
13735
13736 (define_expand "log<mode>2"
13737   [(use (match_operand:MODEF 0 "register_operand" ""))
13738    (use (match_operand:MODEF 1 "register_operand" ""))]
13739   "TARGET_USE_FANCY_MATH_387
13740    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13741        || TARGET_MIX_SSE_I387)
13742    && flag_unsafe_math_optimizations"
13743 {
13744   rtx op0 = gen_reg_rtx (XFmode);
13745
13746   rtx op2 = gen_reg_rtx (XFmode);
13747   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13748
13749   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13750   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13751   DONE;
13752 })
13753
13754 (define_expand "log10xf2"
13755   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13756                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13757                                (match_dup 2)] UNSPEC_FYL2X))
13758               (clobber (match_scratch:XF 3 ""))])]
13759   "TARGET_USE_FANCY_MATH_387
13760    && flag_unsafe_math_optimizations"
13761 {
13762   operands[2] = gen_reg_rtx (XFmode);
13763   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13764 })
13765
13766 (define_expand "log10<mode>2"
13767   [(use (match_operand:MODEF 0 "register_operand" ""))
13768    (use (match_operand:MODEF 1 "register_operand" ""))]
13769   "TARGET_USE_FANCY_MATH_387
13770    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13771        || TARGET_MIX_SSE_I387)
13772    && flag_unsafe_math_optimizations"
13773 {
13774   rtx op0 = gen_reg_rtx (XFmode);
13775
13776   rtx op2 = gen_reg_rtx (XFmode);
13777   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13778
13779   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13780   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13781   DONE;
13782 })
13783
13784 (define_expand "log2xf2"
13785   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13786                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13787                                (match_dup 2)] UNSPEC_FYL2X))
13788               (clobber (match_scratch:XF 3 ""))])]
13789   "TARGET_USE_FANCY_MATH_387
13790    && flag_unsafe_math_optimizations"
13791 {
13792   operands[2] = gen_reg_rtx (XFmode);
13793   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13794 })
13795
13796 (define_expand "log2<mode>2"
13797   [(use (match_operand:MODEF 0 "register_operand" ""))
13798    (use (match_operand:MODEF 1 "register_operand" ""))]
13799   "TARGET_USE_FANCY_MATH_387
13800    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13801        || TARGET_MIX_SSE_I387)
13802    && flag_unsafe_math_optimizations"
13803 {
13804   rtx op0 = gen_reg_rtx (XFmode);
13805
13806   rtx op2 = gen_reg_rtx (XFmode);
13807   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13808
13809   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13810   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13811   DONE;
13812 })
13813
13814 (define_insn "fyl2xp1xf3_i387"
13815   [(set (match_operand:XF 0 "register_operand" "=f")
13816         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13817                     (match_operand:XF 2 "register_operand" "u")]
13818                    UNSPEC_FYL2XP1))
13819    (clobber (match_scratch:XF 3 "=2"))]
13820   "TARGET_USE_FANCY_MATH_387
13821    && flag_unsafe_math_optimizations"
13822   "fyl2xp1"
13823   [(set_attr "type" "fpspc")
13824    (set_attr "mode" "XF")])
13825
13826 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13827   [(set (match_operand:XF 0 "register_operand" "=f")
13828         (unspec:XF [(float_extend:XF
13829                       (match_operand:MODEF 1 "register_operand" "0"))
13830                     (match_operand:XF 2 "register_operand" "u")]
13831                    UNSPEC_FYL2XP1))
13832    (clobber (match_scratch:XF 3 "=2"))]
13833   "TARGET_USE_FANCY_MATH_387
13834    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13835        || TARGET_MIX_SSE_I387)
13836    && flag_unsafe_math_optimizations"
13837   "fyl2xp1"
13838   [(set_attr "type" "fpspc")
13839    (set_attr "mode" "XF")])
13840
13841 (define_expand "log1pxf2"
13842   [(use (match_operand:XF 0 "register_operand" ""))
13843    (use (match_operand:XF 1 "register_operand" ""))]
13844   "TARGET_USE_FANCY_MATH_387
13845    && flag_unsafe_math_optimizations"
13846 {
13847   if (optimize_insn_for_size_p ())
13848     FAIL;
13849
13850   ix86_emit_i387_log1p (operands[0], operands[1]);
13851   DONE;
13852 })
13853
13854 (define_expand "log1p<mode>2"
13855   [(use (match_operand:MODEF 0 "register_operand" ""))
13856    (use (match_operand:MODEF 1 "register_operand" ""))]
13857   "TARGET_USE_FANCY_MATH_387
13858    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13859        || TARGET_MIX_SSE_I387)
13860    && flag_unsafe_math_optimizations"
13861 {
13862   rtx op0;
13863
13864   if (optimize_insn_for_size_p ())
13865     FAIL;
13866
13867   op0 = gen_reg_rtx (XFmode);
13868
13869   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13870
13871   ix86_emit_i387_log1p (op0, operands[1]);
13872   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13873   DONE;
13874 })
13875
13876 (define_insn "fxtractxf3_i387"
13877   [(set (match_operand:XF 0 "register_operand" "=f")
13878         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13879                    UNSPEC_XTRACT_FRACT))
13880    (set (match_operand:XF 1 "register_operand" "=u")
13881         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13882   "TARGET_USE_FANCY_MATH_387
13883    && flag_unsafe_math_optimizations"
13884   "fxtract"
13885   [(set_attr "type" "fpspc")
13886    (set_attr "mode" "XF")])
13887
13888 (define_insn "fxtract_extend<mode>xf3_i387"
13889   [(set (match_operand:XF 0 "register_operand" "=f")
13890         (unspec:XF [(float_extend:XF
13891                       (match_operand:MODEF 2 "register_operand" "0"))]
13892                    UNSPEC_XTRACT_FRACT))
13893    (set (match_operand:XF 1 "register_operand" "=u")
13894         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13895   "TARGET_USE_FANCY_MATH_387
13896    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13897        || TARGET_MIX_SSE_I387)
13898    && flag_unsafe_math_optimizations"
13899   "fxtract"
13900   [(set_attr "type" "fpspc")
13901    (set_attr "mode" "XF")])
13902
13903 (define_expand "logbxf2"
13904   [(parallel [(set (match_dup 2)
13905                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13906                               UNSPEC_XTRACT_FRACT))
13907               (set (match_operand:XF 0 "register_operand" "")
13908                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13909   "TARGET_USE_FANCY_MATH_387
13910    && flag_unsafe_math_optimizations"
13911   "operands[2] = gen_reg_rtx (XFmode);")
13912
13913 (define_expand "logb<mode>2"
13914   [(use (match_operand:MODEF 0 "register_operand" ""))
13915    (use (match_operand:MODEF 1 "register_operand" ""))]
13916   "TARGET_USE_FANCY_MATH_387
13917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13918        || TARGET_MIX_SSE_I387)
13919    && flag_unsafe_math_optimizations"
13920 {
13921   rtx op0 = gen_reg_rtx (XFmode);
13922   rtx op1 = gen_reg_rtx (XFmode);
13923
13924   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13925   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13926   DONE;
13927 })
13928
13929 (define_expand "ilogbxf2"
13930   [(use (match_operand:SI 0 "register_operand" ""))
13931    (use (match_operand:XF 1 "register_operand" ""))]
13932   "TARGET_USE_FANCY_MATH_387
13933    && flag_unsafe_math_optimizations"
13934 {
13935   rtx op0, op1;
13936
13937   if (optimize_insn_for_size_p ())
13938     FAIL;
13939
13940   op0 = gen_reg_rtx (XFmode);
13941   op1 = gen_reg_rtx (XFmode);
13942
13943   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13944   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13945   DONE;
13946 })
13947
13948 (define_expand "ilogb<mode>2"
13949   [(use (match_operand:SI 0 "register_operand" ""))
13950    (use (match_operand:MODEF 1 "register_operand" ""))]
13951   "TARGET_USE_FANCY_MATH_387
13952    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13953        || TARGET_MIX_SSE_I387)
13954    && flag_unsafe_math_optimizations"
13955 {
13956   rtx op0, op1;
13957
13958   if (optimize_insn_for_size_p ())
13959     FAIL;
13960
13961   op0 = gen_reg_rtx (XFmode);
13962   op1 = gen_reg_rtx (XFmode);
13963
13964   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13965   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13966   DONE;
13967 })
13968
13969 (define_insn "*f2xm1xf2_i387"
13970   [(set (match_operand:XF 0 "register_operand" "=f")
13971         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13972                    UNSPEC_F2XM1))]
13973   "TARGET_USE_FANCY_MATH_387
13974    && flag_unsafe_math_optimizations"
13975   "f2xm1"
13976   [(set_attr "type" "fpspc")
13977    (set_attr "mode" "XF")])
13978
13979 (define_insn "*fscalexf4_i387"
13980   [(set (match_operand:XF 0 "register_operand" "=f")
13981         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13982                     (match_operand:XF 3 "register_operand" "1")]
13983                    UNSPEC_FSCALE_FRACT))
13984    (set (match_operand:XF 1 "register_operand" "=u")
13985         (unspec:XF [(match_dup 2) (match_dup 3)]
13986                    UNSPEC_FSCALE_EXP))]
13987   "TARGET_USE_FANCY_MATH_387
13988    && flag_unsafe_math_optimizations"
13989   "fscale"
13990   [(set_attr "type" "fpspc")
13991    (set_attr "mode" "XF")])
13992
13993 (define_expand "expNcorexf3"
13994   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13995                                (match_operand:XF 2 "register_operand" "")))
13996    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13997    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13998    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13999    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14000    (parallel [(set (match_operand:XF 0 "register_operand" "")
14001                    (unspec:XF [(match_dup 8) (match_dup 4)]
14002                               UNSPEC_FSCALE_FRACT))
14003               (set (match_dup 9)
14004                    (unspec:XF [(match_dup 8) (match_dup 4)]
14005                               UNSPEC_FSCALE_EXP))])]
14006   "TARGET_USE_FANCY_MATH_387
14007    && flag_unsafe_math_optimizations"
14008 {
14009   int i;
14010
14011   if (optimize_insn_for_size_p ())
14012     FAIL;
14013
14014   for (i = 3; i < 10; i++)
14015     operands[i] = gen_reg_rtx (XFmode);
14016
14017   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14018 })
14019
14020 (define_expand "expxf2"
14021   [(use (match_operand:XF 0 "register_operand" ""))
14022    (use (match_operand:XF 1 "register_operand" ""))]
14023   "TARGET_USE_FANCY_MATH_387
14024    && flag_unsafe_math_optimizations"
14025 {
14026   rtx op2;
14027
14028   if (optimize_insn_for_size_p ())
14029     FAIL;
14030
14031   op2 = gen_reg_rtx (XFmode);
14032   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14033
14034   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14035   DONE;
14036 })
14037
14038 (define_expand "exp<mode>2"
14039   [(use (match_operand:MODEF 0 "register_operand" ""))
14040    (use (match_operand:MODEF 1 "general_operand" ""))]
14041  "TARGET_USE_FANCY_MATH_387
14042    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14043        || TARGET_MIX_SSE_I387)
14044    && flag_unsafe_math_optimizations"
14045 {
14046   rtx op0, op1;
14047
14048   if (optimize_insn_for_size_p ())
14049     FAIL;
14050
14051   op0 = gen_reg_rtx (XFmode);
14052   op1 = gen_reg_rtx (XFmode);
14053
14054   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14055   emit_insn (gen_expxf2 (op0, op1));
14056   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14057   DONE;
14058 })
14059
14060 (define_expand "exp10xf2"
14061   [(use (match_operand:XF 0 "register_operand" ""))
14062    (use (match_operand:XF 1 "register_operand" ""))]
14063   "TARGET_USE_FANCY_MATH_387
14064    && flag_unsafe_math_optimizations"
14065 {
14066   rtx op2;
14067
14068   if (optimize_insn_for_size_p ())
14069     FAIL;
14070
14071   op2 = gen_reg_rtx (XFmode);
14072   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14073
14074   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14075   DONE;
14076 })
14077
14078 (define_expand "exp10<mode>2"
14079   [(use (match_operand:MODEF 0 "register_operand" ""))
14080    (use (match_operand:MODEF 1 "general_operand" ""))]
14081  "TARGET_USE_FANCY_MATH_387
14082    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14083        || TARGET_MIX_SSE_I387)
14084    && flag_unsafe_math_optimizations"
14085 {
14086   rtx op0, op1;
14087
14088   if (optimize_insn_for_size_p ())
14089     FAIL;
14090
14091   op0 = gen_reg_rtx (XFmode);
14092   op1 = gen_reg_rtx (XFmode);
14093
14094   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14095   emit_insn (gen_exp10xf2 (op0, op1));
14096   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14097   DONE;
14098 })
14099
14100 (define_expand "exp2xf2"
14101   [(use (match_operand:XF 0 "register_operand" ""))
14102    (use (match_operand:XF 1 "register_operand" ""))]
14103   "TARGET_USE_FANCY_MATH_387
14104    && flag_unsafe_math_optimizations"
14105 {
14106   rtx op2;
14107
14108   if (optimize_insn_for_size_p ())
14109     FAIL;
14110
14111   op2 = gen_reg_rtx (XFmode);
14112   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14113
14114   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14115   DONE;
14116 })
14117
14118 (define_expand "exp2<mode>2"
14119   [(use (match_operand:MODEF 0 "register_operand" ""))
14120    (use (match_operand:MODEF 1 "general_operand" ""))]
14121  "TARGET_USE_FANCY_MATH_387
14122    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14123        || TARGET_MIX_SSE_I387)
14124    && flag_unsafe_math_optimizations"
14125 {
14126   rtx op0, op1;
14127
14128   if (optimize_insn_for_size_p ())
14129     FAIL;
14130
14131   op0 = gen_reg_rtx (XFmode);
14132   op1 = gen_reg_rtx (XFmode);
14133
14134   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14135   emit_insn (gen_exp2xf2 (op0, op1));
14136   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14137   DONE;
14138 })
14139
14140 (define_expand "expm1xf2"
14141   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14142                                (match_dup 2)))
14143    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14144    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14145    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14146    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14147    (parallel [(set (match_dup 7)
14148                    (unspec:XF [(match_dup 6) (match_dup 4)]
14149                               UNSPEC_FSCALE_FRACT))
14150               (set (match_dup 8)
14151                    (unspec:XF [(match_dup 6) (match_dup 4)]
14152                               UNSPEC_FSCALE_EXP))])
14153    (parallel [(set (match_dup 10)
14154                    (unspec:XF [(match_dup 9) (match_dup 8)]
14155                               UNSPEC_FSCALE_FRACT))
14156               (set (match_dup 11)
14157                    (unspec:XF [(match_dup 9) (match_dup 8)]
14158                               UNSPEC_FSCALE_EXP))])
14159    (set (match_dup 12) (minus:XF (match_dup 10)
14160                                  (float_extend:XF (match_dup 13))))
14161    (set (match_operand:XF 0 "register_operand" "")
14162         (plus:XF (match_dup 12) (match_dup 7)))]
14163   "TARGET_USE_FANCY_MATH_387
14164    && flag_unsafe_math_optimizations"
14165 {
14166   int i;
14167
14168   if (optimize_insn_for_size_p ())
14169     FAIL;
14170
14171   for (i = 2; i < 13; i++)
14172     operands[i] = gen_reg_rtx (XFmode);
14173
14174   operands[13]
14175     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14176
14177   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14178 })
14179
14180 (define_expand "expm1<mode>2"
14181   [(use (match_operand:MODEF 0 "register_operand" ""))
14182    (use (match_operand:MODEF 1 "general_operand" ""))]
14183  "TARGET_USE_FANCY_MATH_387
14184    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14185        || TARGET_MIX_SSE_I387)
14186    && flag_unsafe_math_optimizations"
14187 {
14188   rtx op0, op1;
14189
14190   if (optimize_insn_for_size_p ())
14191     FAIL;
14192
14193   op0 = gen_reg_rtx (XFmode);
14194   op1 = gen_reg_rtx (XFmode);
14195
14196   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14197   emit_insn (gen_expm1xf2 (op0, op1));
14198   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14199   DONE;
14200 })
14201
14202 (define_expand "ldexpxf3"
14203   [(set (match_dup 3)
14204         (float:XF (match_operand:SI 2 "register_operand" "")))
14205    (parallel [(set (match_operand:XF 0 " register_operand" "")
14206                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14207                                (match_dup 3)]
14208                               UNSPEC_FSCALE_FRACT))
14209               (set (match_dup 4)
14210                    (unspec:XF [(match_dup 1) (match_dup 3)]
14211                               UNSPEC_FSCALE_EXP))])]
14212   "TARGET_USE_FANCY_MATH_387
14213    && flag_unsafe_math_optimizations"
14214 {
14215   if (optimize_insn_for_size_p ())
14216     FAIL;
14217
14218   operands[3] = gen_reg_rtx (XFmode);
14219   operands[4] = gen_reg_rtx (XFmode);
14220 })
14221
14222 (define_expand "ldexp<mode>3"
14223   [(use (match_operand:MODEF 0 "register_operand" ""))
14224    (use (match_operand:MODEF 1 "general_operand" ""))
14225    (use (match_operand:SI 2 "register_operand" ""))]
14226  "TARGET_USE_FANCY_MATH_387
14227    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14228        || TARGET_MIX_SSE_I387)
14229    && flag_unsafe_math_optimizations"
14230 {
14231   rtx op0, op1;
14232
14233   if (optimize_insn_for_size_p ())
14234     FAIL;
14235
14236   op0 = gen_reg_rtx (XFmode);
14237   op1 = gen_reg_rtx (XFmode);
14238
14239   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14240   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14241   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14242   DONE;
14243 })
14244
14245 (define_expand "scalbxf3"
14246   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14247                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14248                                (match_operand:XF 2 "register_operand" "")]
14249                               UNSPEC_FSCALE_FRACT))
14250               (set (match_dup 3)
14251                    (unspec:XF [(match_dup 1) (match_dup 2)]
14252                               UNSPEC_FSCALE_EXP))])]
14253   "TARGET_USE_FANCY_MATH_387
14254    && flag_unsafe_math_optimizations"
14255 {
14256   if (optimize_insn_for_size_p ())
14257     FAIL;
14258
14259   operands[3] = gen_reg_rtx (XFmode);
14260 })
14261
14262 (define_expand "scalb<mode>3"
14263   [(use (match_operand:MODEF 0 "register_operand" ""))
14264    (use (match_operand:MODEF 1 "general_operand" ""))
14265    (use (match_operand:MODEF 2 "general_operand" ""))]
14266  "TARGET_USE_FANCY_MATH_387
14267    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14268        || TARGET_MIX_SSE_I387)
14269    && flag_unsafe_math_optimizations"
14270 {
14271   rtx op0, op1, op2;
14272
14273   if (optimize_insn_for_size_p ())
14274     FAIL;
14275
14276   op0 = gen_reg_rtx (XFmode);
14277   op1 = gen_reg_rtx (XFmode);
14278   op2 = gen_reg_rtx (XFmode);
14279
14280   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14281   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14282   emit_insn (gen_scalbxf3 (op0, op1, op2));
14283   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14284   DONE;
14285 })
14286
14287 (define_expand "significandxf2"
14288   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14289                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14290                               UNSPEC_XTRACT_FRACT))
14291               (set (match_dup 2)
14292                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14293   "TARGET_USE_FANCY_MATH_387
14294    && flag_unsafe_math_optimizations"
14295   "operands[2] = gen_reg_rtx (XFmode);")
14296
14297 (define_expand "significand<mode>2"
14298   [(use (match_operand:MODEF 0 "register_operand" ""))
14299    (use (match_operand:MODEF 1 "register_operand" ""))]
14300   "TARGET_USE_FANCY_MATH_387
14301    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14302        || TARGET_MIX_SSE_I387)
14303    && flag_unsafe_math_optimizations"
14304 {
14305   rtx op0 = gen_reg_rtx (XFmode);
14306   rtx op1 = gen_reg_rtx (XFmode);
14307
14308   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14309   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14310   DONE;
14311 })
14312 \f
14313
14314 (define_insn "sse4_1_round<mode>2"
14315   [(set (match_operand:MODEF 0 "register_operand" "=x")
14316         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14317                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14318                       UNSPEC_ROUND))]
14319   "TARGET_ROUND"
14320   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14321   [(set_attr "type" "ssecvt")
14322    (set_attr "prefix_extra" "1")
14323    (set_attr "prefix" "maybe_vex")
14324    (set_attr "mode" "<MODE>")])
14325
14326 (define_insn "rintxf2"
14327   [(set (match_operand:XF 0 "register_operand" "=f")
14328         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14329                    UNSPEC_FRNDINT))]
14330   "TARGET_USE_FANCY_MATH_387
14331    && flag_unsafe_math_optimizations"
14332   "frndint"
14333   [(set_attr "type" "fpspc")
14334    (set_attr "mode" "XF")])
14335
14336 (define_expand "rint<mode>2"
14337   [(use (match_operand:MODEF 0 "register_operand" ""))
14338    (use (match_operand:MODEF 1 "register_operand" ""))]
14339   "(TARGET_USE_FANCY_MATH_387
14340     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14341         || TARGET_MIX_SSE_I387)
14342     && flag_unsafe_math_optimizations)
14343    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14344        && !flag_trapping_math)"
14345 {
14346   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14347       && !flag_trapping_math)
14348     {
14349       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14350         FAIL;
14351       if (TARGET_ROUND)
14352         emit_insn (gen_sse4_1_round<mode>2
14353                    (operands[0], operands[1], GEN_INT (0x04)));
14354       else
14355         ix86_expand_rint (operand0, operand1);
14356     }
14357   else
14358     {
14359       rtx op0 = gen_reg_rtx (XFmode);
14360       rtx op1 = gen_reg_rtx (XFmode);
14361
14362       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14363       emit_insn (gen_rintxf2 (op0, op1));
14364
14365       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14366     }
14367   DONE;
14368 })
14369
14370 (define_expand "round<mode>2"
14371   [(match_operand:MODEF 0 "register_operand" "")
14372    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14373   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14374    && !flag_trapping_math && !flag_rounding_math"
14375 {
14376   if (optimize_insn_for_size_p ())
14377     FAIL;
14378   if (TARGET_64BIT || (<MODE>mode != DFmode))
14379     ix86_expand_round (operand0, operand1);
14380   else
14381     ix86_expand_rounddf_32 (operand0, operand1);
14382   DONE;
14383 })
14384
14385 (define_insn_and_split "*fistdi2_1"
14386   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14387         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14388                    UNSPEC_FIST))]
14389   "TARGET_USE_FANCY_MATH_387
14390    && can_create_pseudo_p ()"
14391   "#"
14392   "&& 1"
14393   [(const_int 0)]
14394 {
14395   if (memory_operand (operands[0], VOIDmode))
14396     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14397   else
14398     {
14399       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14400       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14401                                          operands[2]));
14402     }
14403   DONE;
14404 }
14405   [(set_attr "type" "fpspc")
14406    (set_attr "mode" "DI")])
14407
14408 (define_insn "fistdi2"
14409   [(set (match_operand:DI 0 "memory_operand" "=m")
14410         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14411                    UNSPEC_FIST))
14412    (clobber (match_scratch:XF 2 "=&1f"))]
14413   "TARGET_USE_FANCY_MATH_387"
14414   "* return output_fix_trunc (insn, operands, 0);"
14415   [(set_attr "type" "fpspc")
14416    (set_attr "mode" "DI")])
14417
14418 (define_insn "fistdi2_with_temp"
14419   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14420         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14421                    UNSPEC_FIST))
14422    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14423    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14424   "TARGET_USE_FANCY_MATH_387"
14425   "#"
14426   [(set_attr "type" "fpspc")
14427    (set_attr "mode" "DI")])
14428
14429 (define_split
14430   [(set (match_operand:DI 0 "register_operand" "")
14431         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14432                    UNSPEC_FIST))
14433    (clobber (match_operand:DI 2 "memory_operand" ""))
14434    (clobber (match_scratch 3 ""))]
14435   "reload_completed"
14436   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14437               (clobber (match_dup 3))])
14438    (set (match_dup 0) (match_dup 2))])
14439
14440 (define_split
14441   [(set (match_operand:DI 0 "memory_operand" "")
14442         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14443                    UNSPEC_FIST))
14444    (clobber (match_operand:DI 2 "memory_operand" ""))
14445    (clobber (match_scratch 3 ""))]
14446   "reload_completed"
14447   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14448               (clobber (match_dup 3))])])
14449
14450 (define_insn_and_split "*fist<mode>2_1"
14451   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14452         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14453                            UNSPEC_FIST))]
14454   "TARGET_USE_FANCY_MATH_387
14455    && can_create_pseudo_p ()"
14456   "#"
14457   "&& 1"
14458   [(const_int 0)]
14459 {
14460   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14461   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14462                                         operands[2]));
14463   DONE;
14464 }
14465   [(set_attr "type" "fpspc")
14466    (set_attr "mode" "<MODE>")])
14467
14468 (define_insn "fist<mode>2"
14469   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14470         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14471                            UNSPEC_FIST))]
14472   "TARGET_USE_FANCY_MATH_387"
14473   "* return output_fix_trunc (insn, operands, 0);"
14474   [(set_attr "type" "fpspc")
14475    (set_attr "mode" "<MODE>")])
14476
14477 (define_insn "fist<mode>2_with_temp"
14478   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14479         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14480                            UNSPEC_FIST))
14481    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14482   "TARGET_USE_FANCY_MATH_387"
14483   "#"
14484   [(set_attr "type" "fpspc")
14485    (set_attr "mode" "<MODE>")])
14486
14487 (define_split
14488   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14489         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14490                            UNSPEC_FIST))
14491    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14492   "reload_completed"
14493   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14494    (set (match_dup 0) (match_dup 2))])
14495
14496 (define_split
14497   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14498         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14499                            UNSPEC_FIST))
14500    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14501   "reload_completed"
14502   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14503
14504 (define_expand "lrintxf<mode>2"
14505   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14506      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14507                       UNSPEC_FIST))]
14508   "TARGET_USE_FANCY_MATH_387")
14509
14510 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14511   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14512      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14513                         UNSPEC_FIX_NOTRUNC))]
14514   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14515    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14516
14517 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14518   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14519    (match_operand:MODEF 1 "register_operand" "")]
14520   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14521    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14522    && !flag_trapping_math && !flag_rounding_math"
14523 {
14524   if (optimize_insn_for_size_p ())
14525     FAIL;
14526   ix86_expand_lround (operand0, operand1);
14527   DONE;
14528 })
14529
14530 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14531 (define_insn_and_split "frndintxf2_floor"
14532   [(set (match_operand:XF 0 "register_operand" "")
14533         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14534          UNSPEC_FRNDINT_FLOOR))
14535    (clobber (reg:CC FLAGS_REG))]
14536   "TARGET_USE_FANCY_MATH_387
14537    && flag_unsafe_math_optimizations
14538    && can_create_pseudo_p ()"
14539   "#"
14540   "&& 1"
14541   [(const_int 0)]
14542 {
14543   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14544
14545   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14546   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14547
14548   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14549                                         operands[2], operands[3]));
14550   DONE;
14551 }
14552   [(set_attr "type" "frndint")
14553    (set_attr "i387_cw" "floor")
14554    (set_attr "mode" "XF")])
14555
14556 (define_insn "frndintxf2_floor_i387"
14557   [(set (match_operand:XF 0 "register_operand" "=f")
14558         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14559          UNSPEC_FRNDINT_FLOOR))
14560    (use (match_operand:HI 2 "memory_operand" "m"))
14561    (use (match_operand:HI 3 "memory_operand" "m"))]
14562   "TARGET_USE_FANCY_MATH_387
14563    && flag_unsafe_math_optimizations"
14564   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14565   [(set_attr "type" "frndint")
14566    (set_attr "i387_cw" "floor")
14567    (set_attr "mode" "XF")])
14568
14569 (define_expand "floorxf2"
14570   [(use (match_operand:XF 0 "register_operand" ""))
14571    (use (match_operand:XF 1 "register_operand" ""))]
14572   "TARGET_USE_FANCY_MATH_387
14573    && flag_unsafe_math_optimizations"
14574 {
14575   if (optimize_insn_for_size_p ())
14576     FAIL;
14577   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14578   DONE;
14579 })
14580
14581 (define_expand "floor<mode>2"
14582   [(use (match_operand:MODEF 0 "register_operand" ""))
14583    (use (match_operand:MODEF 1 "register_operand" ""))]
14584   "(TARGET_USE_FANCY_MATH_387
14585     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586         || TARGET_MIX_SSE_I387)
14587     && flag_unsafe_math_optimizations)
14588    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589        && !flag_trapping_math)"
14590 {
14591   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14592       && !flag_trapping_math
14593       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14594     {
14595       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14596         FAIL;
14597       if (TARGET_ROUND)
14598         emit_insn (gen_sse4_1_round<mode>2
14599                    (operands[0], operands[1], GEN_INT (0x01)));
14600       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14601         ix86_expand_floorceil (operand0, operand1, true);
14602       else
14603         ix86_expand_floorceildf_32 (operand0, operand1, true);
14604     }
14605   else
14606     {
14607       rtx op0, op1;
14608
14609       if (optimize_insn_for_size_p ())
14610         FAIL;
14611
14612       op0 = gen_reg_rtx (XFmode);
14613       op1 = gen_reg_rtx (XFmode);
14614       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14615       emit_insn (gen_frndintxf2_floor (op0, op1));
14616
14617       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14618     }
14619   DONE;
14620 })
14621
14622 (define_insn_and_split "*fist<mode>2_floor_1"
14623   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14624         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14625          UNSPEC_FIST_FLOOR))
14626    (clobber (reg:CC FLAGS_REG))]
14627   "TARGET_USE_FANCY_MATH_387
14628    && flag_unsafe_math_optimizations
14629    && can_create_pseudo_p ()"
14630   "#"
14631   "&& 1"
14632   [(const_int 0)]
14633 {
14634   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14635
14636   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14638   if (memory_operand (operands[0], VOIDmode))
14639     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14640                                       operands[2], operands[3]));
14641   else
14642     {
14643       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14644       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14645                                                   operands[2], operands[3],
14646                                                   operands[4]));
14647     }
14648   DONE;
14649 }
14650   [(set_attr "type" "fistp")
14651    (set_attr "i387_cw" "floor")
14652    (set_attr "mode" "<MODE>")])
14653
14654 (define_insn "fistdi2_floor"
14655   [(set (match_operand:DI 0 "memory_operand" "=m")
14656         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14657          UNSPEC_FIST_FLOOR))
14658    (use (match_operand:HI 2 "memory_operand" "m"))
14659    (use (match_operand:HI 3 "memory_operand" "m"))
14660    (clobber (match_scratch:XF 4 "=&1f"))]
14661   "TARGET_USE_FANCY_MATH_387
14662    && flag_unsafe_math_optimizations"
14663   "* return output_fix_trunc (insn, operands, 0);"
14664   [(set_attr "type" "fistp")
14665    (set_attr "i387_cw" "floor")
14666    (set_attr "mode" "DI")])
14667
14668 (define_insn "fistdi2_floor_with_temp"
14669   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14670         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14671          UNSPEC_FIST_FLOOR))
14672    (use (match_operand:HI 2 "memory_operand" "m,m"))
14673    (use (match_operand:HI 3 "memory_operand" "m,m"))
14674    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14675    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14676   "TARGET_USE_FANCY_MATH_387
14677    && flag_unsafe_math_optimizations"
14678   "#"
14679   [(set_attr "type" "fistp")
14680    (set_attr "i387_cw" "floor")
14681    (set_attr "mode" "DI")])
14682
14683 (define_split
14684   [(set (match_operand:DI 0 "register_operand" "")
14685         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14686          UNSPEC_FIST_FLOOR))
14687    (use (match_operand:HI 2 "memory_operand" ""))
14688    (use (match_operand:HI 3 "memory_operand" ""))
14689    (clobber (match_operand:DI 4 "memory_operand" ""))
14690    (clobber (match_scratch 5 ""))]
14691   "reload_completed"
14692   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14693               (use (match_dup 2))
14694               (use (match_dup 3))
14695               (clobber (match_dup 5))])
14696    (set (match_dup 0) (match_dup 4))])
14697
14698 (define_split
14699   [(set (match_operand:DI 0 "memory_operand" "")
14700         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14701          UNSPEC_FIST_FLOOR))
14702    (use (match_operand:HI 2 "memory_operand" ""))
14703    (use (match_operand:HI 3 "memory_operand" ""))
14704    (clobber (match_operand:DI 4 "memory_operand" ""))
14705    (clobber (match_scratch 5 ""))]
14706   "reload_completed"
14707   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14708               (use (match_dup 2))
14709               (use (match_dup 3))
14710               (clobber (match_dup 5))])])
14711
14712 (define_insn "fist<mode>2_floor"
14713   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14714         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14715          UNSPEC_FIST_FLOOR))
14716    (use (match_operand:HI 2 "memory_operand" "m"))
14717    (use (match_operand:HI 3 "memory_operand" "m"))]
14718   "TARGET_USE_FANCY_MATH_387
14719    && flag_unsafe_math_optimizations"
14720   "* return output_fix_trunc (insn, operands, 0);"
14721   [(set_attr "type" "fistp")
14722    (set_attr "i387_cw" "floor")
14723    (set_attr "mode" "<MODE>")])
14724
14725 (define_insn "fist<mode>2_floor_with_temp"
14726   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14727         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14728          UNSPEC_FIST_FLOOR))
14729    (use (match_operand:HI 2 "memory_operand" "m,m"))
14730    (use (match_operand:HI 3 "memory_operand" "m,m"))
14731    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14732   "TARGET_USE_FANCY_MATH_387
14733    && flag_unsafe_math_optimizations"
14734   "#"
14735   [(set_attr "type" "fistp")
14736    (set_attr "i387_cw" "floor")
14737    (set_attr "mode" "<MODE>")])
14738
14739 (define_split
14740   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14741         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14742          UNSPEC_FIST_FLOOR))
14743    (use (match_operand:HI 2 "memory_operand" ""))
14744    (use (match_operand:HI 3 "memory_operand" ""))
14745    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14746   "reload_completed"
14747   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14748                                   UNSPEC_FIST_FLOOR))
14749               (use (match_dup 2))
14750               (use (match_dup 3))])
14751    (set (match_dup 0) (match_dup 4))])
14752
14753 (define_split
14754   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14755         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14756          UNSPEC_FIST_FLOOR))
14757    (use (match_operand:HI 2 "memory_operand" ""))
14758    (use (match_operand:HI 3 "memory_operand" ""))
14759    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14760   "reload_completed"
14761   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14762                                   UNSPEC_FIST_FLOOR))
14763               (use (match_dup 2))
14764               (use (match_dup 3))])])
14765
14766 (define_expand "lfloorxf<mode>2"
14767   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14768                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14769                     UNSPEC_FIST_FLOOR))
14770               (clobber (reg:CC FLAGS_REG))])]
14771   "TARGET_USE_FANCY_MATH_387
14772    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14773    && flag_unsafe_math_optimizations")
14774
14775 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14776   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14777    (match_operand:MODEF 1 "register_operand" "")]
14778   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14779    && !flag_trapping_math"
14780 {
14781   if (TARGET_64BIT && optimize_insn_for_size_p ())
14782     FAIL;
14783   ix86_expand_lfloorceil (operand0, operand1, true);
14784   DONE;
14785 })
14786
14787 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14788 (define_insn_and_split "frndintxf2_ceil"
14789   [(set (match_operand:XF 0 "register_operand" "")
14790         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14791          UNSPEC_FRNDINT_CEIL))
14792    (clobber (reg:CC FLAGS_REG))]
14793   "TARGET_USE_FANCY_MATH_387
14794    && flag_unsafe_math_optimizations
14795    && can_create_pseudo_p ()"
14796   "#"
14797   "&& 1"
14798   [(const_int 0)]
14799 {
14800   ix86_optimize_mode_switching[I387_CEIL] = 1;
14801
14802   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14803   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14804
14805   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14806                                        operands[2], operands[3]));
14807   DONE;
14808 }
14809   [(set_attr "type" "frndint")
14810    (set_attr "i387_cw" "ceil")
14811    (set_attr "mode" "XF")])
14812
14813 (define_insn "frndintxf2_ceil_i387"
14814   [(set (match_operand:XF 0 "register_operand" "=f")
14815         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14816          UNSPEC_FRNDINT_CEIL))
14817    (use (match_operand:HI 2 "memory_operand" "m"))
14818    (use (match_operand:HI 3 "memory_operand" "m"))]
14819   "TARGET_USE_FANCY_MATH_387
14820    && flag_unsafe_math_optimizations"
14821   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14822   [(set_attr "type" "frndint")
14823    (set_attr "i387_cw" "ceil")
14824    (set_attr "mode" "XF")])
14825
14826 (define_expand "ceilxf2"
14827   [(use (match_operand:XF 0 "register_operand" ""))
14828    (use (match_operand:XF 1 "register_operand" ""))]
14829   "TARGET_USE_FANCY_MATH_387
14830    && flag_unsafe_math_optimizations"
14831 {
14832   if (optimize_insn_for_size_p ())
14833     FAIL;
14834   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14835   DONE;
14836 })
14837
14838 (define_expand "ceil<mode>2"
14839   [(use (match_operand:MODEF 0 "register_operand" ""))
14840    (use (match_operand:MODEF 1 "register_operand" ""))]
14841   "(TARGET_USE_FANCY_MATH_387
14842     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14843         || TARGET_MIX_SSE_I387)
14844     && flag_unsafe_math_optimizations)
14845    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846        && !flag_trapping_math)"
14847 {
14848   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14849       && !flag_trapping_math
14850       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14851     {
14852       if (TARGET_ROUND)
14853         emit_insn (gen_sse4_1_round<mode>2
14854                    (operands[0], operands[1], GEN_INT (0x02)));
14855       else if (optimize_insn_for_size_p ())
14856         FAIL;
14857       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14858         ix86_expand_floorceil (operand0, operand1, false);
14859       else
14860         ix86_expand_floorceildf_32 (operand0, operand1, false);
14861     }
14862   else
14863     {
14864       rtx op0, op1;
14865
14866       if (optimize_insn_for_size_p ())
14867         FAIL;
14868
14869       op0 = gen_reg_rtx (XFmode);
14870       op1 = gen_reg_rtx (XFmode);
14871       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14872       emit_insn (gen_frndintxf2_ceil (op0, op1));
14873
14874       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14875     }
14876   DONE;
14877 })
14878
14879 (define_insn_and_split "*fist<mode>2_ceil_1"
14880   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14881         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14882          UNSPEC_FIST_CEIL))
14883    (clobber (reg:CC FLAGS_REG))]
14884   "TARGET_USE_FANCY_MATH_387
14885    && flag_unsafe_math_optimizations
14886    && can_create_pseudo_p ()"
14887   "#"
14888   "&& 1"
14889   [(const_int 0)]
14890 {
14891   ix86_optimize_mode_switching[I387_CEIL] = 1;
14892
14893   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14894   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14895   if (memory_operand (operands[0], VOIDmode))
14896     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14897                                      operands[2], operands[3]));
14898   else
14899     {
14900       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14901       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14902                                                  operands[2], operands[3],
14903                                                  operands[4]));
14904     }
14905   DONE;
14906 }
14907   [(set_attr "type" "fistp")
14908    (set_attr "i387_cw" "ceil")
14909    (set_attr "mode" "<MODE>")])
14910
14911 (define_insn "fistdi2_ceil"
14912   [(set (match_operand:DI 0 "memory_operand" "=m")
14913         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14914          UNSPEC_FIST_CEIL))
14915    (use (match_operand:HI 2 "memory_operand" "m"))
14916    (use (match_operand:HI 3 "memory_operand" "m"))
14917    (clobber (match_scratch:XF 4 "=&1f"))]
14918   "TARGET_USE_FANCY_MATH_387
14919    && flag_unsafe_math_optimizations"
14920   "* return output_fix_trunc (insn, operands, 0);"
14921   [(set_attr "type" "fistp")
14922    (set_attr "i387_cw" "ceil")
14923    (set_attr "mode" "DI")])
14924
14925 (define_insn "fistdi2_ceil_with_temp"
14926   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14927         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14928          UNSPEC_FIST_CEIL))
14929    (use (match_operand:HI 2 "memory_operand" "m,m"))
14930    (use (match_operand:HI 3 "memory_operand" "m,m"))
14931    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14932    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14933   "TARGET_USE_FANCY_MATH_387
14934    && flag_unsafe_math_optimizations"
14935   "#"
14936   [(set_attr "type" "fistp")
14937    (set_attr "i387_cw" "ceil")
14938    (set_attr "mode" "DI")])
14939
14940 (define_split
14941   [(set (match_operand:DI 0 "register_operand" "")
14942         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14943          UNSPEC_FIST_CEIL))
14944    (use (match_operand:HI 2 "memory_operand" ""))
14945    (use (match_operand:HI 3 "memory_operand" ""))
14946    (clobber (match_operand:DI 4 "memory_operand" ""))
14947    (clobber (match_scratch 5 ""))]
14948   "reload_completed"
14949   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14950               (use (match_dup 2))
14951               (use (match_dup 3))
14952               (clobber (match_dup 5))])
14953    (set (match_dup 0) (match_dup 4))])
14954
14955 (define_split
14956   [(set (match_operand:DI 0 "memory_operand" "")
14957         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14958          UNSPEC_FIST_CEIL))
14959    (use (match_operand:HI 2 "memory_operand" ""))
14960    (use (match_operand:HI 3 "memory_operand" ""))
14961    (clobber (match_operand:DI 4 "memory_operand" ""))
14962    (clobber (match_scratch 5 ""))]
14963   "reload_completed"
14964   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14965               (use (match_dup 2))
14966               (use (match_dup 3))
14967               (clobber (match_dup 5))])])
14968
14969 (define_insn "fist<mode>2_ceil"
14970   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14971         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14972          UNSPEC_FIST_CEIL))
14973    (use (match_operand:HI 2 "memory_operand" "m"))
14974    (use (match_operand:HI 3 "memory_operand" "m"))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && flag_unsafe_math_optimizations"
14977   "* return output_fix_trunc (insn, operands, 0);"
14978   [(set_attr "type" "fistp")
14979    (set_attr "i387_cw" "ceil")
14980    (set_attr "mode" "<MODE>")])
14981
14982 (define_insn "fist<mode>2_ceil_with_temp"
14983   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14984         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14985          UNSPEC_FIST_CEIL))
14986    (use (match_operand:HI 2 "memory_operand" "m,m"))
14987    (use (match_operand:HI 3 "memory_operand" "m,m"))
14988    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14989   "TARGET_USE_FANCY_MATH_387
14990    && flag_unsafe_math_optimizations"
14991   "#"
14992   [(set_attr "type" "fistp")
14993    (set_attr "i387_cw" "ceil")
14994    (set_attr "mode" "<MODE>")])
14995
14996 (define_split
14997   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14998         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14999          UNSPEC_FIST_CEIL))
15000    (use (match_operand:HI 2 "memory_operand" ""))
15001    (use (match_operand:HI 3 "memory_operand" ""))
15002    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15003   "reload_completed"
15004   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15005                                   UNSPEC_FIST_CEIL))
15006               (use (match_dup 2))
15007               (use (match_dup 3))])
15008    (set (match_dup 0) (match_dup 4))])
15009
15010 (define_split
15011   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15012         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15013          UNSPEC_FIST_CEIL))
15014    (use (match_operand:HI 2 "memory_operand" ""))
15015    (use (match_operand:HI 3 "memory_operand" ""))
15016    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15017   "reload_completed"
15018   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15019                                   UNSPEC_FIST_CEIL))
15020               (use (match_dup 2))
15021               (use (match_dup 3))])])
15022
15023 (define_expand "lceilxf<mode>2"
15024   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15025                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15026                     UNSPEC_FIST_CEIL))
15027               (clobber (reg:CC FLAGS_REG))])]
15028   "TARGET_USE_FANCY_MATH_387
15029    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15030    && flag_unsafe_math_optimizations")
15031
15032 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15033   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15034    (match_operand:MODEF 1 "register_operand" "")]
15035   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15036    && !flag_trapping_math"
15037 {
15038   ix86_expand_lfloorceil (operand0, operand1, false);
15039   DONE;
15040 })
15041
15042 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15043 (define_insn_and_split "frndintxf2_trunc"
15044   [(set (match_operand:XF 0 "register_operand" "")
15045         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15046          UNSPEC_FRNDINT_TRUNC))
15047    (clobber (reg:CC FLAGS_REG))]
15048   "TARGET_USE_FANCY_MATH_387
15049    && flag_unsafe_math_optimizations
15050    && can_create_pseudo_p ()"
15051   "#"
15052   "&& 1"
15053   [(const_int 0)]
15054 {
15055   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15056
15057   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15058   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15059
15060   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15061                                         operands[2], operands[3]));
15062   DONE;
15063 }
15064   [(set_attr "type" "frndint")
15065    (set_attr "i387_cw" "trunc")
15066    (set_attr "mode" "XF")])
15067
15068 (define_insn "frndintxf2_trunc_i387"
15069   [(set (match_operand:XF 0 "register_operand" "=f")
15070         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15071          UNSPEC_FRNDINT_TRUNC))
15072    (use (match_operand:HI 2 "memory_operand" "m"))
15073    (use (match_operand:HI 3 "memory_operand" "m"))]
15074   "TARGET_USE_FANCY_MATH_387
15075    && flag_unsafe_math_optimizations"
15076   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15077   [(set_attr "type" "frndint")
15078    (set_attr "i387_cw" "trunc")
15079    (set_attr "mode" "XF")])
15080
15081 (define_expand "btruncxf2"
15082   [(use (match_operand:XF 0 "register_operand" ""))
15083    (use (match_operand:XF 1 "register_operand" ""))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && flag_unsafe_math_optimizations"
15086 {
15087   if (optimize_insn_for_size_p ())
15088     FAIL;
15089   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15090   DONE;
15091 })
15092
15093 (define_expand "btrunc<mode>2"
15094   [(use (match_operand:MODEF 0 "register_operand" ""))
15095    (use (match_operand:MODEF 1 "register_operand" ""))]
15096   "(TARGET_USE_FANCY_MATH_387
15097     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15098         || TARGET_MIX_SSE_I387)
15099     && flag_unsafe_math_optimizations)
15100    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15101        && !flag_trapping_math)"
15102 {
15103   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15104       && !flag_trapping_math
15105       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15106     {
15107       if (TARGET_ROUND)
15108         emit_insn (gen_sse4_1_round<mode>2
15109                    (operands[0], operands[1], GEN_INT (0x03)));
15110       else if (optimize_insn_for_size_p ())
15111         FAIL;
15112       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15113         ix86_expand_trunc (operand0, operand1);
15114       else
15115         ix86_expand_truncdf_32 (operand0, operand1);
15116     }
15117   else
15118     {
15119       rtx op0, op1;
15120
15121       if (optimize_insn_for_size_p ())
15122         FAIL;
15123
15124       op0 = gen_reg_rtx (XFmode);
15125       op1 = gen_reg_rtx (XFmode);
15126       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15127       emit_insn (gen_frndintxf2_trunc (op0, op1));
15128
15129       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15130     }
15131   DONE;
15132 })
15133
15134 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15135 (define_insn_and_split "frndintxf2_mask_pm"
15136   [(set (match_operand:XF 0 "register_operand" "")
15137         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15138          UNSPEC_FRNDINT_MASK_PM))
15139    (clobber (reg:CC FLAGS_REG))]
15140   "TARGET_USE_FANCY_MATH_387
15141    && flag_unsafe_math_optimizations
15142    && can_create_pseudo_p ()"
15143   "#"
15144   "&& 1"
15145   [(const_int 0)]
15146 {
15147   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15148
15149   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15150   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15151
15152   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15153                                           operands[2], operands[3]));
15154   DONE;
15155 }
15156   [(set_attr "type" "frndint")
15157    (set_attr "i387_cw" "mask_pm")
15158    (set_attr "mode" "XF")])
15159
15160 (define_insn "frndintxf2_mask_pm_i387"
15161   [(set (match_operand:XF 0 "register_operand" "=f")
15162         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15163          UNSPEC_FRNDINT_MASK_PM))
15164    (use (match_operand:HI 2 "memory_operand" "m"))
15165    (use (match_operand:HI 3 "memory_operand" "m"))]
15166   "TARGET_USE_FANCY_MATH_387
15167    && flag_unsafe_math_optimizations"
15168   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15169   [(set_attr "type" "frndint")
15170    (set_attr "i387_cw" "mask_pm")
15171    (set_attr "mode" "XF")])
15172
15173 (define_expand "nearbyintxf2"
15174   [(use (match_operand:XF 0 "register_operand" ""))
15175    (use (match_operand:XF 1 "register_operand" ""))]
15176   "TARGET_USE_FANCY_MATH_387
15177    && flag_unsafe_math_optimizations"
15178 {
15179   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15180   DONE;
15181 })
15182
15183 (define_expand "nearbyint<mode>2"
15184   [(use (match_operand:MODEF 0 "register_operand" ""))
15185    (use (match_operand:MODEF 1 "register_operand" ""))]
15186   "TARGET_USE_FANCY_MATH_387
15187    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15188        || TARGET_MIX_SSE_I387)
15189    && flag_unsafe_math_optimizations"
15190 {
15191   rtx op0 = gen_reg_rtx (XFmode);
15192   rtx op1 = gen_reg_rtx (XFmode);
15193
15194   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15195   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15196
15197   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15198   DONE;
15199 })
15200
15201 (define_insn "fxam<mode>2_i387"
15202   [(set (match_operand:HI 0 "register_operand" "=a")
15203         (unspec:HI
15204           [(match_operand:X87MODEF 1 "register_operand" "f")]
15205           UNSPEC_FXAM))]
15206   "TARGET_USE_FANCY_MATH_387"
15207   "fxam\n\tfnstsw\t%0"
15208   [(set_attr "type" "multi")
15209    (set_attr "length" "4")
15210    (set_attr "unit" "i387")
15211    (set_attr "mode" "<MODE>")])
15212
15213 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15214   [(set (match_operand:HI 0 "register_operand" "")
15215         (unspec:HI
15216           [(match_operand:MODEF 1 "memory_operand" "")]
15217           UNSPEC_FXAM_MEM))]
15218   "TARGET_USE_FANCY_MATH_387
15219    && can_create_pseudo_p ()"
15220   "#"
15221   "&& 1"
15222   [(set (match_dup 2)(match_dup 1))
15223    (set (match_dup 0)
15224         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15225 {
15226   operands[2] = gen_reg_rtx (<MODE>mode);
15227
15228   MEM_VOLATILE_P (operands[1]) = 1;
15229 }
15230   [(set_attr "type" "multi")
15231    (set_attr "unit" "i387")
15232    (set_attr "mode" "<MODE>")])
15233
15234 (define_expand "isinfxf2"
15235   [(use (match_operand:SI 0 "register_operand" ""))
15236    (use (match_operand:XF 1 "register_operand" ""))]
15237   "TARGET_USE_FANCY_MATH_387
15238    && TARGET_C99_FUNCTIONS"
15239 {
15240   rtx mask = GEN_INT (0x45);
15241   rtx val = GEN_INT (0x05);
15242
15243   rtx cond;
15244
15245   rtx scratch = gen_reg_rtx (HImode);
15246   rtx res = gen_reg_rtx (QImode);
15247
15248   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15249
15250   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15251   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15252   cond = gen_rtx_fmt_ee (EQ, QImode,
15253                          gen_rtx_REG (CCmode, FLAGS_REG),
15254                          const0_rtx);
15255   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15256   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15257   DONE;
15258 })
15259
15260 (define_expand "isinf<mode>2"
15261   [(use (match_operand:SI 0 "register_operand" ""))
15262    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15263   "TARGET_USE_FANCY_MATH_387
15264    && TARGET_C99_FUNCTIONS
15265    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15266 {
15267   rtx mask = GEN_INT (0x45);
15268   rtx val = GEN_INT (0x05);
15269
15270   rtx cond;
15271
15272   rtx scratch = gen_reg_rtx (HImode);
15273   rtx res = gen_reg_rtx (QImode);
15274
15275   /* Remove excess precision by forcing value through memory. */
15276   if (memory_operand (operands[1], VOIDmode))
15277     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15278   else
15279     {
15280       enum ix86_stack_slot slot = (virtuals_instantiated
15281                                    ? SLOT_TEMP
15282                                    : SLOT_VIRTUAL);
15283       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15284
15285       emit_move_insn (temp, operands[1]);
15286       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15287     }
15288
15289   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15290   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15291   cond = gen_rtx_fmt_ee (EQ, QImode,
15292                          gen_rtx_REG (CCmode, FLAGS_REG),
15293                          const0_rtx);
15294   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15295   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15296   DONE;
15297 })
15298
15299 (define_expand "signbitxf2"
15300   [(use (match_operand:SI 0 "register_operand" ""))
15301    (use (match_operand:XF 1 "register_operand" ""))]
15302   "TARGET_USE_FANCY_MATH_387"
15303 {
15304   rtx scratch = gen_reg_rtx (HImode);
15305
15306   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15307   emit_insn (gen_andsi3 (operands[0],
15308              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15309   DONE;
15310 })
15311
15312 (define_insn "movmsk_df"
15313   [(set (match_operand:SI 0 "register_operand" "=r")
15314         (unspec:SI
15315           [(match_operand:DF 1 "register_operand" "x")]
15316           UNSPEC_MOVMSK))]
15317   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15318   "%vmovmskpd\t{%1, %0|%0, %1}"
15319   [(set_attr "type" "ssemov")
15320    (set_attr "prefix" "maybe_vex")
15321    (set_attr "mode" "DF")])
15322
15323 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15324 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15325 (define_expand "signbitdf2"
15326   [(use (match_operand:SI 0 "register_operand" ""))
15327    (use (match_operand:DF 1 "register_operand" ""))]
15328   "TARGET_USE_FANCY_MATH_387
15329    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15330 {
15331   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15332     {
15333       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15334       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15335     }
15336   else
15337     {
15338       rtx scratch = gen_reg_rtx (HImode);
15339
15340       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15341       emit_insn (gen_andsi3 (operands[0],
15342                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15343     }
15344   DONE;
15345 })
15346
15347 (define_expand "signbitsf2"
15348   [(use (match_operand:SI 0 "register_operand" ""))
15349    (use (match_operand:SF 1 "register_operand" ""))]
15350   "TARGET_USE_FANCY_MATH_387
15351    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15352 {
15353   rtx scratch = gen_reg_rtx (HImode);
15354
15355   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15356   emit_insn (gen_andsi3 (operands[0],
15357              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15358   DONE;
15359 })
15360 \f
15361 ;; Block operation instructions
15362
15363 (define_insn "cld"
15364   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15365   ""
15366   "cld"
15367   [(set_attr "length" "1")
15368    (set_attr "length_immediate" "0")
15369    (set_attr "modrm" "0")])
15370
15371 (define_expand "movmem<mode>"
15372   [(use (match_operand:BLK 0 "memory_operand" ""))
15373    (use (match_operand:BLK 1 "memory_operand" ""))
15374    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15375    (use (match_operand:SWI48 3 "const_int_operand" ""))
15376    (use (match_operand:SI 4 "const_int_operand" ""))
15377    (use (match_operand:SI 5 "const_int_operand" ""))]
15378   ""
15379 {
15380  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15381                          operands[4], operands[5]))
15382    DONE;
15383  else
15384    FAIL;
15385 })
15386
15387 ;; Most CPUs don't like single string operations
15388 ;; Handle this case here to simplify previous expander.
15389
15390 (define_expand "strmov"
15391   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15392    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15393    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15394               (clobber (reg:CC FLAGS_REG))])
15395    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15396               (clobber (reg:CC FLAGS_REG))])]
15397   ""
15398 {
15399   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15400
15401   /* If .md ever supports :P for Pmode, these can be directly
15402      in the pattern above.  */
15403   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15404   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15405
15406   /* Can't use this if the user has appropriated esi or edi.  */
15407   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15408       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15409     {
15410       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15411                                       operands[2], operands[3],
15412                                       operands[5], operands[6]));
15413       DONE;
15414     }
15415
15416   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15417 })
15418
15419 (define_expand "strmov_singleop"
15420   [(parallel [(set (match_operand 1 "memory_operand" "")
15421                    (match_operand 3 "memory_operand" ""))
15422               (set (match_operand 0 "register_operand" "")
15423                    (match_operand 4 "" ""))
15424               (set (match_operand 2 "register_operand" "")
15425                    (match_operand 5 "" ""))])]
15426   ""
15427   "ix86_current_function_needs_cld = 1;")
15428
15429 (define_insn "*strmovdi_rex_1"
15430   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15431         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15432    (set (match_operand:DI 0 "register_operand" "=D")
15433         (plus:DI (match_dup 2)
15434                  (const_int 8)))
15435    (set (match_operand:DI 1 "register_operand" "=S")
15436         (plus:DI (match_dup 3)
15437                  (const_int 8)))]
15438   "TARGET_64BIT"
15439   "movsq"
15440   [(set_attr "type" "str")
15441    (set_attr "memory" "both")
15442    (set_attr "mode" "DI")])
15443
15444 (define_insn "*strmovsi_1"
15445   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15446         (mem:SI (match_operand:P 3 "register_operand" "1")))
15447    (set (match_operand:P 0 "register_operand" "=D")
15448         (plus:P (match_dup 2)
15449                 (const_int 4)))
15450    (set (match_operand:P 1 "register_operand" "=S")
15451         (plus:P (match_dup 3)
15452                 (const_int 4)))]
15453   ""
15454   "movs{l|d}"
15455   [(set_attr "type" "str")
15456    (set_attr "memory" "both")
15457    (set_attr "mode" "SI")])
15458
15459 (define_insn "*strmovhi_1"
15460   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15461         (mem:HI (match_operand:P 3 "register_operand" "1")))
15462    (set (match_operand:P 0 "register_operand" "=D")
15463         (plus:P (match_dup 2)
15464                 (const_int 2)))
15465    (set (match_operand:P 1 "register_operand" "=S")
15466         (plus:P (match_dup 3)
15467                 (const_int 2)))]
15468   ""
15469   "movsw"
15470   [(set_attr "type" "str")
15471    (set_attr "memory" "both")
15472    (set_attr "mode" "HI")])
15473
15474 (define_insn "*strmovqi_1"
15475   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15476         (mem:QI (match_operand:P 3 "register_operand" "1")))
15477    (set (match_operand:P 0 "register_operand" "=D")
15478         (plus:P (match_dup 2)
15479                 (const_int 1)))
15480    (set (match_operand:P 1 "register_operand" "=S")
15481         (plus:P (match_dup 3)
15482                 (const_int 1)))]
15483   ""
15484   "movsb"
15485   [(set_attr "type" "str")
15486    (set_attr "memory" "both")
15487    (set (attr "prefix_rex")
15488         (if_then_else
15489           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15490           (const_string "0")
15491           (const_string "*")))
15492    (set_attr "mode" "QI")])
15493
15494 (define_expand "rep_mov"
15495   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15496               (set (match_operand 0 "register_operand" "")
15497                    (match_operand 5 "" ""))
15498               (set (match_operand 2 "register_operand" "")
15499                    (match_operand 6 "" ""))
15500               (set (match_operand 1 "memory_operand" "")
15501                    (match_operand 3 "memory_operand" ""))
15502               (use (match_dup 4))])]
15503   ""
15504   "ix86_current_function_needs_cld = 1;")
15505
15506 (define_insn "*rep_movdi_rex64"
15507   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15508    (set (match_operand:DI 0 "register_operand" "=D")
15509         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15510                             (const_int 3))
15511                  (match_operand:DI 3 "register_operand" "0")))
15512    (set (match_operand:DI 1 "register_operand" "=S")
15513         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15514                  (match_operand:DI 4 "register_operand" "1")))
15515    (set (mem:BLK (match_dup 3))
15516         (mem:BLK (match_dup 4)))
15517    (use (match_dup 5))]
15518   "TARGET_64BIT"
15519   "rep{%;} movsq"
15520   [(set_attr "type" "str")
15521    (set_attr "prefix_rep" "1")
15522    (set_attr "memory" "both")
15523    (set_attr "mode" "DI")])
15524
15525 (define_insn "*rep_movsi"
15526   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15527    (set (match_operand:P 0 "register_operand" "=D")
15528         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15529                           (const_int 2))
15530                  (match_operand:P 3 "register_operand" "0")))
15531    (set (match_operand:P 1 "register_operand" "=S")
15532         (plus:P (ashift:P (match_dup 5) (const_int 2))
15533                 (match_operand:P 4 "register_operand" "1")))
15534    (set (mem:BLK (match_dup 3))
15535         (mem:BLK (match_dup 4)))
15536    (use (match_dup 5))]
15537   ""
15538   "rep{%;} movs{l|d}"
15539   [(set_attr "type" "str")
15540    (set_attr "prefix_rep" "1")
15541    (set_attr "memory" "both")
15542    (set_attr "mode" "SI")])
15543
15544 (define_insn "*rep_movqi"
15545   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15546    (set (match_operand:P 0 "register_operand" "=D")
15547         (plus:P (match_operand:P 3 "register_operand" "0")
15548                 (match_operand:P 5 "register_operand" "2")))
15549    (set (match_operand:P 1 "register_operand" "=S")
15550         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15551    (set (mem:BLK (match_dup 3))
15552         (mem:BLK (match_dup 4)))
15553    (use (match_dup 5))]
15554   ""
15555   "rep{%;} movsb"
15556   [(set_attr "type" "str")
15557    (set_attr "prefix_rep" "1")
15558    (set_attr "memory" "both")
15559    (set_attr "mode" "QI")])
15560
15561 (define_expand "setmem<mode>"
15562    [(use (match_operand:BLK 0 "memory_operand" ""))
15563     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15564     (use (match_operand 2 "const_int_operand" ""))
15565     (use (match_operand 3 "const_int_operand" ""))
15566     (use (match_operand:SI 4 "const_int_operand" ""))
15567     (use (match_operand:SI 5 "const_int_operand" ""))]
15568   ""
15569 {
15570  if (ix86_expand_setmem (operands[0], operands[1],
15571                          operands[2], operands[3],
15572                          operands[4], operands[5]))
15573    DONE;
15574  else
15575    FAIL;
15576 })
15577
15578 ;; Most CPUs don't like single string operations
15579 ;; Handle this case here to simplify previous expander.
15580
15581 (define_expand "strset"
15582   [(set (match_operand 1 "memory_operand" "")
15583         (match_operand 2 "register_operand" ""))
15584    (parallel [(set (match_operand 0 "register_operand" "")
15585                    (match_dup 3))
15586               (clobber (reg:CC FLAGS_REG))])]
15587   ""
15588 {
15589   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15590     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15591
15592   /* If .md ever supports :P for Pmode, this can be directly
15593      in the pattern above.  */
15594   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15595                               GEN_INT (GET_MODE_SIZE (GET_MODE
15596                                                       (operands[2]))));
15597   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15598     {
15599       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15600                                       operands[3]));
15601       DONE;
15602     }
15603 })
15604
15605 (define_expand "strset_singleop"
15606   [(parallel [(set (match_operand 1 "memory_operand" "")
15607                    (match_operand 2 "register_operand" ""))
15608               (set (match_operand 0 "register_operand" "")
15609                    (match_operand 3 "" ""))])]
15610   ""
15611   "ix86_current_function_needs_cld = 1;")
15612
15613 (define_insn "*strsetdi_rex_1"
15614   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15615         (match_operand:DI 2 "register_operand" "a"))
15616    (set (match_operand:DI 0 "register_operand" "=D")
15617         (plus:DI (match_dup 1)
15618                  (const_int 8)))]
15619   "TARGET_64BIT"
15620   "stosq"
15621   [(set_attr "type" "str")
15622    (set_attr "memory" "store")
15623    (set_attr "mode" "DI")])
15624
15625 (define_insn "*strsetsi_1"
15626   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15627         (match_operand:SI 2 "register_operand" "a"))
15628    (set (match_operand:P 0 "register_operand" "=D")
15629         (plus:P (match_dup 1)
15630                 (const_int 4)))]
15631   ""
15632   "stos{l|d}"
15633   [(set_attr "type" "str")
15634    (set_attr "memory" "store")
15635    (set_attr "mode" "SI")])
15636
15637 (define_insn "*strsethi_1"
15638   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15639         (match_operand:HI 2 "register_operand" "a"))
15640    (set (match_operand:P 0 "register_operand" "=D")
15641         (plus:P (match_dup 1)
15642                 (const_int 2)))]
15643   ""
15644   "stosw"
15645   [(set_attr "type" "str")
15646    (set_attr "memory" "store")
15647    (set_attr "mode" "HI")])
15648
15649 (define_insn "*strsetqi_1"
15650   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15651         (match_operand:QI 2 "register_operand" "a"))
15652    (set (match_operand:P 0 "register_operand" "=D")
15653         (plus:P (match_dup 1)
15654                 (const_int 1)))]
15655   ""
15656   "stosb"
15657   [(set_attr "type" "str")
15658    (set_attr "memory" "store")
15659    (set (attr "prefix_rex")
15660         (if_then_else
15661           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15662           (const_string "0")
15663           (const_string "*")))
15664    (set_attr "mode" "QI")])
15665
15666 (define_expand "rep_stos"
15667   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15668               (set (match_operand 0 "register_operand" "")
15669                    (match_operand 4 "" ""))
15670               (set (match_operand 2 "memory_operand" "") (const_int 0))
15671               (use (match_operand 3 "register_operand" ""))
15672               (use (match_dup 1))])]
15673   ""
15674   "ix86_current_function_needs_cld = 1;")
15675
15676 (define_insn "*rep_stosdi_rex64"
15677   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15678    (set (match_operand:DI 0 "register_operand" "=D")
15679         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15680                             (const_int 3))
15681                  (match_operand:DI 3 "register_operand" "0")))
15682    (set (mem:BLK (match_dup 3))
15683         (const_int 0))
15684    (use (match_operand:DI 2 "register_operand" "a"))
15685    (use (match_dup 4))]
15686   "TARGET_64BIT"
15687   "rep{%;} stosq"
15688   [(set_attr "type" "str")
15689    (set_attr "prefix_rep" "1")
15690    (set_attr "memory" "store")
15691    (set_attr "mode" "DI")])
15692
15693 (define_insn "*rep_stossi"
15694   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15695    (set (match_operand:P 0 "register_operand" "=D")
15696         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15697                           (const_int 2))
15698                  (match_operand:P 3 "register_operand" "0")))
15699    (set (mem:BLK (match_dup 3))
15700         (const_int 0))
15701    (use (match_operand:SI 2 "register_operand" "a"))
15702    (use (match_dup 4))]
15703   ""
15704   "rep{%;} stos{l|d}"
15705   [(set_attr "type" "str")
15706    (set_attr "prefix_rep" "1")
15707    (set_attr "memory" "store")
15708    (set_attr "mode" "SI")])
15709
15710 (define_insn "*rep_stosqi"
15711   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15712    (set (match_operand:P 0 "register_operand" "=D")
15713         (plus:P (match_operand:P 3 "register_operand" "0")
15714                 (match_operand:P 4 "register_operand" "1")))
15715    (set (mem:BLK (match_dup 3))
15716         (const_int 0))
15717    (use (match_operand:QI 2 "register_operand" "a"))
15718    (use (match_dup 4))]
15719   ""
15720   "rep{%;} stosb"
15721   [(set_attr "type" "str")
15722    (set_attr "prefix_rep" "1")
15723    (set_attr "memory" "store")
15724    (set (attr "prefix_rex")
15725         (if_then_else
15726           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15727           (const_string "0")
15728           (const_string "*")))
15729    (set_attr "mode" "QI")])
15730
15731 (define_expand "cmpstrnsi"
15732   [(set (match_operand:SI 0 "register_operand" "")
15733         (compare:SI (match_operand:BLK 1 "general_operand" "")
15734                     (match_operand:BLK 2 "general_operand" "")))
15735    (use (match_operand 3 "general_operand" ""))
15736    (use (match_operand 4 "immediate_operand" ""))]
15737   ""
15738 {
15739   rtx addr1, addr2, out, outlow, count, countreg, align;
15740
15741   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15742     FAIL;
15743
15744   /* Can't use this if the user has appropriated esi or edi.  */
15745   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15746     FAIL;
15747
15748   out = operands[0];
15749   if (!REG_P (out))
15750     out = gen_reg_rtx (SImode);
15751
15752   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15753   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15754   if (addr1 != XEXP (operands[1], 0))
15755     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15756   if (addr2 != XEXP (operands[2], 0))
15757     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15758
15759   count = operands[3];
15760   countreg = ix86_zero_extend_to_Pmode (count);
15761
15762   /* %%% Iff we are testing strict equality, we can use known alignment
15763      to good advantage.  This may be possible with combine, particularly
15764      once cc0 is dead.  */
15765   align = operands[4];
15766
15767   if (CONST_INT_P (count))
15768     {
15769       if (INTVAL (count) == 0)
15770         {
15771           emit_move_insn (operands[0], const0_rtx);
15772           DONE;
15773         }
15774       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15775                                      operands[1], operands[2]));
15776     }
15777   else
15778     {
15779       rtx (*gen_cmp) (rtx, rtx);
15780
15781       gen_cmp = (TARGET_64BIT
15782                  ? gen_cmpdi_1 : gen_cmpsi_1);
15783
15784       emit_insn (gen_cmp (countreg, countreg));
15785       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15786                                   operands[1], operands[2]));
15787     }
15788
15789   outlow = gen_lowpart (QImode, out);
15790   emit_insn (gen_cmpintqi (outlow));
15791   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15792
15793   if (operands[0] != out)
15794     emit_move_insn (operands[0], out);
15795
15796   DONE;
15797 })
15798
15799 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15800
15801 (define_expand "cmpintqi"
15802   [(set (match_dup 1)
15803         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15804    (set (match_dup 2)
15805         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15806    (parallel [(set (match_operand:QI 0 "register_operand" "")
15807                    (minus:QI (match_dup 1)
15808                              (match_dup 2)))
15809               (clobber (reg:CC FLAGS_REG))])]
15810   ""
15811 {
15812   operands[1] = gen_reg_rtx (QImode);
15813   operands[2] = gen_reg_rtx (QImode);
15814 })
15815
15816 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15817 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15818
15819 (define_expand "cmpstrnqi_nz_1"
15820   [(parallel [(set (reg:CC FLAGS_REG)
15821                    (compare:CC (match_operand 4 "memory_operand" "")
15822                                (match_operand 5 "memory_operand" "")))
15823               (use (match_operand 2 "register_operand" ""))
15824               (use (match_operand:SI 3 "immediate_operand" ""))
15825               (clobber (match_operand 0 "register_operand" ""))
15826               (clobber (match_operand 1 "register_operand" ""))
15827               (clobber (match_dup 2))])]
15828   ""
15829   "ix86_current_function_needs_cld = 1;")
15830
15831 (define_insn "*cmpstrnqi_nz_1"
15832   [(set (reg:CC FLAGS_REG)
15833         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15834                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15835    (use (match_operand:P 6 "register_operand" "2"))
15836    (use (match_operand:SI 3 "immediate_operand" "i"))
15837    (clobber (match_operand:P 0 "register_operand" "=S"))
15838    (clobber (match_operand:P 1 "register_operand" "=D"))
15839    (clobber (match_operand:P 2 "register_operand" "=c"))]
15840   ""
15841   "repz{%;} cmpsb"
15842   [(set_attr "type" "str")
15843    (set_attr "mode" "QI")
15844    (set (attr "prefix_rex")
15845         (if_then_else
15846           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15847           (const_string "0")
15848           (const_string "*")))
15849    (set_attr "prefix_rep" "1")])
15850
15851 ;; The same, but the count is not known to not be zero.
15852
15853 (define_expand "cmpstrnqi_1"
15854   [(parallel [(set (reg:CC FLAGS_REG)
15855                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15856                                      (const_int 0))
15857                   (compare:CC (match_operand 4 "memory_operand" "")
15858                               (match_operand 5 "memory_operand" ""))
15859                   (const_int 0)))
15860               (use (match_operand:SI 3 "immediate_operand" ""))
15861               (use (reg:CC FLAGS_REG))
15862               (clobber (match_operand 0 "register_operand" ""))
15863               (clobber (match_operand 1 "register_operand" ""))
15864               (clobber (match_dup 2))])]
15865   ""
15866   "ix86_current_function_needs_cld = 1;")
15867
15868 (define_insn "*cmpstrnqi_1"
15869   [(set (reg:CC FLAGS_REG)
15870         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15871                              (const_int 0))
15872           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15873                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15874           (const_int 0)))
15875    (use (match_operand:SI 3 "immediate_operand" "i"))
15876    (use (reg:CC FLAGS_REG))
15877    (clobber (match_operand:P 0 "register_operand" "=S"))
15878    (clobber (match_operand:P 1 "register_operand" "=D"))
15879    (clobber (match_operand:P 2 "register_operand" "=c"))]
15880   ""
15881   "repz{%;} cmpsb"
15882   [(set_attr "type" "str")
15883    (set_attr "mode" "QI")
15884    (set (attr "prefix_rex")
15885         (if_then_else
15886           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15887           (const_string "0")
15888           (const_string "*")))
15889    (set_attr "prefix_rep" "1")])
15890
15891 (define_expand "strlen<mode>"
15892   [(set (match_operand:SWI48x 0 "register_operand" "")
15893         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15894                         (match_operand:QI 2 "immediate_operand" "")
15895                         (match_operand 3 "immediate_operand" "")]
15896                        UNSPEC_SCAS))]
15897   ""
15898 {
15899  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15900    DONE;
15901  else
15902    FAIL;
15903 })
15904
15905 (define_expand "strlenqi_1"
15906   [(parallel [(set (match_operand 0 "register_operand" "")
15907                    (match_operand 2 "" ""))
15908               (clobber (match_operand 1 "register_operand" ""))
15909               (clobber (reg:CC FLAGS_REG))])]
15910   ""
15911   "ix86_current_function_needs_cld = 1;")
15912
15913 (define_insn "*strlenqi_1"
15914   [(set (match_operand:P 0 "register_operand" "=&c")
15915         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15916                    (match_operand:QI 2 "register_operand" "a")
15917                    (match_operand:P 3 "immediate_operand" "i")
15918                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15919    (clobber (match_operand:P 1 "register_operand" "=D"))
15920    (clobber (reg:CC FLAGS_REG))]
15921   ""
15922   "repnz{%;} scasb"
15923   [(set_attr "type" "str")
15924    (set_attr "mode" "QI")
15925    (set (attr "prefix_rex")
15926         (if_then_else
15927           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15928           (const_string "0")
15929           (const_string "*")))
15930    (set_attr "prefix_rep" "1")])
15931
15932 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15933 ;; handled in combine, but it is not currently up to the task.
15934 ;; When used for their truth value, the cmpstrn* expanders generate
15935 ;; code like this:
15936 ;;
15937 ;;   repz cmpsb
15938 ;;   seta       %al
15939 ;;   setb       %dl
15940 ;;   cmpb       %al, %dl
15941 ;;   jcc        label
15942 ;;
15943 ;; The intermediate three instructions are unnecessary.
15944
15945 ;; This one handles cmpstrn*_nz_1...
15946 (define_peephole2
15947   [(parallel[
15948      (set (reg:CC FLAGS_REG)
15949           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15950                       (mem:BLK (match_operand 5 "register_operand" ""))))
15951      (use (match_operand 6 "register_operand" ""))
15952      (use (match_operand:SI 3 "immediate_operand" ""))
15953      (clobber (match_operand 0 "register_operand" ""))
15954      (clobber (match_operand 1 "register_operand" ""))
15955      (clobber (match_operand 2 "register_operand" ""))])
15956    (set (match_operand:QI 7 "register_operand" "")
15957         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15958    (set (match_operand:QI 8 "register_operand" "")
15959         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15960    (set (reg FLAGS_REG)
15961         (compare (match_dup 7) (match_dup 8)))
15962   ]
15963   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15964   [(parallel[
15965      (set (reg:CC FLAGS_REG)
15966           (compare:CC (mem:BLK (match_dup 4))
15967                       (mem:BLK (match_dup 5))))
15968      (use (match_dup 6))
15969      (use (match_dup 3))
15970      (clobber (match_dup 0))
15971      (clobber (match_dup 1))
15972      (clobber (match_dup 2))])])
15973
15974 ;; ...and this one handles cmpstrn*_1.
15975 (define_peephole2
15976   [(parallel[
15977      (set (reg:CC FLAGS_REG)
15978           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15979                                (const_int 0))
15980             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15981                         (mem:BLK (match_operand 5 "register_operand" "")))
15982             (const_int 0)))
15983      (use (match_operand:SI 3 "immediate_operand" ""))
15984      (use (reg:CC FLAGS_REG))
15985      (clobber (match_operand 0 "register_operand" ""))
15986      (clobber (match_operand 1 "register_operand" ""))
15987      (clobber (match_operand 2 "register_operand" ""))])
15988    (set (match_operand:QI 7 "register_operand" "")
15989         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15990    (set (match_operand:QI 8 "register_operand" "")
15991         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15992    (set (reg FLAGS_REG)
15993         (compare (match_dup 7) (match_dup 8)))
15994   ]
15995   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15996   [(parallel[
15997      (set (reg:CC FLAGS_REG)
15998           (if_then_else:CC (ne (match_dup 6)
15999                                (const_int 0))
16000             (compare:CC (mem:BLK (match_dup 4))
16001                         (mem:BLK (match_dup 5)))
16002             (const_int 0)))
16003      (use (match_dup 3))
16004      (use (reg:CC FLAGS_REG))
16005      (clobber (match_dup 0))
16006      (clobber (match_dup 1))
16007      (clobber (match_dup 2))])])
16008 \f
16009 ;; Conditional move instructions.
16010
16011 (define_expand "mov<mode>cc"
16012   [(set (match_operand:SWIM 0 "register_operand" "")
16013         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16014                            (match_operand:SWIM 2 "general_operand" "")
16015                            (match_operand:SWIM 3 "general_operand" "")))]
16016   ""
16017   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16018
16019 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16020 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16021 ;; So just document what we're doing explicitly.
16022
16023 (define_expand "x86_mov<mode>cc_0_m1"
16024   [(parallel
16025     [(set (match_operand:SWI48 0 "register_operand" "")
16026           (if_then_else:SWI48
16027             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16028              [(match_operand 1 "flags_reg_operand" "")
16029               (const_int 0)])
16030             (const_int -1)
16031             (const_int 0)))
16032      (clobber (reg:CC FLAGS_REG))])])
16033
16034 (define_insn "*x86_mov<mode>cc_0_m1"
16035   [(set (match_operand:SWI48 0 "register_operand" "=r")
16036         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16037                              [(reg FLAGS_REG) (const_int 0)])
16038           (const_int -1)
16039           (const_int 0)))
16040    (clobber (reg:CC FLAGS_REG))]
16041   ""
16042   "sbb{<imodesuffix>}\t%0, %0"
16043   ; Since we don't have the proper number of operands for an alu insn,
16044   ; fill in all the blanks.
16045   [(set_attr "type" "alu")
16046    (set_attr "use_carry" "1")
16047    (set_attr "pent_pair" "pu")
16048    (set_attr "memory" "none")
16049    (set_attr "imm_disp" "false")
16050    (set_attr "mode" "<MODE>")
16051    (set_attr "length_immediate" "0")])
16052
16053 (define_insn "*x86_mov<mode>cc_0_m1_se"
16054   [(set (match_operand:SWI48 0 "register_operand" "=r")
16055         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16056                              [(reg FLAGS_REG) (const_int 0)])
16057                             (const_int 1)
16058                             (const_int 0)))
16059    (clobber (reg:CC FLAGS_REG))]
16060   ""
16061   "sbb{<imodesuffix>}\t%0, %0"
16062   [(set_attr "type" "alu")
16063    (set_attr "use_carry" "1")
16064    (set_attr "pent_pair" "pu")
16065    (set_attr "memory" "none")
16066    (set_attr "imm_disp" "false")
16067    (set_attr "mode" "<MODE>")
16068    (set_attr "length_immediate" "0")])
16069
16070 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16071   [(set (match_operand:SWI48 0 "register_operand" "=r")
16072         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16073                     [(reg FLAGS_REG) (const_int 0)])))]
16074   ""
16075   "sbb{<imodesuffix>}\t%0, %0"
16076   [(set_attr "type" "alu")
16077    (set_attr "use_carry" "1")
16078    (set_attr "pent_pair" "pu")
16079    (set_attr "memory" "none")
16080    (set_attr "imm_disp" "false")
16081    (set_attr "mode" "<MODE>")
16082    (set_attr "length_immediate" "0")])
16083
16084 (define_insn "*mov<mode>cc_noc"
16085   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16086         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16087                                [(reg FLAGS_REG) (const_int 0)])
16088           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16089           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16090   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16091   "@
16092    cmov%O2%C1\t{%2, %0|%0, %2}
16093    cmov%O2%c1\t{%3, %0|%0, %3}"
16094   [(set_attr "type" "icmov")
16095    (set_attr "mode" "<MODE>")])
16096
16097 (define_insn_and_split "*movqicc_noc"
16098   [(set (match_operand:QI 0 "register_operand" "=r,r")
16099         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16100                            [(match_operand 4 "flags_reg_operand" "")
16101                             (const_int 0)])
16102                       (match_operand:QI 2 "register_operand" "r,0")
16103                       (match_operand:QI 3 "register_operand" "0,r")))]
16104   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16105   "#"
16106   "&& reload_completed"
16107   [(set (match_dup 0)
16108         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16109                       (match_dup 2)
16110                       (match_dup 3)))]
16111   "operands[0] = gen_lowpart (SImode, operands[0]);
16112    operands[2] = gen_lowpart (SImode, operands[2]);
16113    operands[3] = gen_lowpart (SImode, operands[3]);"
16114   [(set_attr "type" "icmov")
16115    (set_attr "mode" "SI")])
16116
16117 (define_expand "mov<mode>cc"
16118   [(set (match_operand:X87MODEF 0 "register_operand" "")
16119         (if_then_else:X87MODEF
16120           (match_operand 1 "ix86_fp_comparison_operator" "")
16121           (match_operand:X87MODEF 2 "register_operand" "")
16122           (match_operand:X87MODEF 3 "register_operand" "")))]
16123   "(TARGET_80387 && TARGET_CMOVE)
16124    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16125   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16126
16127 (define_insn "*movxfcc_1"
16128   [(set (match_operand:XF 0 "register_operand" "=f,f")
16129         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16130                                 [(reg FLAGS_REG) (const_int 0)])
16131                       (match_operand:XF 2 "register_operand" "f,0")
16132                       (match_operand:XF 3 "register_operand" "0,f")))]
16133   "TARGET_80387 && TARGET_CMOVE"
16134   "@
16135    fcmov%F1\t{%2, %0|%0, %2}
16136    fcmov%f1\t{%3, %0|%0, %3}"
16137   [(set_attr "type" "fcmov")
16138    (set_attr "mode" "XF")])
16139
16140 (define_insn "*movdfcc_1_rex64"
16141   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16142         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16143                                 [(reg FLAGS_REG) (const_int 0)])
16144                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16145                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16146   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16147    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16148   "@
16149    fcmov%F1\t{%2, %0|%0, %2}
16150    fcmov%f1\t{%3, %0|%0, %3}
16151    cmov%O2%C1\t{%2, %0|%0, %2}
16152    cmov%O2%c1\t{%3, %0|%0, %3}"
16153   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16154    (set_attr "mode" "DF,DF,DI,DI")])
16155
16156 (define_insn "*movdfcc_1"
16157   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16158         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16159                                 [(reg FLAGS_REG) (const_int 0)])
16160                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16161                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16162   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16163    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16164   "@
16165    fcmov%F1\t{%2, %0|%0, %2}
16166    fcmov%f1\t{%3, %0|%0, %3}
16167    #
16168    #"
16169   [(set_attr "type" "fcmov,fcmov,multi,multi")
16170    (set_attr "mode" "DF,DF,DI,DI")])
16171
16172 (define_split
16173   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16174         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16175                                 [(match_operand 4 "flags_reg_operand" "")
16176                                  (const_int 0)])
16177                       (match_operand:DF 2 "nonimmediate_operand" "")
16178                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16179   "!TARGET_64BIT && reload_completed"
16180   [(set (match_dup 2)
16181         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16182                       (match_dup 5)
16183                       (match_dup 6)))
16184    (set (match_dup 3)
16185         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16186                       (match_dup 7)
16187                       (match_dup 8)))]
16188 {
16189   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16190   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16191 })
16192
16193 (define_insn "*movsfcc_1_387"
16194   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16195         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16196                                 [(reg FLAGS_REG) (const_int 0)])
16197                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16198                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16199   "TARGET_80387 && TARGET_CMOVE
16200    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16201   "@
16202    fcmov%F1\t{%2, %0|%0, %2}
16203    fcmov%f1\t{%3, %0|%0, %3}
16204    cmov%O2%C1\t{%2, %0|%0, %2}
16205    cmov%O2%c1\t{%3, %0|%0, %3}"
16206   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16207    (set_attr "mode" "SF,SF,SI,SI")])
16208
16209 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16210 ;; the scalar versions to have only XMM registers as operands.
16211
16212 ;; XOP conditional move
16213 (define_insn "*xop_pcmov_<mode>"
16214   [(set (match_operand:MODEF 0 "register_operand" "=x")
16215         (if_then_else:MODEF
16216           (match_operand:MODEF 1 "register_operand" "x")
16217           (match_operand:MODEF 2 "register_operand" "x")
16218           (match_operand:MODEF 3 "register_operand" "x")))]
16219   "TARGET_XOP"
16220   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16221   [(set_attr "type" "sse4arg")])
16222
16223 ;; These versions of the min/max patterns are intentionally ignorant of
16224 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16225 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16226 ;; are undefined in this condition, we're certain this is correct.
16227
16228 (define_insn "*avx_<code><mode>3"
16229   [(set (match_operand:MODEF 0 "register_operand" "=x")
16230         (smaxmin:MODEF
16231           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16232           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16233   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16234   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16235   [(set_attr "type" "sseadd")
16236    (set_attr "prefix" "vex")
16237    (set_attr "mode" "<MODE>")])
16238
16239 (define_insn "<code><mode>3"
16240   [(set (match_operand:MODEF 0 "register_operand" "=x")
16241         (smaxmin:MODEF
16242           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16243           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16244   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16245   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16246   [(set_attr "type" "sseadd")
16247    (set_attr "mode" "<MODE>")])
16248
16249 ;; These versions of the min/max patterns implement exactly the operations
16250 ;;   min = (op1 < op2 ? op1 : op2)
16251 ;;   max = (!(op1 < op2) ? op1 : op2)
16252 ;; Their operands are not commutative, and thus they may be used in the
16253 ;; presence of -0.0 and NaN.
16254
16255 (define_insn "*avx_ieee_smin<mode>3"
16256   [(set (match_operand:MODEF 0 "register_operand" "=x")
16257         (unspec:MODEF
16258           [(match_operand:MODEF 1 "register_operand" "x")
16259            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16260          UNSPEC_IEEE_MIN))]
16261   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16262   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16263   [(set_attr "type" "sseadd")
16264    (set_attr "prefix" "vex")
16265    (set_attr "mode" "<MODE>")])
16266
16267 (define_insn "*ieee_smin<mode>3"
16268   [(set (match_operand:MODEF 0 "register_operand" "=x")
16269         (unspec:MODEF
16270           [(match_operand:MODEF 1 "register_operand" "0")
16271            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16272          UNSPEC_IEEE_MIN))]
16273   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16274   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16275   [(set_attr "type" "sseadd")
16276    (set_attr "mode" "<MODE>")])
16277
16278 (define_insn "*avx_ieee_smax<mode>3"
16279   [(set (match_operand:MODEF 0 "register_operand" "=x")
16280         (unspec:MODEF
16281           [(match_operand:MODEF 1 "register_operand" "0")
16282            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16283          UNSPEC_IEEE_MAX))]
16284   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16285   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16286   [(set_attr "type" "sseadd")
16287    (set_attr "prefix" "vex")
16288    (set_attr "mode" "<MODE>")])
16289
16290 (define_insn "*ieee_smax<mode>3"
16291   [(set (match_operand:MODEF 0 "register_operand" "=x")
16292         (unspec:MODEF
16293           [(match_operand:MODEF 1 "register_operand" "0")
16294            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16295          UNSPEC_IEEE_MAX))]
16296   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16297   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16298   [(set_attr "type" "sseadd")
16299    (set_attr "mode" "<MODE>")])
16300
16301 ;; Make two stack loads independent:
16302 ;;   fld aa              fld aa
16303 ;;   fld %st(0)     ->   fld bb
16304 ;;   fmul bb             fmul %st(1), %st
16305 ;;
16306 ;; Actually we only match the last two instructions for simplicity.
16307 (define_peephole2
16308   [(set (match_operand 0 "fp_register_operand" "")
16309         (match_operand 1 "fp_register_operand" ""))
16310    (set (match_dup 0)
16311         (match_operator 2 "binary_fp_operator"
16312            [(match_dup 0)
16313             (match_operand 3 "memory_operand" "")]))]
16314   "REGNO (operands[0]) != REGNO (operands[1])"
16315   [(set (match_dup 0) (match_dup 3))
16316    (set (match_dup 0) (match_dup 4))]
16317
16318   ;; The % modifier is not operational anymore in peephole2's, so we have to
16319   ;; swap the operands manually in the case of addition and multiplication.
16320   "if (COMMUTATIVE_ARITH_P (operands[2]))
16321      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16322                                    GET_MODE (operands[2]),
16323                                    operands[0], operands[1]);
16324    else
16325      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16326                                    GET_MODE (operands[2]),
16327                                    operands[1], operands[0]);")
16328
16329 ;; Conditional addition patterns
16330 (define_expand "add<mode>cc"
16331   [(match_operand:SWI 0 "register_operand" "")
16332    (match_operand 1 "ordered_comparison_operator" "")
16333    (match_operand:SWI 2 "register_operand" "")
16334    (match_operand:SWI 3 "const_int_operand" "")]
16335   ""
16336   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16337 \f
16338 ;; Misc patterns (?)
16339
16340 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16341 ;; Otherwise there will be nothing to keep
16342 ;;
16343 ;; [(set (reg ebp) (reg esp))]
16344 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16345 ;;  (clobber (eflags)]
16346 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16347 ;;
16348 ;; in proper program order.
16349
16350 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16351   [(set (match_operand:P 0 "register_operand" "=r,r")
16352         (plus:P (match_operand:P 1 "register_operand" "0,r")
16353                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16354    (clobber (reg:CC FLAGS_REG))
16355    (clobber (mem:BLK (scratch)))]
16356   ""
16357 {
16358   switch (get_attr_type (insn))
16359     {
16360     case TYPE_IMOV:
16361       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16362
16363     case TYPE_ALU:
16364       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16365       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16366         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16367
16368       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16369
16370     default:
16371       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16372       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16373     }
16374 }
16375   [(set (attr "type")
16376         (cond [(and (eq_attr "alternative" "0")
16377                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16378                  (const_string "alu")
16379                (match_operand:<MODE> 2 "const0_operand" "")
16380                  (const_string "imov")
16381               ]
16382               (const_string "lea")))
16383    (set (attr "length_immediate")
16384         (cond [(eq_attr "type" "imov")
16385                  (const_string "0")
16386                (and (eq_attr "type" "alu")
16387                     (match_operand 2 "const128_operand" ""))
16388                  (const_string "1")
16389               ]
16390               (const_string "*")))
16391    (set_attr "mode" "<MODE>")])
16392
16393 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16394   [(set (match_operand:P 0 "register_operand" "=r")
16395         (minus:P (match_operand:P 1 "register_operand" "0")
16396                  (match_operand:P 2 "register_operand" "r")))
16397    (clobber (reg:CC FLAGS_REG))
16398    (clobber (mem:BLK (scratch)))]
16399   ""
16400   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16401   [(set_attr "type" "alu")
16402    (set_attr "mode" "<MODE>")])
16403
16404 (define_insn "allocate_stack_worker_probe_<mode>"
16405   [(set (match_operand:P 0 "register_operand" "=a")
16406         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16407                             UNSPECV_STACK_PROBE))
16408    (clobber (reg:CC FLAGS_REG))]
16409   "ix86_target_stack_probe ()"
16410   "call\t___chkstk_ms"
16411   [(set_attr "type" "multi")
16412    (set_attr "length" "5")])
16413
16414 (define_expand "allocate_stack"
16415   [(match_operand 0 "register_operand" "")
16416    (match_operand 1 "general_operand" "")]
16417   "ix86_target_stack_probe ()"
16418 {
16419   rtx x;
16420
16421 #ifndef CHECK_STACK_LIMIT
16422 #define CHECK_STACK_LIMIT 0
16423 #endif
16424
16425   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16426       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16427     {
16428       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16429                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16430       if (x != stack_pointer_rtx)
16431         emit_move_insn (stack_pointer_rtx, x);
16432     }
16433   else
16434     {
16435       x = copy_to_mode_reg (Pmode, operands[1]);
16436       if (TARGET_64BIT)
16437         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16438       else
16439         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16440       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16441                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16442       if (x != stack_pointer_rtx)
16443         emit_move_insn (stack_pointer_rtx, x);
16444     }
16445
16446   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16447   DONE;
16448 })
16449
16450 ;; Use IOR for stack probes, this is shorter.
16451 (define_expand "probe_stack"
16452   [(match_operand 0 "memory_operand" "")]
16453   ""
16454 {
16455   rtx (*gen_ior3) (rtx, rtx, rtx);
16456
16457   gen_ior3 = (GET_MODE (operands[0]) == DImode
16458               ? gen_iordi3 : gen_iorsi3);
16459
16460   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16461   DONE;
16462 })
16463
16464 (define_insn "adjust_stack_and_probe<mode>"
16465   [(set (match_operand:P 0 "register_operand" "=r")
16466         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16467                             UNSPECV_PROBE_STACK_RANGE))
16468    (set (reg:P SP_REG)
16469         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16470    (clobber (reg:CC FLAGS_REG))
16471    (clobber (mem:BLK (scratch)))]
16472   ""
16473   "* return output_adjust_stack_and_probe (operands[0]);"
16474   [(set_attr "type" "multi")])
16475
16476 (define_insn "probe_stack_range<mode>"
16477   [(set (match_operand:P 0 "register_operand" "=r")
16478         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16479                             (match_operand:P 2 "const_int_operand" "n")]
16480                             UNSPECV_PROBE_STACK_RANGE))
16481    (clobber (reg:CC FLAGS_REG))]
16482   ""
16483   "* return output_probe_stack_range (operands[0], operands[2]);"
16484   [(set_attr "type" "multi")])
16485
16486 (define_expand "builtin_setjmp_receiver"
16487   [(label_ref (match_operand 0 "" ""))]
16488   "!TARGET_64BIT && flag_pic"
16489 {
16490 #if TARGET_MACHO
16491   if (TARGET_MACHO)
16492     {
16493       rtx xops[3];
16494       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16495       rtx label_rtx = gen_label_rtx ();
16496       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16497       xops[0] = xops[1] = picreg;
16498       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16499       ix86_expand_binary_operator (MINUS, SImode, xops);
16500     }
16501   else
16502 #endif
16503     emit_insn (gen_set_got (pic_offset_table_rtx));
16504   DONE;
16505 })
16506 \f
16507 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16508
16509 (define_split
16510   [(set (match_operand 0 "register_operand" "")
16511         (match_operator 3 "promotable_binary_operator"
16512            [(match_operand 1 "register_operand" "")
16513             (match_operand 2 "aligned_operand" "")]))
16514    (clobber (reg:CC FLAGS_REG))]
16515   "! TARGET_PARTIAL_REG_STALL && reload_completed
16516    && ((GET_MODE (operands[0]) == HImode
16517         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16518             /* ??? next two lines just !satisfies_constraint_K (...) */
16519             || !CONST_INT_P (operands[2])
16520             || satisfies_constraint_K (operands[2])))
16521        || (GET_MODE (operands[0]) == QImode
16522            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16523   [(parallel [(set (match_dup 0)
16524                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16525               (clobber (reg:CC FLAGS_REG))])]
16526   "operands[0] = gen_lowpart (SImode, operands[0]);
16527    operands[1] = gen_lowpart (SImode, operands[1]);
16528    if (GET_CODE (operands[3]) != ASHIFT)
16529      operands[2] = gen_lowpart (SImode, operands[2]);
16530    PUT_MODE (operands[3], SImode);")
16531
16532 ; Promote the QImode tests, as i386 has encoding of the AND
16533 ; instruction with 32-bit sign-extended immediate and thus the
16534 ; instruction size is unchanged, except in the %eax case for
16535 ; which it is increased by one byte, hence the ! optimize_size.
16536 (define_split
16537   [(set (match_operand 0 "flags_reg_operand" "")
16538         (match_operator 2 "compare_operator"
16539           [(and (match_operand 3 "aligned_operand" "")
16540                 (match_operand 4 "const_int_operand" ""))
16541            (const_int 0)]))
16542    (set (match_operand 1 "register_operand" "")
16543         (and (match_dup 3) (match_dup 4)))]
16544   "! TARGET_PARTIAL_REG_STALL && reload_completed
16545    && optimize_insn_for_speed_p ()
16546    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16547        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16548    /* Ensure that the operand will remain sign-extended immediate.  */
16549    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16550   [(parallel [(set (match_dup 0)
16551                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16552                                     (const_int 0)]))
16553               (set (match_dup 1)
16554                    (and:SI (match_dup 3) (match_dup 4)))])]
16555 {
16556   operands[4]
16557     = gen_int_mode (INTVAL (operands[4])
16558                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16559   operands[1] = gen_lowpart (SImode, operands[1]);
16560   operands[3] = gen_lowpart (SImode, operands[3]);
16561 })
16562
16563 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16564 ; the TEST instruction with 32-bit sign-extended immediate and thus
16565 ; the instruction size would at least double, which is not what we
16566 ; want even with ! optimize_size.
16567 (define_split
16568   [(set (match_operand 0 "flags_reg_operand" "")
16569         (match_operator 1 "compare_operator"
16570           [(and (match_operand:HI 2 "aligned_operand" "")
16571                 (match_operand:HI 3 "const_int_operand" ""))
16572            (const_int 0)]))]
16573   "! TARGET_PARTIAL_REG_STALL && reload_completed
16574    && ! TARGET_FAST_PREFIX
16575    && optimize_insn_for_speed_p ()
16576    /* Ensure that the operand will remain sign-extended immediate.  */
16577    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16578   [(set (match_dup 0)
16579         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16580                          (const_int 0)]))]
16581 {
16582   operands[3]
16583     = gen_int_mode (INTVAL (operands[3])
16584                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16585   operands[2] = gen_lowpart (SImode, operands[2]);
16586 })
16587
16588 (define_split
16589   [(set (match_operand 0 "register_operand" "")
16590         (neg (match_operand 1 "register_operand" "")))
16591    (clobber (reg:CC FLAGS_REG))]
16592   "! TARGET_PARTIAL_REG_STALL && reload_completed
16593    && (GET_MODE (operands[0]) == HImode
16594        || (GET_MODE (operands[0]) == QImode
16595            && (TARGET_PROMOTE_QImode
16596                || optimize_insn_for_size_p ())))"
16597   [(parallel [(set (match_dup 0)
16598                    (neg:SI (match_dup 1)))
16599               (clobber (reg:CC FLAGS_REG))])]
16600   "operands[0] = gen_lowpart (SImode, operands[0]);
16601    operands[1] = gen_lowpart (SImode, operands[1]);")
16602
16603 (define_split
16604   [(set (match_operand 0 "register_operand" "")
16605         (not (match_operand 1 "register_operand" "")))]
16606   "! TARGET_PARTIAL_REG_STALL && reload_completed
16607    && (GET_MODE (operands[0]) == HImode
16608        || (GET_MODE (operands[0]) == QImode
16609            && (TARGET_PROMOTE_QImode
16610                || optimize_insn_for_size_p ())))"
16611   [(set (match_dup 0)
16612         (not:SI (match_dup 1)))]
16613   "operands[0] = gen_lowpart (SImode, operands[0]);
16614    operands[1] = gen_lowpart (SImode, operands[1]);")
16615
16616 (define_split
16617   [(set (match_operand 0 "register_operand" "")
16618         (if_then_else (match_operator 1 "ordered_comparison_operator"
16619                                 [(reg FLAGS_REG) (const_int 0)])
16620                       (match_operand 2 "register_operand" "")
16621                       (match_operand 3 "register_operand" "")))]
16622   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16623    && (GET_MODE (operands[0]) == HImode
16624        || (GET_MODE (operands[0]) == QImode
16625            && (TARGET_PROMOTE_QImode
16626                || optimize_insn_for_size_p ())))"
16627   [(set (match_dup 0)
16628         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16629   "operands[0] = gen_lowpart (SImode, operands[0]);
16630    operands[2] = gen_lowpart (SImode, operands[2]);
16631    operands[3] = gen_lowpart (SImode, operands[3]);")
16632 \f
16633 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16634 ;; transform a complex memory operation into two memory to register operations.
16635
16636 ;; Don't push memory operands
16637 (define_peephole2
16638   [(set (match_operand:SWI 0 "push_operand" "")
16639         (match_operand:SWI 1 "memory_operand" ""))
16640    (match_scratch:SWI 2 "<r>")]
16641   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16642    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16643   [(set (match_dup 2) (match_dup 1))
16644    (set (match_dup 0) (match_dup 2))])
16645
16646 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16647 ;; SImode pushes.
16648 (define_peephole2
16649   [(set (match_operand:SF 0 "push_operand" "")
16650         (match_operand:SF 1 "memory_operand" ""))
16651    (match_scratch:SF 2 "r")]
16652   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16653    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16654   [(set (match_dup 2) (match_dup 1))
16655    (set (match_dup 0) (match_dup 2))])
16656
16657 ;; Don't move an immediate directly to memory when the instruction
16658 ;; gets too big.
16659 (define_peephole2
16660   [(match_scratch:SWI124 1 "<r>")
16661    (set (match_operand:SWI124 0 "memory_operand" "")
16662         (const_int 0))]
16663   "optimize_insn_for_speed_p ()
16664    && !TARGET_USE_MOV0
16665    && TARGET_SPLIT_LONG_MOVES
16666    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16667    && peep2_regno_dead_p (0, FLAGS_REG)"
16668   [(parallel [(set (match_dup 2) (const_int 0))
16669               (clobber (reg:CC FLAGS_REG))])
16670    (set (match_dup 0) (match_dup 1))]
16671   "operands[2] = gen_lowpart (SImode, operands[1]);")
16672
16673 (define_peephole2
16674   [(match_scratch:SWI124 2 "<r>")
16675    (set (match_operand:SWI124 0 "memory_operand" "")
16676         (match_operand:SWI124 1 "immediate_operand" ""))]
16677   "optimize_insn_for_speed_p ()
16678    && TARGET_SPLIT_LONG_MOVES
16679    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16680   [(set (match_dup 2) (match_dup 1))
16681    (set (match_dup 0) (match_dup 2))])
16682
16683 ;; Don't compare memory with zero, load and use a test instead.
16684 (define_peephole2
16685   [(set (match_operand 0 "flags_reg_operand" "")
16686         (match_operator 1 "compare_operator"
16687           [(match_operand:SI 2 "memory_operand" "")
16688            (const_int 0)]))
16689    (match_scratch:SI 3 "r")]
16690   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16691   [(set (match_dup 3) (match_dup 2))
16692    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16693
16694 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16695 ;; Don't split NOTs with a displacement operand, because resulting XOR
16696 ;; will not be pairable anyway.
16697 ;;
16698 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16699 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16700 ;; so this split helps here as well.
16701 ;;
16702 ;; Note: Can't do this as a regular split because we can't get proper
16703 ;; lifetime information then.
16704
16705 (define_peephole2
16706   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16707         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16708   "optimize_insn_for_speed_p ()
16709    && ((TARGET_NOT_UNPAIRABLE
16710         && (!MEM_P (operands[0])
16711             || !memory_displacement_operand (operands[0], <MODE>mode)))
16712        || (TARGET_NOT_VECTORMODE
16713            && long_memory_operand (operands[0], <MODE>mode)))
16714    && peep2_regno_dead_p (0, FLAGS_REG)"
16715   [(parallel [(set (match_dup 0)
16716                    (xor:SWI124 (match_dup 1) (const_int -1)))
16717               (clobber (reg:CC FLAGS_REG))])])
16718
16719 ;; Non pairable "test imm, reg" instructions can be translated to
16720 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16721 ;; byte opcode instead of two, have a short form for byte operands),
16722 ;; so do it for other CPUs as well.  Given that the value was dead,
16723 ;; this should not create any new dependencies.  Pass on the sub-word
16724 ;; versions if we're concerned about partial register stalls.
16725
16726 (define_peephole2
16727   [(set (match_operand 0 "flags_reg_operand" "")
16728         (match_operator 1 "compare_operator"
16729           [(and:SI (match_operand:SI 2 "register_operand" "")
16730                    (match_operand:SI 3 "immediate_operand" ""))
16731            (const_int 0)]))]
16732   "ix86_match_ccmode (insn, CCNOmode)
16733    && (true_regnum (operands[2]) != AX_REG
16734        || satisfies_constraint_K (operands[3]))
16735    && peep2_reg_dead_p (1, operands[2])"
16736   [(parallel
16737      [(set (match_dup 0)
16738            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16739                             (const_int 0)]))
16740       (set (match_dup 2)
16741            (and:SI (match_dup 2) (match_dup 3)))])])
16742
16743 ;; We don't need to handle HImode case, because it will be promoted to SImode
16744 ;; on ! TARGET_PARTIAL_REG_STALL
16745
16746 (define_peephole2
16747   [(set (match_operand 0 "flags_reg_operand" "")
16748         (match_operator 1 "compare_operator"
16749           [(and:QI (match_operand:QI 2 "register_operand" "")
16750                    (match_operand:QI 3 "immediate_operand" ""))
16751            (const_int 0)]))]
16752   "! TARGET_PARTIAL_REG_STALL
16753    && ix86_match_ccmode (insn, CCNOmode)
16754    && true_regnum (operands[2]) != AX_REG
16755    && peep2_reg_dead_p (1, operands[2])"
16756   [(parallel
16757      [(set (match_dup 0)
16758            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16759                             (const_int 0)]))
16760       (set (match_dup 2)
16761            (and:QI (match_dup 2) (match_dup 3)))])])
16762
16763 (define_peephole2
16764   [(set (match_operand 0 "flags_reg_operand" "")
16765         (match_operator 1 "compare_operator"
16766           [(and:SI
16767              (zero_extract:SI
16768                (match_operand 2 "ext_register_operand" "")
16769                (const_int 8)
16770                (const_int 8))
16771              (match_operand 3 "const_int_operand" ""))
16772            (const_int 0)]))]
16773   "! TARGET_PARTIAL_REG_STALL
16774    && ix86_match_ccmode (insn, CCNOmode)
16775    && true_regnum (operands[2]) != AX_REG
16776    && peep2_reg_dead_p (1, operands[2])"
16777   [(parallel [(set (match_dup 0)
16778                    (match_op_dup 1
16779                      [(and:SI
16780                         (zero_extract:SI
16781                           (match_dup 2)
16782                           (const_int 8)
16783                           (const_int 8))
16784                         (match_dup 3))
16785                       (const_int 0)]))
16786               (set (zero_extract:SI (match_dup 2)
16787                                     (const_int 8)
16788                                     (const_int 8))
16789                    (and:SI
16790                      (zero_extract:SI
16791                        (match_dup 2)
16792                        (const_int 8)
16793                        (const_int 8))
16794                      (match_dup 3)))])])
16795
16796 ;; Don't do logical operations with memory inputs.
16797 (define_peephole2
16798   [(match_scratch:SI 2 "r")
16799    (parallel [(set (match_operand:SI 0 "register_operand" "")
16800                    (match_operator:SI 3 "arith_or_logical_operator"
16801                      [(match_dup 0)
16802                       (match_operand:SI 1 "memory_operand" "")]))
16803               (clobber (reg:CC FLAGS_REG))])]
16804   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16805   [(set (match_dup 2) (match_dup 1))
16806    (parallel [(set (match_dup 0)
16807                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16808               (clobber (reg:CC FLAGS_REG))])])
16809
16810 (define_peephole2
16811   [(match_scratch:SI 2 "r")
16812    (parallel [(set (match_operand:SI 0 "register_operand" "")
16813                    (match_operator:SI 3 "arith_or_logical_operator"
16814                      [(match_operand:SI 1 "memory_operand" "")
16815                       (match_dup 0)]))
16816               (clobber (reg:CC FLAGS_REG))])]
16817   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16818   [(set (match_dup 2) (match_dup 1))
16819    (parallel [(set (match_dup 0)
16820                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16821               (clobber (reg:CC FLAGS_REG))])])
16822
16823 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16824 ;; refers to the destination of the load!
16825
16826 (define_peephole2
16827   [(set (match_operand:SI 0 "register_operand" "")
16828         (match_operand:SI 1 "register_operand" ""))
16829    (parallel [(set (match_dup 0)
16830                    (match_operator:SI 3 "commutative_operator"
16831                      [(match_dup 0)
16832                       (match_operand:SI 2 "memory_operand" "")]))
16833               (clobber (reg:CC FLAGS_REG))])]
16834   "REGNO (operands[0]) != REGNO (operands[1])
16835    && GENERAL_REGNO_P (REGNO (operands[0]))
16836    && GENERAL_REGNO_P (REGNO (operands[1]))"
16837   [(set (match_dup 0) (match_dup 4))
16838    (parallel [(set (match_dup 0)
16839                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16840               (clobber (reg:CC FLAGS_REG))])]
16841   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16842
16843 (define_peephole2
16844   [(set (match_operand 0 "register_operand" "")
16845         (match_operand 1 "register_operand" ""))
16846    (set (match_dup 0)
16847                    (match_operator 3 "commutative_operator"
16848                      [(match_dup 0)
16849                       (match_operand 2 "memory_operand" "")]))]
16850   "REGNO (operands[0]) != REGNO (operands[1])
16851    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16852        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16853   [(set (match_dup 0) (match_dup 2))
16854    (set (match_dup 0)
16855         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16856
16857 ; Don't do logical operations with memory outputs
16858 ;
16859 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16860 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16861 ; the same decoder scheduling characteristics as the original.
16862
16863 (define_peephole2
16864   [(match_scratch:SI 2 "r")
16865    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16866                    (match_operator:SI 3 "arith_or_logical_operator"
16867                      [(match_dup 0)
16868                       (match_operand:SI 1 "nonmemory_operand" "")]))
16869               (clobber (reg:CC FLAGS_REG))])]
16870   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16871    /* Do not split stack checking probes.  */
16872    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16873   [(set (match_dup 2) (match_dup 0))
16874    (parallel [(set (match_dup 2)
16875                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16876               (clobber (reg:CC FLAGS_REG))])
16877    (set (match_dup 0) (match_dup 2))])
16878
16879 (define_peephole2
16880   [(match_scratch:SI 2 "r")
16881    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16882                    (match_operator:SI 3 "arith_or_logical_operator"
16883                      [(match_operand:SI 1 "nonmemory_operand" "")
16884                       (match_dup 0)]))
16885               (clobber (reg:CC FLAGS_REG))])]
16886   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16887    /* Do not split stack checking probes.  */
16888    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16889   [(set (match_dup 2) (match_dup 0))
16890    (parallel [(set (match_dup 2)
16891                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16892               (clobber (reg:CC FLAGS_REG))])
16893    (set (match_dup 0) (match_dup 2))])
16894
16895 ;; Attempt to always use XOR for zeroing registers.
16896 (define_peephole2
16897   [(set (match_operand 0 "register_operand" "")
16898         (match_operand 1 "const0_operand" ""))]
16899   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16900    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16901    && GENERAL_REG_P (operands[0])
16902    && peep2_regno_dead_p (0, FLAGS_REG)"
16903   [(parallel [(set (match_dup 0) (const_int 0))
16904               (clobber (reg:CC FLAGS_REG))])]
16905   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16906
16907 (define_peephole2
16908   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16909         (const_int 0))]
16910   "(GET_MODE (operands[0]) == QImode
16911     || GET_MODE (operands[0]) == HImode)
16912    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16913    && peep2_regno_dead_p (0, FLAGS_REG)"
16914   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16915               (clobber (reg:CC FLAGS_REG))])])
16916
16917 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16918 (define_peephole2
16919   [(set (match_operand:SWI248 0 "register_operand" "")
16920         (const_int -1))]
16921   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16922    && peep2_regno_dead_p (0, FLAGS_REG)"
16923   [(parallel [(set (match_dup 0) (const_int -1))
16924               (clobber (reg:CC FLAGS_REG))])]
16925 {
16926   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16927     operands[0] = gen_lowpart (SImode, operands[0]);
16928 })
16929
16930 ;; Attempt to convert simple lea to add/shift.
16931 ;; These can be created by move expanders.
16932
16933 (define_peephole2
16934   [(set (match_operand:SWI48 0 "register_operand" "")
16935         (plus:SWI48 (match_dup 0)
16936                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16937   "peep2_regno_dead_p (0, FLAGS_REG)"
16938   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16939               (clobber (reg:CC FLAGS_REG))])])
16940
16941 (define_peephole2
16942   [(set (match_operand:SI 0 "register_operand" "")
16943         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16944                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16945   "TARGET_64BIT
16946    && peep2_regno_dead_p (0, FLAGS_REG)
16947    && REGNO (operands[0]) == REGNO (operands[1])"
16948   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16949               (clobber (reg:CC FLAGS_REG))])]
16950   "operands[2] = gen_lowpart (SImode, operands[2]);")
16951
16952 (define_peephole2
16953   [(set (match_operand:SWI48 0 "register_operand" "")
16954         (mult:SWI48 (match_dup 0)
16955                     (match_operand:SWI48 1 "const_int_operand" "")))]
16956   "exact_log2 (INTVAL (operands[1])) >= 0
16957    && peep2_regno_dead_p (0, FLAGS_REG)"
16958   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16959               (clobber (reg:CC FLAGS_REG))])]
16960   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16961
16962 (define_peephole2
16963   [(set (match_operand:SI 0 "register_operand" "")
16964         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16965                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16966   "TARGET_64BIT
16967    && exact_log2 (INTVAL (operands[2])) >= 0
16968    && REGNO (operands[0]) == REGNO (operands[1])
16969    && peep2_regno_dead_p (0, FLAGS_REG)"
16970   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16971               (clobber (reg:CC FLAGS_REG))])]
16972   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16973
16974 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16975 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16976 ;; On many CPUs it is also faster, since special hardware to avoid esp
16977 ;; dependencies is present.
16978
16979 ;; While some of these conversions may be done using splitters, we use
16980 ;; peepholes in order to allow combine_stack_adjustments pass to see
16981 ;; nonobfuscated RTL.
16982
16983 ;; Convert prologue esp subtractions to push.
16984 ;; We need register to push.  In order to keep verify_flow_info happy we have
16985 ;; two choices
16986 ;; - use scratch and clobber it in order to avoid dependencies
16987 ;; - use already live register
16988 ;; We can't use the second way right now, since there is no reliable way how to
16989 ;; verify that given register is live.  First choice will also most likely in
16990 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16991 ;; call clobbered registers are dead.  We may want to use base pointer as an
16992 ;; alternative when no register is available later.
16993
16994 (define_peephole2
16995   [(match_scratch:P 1 "r")
16996    (parallel [(set (reg:P SP_REG)
16997                    (plus:P (reg:P SP_REG)
16998                            (match_operand:P 0 "const_int_operand" "")))
16999               (clobber (reg:CC FLAGS_REG))
17000               (clobber (mem:BLK (scratch)))])]
17001   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17002    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17003   [(clobber (match_dup 1))
17004    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17005               (clobber (mem:BLK (scratch)))])])
17006
17007 (define_peephole2
17008   [(match_scratch:P 1 "r")
17009    (parallel [(set (reg:P SP_REG)
17010                    (plus:P (reg:P SP_REG)
17011                            (match_operand:P 0 "const_int_operand" "")))
17012               (clobber (reg:CC FLAGS_REG))
17013               (clobber (mem:BLK (scratch)))])]
17014   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17015    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17016   [(clobber (match_dup 1))
17017    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17018    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17019               (clobber (mem:BLK (scratch)))])])
17020
17021 ;; Convert esp subtractions to push.
17022 (define_peephole2
17023   [(match_scratch:P 1 "r")
17024    (parallel [(set (reg:P SP_REG)
17025                    (plus:P (reg:P SP_REG)
17026                            (match_operand:P 0 "const_int_operand" "")))
17027               (clobber (reg:CC FLAGS_REG))])]
17028   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17029    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17030   [(clobber (match_dup 1))
17031    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17032
17033 (define_peephole2
17034   [(match_scratch:P 1 "r")
17035    (parallel [(set (reg:P SP_REG)
17036                    (plus:P (reg:P SP_REG)
17037                            (match_operand:P 0 "const_int_operand" "")))
17038               (clobber (reg:CC FLAGS_REG))])]
17039   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17040    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17041   [(clobber (match_dup 1))
17042    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17043    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17044
17045 ;; Convert epilogue deallocator to pop.
17046 (define_peephole2
17047   [(match_scratch:P 1 "r")
17048    (parallel [(set (reg:P SP_REG)
17049                    (plus:P (reg:P SP_REG)
17050                            (match_operand:P 0 "const_int_operand" "")))
17051               (clobber (reg:CC FLAGS_REG))
17052               (clobber (mem:BLK (scratch)))])]
17053   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17054    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17055   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17056               (clobber (mem:BLK (scratch)))])])
17057
17058 ;; Two pops case is tricky, since pop causes dependency
17059 ;; on destination register.  We use two registers if available.
17060 (define_peephole2
17061   [(match_scratch:P 1 "r")
17062    (match_scratch:P 2 "r")
17063    (parallel [(set (reg:P SP_REG)
17064                    (plus:P (reg:P SP_REG)
17065                            (match_operand:P 0 "const_int_operand" "")))
17066               (clobber (reg:CC FLAGS_REG))
17067               (clobber (mem:BLK (scratch)))])]
17068   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17069    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17070   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17071               (clobber (mem:BLK (scratch)))])
17072    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17073
17074 (define_peephole2
17075   [(match_scratch:P 1 "r")
17076    (parallel [(set (reg:P SP_REG)
17077                    (plus:P (reg:P SP_REG)
17078                            (match_operand:P 0 "const_int_operand" "")))
17079               (clobber (reg:CC FLAGS_REG))
17080               (clobber (mem:BLK (scratch)))])]
17081   "optimize_insn_for_size_p ()
17082    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17083   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17084               (clobber (mem:BLK (scratch)))])
17085    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17086
17087 ;; Convert esp additions to pop.
17088 (define_peephole2
17089   [(match_scratch:P 1 "r")
17090    (parallel [(set (reg:P SP_REG)
17091                    (plus:P (reg:P SP_REG)
17092                            (match_operand:P 0 "const_int_operand" "")))
17093               (clobber (reg:CC FLAGS_REG))])]
17094   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17095   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17096
17097 ;; Two pops case is tricky, since pop causes dependency
17098 ;; on destination register.  We use two registers if available.
17099 (define_peephole2
17100   [(match_scratch:P 1 "r")
17101    (match_scratch:P 2 "r")
17102    (parallel [(set (reg:P SP_REG)
17103                    (plus:P (reg:P SP_REG)
17104                            (match_operand:P 0 "const_int_operand" "")))
17105               (clobber (reg:CC FLAGS_REG))])]
17106   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17107   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17108    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17109
17110 (define_peephole2
17111   [(match_scratch:P 1 "r")
17112    (parallel [(set (reg:P SP_REG)
17113                    (plus:P (reg:P SP_REG)
17114                            (match_operand:P 0 "const_int_operand" "")))
17115               (clobber (reg:CC FLAGS_REG))])]
17116   "optimize_insn_for_size_p ()
17117    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17118   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17119    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17120 \f
17121 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17122 ;; required and register dies.  Similarly for 128 to -128.
17123 (define_peephole2
17124   [(set (match_operand 0 "flags_reg_operand" "")
17125         (match_operator 1 "compare_operator"
17126           [(match_operand 2 "register_operand" "")
17127            (match_operand 3 "const_int_operand" "")]))]
17128   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17129      && incdec_operand (operands[3], GET_MODE (operands[3])))
17130     || (!TARGET_FUSE_CMP_AND_BRANCH
17131         && INTVAL (operands[3]) == 128))
17132    && ix86_match_ccmode (insn, CCGCmode)
17133    && peep2_reg_dead_p (1, operands[2])"
17134   [(parallel [(set (match_dup 0)
17135                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17136               (clobber (match_dup 2))])])
17137 \f
17138 ;; Convert imul by three, five and nine into lea
17139 (define_peephole2
17140   [(parallel
17141     [(set (match_operand:SWI48 0 "register_operand" "")
17142           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17143                       (match_operand:SWI48 2 "const_int_operand" "")))
17144      (clobber (reg:CC FLAGS_REG))])]
17145   "INTVAL (operands[2]) == 3
17146    || INTVAL (operands[2]) == 5
17147    || INTVAL (operands[2]) == 9"
17148   [(set (match_dup 0)
17149         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17150                     (match_dup 1)))]
17151   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17152
17153 (define_peephole2
17154   [(parallel
17155     [(set (match_operand:SWI48 0 "register_operand" "")
17156           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17157                       (match_operand:SWI48 2 "const_int_operand" "")))
17158      (clobber (reg:CC FLAGS_REG))])]
17159   "optimize_insn_for_speed_p ()
17160    && (INTVAL (operands[2]) == 3
17161        || INTVAL (operands[2]) == 5
17162        || INTVAL (operands[2]) == 9)"
17163   [(set (match_dup 0) (match_dup 1))
17164    (set (match_dup 0)
17165         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17166                     (match_dup 0)))]
17167   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17168
17169 ;; imul $32bit_imm, mem, reg is vector decoded, while
17170 ;; imul $32bit_imm, reg, reg is direct decoded.
17171 (define_peephole2
17172   [(match_scratch:SWI48 3 "r")
17173    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17174                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17175                                (match_operand:SWI48 2 "immediate_operand" "")))
17176               (clobber (reg:CC FLAGS_REG))])]
17177   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17178    && !satisfies_constraint_K (operands[2])"
17179   [(set (match_dup 3) (match_dup 1))
17180    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17181               (clobber (reg:CC FLAGS_REG))])])
17182
17183 (define_peephole2
17184   [(match_scratch:SI 3 "r")
17185    (parallel [(set (match_operand:DI 0 "register_operand" "")
17186                    (zero_extend:DI
17187                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17188                               (match_operand:SI 2 "immediate_operand" ""))))
17189               (clobber (reg:CC FLAGS_REG))])]
17190   "TARGET_64BIT
17191    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17192    && !satisfies_constraint_K (operands[2])"
17193   [(set (match_dup 3) (match_dup 1))
17194    (parallel [(set (match_dup 0)
17195                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17196               (clobber (reg:CC FLAGS_REG))])])
17197
17198 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17199 ;; Convert it into imul reg, reg
17200 ;; It would be better to force assembler to encode instruction using long
17201 ;; immediate, but there is apparently no way to do so.
17202 (define_peephole2
17203   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17204                    (mult:SWI248
17205                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17206                     (match_operand:SWI248 2 "const_int_operand" "")))
17207               (clobber (reg:CC FLAGS_REG))])
17208    (match_scratch:SWI248 3 "r")]
17209   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17210    && satisfies_constraint_K (operands[2])"
17211   [(set (match_dup 3) (match_dup 2))
17212    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17213               (clobber (reg:CC FLAGS_REG))])]
17214 {
17215   if (!rtx_equal_p (operands[0], operands[1]))
17216     emit_move_insn (operands[0], operands[1]);
17217 })
17218
17219 ;; After splitting up read-modify operations, array accesses with memory
17220 ;; operands might end up in form:
17221 ;;  sall    $2, %eax
17222 ;;  movl    4(%esp), %edx
17223 ;;  addl    %edx, %eax
17224 ;; instead of pre-splitting:
17225 ;;  sall    $2, %eax
17226 ;;  addl    4(%esp), %eax
17227 ;; Turn it into:
17228 ;;  movl    4(%esp), %edx
17229 ;;  leal    (%edx,%eax,4), %eax
17230
17231 (define_peephole2
17232   [(match_scratch:P 5 "r")
17233    (parallel [(set (match_operand 0 "register_operand" "")
17234                    (ashift (match_operand 1 "register_operand" "")
17235                            (match_operand 2 "const_int_operand" "")))
17236                (clobber (reg:CC FLAGS_REG))])
17237    (parallel [(set (match_operand 3 "register_operand" "")
17238                    (plus (match_dup 0)
17239                          (match_operand 4 "x86_64_general_operand" "")))
17240                    (clobber (reg:CC FLAGS_REG))])]
17241   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17242    /* Validate MODE for lea.  */
17243    && ((!TARGET_PARTIAL_REG_STALL
17244         && (GET_MODE (operands[0]) == QImode
17245             || GET_MODE (operands[0]) == HImode))
17246        || GET_MODE (operands[0]) == SImode
17247        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17248    && (rtx_equal_p (operands[0], operands[3])
17249        || peep2_reg_dead_p (2, operands[0]))
17250    /* We reorder load and the shift.  */
17251    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17252   [(set (match_dup 5) (match_dup 4))
17253    (set (match_dup 0) (match_dup 1))]
17254 {
17255   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17256   int scale = 1 << INTVAL (operands[2]);
17257   rtx index = gen_lowpart (Pmode, operands[1]);
17258   rtx base = gen_lowpart (Pmode, operands[5]);
17259   rtx dest = gen_lowpart (mode, operands[3]);
17260
17261   operands[1] = gen_rtx_PLUS (Pmode, base,
17262                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17263   operands[5] = base;
17264   if (mode != Pmode)
17265     {
17266       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17267       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17268     }
17269   operands[0] = dest;
17270 })
17271 \f
17272 ;; Call-value patterns last so that the wildcard operand does not
17273 ;; disrupt insn-recog's switch tables.
17274
17275 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17276   [(parallel
17277     [(set (match_operand 0 "" "")
17278           (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17279                 (match_operand:SI 2 "" "")))
17280      (set (reg:SI SP_REG)
17281           (plus:SI (reg:SI SP_REG)
17282                    (match_operand:SI 3 "immediate_operand" "")))])
17283    (unspec [(match_operand 4 "const_int_operand" "")]
17284            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17285   "TARGET_VZEROUPPER && !TARGET_64BIT"
17286   "#"
17287   "&& reload_completed"
17288   [(const_int 0)]
17289   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17290   [(set_attr "type" "callv")])
17291
17292 (define_insn "*call_value_pop_0"
17293   [(set (match_operand 0 "" "")
17294         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17295               (match_operand:SI 2 "" "")))
17296    (set (reg:SI SP_REG)
17297         (plus:SI (reg:SI SP_REG)
17298                  (match_operand:SI 3 "immediate_operand" "")))]
17299   "!TARGET_64BIT"
17300   { return ix86_output_call_insn (insn, operands[1], 1); }
17301   [(set_attr "type" "callv")])
17302
17303 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17304   [(parallel
17305     [(set (match_operand 0 "" "")
17306           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17307                 (match_operand:SI 2 "" "")))
17308      (set (reg:SI SP_REG)
17309           (plus:SI (reg:SI SP_REG)
17310                    (match_operand:SI 3 "immediate_operand" "i")))])
17311    (unspec [(match_operand 4 "const_int_operand" "")]
17312            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17313   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17314   "#"
17315   "&& reload_completed"
17316   [(const_int 0)]
17317   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17318   [(set_attr "type" "callv")])
17319
17320 (define_insn "*call_value_pop_1"
17321   [(set (match_operand 0 "" "")
17322         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17323               (match_operand:SI 2 "" "")))
17324    (set (reg:SI SP_REG)
17325         (plus:SI (reg:SI SP_REG)
17326                  (match_operand:SI 3 "immediate_operand" "i")))]
17327   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17328   { return ix86_output_call_insn (insn, operands[1], 1); }
17329   [(set_attr "type" "callv")])
17330
17331 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17332  [(parallel
17333    [(set (match_operand 0 "" "")
17334           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17335                 (match_operand:SI 2 "" "")))
17336      (set (reg:SI SP_REG)
17337           (plus:SI (reg:SI SP_REG)
17338                    (match_operand:SI 3 "immediate_operand" "i,i")))])
17339    (unspec [(match_operand 4 "const_int_operand" "")]
17340            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17341   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17342   "#"
17343   "&& reload_completed"
17344   [(const_int 0)]
17345   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17346   [(set_attr "type" "callv")])
17347
17348 (define_insn "*sibcall_value_pop_1"
17349   [(set (match_operand 0 "" "")
17350         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17351               (match_operand:SI 2 "" "")))
17352    (set (reg:SI SP_REG)
17353         (plus:SI (reg:SI SP_REG)
17354                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17355   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17356   { return ix86_output_call_insn (insn, operands[1], 1); }
17357   [(set_attr "type" "callv")])
17358
17359 (define_insn_and_split "*call_value_0_vzeroupper"
17360   [(set (match_operand 0 "" "")
17361         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17362               (match_operand:SI 2 "" "")))
17363    (unspec [(match_operand 3 "const_int_operand" "")]
17364            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17365   "TARGET_VZEROUPPER && !TARGET_64BIT"
17366   "#"
17367   "&& reload_completed"
17368   [(const_int 0)]
17369   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17370   [(set_attr "type" "callv")])
17371
17372 (define_insn "*call_value_0"
17373   [(set (match_operand 0 "" "")
17374         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17375               (match_operand:SI 2 "" "")))]
17376   "!TARGET_64BIT"
17377   { return ix86_output_call_insn (insn, operands[1], 1); }
17378   [(set_attr "type" "callv")])
17379
17380 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17381   [(set (match_operand 0 "" "")
17382         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17383               (match_operand:DI 2 "const_int_operand" "")))
17384    (unspec [(match_operand 3 "const_int_operand" "")]
17385            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17386   "TARGET_VZEROUPPER && TARGET_64BIT"
17387   "#"
17388   "&& reload_completed"
17389   [(const_int 0)]
17390   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17391   [(set_attr "type" "callv")])
17392
17393 (define_insn "*call_value_0_rex64"
17394   [(set (match_operand 0 "" "")
17395         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17396               (match_operand:DI 2 "const_int_operand" "")))]
17397   "TARGET_64BIT"
17398   { return ix86_output_call_insn (insn, operands[1], 1); }
17399   [(set_attr "type" "callv")])
17400
17401 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17402   [(parallel
17403     [(set (match_operand 0 "" "")
17404           (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17405                 (match_operand:DI 2 "const_int_operand" "")))
17406      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17407      (clobber (reg:TI XMM6_REG))
17408      (clobber (reg:TI XMM7_REG))
17409      (clobber (reg:TI XMM8_REG))
17410      (clobber (reg:TI XMM9_REG))
17411      (clobber (reg:TI XMM10_REG))
17412      (clobber (reg:TI XMM11_REG))
17413      (clobber (reg:TI XMM12_REG))
17414      (clobber (reg:TI XMM13_REG))
17415      (clobber (reg:TI XMM14_REG))
17416      (clobber (reg:TI XMM15_REG))
17417      (clobber (reg:DI SI_REG))
17418      (clobber (reg:DI DI_REG))])
17419    (unspec [(match_operand 3 "const_int_operand" "")]
17420            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17421   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17422   "#"
17423   "&& reload_completed"
17424   [(const_int 0)]
17425   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17426   [(set_attr "type" "callv")])
17427
17428 (define_insn "*call_value_0_rex64_ms_sysv"
17429   [(set (match_operand 0 "" "")
17430         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17431               (match_operand:DI 2 "const_int_operand" "")))
17432    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17433    (clobber (reg:TI XMM6_REG))
17434    (clobber (reg:TI XMM7_REG))
17435    (clobber (reg:TI XMM8_REG))
17436    (clobber (reg:TI XMM9_REG))
17437    (clobber (reg:TI XMM10_REG))
17438    (clobber (reg:TI XMM11_REG))
17439    (clobber (reg:TI XMM12_REG))
17440    (clobber (reg:TI XMM13_REG))
17441    (clobber (reg:TI XMM14_REG))
17442    (clobber (reg:TI XMM15_REG))
17443    (clobber (reg:DI SI_REG))
17444    (clobber (reg:DI DI_REG))]
17445   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17446   { return ix86_output_call_insn (insn, operands[1], 1); }
17447   [(set_attr "type" "callv")])
17448
17449 (define_insn_and_split "*call_value_1_vzeroupper"
17450   [(set (match_operand 0 "" "")
17451         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17452               (match_operand:SI 2 "" "")))
17453    (unspec [(match_operand 3 "const_int_operand" "")]
17454            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17455   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17456   "#"
17457   "&& reload_completed"
17458   [(const_int 0)]
17459   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17460   [(set_attr "type" "callv")])
17461
17462 (define_insn "*call_value_1"
17463   [(set (match_operand 0 "" "")
17464         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17465               (match_operand:SI 2 "" "")))]
17466   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17467   { return ix86_output_call_insn (insn, operands[1], 1); }
17468   [(set_attr "type" "callv")])
17469
17470 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17471   [(set (match_operand 0 "" "")
17472         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17473               (match_operand:SI 2 "" "")))
17474    (unspec [(match_operand 3 "const_int_operand" "")]
17475            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17476   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17477   "#"
17478   "&& reload_completed"
17479   [(const_int 0)]
17480   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17481   [(set_attr "type" "callv")])
17482
17483 (define_insn "*sibcall_value_1"
17484   [(set (match_operand 0 "" "")
17485         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17486               (match_operand:SI 2 "" "")))]
17487   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17488   { return ix86_output_call_insn (insn, operands[1], 1); }
17489   [(set_attr "type" "callv")])
17490
17491 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17492   [(set (match_operand 0 "" "")
17493         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17494               (match_operand:DI 2 "" "")))
17495    (unspec [(match_operand 3 "const_int_operand" "")]
17496            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17497   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17498    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17499   "#"
17500   "&& reload_completed"
17501   [(const_int 0)]
17502   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17503   [(set_attr "type" "callv")])
17504
17505 (define_insn "*call_value_1_rex64"
17506   [(set (match_operand 0 "" "")
17507         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17508               (match_operand:DI 2 "" "")))]
17509   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17510    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17511   { return ix86_output_call_insn (insn, operands[1], 1); }
17512   [(set_attr "type" "callv")])
17513
17514 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17515   [(parallel
17516     [(set (match_operand 0 "" "")
17517           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17518                 (match_operand:DI 2 "" "")))
17519      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17520      (clobber (reg:TI XMM6_REG))
17521      (clobber (reg:TI XMM7_REG))
17522      (clobber (reg:TI XMM8_REG))
17523      (clobber (reg:TI XMM9_REG))
17524      (clobber (reg:TI XMM10_REG))
17525      (clobber (reg:TI XMM11_REG))
17526      (clobber (reg:TI XMM12_REG))
17527      (clobber (reg:TI XMM13_REG))
17528      (clobber (reg:TI XMM14_REG))
17529      (clobber (reg:TI XMM15_REG))
17530      (clobber (reg:DI SI_REG))
17531      (clobber (reg:DI DI_REG))])
17532    (unspec [(match_operand 3 "const_int_operand" "")]
17533            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17534   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17535   "#"
17536   "&& reload_completed"
17537   [(const_int 0)]
17538   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17539   [(set_attr "type" "callv")])
17540
17541 (define_insn "*call_value_1_rex64_ms_sysv"
17542   [(set (match_operand 0 "" "")
17543         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17544               (match_operand:DI 2 "" "")))
17545    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17546    (clobber (reg:TI XMM6_REG))
17547    (clobber (reg:TI XMM7_REG))
17548    (clobber (reg:TI XMM8_REG))
17549    (clobber (reg:TI XMM9_REG))
17550    (clobber (reg:TI XMM10_REG))
17551    (clobber (reg:TI XMM11_REG))
17552    (clobber (reg:TI XMM12_REG))
17553    (clobber (reg:TI XMM13_REG))
17554    (clobber (reg:TI XMM14_REG))
17555    (clobber (reg:TI XMM15_REG))
17556    (clobber (reg:DI SI_REG))
17557    (clobber (reg:DI DI_REG))]
17558   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17559   { return ix86_output_call_insn (insn, operands[1], 1); }
17560   [(set_attr "type" "callv")])
17561
17562 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17563   [(set (match_operand 0 "" "")
17564         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17565               (match_operand:DI 2 "" "")))
17566    (unspec [(match_operand 3 "const_int_operand" "")]
17567            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17568   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17569   "#"
17570   "&& reload_completed"
17571   [(const_int 0)]
17572   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17573   [(set_attr "type" "callv")])
17574
17575 (define_insn "*call_value_1_rex64_large"
17576   [(set (match_operand 0 "" "")
17577         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17578               (match_operand:DI 2 "" "")))]
17579   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17580   { return ix86_output_call_insn (insn, operands[1], 1); }
17581   [(set_attr "type" "callv")])
17582
17583 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17584   [(set (match_operand 0 "" "")
17585         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17586               (match_operand:DI 2 "" "")))
17587    (unspec [(match_operand 3 "const_int_operand" "")]
17588            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17589   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17590   "#"
17591   "&& reload_completed"
17592   [(const_int 0)]
17593   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17594   [(set_attr "type" "callv")])
17595
17596 (define_insn "*sibcall_value_1_rex64"
17597   [(set (match_operand 0 "" "")
17598         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17599               (match_operand:DI 2 "" "")))]
17600   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17601   { return ix86_output_call_insn (insn, operands[1], 1); }
17602   [(set_attr "type" "callv")])
17603 \f
17604 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17605 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17606 ;; caught for use by garbage collectors and the like.  Using an insn that
17607 ;; maps to SIGILL makes it more likely the program will rightfully die.
17608 ;; Keeping with tradition, "6" is in honor of #UD.
17609 (define_insn "trap"
17610   [(trap_if (const_int 1) (const_int 6))]
17611   ""
17612   { return ASM_SHORT "0x0b0f"; }
17613   [(set_attr "length" "2")])
17614
17615 (define_expand "prefetch"
17616   [(prefetch (match_operand 0 "address_operand" "")
17617              (match_operand:SI 1 "const_int_operand" "")
17618              (match_operand:SI 2 "const_int_operand" ""))]
17619   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17620 {
17621   int rw = INTVAL (operands[1]);
17622   int locality = INTVAL (operands[2]);
17623
17624   gcc_assert (rw == 0 || rw == 1);
17625   gcc_assert (locality >= 0 && locality <= 3);
17626   gcc_assert (GET_MODE (operands[0]) == Pmode
17627               || GET_MODE (operands[0]) == VOIDmode);
17628
17629   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17630      supported by SSE counterpart or the SSE prefetch is not available
17631      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17632      of locality.  */
17633   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17634     operands[2] = GEN_INT (3);
17635   else
17636     operands[1] = const0_rtx;
17637 })
17638
17639 (define_insn "*prefetch_sse_<mode>"
17640   [(prefetch (match_operand:P 0 "address_operand" "p")
17641              (const_int 0)
17642              (match_operand:SI 1 "const_int_operand" ""))]
17643   "TARGET_PREFETCH_SSE"
17644 {
17645   static const char * const patterns[4] = {
17646    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17647   };
17648
17649   int locality = INTVAL (operands[1]);
17650   gcc_assert (locality >= 0 && locality <= 3);
17651
17652   return patterns[locality];
17653 }
17654   [(set_attr "type" "sse")
17655    (set_attr "atom_sse_attr" "prefetch")
17656    (set (attr "length_address")
17657         (symbol_ref "memory_address_length (operands[0])"))
17658    (set_attr "memory" "none")])
17659
17660 (define_insn "*prefetch_3dnow_<mode>"
17661   [(prefetch (match_operand:P 0 "address_operand" "p")
17662              (match_operand:SI 1 "const_int_operand" "n")
17663              (const_int 3))]
17664   "TARGET_3DNOW"
17665 {
17666   if (INTVAL (operands[1]) == 0)
17667     return "prefetch\t%a0";
17668   else
17669     return "prefetchw\t%a0";
17670 }
17671   [(set_attr "type" "mmx")
17672    (set (attr "length_address")
17673         (symbol_ref "memory_address_length (operands[0])"))
17674    (set_attr "memory" "none")])
17675
17676 (define_expand "stack_protect_set"
17677   [(match_operand 0 "memory_operand" "")
17678    (match_operand 1 "memory_operand" "")]
17679   ""
17680 {
17681   rtx (*insn)(rtx, rtx);
17682
17683 #ifdef TARGET_THREAD_SSP_OFFSET
17684   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17685   insn = (TARGET_64BIT
17686           ? gen_stack_tls_protect_set_di
17687           : gen_stack_tls_protect_set_si);
17688 #else
17689   insn = (TARGET_64BIT
17690           ? gen_stack_protect_set_di
17691           : gen_stack_protect_set_si);
17692 #endif
17693
17694   emit_insn (insn (operands[0], operands[1]));
17695   DONE;
17696 })
17697
17698 (define_insn "stack_protect_set_<mode>"
17699   [(set (match_operand:P 0 "memory_operand" "=m")
17700         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17701    (set (match_scratch:P 2 "=&r") (const_int 0))
17702    (clobber (reg:CC FLAGS_REG))]
17703   ""
17704   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17705   [(set_attr "type" "multi")])
17706
17707 (define_insn "stack_tls_protect_set_<mode>"
17708   [(set (match_operand:P 0 "memory_operand" "=m")
17709         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17710                   UNSPEC_SP_TLS_SET))
17711    (set (match_scratch:P 2 "=&r") (const_int 0))
17712    (clobber (reg:CC FLAGS_REG))]
17713   ""
17714   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17715   [(set_attr "type" "multi")])
17716
17717 (define_expand "stack_protect_test"
17718   [(match_operand 0 "memory_operand" "")
17719    (match_operand 1 "memory_operand" "")
17720    (match_operand 2 "" "")]
17721   ""
17722 {
17723   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17724
17725   rtx (*insn)(rtx, rtx, rtx);
17726
17727 #ifdef TARGET_THREAD_SSP_OFFSET
17728   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17729   insn = (TARGET_64BIT
17730           ? gen_stack_tls_protect_test_di
17731           : gen_stack_tls_protect_test_si);
17732 #else
17733   insn = (TARGET_64BIT
17734           ? gen_stack_protect_test_di
17735           : gen_stack_protect_test_si);
17736 #endif
17737
17738   emit_insn (insn (flags, operands[0], operands[1]));
17739
17740   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17741                                   flags, const0_rtx, operands[2]));
17742   DONE;
17743 })
17744
17745 (define_insn "stack_protect_test_<mode>"
17746   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17747         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17748                      (match_operand:P 2 "memory_operand" "m")]
17749                     UNSPEC_SP_TEST))
17750    (clobber (match_scratch:P 3 "=&r"))]
17751   ""
17752   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17753   [(set_attr "type" "multi")])
17754
17755 (define_insn "stack_tls_protect_test_<mode>"
17756   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17757         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17758                      (match_operand:P 2 "const_int_operand" "i")]
17759                     UNSPEC_SP_TLS_TEST))
17760    (clobber (match_scratch:P 3 "=r"))]
17761   ""
17762   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17763   [(set_attr "type" "multi")])
17764
17765 (define_insn "sse4_2_crc32<mode>"
17766   [(set (match_operand:SI 0 "register_operand" "=r")
17767         (unspec:SI
17768           [(match_operand:SI 1 "register_operand" "0")
17769            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17770           UNSPEC_CRC32))]
17771   "TARGET_SSE4_2 || TARGET_CRC32"
17772   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17773   [(set_attr "type" "sselog1")
17774    (set_attr "prefix_rep" "1")
17775    (set_attr "prefix_extra" "1")
17776    (set (attr "prefix_data16")
17777      (if_then_else (match_operand:HI 2 "" "")
17778        (const_string "1")
17779        (const_string "*")))
17780    (set (attr "prefix_rex")
17781      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17782        (const_string "1")
17783        (const_string "*")))
17784    (set_attr "mode" "SI")])
17785
17786 (define_insn "sse4_2_crc32di"
17787   [(set (match_operand:DI 0 "register_operand" "=r")
17788         (unspec:DI
17789           [(match_operand:DI 1 "register_operand" "0")
17790            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17791           UNSPEC_CRC32))]
17792   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17793   "crc32{q}\t{%2, %0|%0, %2}"
17794   [(set_attr "type" "sselog1")
17795    (set_attr "prefix_rep" "1")
17796    (set_attr "prefix_extra" "1")
17797    (set_attr "mode" "DI")])
17798
17799 (define_expand "rdpmc"
17800   [(match_operand:DI 0 "register_operand" "")
17801    (match_operand:SI 1 "register_operand" "")]
17802   ""
17803 {
17804   rtx reg = gen_reg_rtx (DImode);
17805   rtx si;
17806
17807   /* Force operand 1 into ECX.  */
17808   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17809   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17810   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17811                                 UNSPECV_RDPMC);
17812
17813   if (TARGET_64BIT)
17814     {
17815       rtvec vec = rtvec_alloc (2);
17816       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17817       rtx upper = gen_reg_rtx (DImode);
17818       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17819                                         gen_rtvec (1, const0_rtx),
17820                                         UNSPECV_RDPMC);
17821       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17822       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17823       emit_insn (load);
17824       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17825                                    NULL, 1, OPTAB_DIRECT);
17826       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17827                                  OPTAB_DIRECT);
17828     }
17829   else
17830     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17831   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17832   DONE;
17833 })
17834
17835 (define_insn "*rdpmc"
17836   [(set (match_operand:DI 0 "register_operand" "=A")
17837         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17838                             UNSPECV_RDPMC))]
17839   "!TARGET_64BIT"
17840   "rdpmc"
17841   [(set_attr "type" "other")
17842    (set_attr "length" "2")])
17843
17844 (define_insn "*rdpmc_rex64"
17845   [(set (match_operand:DI 0 "register_operand" "=a")
17846         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17847                             UNSPECV_RDPMC))
17848   (set (match_operand:DI 1 "register_operand" "=d")
17849        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17850   "TARGET_64BIT"
17851   "rdpmc"
17852   [(set_attr "type" "other")
17853    (set_attr "length" "2")])
17854
17855 (define_expand "rdtsc"
17856   [(set (match_operand:DI 0 "register_operand" "")
17857         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17858   ""
17859 {
17860   if (TARGET_64BIT)
17861     {
17862       rtvec vec = rtvec_alloc (2);
17863       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17864       rtx upper = gen_reg_rtx (DImode);
17865       rtx lower = gen_reg_rtx (DImode);
17866       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17867                                          gen_rtvec (1, const0_rtx),
17868                                          UNSPECV_RDTSC);
17869       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17870       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17871       emit_insn (load);
17872       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17873                                    NULL, 1, OPTAB_DIRECT);
17874       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17875                                    OPTAB_DIRECT);
17876       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17877       DONE;
17878     }
17879 })
17880
17881 (define_insn "*rdtsc"
17882   [(set (match_operand:DI 0 "register_operand" "=A")
17883         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17884   "!TARGET_64BIT"
17885   "rdtsc"
17886   [(set_attr "type" "other")
17887    (set_attr "length" "2")])
17888
17889 (define_insn "*rdtsc_rex64"
17890   [(set (match_operand:DI 0 "register_operand" "=a")
17891         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17892    (set (match_operand:DI 1 "register_operand" "=d")
17893         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17894   "TARGET_64BIT"
17895   "rdtsc"
17896   [(set_attr "type" "other")
17897    (set_attr "length" "2")])
17898
17899 (define_expand "rdtscp"
17900   [(match_operand:DI 0 "register_operand" "")
17901    (match_operand:SI 1 "memory_operand" "")]
17902   ""
17903 {
17904   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17905                                     gen_rtvec (1, const0_rtx),
17906                                     UNSPECV_RDTSCP);
17907   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17908                                     gen_rtvec (1, const0_rtx),
17909                                     UNSPECV_RDTSCP);
17910   rtx reg = gen_reg_rtx (DImode);
17911   rtx tmp = gen_reg_rtx (SImode);
17912
17913   if (TARGET_64BIT)
17914     {
17915       rtvec vec = rtvec_alloc (3);
17916       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17917       rtx upper = gen_reg_rtx (DImode);
17918       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17919       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17920       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17921       emit_insn (load);
17922       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17923                                    NULL, 1, OPTAB_DIRECT);
17924       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17925                                  OPTAB_DIRECT);
17926     }
17927   else
17928     {
17929       rtvec vec = rtvec_alloc (2);
17930       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17931       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17932       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17933       emit_insn (load);
17934     }
17935   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17936   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17937   DONE;
17938 })
17939
17940 (define_insn "*rdtscp"
17941   [(set (match_operand:DI 0 "register_operand" "=A")
17942         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17943    (set (match_operand:SI 1 "register_operand" "=c")
17944         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17945   "!TARGET_64BIT"
17946   "rdtscp"
17947   [(set_attr "type" "other")
17948    (set_attr "length" "3")])
17949
17950 (define_insn "*rdtscp_rex64"
17951   [(set (match_operand:DI 0 "register_operand" "=a")
17952         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17953    (set (match_operand:DI 1 "register_operand" "=d")
17954         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17955    (set (match_operand:SI 2 "register_operand" "=c")
17956         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17957   "TARGET_64BIT"
17958   "rdtscp"
17959   [(set_attr "type" "other")
17960    (set_attr "length" "3")])
17961
17962 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17963 ;;
17964 ;; LWP instructions
17965 ;;
17966 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17967
17968 (define_expand "lwp_llwpcb"
17969   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17970                     UNSPECV_LLWP_INTRINSIC)]
17971   "TARGET_LWP")
17972
17973 (define_insn "*lwp_llwpcb<mode>1"
17974   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17975                     UNSPECV_LLWP_INTRINSIC)]
17976   "TARGET_LWP"
17977   "llwpcb\t%0"
17978   [(set_attr "type" "lwp")
17979    (set_attr "mode" "<MODE>")
17980    (set_attr "length" "5")])
17981
17982 (define_expand "lwp_slwpcb"
17983   [(set (match_operand 0 "register_operand" "=r")
17984         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17985   "TARGET_LWP"
17986 {
17987   if (TARGET_64BIT)
17988     emit_insn (gen_lwp_slwpcbdi (operands[0]));
17989   else
17990     emit_insn (gen_lwp_slwpcbsi (operands[0]));
17991   DONE;
17992 })
17993
17994 (define_insn "lwp_slwpcb<mode>"
17995   [(set (match_operand:P 0 "register_operand" "=r")
17996         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17997   "TARGET_LWP"
17998   "slwpcb\t%0"
17999   [(set_attr "type" "lwp")
18000    (set_attr "mode" "<MODE>")
18001    (set_attr "length" "5")])
18002
18003 (define_expand "lwp_lwpval<mode>3"
18004   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18005                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18006                      (match_operand:SI 3 "const_int_operand" "i")]
18007                     UNSPECV_LWPVAL_INTRINSIC)]
18008   "TARGET_LWP"
18009   "/* Avoid unused variable warning.  */
18010    (void) operand0;")
18011
18012 (define_insn "*lwp_lwpval<mode>3_1"
18013   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18014                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18015                      (match_operand:SI 2 "const_int_operand" "i")]
18016                     UNSPECV_LWPVAL_INTRINSIC)]
18017   "TARGET_LWP"
18018   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18019   [(set_attr "type" "lwp")
18020    (set_attr "mode" "<MODE>")
18021    (set (attr "length")
18022         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18023
18024 (define_expand "lwp_lwpins<mode>3"
18025   [(set (reg:CCC FLAGS_REG)
18026         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18027                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18028                               (match_operand:SI 3 "const_int_operand" "i")]
18029                              UNSPECV_LWPINS_INTRINSIC))
18030    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18031         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18032   "TARGET_LWP")
18033
18034 (define_insn "*lwp_lwpins<mode>3_1"
18035   [(set (reg:CCC FLAGS_REG)
18036         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18037                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18038                               (match_operand:SI 2 "const_int_operand" "i")]
18039                              UNSPECV_LWPINS_INTRINSIC))]
18040   "TARGET_LWP"
18041   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18042   [(set_attr "type" "lwp")
18043    (set_attr "mode" "<MODE>")
18044    (set (attr "length")
18045         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18046
18047 (define_insn "rdfsbase<mode>"
18048   [(set (match_operand:SWI48 0 "register_operand" "=r")
18049         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18050   "TARGET_64BIT && TARGET_FSGSBASE"
18051   "rdfsbase %0"
18052   [(set_attr "type" "other")
18053    (set_attr "prefix_extra" "2")])
18054
18055 (define_insn "rdgsbase<mode>"
18056   [(set (match_operand:SWI48 0 "register_operand" "=r")
18057         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18058   "TARGET_64BIT && TARGET_FSGSBASE"
18059   "rdgsbase %0"
18060   [(set_attr "type" "other")
18061    (set_attr "prefix_extra" "2")])
18062
18063 (define_insn "wrfsbase<mode>"
18064   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18065                     UNSPECV_WRFSBASE)]
18066   "TARGET_64BIT && TARGET_FSGSBASE"
18067   "wrfsbase %0"
18068   [(set_attr "type" "other")
18069    (set_attr "prefix_extra" "2")])
18070
18071 (define_insn "wrgsbase<mode>"
18072   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18073                     UNSPECV_WRGSBASE)]
18074   "TARGET_64BIT && TARGET_FSGSBASE"
18075   "wrgsbase %0"
18076   [(set_attr "type" "other")
18077    (set_attr "prefix_extra" "2")])
18078
18079 (define_expand "rdrand<mode>"
18080   [(set (match_operand:SWI248 0 "register_operand" "=r")
18081         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18082   "TARGET_RDRND"
18083 {
18084   rtx retry_label, insn, ccc;
18085
18086   retry_label = gen_label_rtx ();
18087
18088   emit_label (retry_label);
18089
18090   /* Generate rdrand.  */
18091   emit_insn (gen_rdrand<mode>_1 (operands[0]));
18092
18093   /* Retry if the carry flag isn't valid.  */
18094   ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
18095   ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
18096   ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
18097                               gen_rtx_LABEL_REF (VOIDmode, retry_label));
18098   insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
18099   JUMP_LABEL (insn) = retry_label;
18100
18101   DONE;
18102 })
18103
18104 (define_insn "rdrand<mode>_1"
18105   [(set (match_operand:SWI248 0 "register_operand" "=r")
18106         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18107   "TARGET_RDRND"
18108   "rdrand %0"
18109   [(set_attr "type" "other")
18110    (set_attr "prefix_extra" "1")])
18111
18112 (include "mmx.md")
18113 (include "sse.md")
18114 (include "sync.md")