OSDN Git Service

Replace _rdrand_uXX with _rdrandXX_step.
[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   ;; For BMI support
234   UNSPEC_BEXTR
235
236   ;; For RDRAND support
237   UNSPEC_RDRAND
238 ])
239
240 (define_c_enum "unspecv" [
241   UNSPECV_BLOCKAGE
242   UNSPECV_STACK_PROBE
243   UNSPECV_PROBE_STACK_RANGE
244   UNSPECV_EMMS
245   UNSPECV_LDMXCSR
246   UNSPECV_STMXCSR
247   UNSPECV_FEMMS
248   UNSPECV_CLFLUSH
249   UNSPECV_ALIGN
250   UNSPECV_MONITOR
251   UNSPECV_MWAIT
252   UNSPECV_CMPXCHG
253   UNSPECV_XCHG
254   UNSPECV_LOCK
255   UNSPECV_PROLOGUE_USE
256   UNSPECV_CLD
257   UNSPECV_NOPS
258   UNSPECV_VZEROALL
259   UNSPECV_VZEROUPPER
260   UNSPECV_RDTSC
261   UNSPECV_RDTSCP
262   UNSPECV_RDPMC
263   UNSPECV_LLWP_INTRINSIC
264   UNSPECV_SLWP_INTRINSIC
265   UNSPECV_LWPVAL_INTRINSIC
266   UNSPECV_LWPINS_INTRINSIC
267   UNSPECV_RDFSBASE
268   UNSPECV_RDGSBASE
269   UNSPECV_WRFSBASE
270   UNSPECV_WRGSBASE
271   UNSPECV_SPLIT_STACK_RETURN
272 ])
273
274 ;; Constants to represent pcomtrue/pcomfalse variants
275 (define_constants
276   [(PCOM_FALSE                  0)
277    (PCOM_TRUE                   1)
278    (COM_FALSE_S                 2)
279    (COM_FALSE_P                 3)
280    (COM_TRUE_S                  4)
281    (COM_TRUE_P                  5)
282   ])
283
284 ;; Constants used in the XOP pperm instruction
285 (define_constants
286   [(PPERM_SRC                   0x00)   /* copy source */
287    (PPERM_INVERT                0x20)   /* invert source */
288    (PPERM_REVERSE               0x40)   /* bit reverse source */
289    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
290    (PPERM_ZERO                  0x80)   /* all 0's */
291    (PPERM_ONES                  0xa0)   /* all 1's */
292    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
293    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
294    (PPERM_SRC1                  0x00)   /* use first source byte */
295    (PPERM_SRC2                  0x10)   /* use second source byte */
296    ])
297
298 ;; Registers by name.
299 (define_constants
300   [(AX_REG                       0)
301    (DX_REG                       1)
302    (CX_REG                       2)
303    (BX_REG                       3)
304    (SI_REG                       4)
305    (DI_REG                       5)
306    (BP_REG                       6)
307    (SP_REG                       7)
308    (ST0_REG                      8)
309    (ST1_REG                      9)
310    (ST2_REG                     10)
311    (ST3_REG                     11)
312    (ST4_REG                     12)
313    (ST5_REG                     13)
314    (ST6_REG                     14)
315    (ST7_REG                     15)
316    (FLAGS_REG                   17)
317    (FPSR_REG                    18)
318    (FPCR_REG                    19)
319    (XMM0_REG                    21)
320    (XMM1_REG                    22)
321    (XMM2_REG                    23)
322    (XMM3_REG                    24)
323    (XMM4_REG                    25)
324    (XMM5_REG                    26)
325    (XMM6_REG                    27)
326    (XMM7_REG                    28)
327    (MM0_REG                     29)
328    (MM1_REG                     30)
329    (MM2_REG                     31)
330    (MM3_REG                     32)
331    (MM4_REG                     33)
332    (MM5_REG                     34)
333    (MM6_REG                     35)
334    (MM7_REG                     36)
335    (R8_REG                      37)
336    (R9_REG                      38)
337    (R10_REG                     39)
338    (R11_REG                     40)
339    (R12_REG                     41)
340    (R13_REG                     42)
341    (XMM8_REG                    45)
342    (XMM9_REG                    46)
343    (XMM10_REG                   47)
344    (XMM11_REG                   48)
345    (XMM12_REG                   49)
346    (XMM13_REG                   50)
347    (XMM14_REG                   51)
348    (XMM15_REG                   52)
349   ])
350
351 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
352 ;; from i386.c.
353
354 ;; In C guard expressions, put expressions which may be compile-time
355 ;; constants first.  This allows for better optimization.  For
356 ;; example, write "TARGET_64BIT && reload_completed", not
357 ;; "reload_completed && TARGET_64BIT".
358
359 \f
360 ;; Processor type.
361 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
362                     atom,generic64,amdfam10,bdver1"
363   (const (symbol_ref "ix86_schedule")))
364
365 ;; A basic instruction type.  Refinements due to arguments to be
366 ;; provided in other attributes.
367 (define_attr "type"
368   "other,multi,
369    alu,alu1,negnot,imov,imovx,lea,
370    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
371    icmp,test,ibr,setcc,icmov,
372    push,pop,call,callv,leave,
373    str,bitmanip,
374    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
375    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
376    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
377    ssemuladd,sse4arg,lwp,
378    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
379   (const_string "other"))
380
381 ;; Main data type used by the insn
382 (define_attr "mode"
383   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
384   (const_string "unknown"))
385
386 ;; The CPU unit operations uses.
387 (define_attr "unit" "integer,i387,sse,mmx,unknown"
388   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
389            (const_string "i387")
390          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
391                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
392                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
393            (const_string "sse")
394          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
395            (const_string "mmx")
396          (eq_attr "type" "other")
397            (const_string "unknown")]
398          (const_string "integer")))
399
400 ;; The (bounding maximum) length of an instruction immediate.
401 (define_attr "length_immediate" ""
402   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
403                           bitmanip")
404            (const_int 0)
405          (eq_attr "unit" "i387,sse,mmx")
406            (const_int 0)
407          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
408                           imul,icmp,push,pop")
409            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
410          (eq_attr "type" "imov,test")
411            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
412          (eq_attr "type" "call")
413            (if_then_else (match_operand 0 "constant_call_address_operand" "")
414              (const_int 4)
415              (const_int 0))
416          (eq_attr "type" "callv")
417            (if_then_else (match_operand 1 "constant_call_address_operand" "")
418              (const_int 4)
419              (const_int 0))
420          ;; We don't know the size before shorten_branches.  Expect
421          ;; the instruction to fit for better scheduling.
422          (eq_attr "type" "ibr")
423            (const_int 1)
424          ]
425          (symbol_ref "/* Update immediate_length and other attributes! */
426                       gcc_unreachable (),1")))
427
428 ;; The (bounding maximum) length of an instruction address.
429 (define_attr "length_address" ""
430   (cond [(eq_attr "type" "str,other,multi,fxch")
431            (const_int 0)
432          (and (eq_attr "type" "call")
433               (match_operand 0 "constant_call_address_operand" ""))
434              (const_int 0)
435          (and (eq_attr "type" "callv")
436               (match_operand 1 "constant_call_address_operand" ""))
437              (const_int 0)
438          ]
439          (symbol_ref "ix86_attr_length_address_default (insn)")))
440
441 ;; Set when length prefix is used.
442 (define_attr "prefix_data16" ""
443   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
444            (const_int 0)
445          (eq_attr "mode" "HI")
446            (const_int 1)
447          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
448            (const_int 1)
449         ]
450         (const_int 0)))
451
452 ;; Set when string REP prefix is used.
453 (define_attr "prefix_rep" ""
454   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
455            (const_int 0)
456          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
457            (const_int 1)
458         ]
459         (const_int 0)))
460
461 ;; Set when 0f opcode prefix is used.
462 (define_attr "prefix_0f" ""
463   (if_then_else
464     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
465          (eq_attr "unit" "sse,mmx"))
466     (const_int 1)
467     (const_int 0)))
468
469 ;; Set when REX opcode prefix is used.
470 (define_attr "prefix_rex" ""
471   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
472            (const_int 0)
473          (and (eq_attr "mode" "DI")
474               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
475                    (eq_attr "unit" "!mmx")))
476            (const_int 1)
477          (and (eq_attr "mode" "QI")
478               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
479                   (const_int 0)))
480            (const_int 1)
481          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
482              (const_int 0))
483            (const_int 1)
484          (and (eq_attr "type" "imovx")
485               (match_operand:QI 1 "ext_QIreg_operand" ""))
486            (const_int 1)
487         ]
488         (const_int 0)))
489
490 ;; There are also additional prefixes in 3DNOW, SSSE3.
491 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
492 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
493 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
494 (define_attr "prefix_extra" ""
495   (cond [(eq_attr "type" "ssemuladd,sse4arg")
496            (const_int 2)
497          (eq_attr "type" "sseiadd1,ssecvt1")
498            (const_int 1)
499         ]
500         (const_int 0)))
501
502 ;; Prefix used: original, VEX or maybe VEX.
503 (define_attr "prefix" "orig,vex,maybe_vex"
504   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
505     (const_string "vex")
506     (const_string "orig")))
507
508 ;; VEX W bit is used.
509 (define_attr "prefix_vex_w" "" (const_int 0))
510
511 ;; The length of VEX prefix
512 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
513 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
514 ;; still prefix_0f 1, with prefix_extra 1.
515 (define_attr "length_vex" ""
516   (if_then_else (and (eq_attr "prefix_0f" "1")
517                      (eq_attr "prefix_extra" "0"))
518     (if_then_else (eq_attr "prefix_vex_w" "1")
519       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
520       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
521     (if_then_else (eq_attr "prefix_vex_w" "1")
522       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
523       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
524
525 ;; Set when modrm byte is used.
526 (define_attr "modrm" ""
527   (cond [(eq_attr "type" "str,leave")
528            (const_int 0)
529          (eq_attr "unit" "i387")
530            (const_int 0)
531          (and (eq_attr "type" "incdec")
532               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
533                    (ior (match_operand:SI 1 "register_operand" "")
534                         (match_operand:HI 1 "register_operand" ""))))
535            (const_int 0)
536          (and (eq_attr "type" "push")
537               (not (match_operand 1 "memory_operand" "")))
538            (const_int 0)
539          (and (eq_attr "type" "pop")
540               (not (match_operand 0 "memory_operand" "")))
541            (const_int 0)
542          (and (eq_attr "type" "imov")
543               (and (not (eq_attr "mode" "DI"))
544                    (ior (and (match_operand 0 "register_operand" "")
545                              (match_operand 1 "immediate_operand" ""))
546                         (ior (and (match_operand 0 "ax_reg_operand" "")
547                                   (match_operand 1 "memory_displacement_only_operand" ""))
548                              (and (match_operand 0 "memory_displacement_only_operand" "")
549                                   (match_operand 1 "ax_reg_operand" ""))))))
550            (const_int 0)
551          (and (eq_attr "type" "call")
552               (match_operand 0 "constant_call_address_operand" ""))
553              (const_int 0)
554          (and (eq_attr "type" "callv")
555               (match_operand 1 "constant_call_address_operand" ""))
556              (const_int 0)
557          (and (eq_attr "type" "alu,alu1,icmp,test")
558               (match_operand 0 "ax_reg_operand" ""))
559              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
560          ]
561          (const_int 1)))
562
563 ;; The (bounding maximum) length of an instruction in bytes.
564 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
565 ;; Later we may want to split them and compute proper length as for
566 ;; other insns.
567 (define_attr "length" ""
568   (cond [(eq_attr "type" "other,multi,fistp,frndint")
569            (const_int 16)
570          (eq_attr "type" "fcmp")
571            (const_int 4)
572          (eq_attr "unit" "i387")
573            (plus (const_int 2)
574                  (plus (attr "prefix_data16")
575                        (attr "length_address")))
576          (ior (eq_attr "prefix" "vex")
577               (and (eq_attr "prefix" "maybe_vex")
578                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
579            (plus (attr "length_vex")
580                  (plus (attr "length_immediate")
581                        (plus (attr "modrm")
582                              (attr "length_address"))))]
583          (plus (plus (attr "modrm")
584                      (plus (attr "prefix_0f")
585                            (plus (attr "prefix_rex")
586                                  (plus (attr "prefix_extra")
587                                        (const_int 1)))))
588                (plus (attr "prefix_rep")
589                      (plus (attr "prefix_data16")
590                            (plus (attr "length_immediate")
591                                  (attr "length_address")))))))
592
593 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
594 ;; `store' if there is a simple memory reference therein, or `unknown'
595 ;; if the instruction is complex.
596
597 (define_attr "memory" "none,load,store,both,unknown"
598   (cond [(eq_attr "type" "other,multi,str,lwp")
599            (const_string "unknown")
600          (eq_attr "type" "lea,fcmov,fpspc")
601            (const_string "none")
602          (eq_attr "type" "fistp,leave")
603            (const_string "both")
604          (eq_attr "type" "frndint")
605            (const_string "load")
606          (eq_attr "type" "push")
607            (if_then_else (match_operand 1 "memory_operand" "")
608              (const_string "both")
609              (const_string "store"))
610          (eq_attr "type" "pop")
611            (if_then_else (match_operand 0 "memory_operand" "")
612              (const_string "both")
613              (const_string "load"))
614          (eq_attr "type" "setcc")
615            (if_then_else (match_operand 0 "memory_operand" "")
616              (const_string "store")
617              (const_string "none"))
618          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
619            (if_then_else (ior (match_operand 0 "memory_operand" "")
620                               (match_operand 1 "memory_operand" ""))
621              (const_string "load")
622              (const_string "none"))
623          (eq_attr "type" "ibr")
624            (if_then_else (match_operand 0 "memory_operand" "")
625              (const_string "load")
626              (const_string "none"))
627          (eq_attr "type" "call")
628            (if_then_else (match_operand 0 "constant_call_address_operand" "")
629              (const_string "none")
630              (const_string "load"))
631          (eq_attr "type" "callv")
632            (if_then_else (match_operand 1 "constant_call_address_operand" "")
633              (const_string "none")
634              (const_string "load"))
635          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
636               (match_operand 1 "memory_operand" ""))
637            (const_string "both")
638          (and (match_operand 0 "memory_operand" "")
639               (match_operand 1 "memory_operand" ""))
640            (const_string "both")
641          (match_operand 0 "memory_operand" "")
642            (const_string "store")
643          (match_operand 1 "memory_operand" "")
644            (const_string "load")
645          (and (eq_attr "type"
646                  "!alu1,negnot,ishift1,
647                    imov,imovx,icmp,test,bitmanip,
648                    fmov,fcmp,fsgn,
649                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
650                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
651               (match_operand 2 "memory_operand" ""))
652            (const_string "load")
653          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
654               (match_operand 3 "memory_operand" ""))
655            (const_string "load")
656         ]
657         (const_string "none")))
658
659 ;; Indicates if an instruction has both an immediate and a displacement.
660
661 (define_attr "imm_disp" "false,true,unknown"
662   (cond [(eq_attr "type" "other,multi")
663            (const_string "unknown")
664          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
665               (and (match_operand 0 "memory_displacement_operand" "")
666                    (match_operand 1 "immediate_operand" "")))
667            (const_string "true")
668          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
669               (and (match_operand 0 "memory_displacement_operand" "")
670                    (match_operand 2 "immediate_operand" "")))
671            (const_string "true")
672         ]
673         (const_string "false")))
674
675 ;; Indicates if an FP operation has an integer source.
676
677 (define_attr "fp_int_src" "false,true"
678   (const_string "false"))
679
680 ;; Defines rounding mode of an FP operation.
681
682 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
683   (const_string "any"))
684
685 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
686 (define_attr "use_carry" "0,1" (const_string "0"))
687
688 ;; Define attribute to indicate unaligned ssemov insns
689 (define_attr "movu" "0,1" (const_string "0"))
690
691 ;; Describe a user's asm statement.
692 (define_asm_attributes
693   [(set_attr "length" "128")
694    (set_attr "type" "multi")])
695
696 (define_code_iterator plusminus [plus minus])
697
698 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
699
700 ;; Base name for define_insn
701 (define_code_attr plusminus_insn
702   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
703    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
704
705 ;; Base name for insn mnemonic.
706 (define_code_attr plusminus_mnemonic
707   [(plus "add") (ss_plus "adds") (us_plus "addus")
708    (minus "sub") (ss_minus "subs") (us_minus "subus")])
709 (define_code_attr plusminus_carry_mnemonic
710   [(plus "adc") (minus "sbb")])
711
712 ;; Mark commutative operators as such in constraints.
713 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
714                         (minus "") (ss_minus "") (us_minus "")])
715
716 ;; Mapping of signed max and min
717 (define_code_iterator smaxmin [smax smin])
718
719 ;; Mapping of unsigned max and min
720 (define_code_iterator umaxmin [umax umin])
721
722 ;; Base name for integer and FP insn mnemonic
723 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
724                               (umax "maxu") (umin "minu")])
725 (define_code_attr maxmin_float [(smax "max") (smin "min")])
726
727 ;; Mapping of logic operators
728 (define_code_iterator any_logic [and ior xor])
729 (define_code_iterator any_or [ior xor])
730
731 ;; Base name for insn mnemonic.
732 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
733
734 ;; Mapping of shift-right operators
735 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
736
737 ;; Base name for define_insn
738 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
739
740 ;; Base name for insn mnemonic.
741 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
742
743 ;; Mapping of rotate operators
744 (define_code_iterator any_rotate [rotate rotatert])
745
746 ;; Base name for define_insn
747 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
748
749 ;; Base name for insn mnemonic.
750 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
751
752 ;; Mapping of abs neg operators
753 (define_code_iterator absneg [abs neg])
754
755 ;; Base name for x87 insn mnemonic.
756 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
757
758 ;; Used in signed and unsigned widening multiplications.
759 (define_code_iterator any_extend [sign_extend zero_extend])
760
761 ;; Various insn prefixes for signed and unsigned operations.
762 (define_code_attr u [(sign_extend "") (zero_extend "u")
763                      (div "") (udiv "u")])
764 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
765
766 ;; Used in signed and unsigned divisions.
767 (define_code_iterator any_div [div udiv])
768
769 ;; Instruction prefix for signed and unsigned operations.
770 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
771                              (div "i") (udiv "")])
772
773 ;; 64bit single word integer modes.
774 (define_mode_iterator SWI1248x [QI HI SI DI])
775
776 ;; 64bit single word integer modes without QImode and HImode.
777 (define_mode_iterator SWI48x [SI DI])
778
779 ;; Single word integer modes.
780 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
781
782 ;; Single word integer modes without SImode and DImode.
783 (define_mode_iterator SWI12 [QI HI])
784
785 ;; Single word integer modes without DImode.
786 (define_mode_iterator SWI124 [QI HI SI])
787
788 ;; Single word integer modes without QImode and DImode.
789 (define_mode_iterator SWI24 [HI SI])
790
791 ;; Single word integer modes without QImode.
792 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
793
794 ;; Single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
796
797 ;; All math-dependant single and double word integer modes.
798 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
799                              (HI "TARGET_HIMODE_MATH")
800                              SI DI (TI "TARGET_64BIT")])
801
802 ;; Math-dependant single word integer modes.
803 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
804                             (HI "TARGET_HIMODE_MATH")
805                             SI (DI "TARGET_64BIT")])
806
807 ;; Math-dependant single word integer modes without DImode.
808 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
809                                (HI "TARGET_HIMODE_MATH")
810                                SI])
811
812 ;; Math-dependant single word integer modes without QImode.
813 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
814                                SI (DI "TARGET_64BIT")])
815
816 ;; Double word integer modes.
817 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
818                            (TI "TARGET_64BIT")])
819
820 ;; Double word integer modes as mode attribute.
821 (define_mode_attr DWI [(SI "DI") (DI "TI")])
822 (define_mode_attr dwi [(SI "di") (DI "ti")])
823
824 ;; Half mode for double word integer modes.
825 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
826                             (DI "TARGET_64BIT")])
827
828 ;; Instruction suffix for integer modes.
829 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
830
831 ;; Pointer size prefix for integer modes (Intel asm dialect)
832 (define_mode_attr iptrsize [(QI "BYTE")
833                             (HI "WORD")
834                             (SI "DWORD")
835                             (DI "QWORD")])
836
837 ;; Register class for integer modes.
838 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
839
840 ;; Immediate operand constraint for integer modes.
841 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
842
843 ;; General operand constraint for word modes.
844 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
845
846 ;; Immediate operand constraint for double integer modes.
847 (define_mode_attr di [(SI "iF") (DI "e")])
848
849 ;; Immediate operand constraint for shifts.
850 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
851
852 ;; General operand predicate for integer modes.
853 (define_mode_attr general_operand
854         [(QI "general_operand")
855          (HI "general_operand")
856          (SI "general_operand")
857          (DI "x86_64_general_operand")
858          (TI "x86_64_general_operand")])
859
860 ;; General sign/zero extend operand predicate for integer modes.
861 (define_mode_attr general_szext_operand
862         [(QI "general_operand")
863          (HI "general_operand")
864          (SI "general_operand")
865          (DI "x86_64_szext_general_operand")])
866
867 ;; Immediate operand predicate for integer modes.
868 (define_mode_attr immediate_operand
869         [(QI "immediate_operand")
870          (HI "immediate_operand")
871          (SI "immediate_operand")
872          (DI "x86_64_immediate_operand")])
873
874 ;; Nonmemory operand predicate for integer modes.
875 (define_mode_attr nonmemory_operand
876         [(QI "nonmemory_operand")
877          (HI "nonmemory_operand")
878          (SI "nonmemory_operand")
879          (DI "x86_64_nonmemory_operand")])
880
881 ;; Operand predicate for shifts.
882 (define_mode_attr shift_operand
883         [(QI "nonimmediate_operand")
884          (HI "nonimmediate_operand")
885          (SI "nonimmediate_operand")
886          (DI "shiftdi_operand")
887          (TI "register_operand")])
888
889 ;; Operand predicate for shift argument.
890 (define_mode_attr shift_immediate_operand
891         [(QI "const_1_to_31_operand")
892          (HI "const_1_to_31_operand")
893          (SI "const_1_to_31_operand")
894          (DI "const_1_to_63_operand")])
895
896 ;; Input operand predicate for arithmetic left shifts.
897 (define_mode_attr ashl_input_operand
898         [(QI "nonimmediate_operand")
899          (HI "nonimmediate_operand")
900          (SI "nonimmediate_operand")
901          (DI "ashldi_input_operand")
902          (TI "reg_or_pm1_operand")])
903
904 ;; SSE and x87 SFmode and DFmode floating point modes
905 (define_mode_iterator MODEF [SF DF])
906
907 ;; All x87 floating point modes
908 (define_mode_iterator X87MODEF [SF DF XF])
909
910 ;; All integer modes handled by x87 fisttp operator.
911 (define_mode_iterator X87MODEI [HI SI DI])
912
913 ;; All integer modes handled by integer x87 operators.
914 (define_mode_iterator X87MODEI12 [HI SI])
915
916 ;; All integer modes handled by SSE cvtts?2si* operators.
917 (define_mode_iterator SSEMODEI24 [SI DI])
918
919 ;; SSE asm suffix for floating point modes
920 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
921
922 ;; SSE vector mode corresponding to a scalar mode
923 (define_mode_attr ssevecmode
924   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
925
926 ;; Instruction suffix for REX 64bit operators.
927 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
928
929 ;; This mode iterator allows :P to be used for patterns that operate on
930 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
931 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
932 \f
933 ;; Scheduling descriptions
934
935 (include "pentium.md")
936 (include "ppro.md")
937 (include "k6.md")
938 (include "athlon.md")
939 (include "bdver1.md")
940 (include "geode.md")
941 (include "atom.md")
942 (include "core2.md")
943
944 \f
945 ;; Operand and operator predicates and constraints
946
947 (include "predicates.md")
948 (include "constraints.md")
949
950 \f
951 ;; Compare and branch/compare and store instructions.
952
953 (define_expand "cbranch<mode>4"
954   [(set (reg:CC FLAGS_REG)
955         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
956                     (match_operand:SDWIM 2 "<general_operand>" "")))
957    (set (pc) (if_then_else
958                (match_operator 0 "ordered_comparison_operator"
959                 [(reg:CC FLAGS_REG) (const_int 0)])
960                (label_ref (match_operand 3 "" ""))
961                (pc)))]
962   ""
963 {
964   if (MEM_P (operands[1]) && MEM_P (operands[2]))
965     operands[1] = force_reg (<MODE>mode, operands[1]);
966   ix86_expand_branch (GET_CODE (operands[0]),
967                       operands[1], operands[2], operands[3]);
968   DONE;
969 })
970
971 (define_expand "cstore<mode>4"
972   [(set (reg:CC FLAGS_REG)
973         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
974                     (match_operand:SWIM 3 "<general_operand>" "")))
975    (set (match_operand:QI 0 "register_operand" "")
976         (match_operator 1 "ordered_comparison_operator"
977           [(reg:CC FLAGS_REG) (const_int 0)]))]
978   ""
979 {
980   if (MEM_P (operands[2]) && MEM_P (operands[3]))
981     operands[2] = force_reg (<MODE>mode, operands[2]);
982   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
983                      operands[2], operands[3]);
984   DONE;
985 })
986
987 (define_expand "cmp<mode>_1"
988   [(set (reg:CC FLAGS_REG)
989         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
990                     (match_operand:SWI48 1 "<general_operand>" "")))])
991
992 (define_insn "*cmp<mode>_ccno_1"
993   [(set (reg FLAGS_REG)
994         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
995                  (match_operand:SWI 1 "const0_operand" "")))]
996   "ix86_match_ccmode (insn, CCNOmode)"
997   "@
998    test{<imodesuffix>}\t%0, %0
999    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1000   [(set_attr "type" "test,icmp")
1001    (set_attr "length_immediate" "0,1")
1002    (set_attr "mode" "<MODE>")])
1003
1004 (define_insn "*cmp<mode>_1"
1005   [(set (reg FLAGS_REG)
1006         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1007                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1008   "ix86_match_ccmode (insn, CCmode)"
1009   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1010   [(set_attr "type" "icmp")
1011    (set_attr "mode" "<MODE>")])
1012
1013 (define_insn "*cmp<mode>_minus_1"
1014   [(set (reg FLAGS_REG)
1015         (compare
1016           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1017                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1018           (const_int 0)))]
1019   "ix86_match_ccmode (insn, CCGOCmode)"
1020   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1021   [(set_attr "type" "icmp")
1022    (set_attr "mode" "<MODE>")])
1023
1024 (define_insn "*cmpqi_ext_1"
1025   [(set (reg FLAGS_REG)
1026         (compare
1027           (match_operand:QI 0 "general_operand" "Qm")
1028           (subreg:QI
1029             (zero_extract:SI
1030               (match_operand 1 "ext_register_operand" "Q")
1031               (const_int 8)
1032               (const_int 8)) 0)))]
1033   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1034   "cmp{b}\t{%h1, %0|%0, %h1}"
1035   [(set_attr "type" "icmp")
1036    (set_attr "mode" "QI")])
1037
1038 (define_insn "*cmpqi_ext_1_rex64"
1039   [(set (reg FLAGS_REG)
1040         (compare
1041           (match_operand:QI 0 "register_operand" "Q")
1042           (subreg:QI
1043             (zero_extract:SI
1044               (match_operand 1 "ext_register_operand" "Q")
1045               (const_int 8)
1046               (const_int 8)) 0)))]
1047   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1048   "cmp{b}\t{%h1, %0|%0, %h1}"
1049   [(set_attr "type" "icmp")
1050    (set_attr "mode" "QI")])
1051
1052 (define_insn "*cmpqi_ext_2"
1053   [(set (reg FLAGS_REG)
1054         (compare
1055           (subreg:QI
1056             (zero_extract:SI
1057               (match_operand 0 "ext_register_operand" "Q")
1058               (const_int 8)
1059               (const_int 8)) 0)
1060           (match_operand:QI 1 "const0_operand" "")))]
1061   "ix86_match_ccmode (insn, CCNOmode)"
1062   "test{b}\t%h0, %h0"
1063   [(set_attr "type" "test")
1064    (set_attr "length_immediate" "0")
1065    (set_attr "mode" "QI")])
1066
1067 (define_expand "cmpqi_ext_3"
1068   [(set (reg:CC FLAGS_REG)
1069         (compare:CC
1070           (subreg:QI
1071             (zero_extract:SI
1072               (match_operand 0 "ext_register_operand" "")
1073               (const_int 8)
1074               (const_int 8)) 0)
1075           (match_operand:QI 1 "immediate_operand" "")))])
1076
1077 (define_insn "*cmpqi_ext_3_insn"
1078   [(set (reg FLAGS_REG)
1079         (compare
1080           (subreg:QI
1081             (zero_extract:SI
1082               (match_operand 0 "ext_register_operand" "Q")
1083               (const_int 8)
1084               (const_int 8)) 0)
1085           (match_operand:QI 1 "general_operand" "Qmn")))]
1086   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1087   "cmp{b}\t{%1, %h0|%h0, %1}"
1088   [(set_attr "type" "icmp")
1089    (set_attr "modrm" "1")
1090    (set_attr "mode" "QI")])
1091
1092 (define_insn "*cmpqi_ext_3_insn_rex64"
1093   [(set (reg FLAGS_REG)
1094         (compare
1095           (subreg:QI
1096             (zero_extract:SI
1097               (match_operand 0 "ext_register_operand" "Q")
1098               (const_int 8)
1099               (const_int 8)) 0)
1100           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1101   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1102   "cmp{b}\t{%1, %h0|%h0, %1}"
1103   [(set_attr "type" "icmp")
1104    (set_attr "modrm" "1")
1105    (set_attr "mode" "QI")])
1106
1107 (define_insn "*cmpqi_ext_4"
1108   [(set (reg FLAGS_REG)
1109         (compare
1110           (subreg:QI
1111             (zero_extract:SI
1112               (match_operand 0 "ext_register_operand" "Q")
1113               (const_int 8)
1114               (const_int 8)) 0)
1115           (subreg:QI
1116             (zero_extract:SI
1117               (match_operand 1 "ext_register_operand" "Q")
1118               (const_int 8)
1119               (const_int 8)) 0)))]
1120   "ix86_match_ccmode (insn, CCmode)"
1121   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1122   [(set_attr "type" "icmp")
1123    (set_attr "mode" "QI")])
1124
1125 ;; These implement float point compares.
1126 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1127 ;; which would allow mix and match FP modes on the compares.  Which is what
1128 ;; the old patterns did, but with many more of them.
1129
1130 (define_expand "cbranchxf4"
1131   [(set (reg:CC FLAGS_REG)
1132         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1133                     (match_operand:XF 2 "nonmemory_operand" "")))
1134    (set (pc) (if_then_else
1135               (match_operator 0 "ix86_fp_comparison_operator"
1136                [(reg:CC FLAGS_REG)
1137                 (const_int 0)])
1138               (label_ref (match_operand 3 "" ""))
1139               (pc)))]
1140   "TARGET_80387"
1141 {
1142   ix86_expand_branch (GET_CODE (operands[0]),
1143                       operands[1], operands[2], operands[3]);
1144   DONE;
1145 })
1146
1147 (define_expand "cstorexf4"
1148   [(set (reg:CC FLAGS_REG)
1149         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1150                     (match_operand:XF 3 "nonmemory_operand" "")))
1151    (set (match_operand:QI 0 "register_operand" "")
1152               (match_operator 1 "ix86_fp_comparison_operator"
1153                [(reg:CC FLAGS_REG)
1154                 (const_int 0)]))]
1155   "TARGET_80387"
1156 {
1157   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1158                      operands[2], operands[3]);
1159   DONE;
1160 })
1161
1162 (define_expand "cbranch<mode>4"
1163   [(set (reg:CC FLAGS_REG)
1164         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1165                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1166    (set (pc) (if_then_else
1167               (match_operator 0 "ix86_fp_comparison_operator"
1168                [(reg:CC FLAGS_REG)
1169                 (const_int 0)])
1170               (label_ref (match_operand 3 "" ""))
1171               (pc)))]
1172   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1173 {
1174   ix86_expand_branch (GET_CODE (operands[0]),
1175                       operands[1], operands[2], operands[3]);
1176   DONE;
1177 })
1178
1179 (define_expand "cstore<mode>4"
1180   [(set (reg:CC FLAGS_REG)
1181         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1182                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1183    (set (match_operand:QI 0 "register_operand" "")
1184               (match_operator 1 "ix86_fp_comparison_operator"
1185                [(reg:CC FLAGS_REG)
1186                 (const_int 0)]))]
1187   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1188 {
1189   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1190                      operands[2], operands[3]);
1191   DONE;
1192 })
1193
1194 (define_expand "cbranchcc4"
1195   [(set (pc) (if_then_else
1196               (match_operator 0 "comparison_operator"
1197                [(match_operand 1 "flags_reg_operand" "")
1198                 (match_operand 2 "const0_operand" "")])
1199               (label_ref (match_operand 3 "" ""))
1200               (pc)))]
1201   ""
1202 {
1203   ix86_expand_branch (GET_CODE (operands[0]),
1204                       operands[1], operands[2], operands[3]);
1205   DONE;
1206 })
1207
1208 (define_expand "cstorecc4"
1209   [(set (match_operand:QI 0 "register_operand" "")
1210               (match_operator 1 "comparison_operator"
1211                [(match_operand 2 "flags_reg_operand" "")
1212                 (match_operand 3 "const0_operand" "")]))]
1213   ""
1214 {
1215   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216                      operands[2], operands[3]);
1217   DONE;
1218 })
1219
1220
1221 ;; FP compares, step 1:
1222 ;; Set the FP condition codes.
1223 ;;
1224 ;; CCFPmode     compare with exceptions
1225 ;; CCFPUmode    compare with no exceptions
1226
1227 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1228 ;; used to manage the reg stack popping would not be preserved.
1229
1230 (define_insn "*cmpfp_0"
1231   [(set (match_operand:HI 0 "register_operand" "=a")
1232         (unspec:HI
1233           [(compare:CCFP
1234              (match_operand 1 "register_operand" "f")
1235              (match_operand 2 "const0_operand" ""))]
1236         UNSPEC_FNSTSW))]
1237   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1238    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1239   "* return output_fp_compare (insn, operands, 0, 0);"
1240   [(set_attr "type" "multi")
1241    (set_attr "unit" "i387")
1242    (set (attr "mode")
1243      (cond [(match_operand:SF 1 "" "")
1244               (const_string "SF")
1245             (match_operand:DF 1 "" "")
1246               (const_string "DF")
1247            ]
1248            (const_string "XF")))])
1249
1250 (define_insn_and_split "*cmpfp_0_cc"
1251   [(set (reg:CCFP FLAGS_REG)
1252         (compare:CCFP
1253           (match_operand 1 "register_operand" "f")
1254           (match_operand 2 "const0_operand" "")))
1255    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1256   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1257    && TARGET_SAHF && !TARGET_CMOVE
1258    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1259   "#"
1260   "&& reload_completed"
1261   [(set (match_dup 0)
1262         (unspec:HI
1263           [(compare:CCFP (match_dup 1)(match_dup 2))]
1264         UNSPEC_FNSTSW))
1265    (set (reg:CC FLAGS_REG)
1266         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1267   ""
1268   [(set_attr "type" "multi")
1269    (set_attr "unit" "i387")
1270    (set (attr "mode")
1271      (cond [(match_operand:SF 1 "" "")
1272               (const_string "SF")
1273             (match_operand:DF 1 "" "")
1274               (const_string "DF")
1275            ]
1276            (const_string "XF")))])
1277
1278 (define_insn "*cmpfp_xf"
1279   [(set (match_operand:HI 0 "register_operand" "=a")
1280         (unspec:HI
1281           [(compare:CCFP
1282              (match_operand:XF 1 "register_operand" "f")
1283              (match_operand:XF 2 "register_operand" "f"))]
1284           UNSPEC_FNSTSW))]
1285   "TARGET_80387"
1286   "* return output_fp_compare (insn, operands, 0, 0);"
1287   [(set_attr "type" "multi")
1288    (set_attr "unit" "i387")
1289    (set_attr "mode" "XF")])
1290
1291 (define_insn_and_split "*cmpfp_xf_cc"
1292   [(set (reg:CCFP FLAGS_REG)
1293         (compare:CCFP
1294           (match_operand:XF 1 "register_operand" "f")
1295           (match_operand:XF 2 "register_operand" "f")))
1296    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1297   "TARGET_80387
1298    && TARGET_SAHF && !TARGET_CMOVE"
1299   "#"
1300   "&& reload_completed"
1301   [(set (match_dup 0)
1302         (unspec:HI
1303           [(compare:CCFP (match_dup 1)(match_dup 2))]
1304         UNSPEC_FNSTSW))
1305    (set (reg:CC FLAGS_REG)
1306         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1307   ""
1308   [(set_attr "type" "multi")
1309    (set_attr "unit" "i387")
1310    (set_attr "mode" "XF")])
1311
1312 (define_insn "*cmpfp_<mode>"
1313   [(set (match_operand:HI 0 "register_operand" "=a")
1314         (unspec:HI
1315           [(compare:CCFP
1316              (match_operand:MODEF 1 "register_operand" "f")
1317              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1318           UNSPEC_FNSTSW))]
1319   "TARGET_80387"
1320   "* return output_fp_compare (insn, operands, 0, 0);"
1321   [(set_attr "type" "multi")
1322    (set_attr "unit" "i387")
1323    (set_attr "mode" "<MODE>")])
1324
1325 (define_insn_and_split "*cmpfp_<mode>_cc"
1326   [(set (reg:CCFP FLAGS_REG)
1327         (compare:CCFP
1328           (match_operand:MODEF 1 "register_operand" "f")
1329           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1330    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1331   "TARGET_80387
1332    && TARGET_SAHF && !TARGET_CMOVE"
1333   "#"
1334   "&& reload_completed"
1335   [(set (match_dup 0)
1336         (unspec:HI
1337           [(compare:CCFP (match_dup 1)(match_dup 2))]
1338         UNSPEC_FNSTSW))
1339    (set (reg:CC FLAGS_REG)
1340         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1341   ""
1342   [(set_attr "type" "multi")
1343    (set_attr "unit" "i387")
1344    (set_attr "mode" "<MODE>")])
1345
1346 (define_insn "*cmpfp_u"
1347   [(set (match_operand:HI 0 "register_operand" "=a")
1348         (unspec:HI
1349           [(compare:CCFPU
1350              (match_operand 1 "register_operand" "f")
1351              (match_operand 2 "register_operand" "f"))]
1352           UNSPEC_FNSTSW))]
1353   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1354    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1355   "* return output_fp_compare (insn, operands, 0, 1);"
1356   [(set_attr "type" "multi")
1357    (set_attr "unit" "i387")
1358    (set (attr "mode")
1359      (cond [(match_operand:SF 1 "" "")
1360               (const_string "SF")
1361             (match_operand:DF 1 "" "")
1362               (const_string "DF")
1363            ]
1364            (const_string "XF")))])
1365
1366 (define_insn_and_split "*cmpfp_u_cc"
1367   [(set (reg:CCFPU FLAGS_REG)
1368         (compare:CCFPU
1369           (match_operand 1 "register_operand" "f")
1370           (match_operand 2 "register_operand" "f")))
1371    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1372   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1373    && TARGET_SAHF && !TARGET_CMOVE
1374    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1375   "#"
1376   "&& reload_completed"
1377   [(set (match_dup 0)
1378         (unspec:HI
1379           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1380         UNSPEC_FNSTSW))
1381    (set (reg:CC FLAGS_REG)
1382         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1383   ""
1384   [(set_attr "type" "multi")
1385    (set_attr "unit" "i387")
1386    (set (attr "mode")
1387      (cond [(match_operand:SF 1 "" "")
1388               (const_string "SF")
1389             (match_operand:DF 1 "" "")
1390               (const_string "DF")
1391            ]
1392            (const_string "XF")))])
1393
1394 (define_insn "*cmpfp_<mode>"
1395   [(set (match_operand:HI 0 "register_operand" "=a")
1396         (unspec:HI
1397           [(compare:CCFP
1398              (match_operand 1 "register_operand" "f")
1399              (match_operator 3 "float_operator"
1400                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1401           UNSPEC_FNSTSW))]
1402   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1403    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1404    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1405   "* return output_fp_compare (insn, operands, 0, 0);"
1406   [(set_attr "type" "multi")
1407    (set_attr "unit" "i387")
1408    (set_attr "fp_int_src" "true")
1409    (set_attr "mode" "<MODE>")])
1410
1411 (define_insn_and_split "*cmpfp_<mode>_cc"
1412   [(set (reg:CCFP FLAGS_REG)
1413         (compare:CCFP
1414           (match_operand 1 "register_operand" "f")
1415           (match_operator 3 "float_operator"
1416             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1417    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1418   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1419    && TARGET_SAHF && !TARGET_CMOVE
1420    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1421    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1422   "#"
1423   "&& reload_completed"
1424   [(set (match_dup 0)
1425         (unspec:HI
1426           [(compare:CCFP
1427              (match_dup 1)
1428              (match_op_dup 3 [(match_dup 2)]))]
1429         UNSPEC_FNSTSW))
1430    (set (reg:CC FLAGS_REG)
1431         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1432   ""
1433   [(set_attr "type" "multi")
1434    (set_attr "unit" "i387")
1435    (set_attr "fp_int_src" "true")
1436    (set_attr "mode" "<MODE>")])
1437
1438 ;; FP compares, step 2
1439 ;; Move the fpsw to ax.
1440
1441 (define_insn "x86_fnstsw_1"
1442   [(set (match_operand:HI 0 "register_operand" "=a")
1443         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1444   "TARGET_80387"
1445   "fnstsw\t%0"
1446   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1447    (set_attr "mode" "SI")
1448    (set_attr "unit" "i387")])
1449
1450 ;; FP compares, step 3
1451 ;; Get ax into flags, general case.
1452
1453 (define_insn "x86_sahf_1"
1454   [(set (reg:CC FLAGS_REG)
1455         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1456                    UNSPEC_SAHF))]
1457   "TARGET_SAHF"
1458 {
1459 #ifndef HAVE_AS_IX86_SAHF
1460   if (TARGET_64BIT)
1461     return ASM_BYTE "0x9e";
1462   else
1463 #endif
1464   return "sahf";
1465 }
1466   [(set_attr "length" "1")
1467    (set_attr "athlon_decode" "vector")
1468    (set_attr "amdfam10_decode" "direct")
1469    (set_attr "bdver1_decode" "direct")
1470    (set_attr "mode" "SI")])
1471
1472 ;; Pentium Pro can do steps 1 through 3 in one go.
1473 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1474 (define_insn "*cmpfp_i_mixed"
1475   [(set (reg:CCFP FLAGS_REG)
1476         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1477                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1478   "TARGET_MIX_SSE_I387
1479    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1480    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1481   "* return output_fp_compare (insn, operands, 1, 0);"
1482   [(set_attr "type" "fcmp,ssecomi")
1483    (set_attr "prefix" "orig,maybe_vex")
1484    (set (attr "mode")
1485      (if_then_else (match_operand:SF 1 "" "")
1486         (const_string "SF")
1487         (const_string "DF")))
1488    (set (attr "prefix_rep")
1489         (if_then_else (eq_attr "type" "ssecomi")
1490                       (const_string "0")
1491                       (const_string "*")))
1492    (set (attr "prefix_data16")
1493         (cond [(eq_attr "type" "fcmp")
1494                  (const_string "*")
1495                (eq_attr "mode" "DF")
1496                  (const_string "1")
1497               ]
1498               (const_string "0")))
1499    (set_attr "athlon_decode" "vector")
1500    (set_attr "amdfam10_decode" "direct")
1501    (set_attr "bdver1_decode" "double")])
1502
1503 (define_insn "*cmpfp_i_sse"
1504   [(set (reg:CCFP FLAGS_REG)
1505         (compare:CCFP (match_operand 0 "register_operand" "x")
1506                       (match_operand 1 "nonimmediate_operand" "xm")))]
1507   "TARGET_SSE_MATH
1508    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1509    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510   "* return output_fp_compare (insn, operands, 1, 0);"
1511   [(set_attr "type" "ssecomi")
1512    (set_attr "prefix" "maybe_vex")
1513    (set (attr "mode")
1514      (if_then_else (match_operand:SF 1 "" "")
1515         (const_string "SF")
1516         (const_string "DF")))
1517    (set_attr "prefix_rep" "0")
1518    (set (attr "prefix_data16")
1519         (if_then_else (eq_attr "mode" "DF")
1520                       (const_string "1")
1521                       (const_string "0")))
1522    (set_attr "athlon_decode" "vector")
1523    (set_attr "amdfam10_decode" "direct")
1524    (set_attr "bdver1_decode" "double")])
1525
1526 (define_insn "*cmpfp_i_i387"
1527   [(set (reg:CCFP FLAGS_REG)
1528         (compare:CCFP (match_operand 0 "register_operand" "f")
1529                       (match_operand 1 "register_operand" "f")))]
1530   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1531    && TARGET_CMOVE
1532    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1533    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1534   "* return output_fp_compare (insn, operands, 1, 0);"
1535   [(set_attr "type" "fcmp")
1536    (set (attr "mode")
1537      (cond [(match_operand:SF 1 "" "")
1538               (const_string "SF")
1539             (match_operand:DF 1 "" "")
1540               (const_string "DF")
1541            ]
1542            (const_string "XF")))
1543    (set_attr "athlon_decode" "vector")
1544    (set_attr "amdfam10_decode" "direct")
1545    (set_attr "bdver1_decode" "double")])
1546
1547 (define_insn "*cmpfp_iu_mixed"
1548   [(set (reg:CCFPU FLAGS_REG)
1549         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1550                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1551   "TARGET_MIX_SSE_I387
1552    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1553    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1554   "* return output_fp_compare (insn, operands, 1, 1);"
1555   [(set_attr "type" "fcmp,ssecomi")
1556    (set_attr "prefix" "orig,maybe_vex")
1557    (set (attr "mode")
1558      (if_then_else (match_operand:SF 1 "" "")
1559         (const_string "SF")
1560         (const_string "DF")))
1561    (set (attr "prefix_rep")
1562         (if_then_else (eq_attr "type" "ssecomi")
1563                       (const_string "0")
1564                       (const_string "*")))
1565    (set (attr "prefix_data16")
1566         (cond [(eq_attr "type" "fcmp")
1567                  (const_string "*")
1568                (eq_attr "mode" "DF")
1569                  (const_string "1")
1570               ]
1571               (const_string "0")))
1572    (set_attr "athlon_decode" "vector")
1573    (set_attr "amdfam10_decode" "direct")
1574    (set_attr "bdver1_decode" "double")])
1575
1576 (define_insn "*cmpfp_iu_sse"
1577   [(set (reg:CCFPU FLAGS_REG)
1578         (compare:CCFPU (match_operand 0 "register_operand" "x")
1579                        (match_operand 1 "nonimmediate_operand" "xm")))]
1580   "TARGET_SSE_MATH
1581    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1582    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583   "* return output_fp_compare (insn, operands, 1, 1);"
1584   [(set_attr "type" "ssecomi")
1585    (set_attr "prefix" "maybe_vex")
1586    (set (attr "mode")
1587      (if_then_else (match_operand:SF 1 "" "")
1588         (const_string "SF")
1589         (const_string "DF")))
1590    (set_attr "prefix_rep" "0")
1591    (set (attr "prefix_data16")
1592         (if_then_else (eq_attr "mode" "DF")
1593                       (const_string "1")
1594                       (const_string "0")))
1595    (set_attr "athlon_decode" "vector")
1596    (set_attr "amdfam10_decode" "direct")
1597    (set_attr "bdver1_decode" "double")])
1598
1599 (define_insn "*cmpfp_iu_387"
1600   [(set (reg:CCFPU FLAGS_REG)
1601         (compare:CCFPU (match_operand 0 "register_operand" "f")
1602                        (match_operand 1 "register_operand" "f")))]
1603   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1604    && TARGET_CMOVE
1605    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1606    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1607   "* return output_fp_compare (insn, operands, 1, 1);"
1608   [(set_attr "type" "fcmp")
1609    (set (attr "mode")
1610      (cond [(match_operand:SF 1 "" "")
1611               (const_string "SF")
1612             (match_operand:DF 1 "" "")
1613               (const_string "DF")
1614            ]
1615            (const_string "XF")))
1616    (set_attr "athlon_decode" "vector")
1617    (set_attr "amdfam10_decode" "direct")
1618    (set_attr "bdver1_decode" "direct")])
1619 \f
1620 ;; Push/pop instructions.
1621
1622 (define_insn "*push<mode>2"
1623   [(set (match_operand:DWI 0 "push_operand" "=<")
1624         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1625   ""
1626   "#")
1627
1628 (define_split
1629   [(set (match_operand:TI 0 "push_operand" "")
1630         (match_operand:TI 1 "general_operand" ""))]
1631   "TARGET_64BIT && reload_completed
1632    && !SSE_REG_P (operands[1])"
1633   [(const_int 0)]
1634   "ix86_split_long_move (operands); DONE;")
1635
1636 (define_insn "*pushdi2_rex64"
1637   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1638         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1639   "TARGET_64BIT"
1640   "@
1641    push{q}\t%1
1642    #"
1643   [(set_attr "type" "push,multi")
1644    (set_attr "mode" "DI")])
1645
1646 ;; Convert impossible pushes of immediate to existing instructions.
1647 ;; First try to get scratch register and go through it.  In case this
1648 ;; fails, push sign extended lower part first and then overwrite
1649 ;; upper part by 32bit move.
1650 (define_peephole2
1651   [(match_scratch:DI 2 "r")
1652    (set (match_operand:DI 0 "push_operand" "")
1653         (match_operand:DI 1 "immediate_operand" ""))]
1654   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1655    && !x86_64_immediate_operand (operands[1], DImode)"
1656   [(set (match_dup 2) (match_dup 1))
1657    (set (match_dup 0) (match_dup 2))])
1658
1659 ;; We need to define this as both peepholer and splitter for case
1660 ;; peephole2 pass is not run.
1661 ;; "&& 1" is needed to keep it from matching the previous pattern.
1662 (define_peephole2
1663   [(set (match_operand:DI 0 "push_operand" "")
1664         (match_operand:DI 1 "immediate_operand" ""))]
1665   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1666    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1667   [(set (match_dup 0) (match_dup 1))
1668    (set (match_dup 2) (match_dup 3))]
1669 {
1670   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1671
1672   operands[1] = gen_lowpart (DImode, operands[2]);
1673   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1674                                                    GEN_INT (4)));
1675 })
1676
1677 (define_split
1678   [(set (match_operand:DI 0 "push_operand" "")
1679         (match_operand:DI 1 "immediate_operand" ""))]
1680   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1681                     ? epilogue_completed : reload_completed)
1682    && !symbolic_operand (operands[1], DImode)
1683    && !x86_64_immediate_operand (operands[1], DImode)"
1684   [(set (match_dup 0) (match_dup 1))
1685    (set (match_dup 2) (match_dup 3))]
1686 {
1687   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1688
1689   operands[1] = gen_lowpart (DImode, operands[2]);
1690   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1691                                                    GEN_INT (4)));
1692 })
1693
1694 (define_split
1695   [(set (match_operand:DI 0 "push_operand" "")
1696         (match_operand:DI 1 "general_operand" ""))]
1697   "!TARGET_64BIT && reload_completed
1698    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1699   [(const_int 0)]
1700   "ix86_split_long_move (operands); DONE;")
1701
1702 (define_insn "*pushsi2"
1703   [(set (match_operand:SI 0 "push_operand" "=<")
1704         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1705   "!TARGET_64BIT"
1706   "push{l}\t%1"
1707   [(set_attr "type" "push")
1708    (set_attr "mode" "SI")])
1709
1710 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1711 ;; "push a byte/word".  But actually we use pushl, which has the effect
1712 ;; of rounding the amount pushed up to a word.
1713
1714 ;; For TARGET_64BIT we always round up to 8 bytes.
1715 (define_insn "*push<mode>2_rex64"
1716   [(set (match_operand:SWI124 0 "push_operand" "=X")
1717         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1718   "TARGET_64BIT"
1719   "push{q}\t%q1"
1720   [(set_attr "type" "push")
1721    (set_attr "mode" "DI")])
1722
1723 (define_insn "*push<mode>2"
1724   [(set (match_operand:SWI12 0 "push_operand" "=X")
1725         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1726   "!TARGET_64BIT"
1727   "push{l}\t%k1"
1728   [(set_attr "type" "push")
1729    (set_attr "mode" "SI")])
1730
1731 (define_insn "*push<mode>2_prologue"
1732   [(set (match_operand:P 0 "push_operand" "=<")
1733         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1734    (clobber (mem:BLK (scratch)))]
1735   ""
1736   "push{<imodesuffix>}\t%1"
1737   [(set_attr "type" "push")
1738    (set_attr "mode" "<MODE>")])
1739
1740 (define_insn "*pop<mode>1"
1741   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1742         (match_operand:P 1 "pop_operand" ">"))]
1743   ""
1744   "pop{<imodesuffix>}\t%0"
1745   [(set_attr "type" "pop")
1746    (set_attr "mode" "<MODE>")])
1747
1748 (define_insn "*pop<mode>1_epilogue"
1749   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1750         (match_operand:P 1 "pop_operand" ">"))
1751    (clobber (mem:BLK (scratch)))]
1752   ""
1753   "pop{<imodesuffix>}\t%0"
1754   [(set_attr "type" "pop")
1755    (set_attr "mode" "<MODE>")])
1756 \f
1757 ;; Move instructions.
1758
1759 (define_expand "movoi"
1760   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1761         (match_operand:OI 1 "general_operand" ""))]
1762   "TARGET_AVX"
1763   "ix86_expand_move (OImode, operands); DONE;")
1764
1765 (define_expand "movti"
1766   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1767         (match_operand:TI 1 "nonimmediate_operand" ""))]
1768   "TARGET_64BIT || TARGET_SSE"
1769 {
1770   if (TARGET_64BIT)
1771     ix86_expand_move (TImode, operands);
1772   else if (push_operand (operands[0], TImode))
1773     ix86_expand_push (TImode, operands[1]);
1774   else
1775     ix86_expand_vector_move (TImode, operands);
1776   DONE;
1777 })
1778
1779 ;; This expands to what emit_move_complex would generate if we didn't
1780 ;; have a movti pattern.  Having this avoids problems with reload on
1781 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1782 ;; to have around all the time.
1783 (define_expand "movcdi"
1784   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1785         (match_operand:CDI 1 "general_operand" ""))]
1786   ""
1787 {
1788   if (push_operand (operands[0], CDImode))
1789     emit_move_complex_push (CDImode, operands[0], operands[1]);
1790   else
1791     emit_move_complex_parts (operands[0], operands[1]);
1792   DONE;
1793 })
1794
1795 (define_expand "mov<mode>"
1796   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1797         (match_operand:SWI1248x 1 "general_operand" ""))]
1798   ""
1799   "ix86_expand_move (<MODE>mode, operands); DONE;")
1800
1801 (define_insn "*mov<mode>_xor"
1802   [(set (match_operand:SWI48 0 "register_operand" "=r")
1803         (match_operand:SWI48 1 "const0_operand" ""))
1804    (clobber (reg:CC FLAGS_REG))]
1805   "reload_completed"
1806   "xor{l}\t%k0, %k0"
1807   [(set_attr "type" "alu1")
1808    (set_attr "mode" "SI")
1809    (set_attr "length_immediate" "0")])
1810
1811 (define_insn "*mov<mode>_or"
1812   [(set (match_operand:SWI48 0 "register_operand" "=r")
1813         (match_operand:SWI48 1 "const_int_operand" ""))
1814    (clobber (reg:CC FLAGS_REG))]
1815   "reload_completed
1816    && operands[1] == constm1_rtx"
1817   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1818   [(set_attr "type" "alu1")
1819    (set_attr "mode" "<MODE>")
1820    (set_attr "length_immediate" "1")])
1821
1822 (define_insn "*movoi_internal_avx"
1823   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1824         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1825   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1826 {
1827   switch (which_alternative)
1828     {
1829     case 0:
1830       return "vxorps\t%0, %0, %0";
1831     case 1:
1832     case 2:
1833       if (misaligned_operand (operands[0], OImode)
1834           || misaligned_operand (operands[1], OImode))
1835         return "vmovdqu\t{%1, %0|%0, %1}";
1836       else
1837         return "vmovdqa\t{%1, %0|%0, %1}";
1838     default:
1839       gcc_unreachable ();
1840     }
1841 }
1842   [(set_attr "type" "sselog1,ssemov,ssemov")
1843    (set_attr "prefix" "vex")
1844    (set_attr "mode" "OI")])
1845
1846 (define_insn "*movti_internal_rex64"
1847   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1848         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1849   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1850 {
1851   switch (which_alternative)
1852     {
1853     case 0:
1854     case 1:
1855       return "#";
1856     case 2:
1857       if (get_attr_mode (insn) == MODE_V4SF)
1858         return "%vxorps\t%0, %d0";
1859       else
1860         return "%vpxor\t%0, %d0";
1861     case 3:
1862     case 4:
1863       /* TDmode values are passed as TImode on the stack.  Moving them
1864          to stack may result in unaligned memory access.  */
1865       if (misaligned_operand (operands[0], TImode)
1866           || misaligned_operand (operands[1], TImode))
1867         {
1868           if (get_attr_mode (insn) == MODE_V4SF)
1869             return "%vmovups\t{%1, %0|%0, %1}";
1870          else
1871            return "%vmovdqu\t{%1, %0|%0, %1}";
1872         }
1873       else
1874         {
1875           if (get_attr_mode (insn) == MODE_V4SF)
1876             return "%vmovaps\t{%1, %0|%0, %1}";
1877          else
1878            return "%vmovdqa\t{%1, %0|%0, %1}";
1879         }
1880     default:
1881       gcc_unreachable ();
1882     }
1883 }
1884   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1885    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1886    (set (attr "mode")
1887         (cond [(eq_attr "alternative" "2,3")
1888                  (if_then_else
1889                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1890                        (const_int 0))
1891                    (const_string "V4SF")
1892                    (const_string "TI"))
1893                (eq_attr "alternative" "4")
1894                  (if_then_else
1895                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1896                             (const_int 0))
1897                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1898                             (const_int 0)))
1899                    (const_string "V4SF")
1900                    (const_string "TI"))]
1901                (const_string "DI")))])
1902
1903 (define_split
1904   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1905         (match_operand:TI 1 "general_operand" ""))]
1906   "reload_completed
1907    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1908   [(const_int 0)]
1909   "ix86_split_long_move (operands); DONE;")
1910
1911 (define_insn "*movti_internal_sse"
1912   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1913         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1914   "TARGET_SSE && !TARGET_64BIT
1915    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1916 {
1917   switch (which_alternative)
1918     {
1919     case 0:
1920       if (get_attr_mode (insn) == MODE_V4SF)
1921         return "%vxorps\t%0, %d0";
1922       else
1923         return "%vpxor\t%0, %d0";
1924     case 1:
1925     case 2:
1926       /* TDmode values are passed as TImode on the stack.  Moving them
1927          to stack may result in unaligned memory access.  */
1928       if (misaligned_operand (operands[0], TImode)
1929           || misaligned_operand (operands[1], TImode))
1930         {
1931           if (get_attr_mode (insn) == MODE_V4SF)
1932             return "%vmovups\t{%1, %0|%0, %1}";
1933          else
1934            return "%vmovdqu\t{%1, %0|%0, %1}";
1935         }
1936       else
1937         {
1938           if (get_attr_mode (insn) == MODE_V4SF)
1939             return "%vmovaps\t{%1, %0|%0, %1}";
1940          else
1941            return "%vmovdqa\t{%1, %0|%0, %1}";
1942         }
1943     default:
1944       gcc_unreachable ();
1945     }
1946 }
1947   [(set_attr "type" "sselog1,ssemov,ssemov")
1948    (set_attr "prefix" "maybe_vex")
1949    (set (attr "mode")
1950         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1951                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1952                         (const_int 0)))
1953                  (const_string "V4SF")
1954                (and (eq_attr "alternative" "2")
1955                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1956                         (const_int 0)))
1957                  (const_string "V4SF")]
1958               (const_string "TI")))])
1959
1960 (define_insn "*movdi_internal_rex64"
1961   [(set (match_operand:DI 0 "nonimmediate_operand"
1962           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1963         (match_operand:DI 1 "general_operand"
1964           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1965   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1966 {
1967   switch (get_attr_type (insn))
1968     {
1969     case TYPE_SSECVT:
1970       if (SSE_REG_P (operands[0]))
1971         return "movq2dq\t{%1, %0|%0, %1}";
1972       else
1973         return "movdq2q\t{%1, %0|%0, %1}";
1974
1975     case TYPE_SSEMOV:
1976       if (TARGET_AVX)
1977         {
1978           if (get_attr_mode (insn) == MODE_TI)
1979             return "vmovdqa\t{%1, %0|%0, %1}";
1980           else
1981             return "vmovq\t{%1, %0|%0, %1}";
1982         }
1983
1984       if (get_attr_mode (insn) == MODE_TI)
1985         return "movdqa\t{%1, %0|%0, %1}";
1986       /* FALLTHRU */
1987
1988     case TYPE_MMXMOV:
1989       /* Moves from and into integer register is done using movd
1990          opcode with REX prefix.  */
1991       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1992         return "movd\t{%1, %0|%0, %1}";
1993       return "movq\t{%1, %0|%0, %1}";
1994
1995     case TYPE_SSELOG1:
1996       return "%vpxor\t%0, %d0";
1997
1998     case TYPE_MMX:
1999       return "pxor\t%0, %0";
2000
2001     case TYPE_MULTI:
2002       return "#";
2003
2004     case TYPE_LEA:
2005       return "lea{q}\t{%a1, %0|%0, %a1}";
2006
2007     default:
2008       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2009       if (get_attr_mode (insn) == MODE_SI)
2010         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011       else if (which_alternative == 2)
2012         return "movabs{q}\t{%1, %0|%0, %1}";
2013       else
2014         return "mov{q}\t{%1, %0|%0, %1}";
2015     }
2016 }
2017   [(set (attr "type")
2018      (cond [(eq_attr "alternative" "5")
2019               (const_string "mmx")
2020             (eq_attr "alternative" "6,7,8,9,10")
2021               (const_string "mmxmov")
2022             (eq_attr "alternative" "11")
2023               (const_string "sselog1")
2024             (eq_attr "alternative" "12,13,14,15,16")
2025               (const_string "ssemov")
2026             (eq_attr "alternative" "17,18")
2027               (const_string "ssecvt")
2028             (eq_attr "alternative" "4")
2029               (const_string "multi")
2030             (match_operand:DI 1 "pic_32bit_operand" "")
2031               (const_string "lea")
2032            ]
2033            (const_string "imov")))
2034    (set (attr "modrm")
2035      (if_then_else
2036        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2037          (const_string "0")
2038          (const_string "*")))
2039    (set (attr "length_immediate")
2040      (if_then_else
2041        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2042          (const_string "8")
2043          (const_string "*")))
2044    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2045    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2046    (set (attr "prefix")
2047      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2048        (const_string "maybe_vex")
2049        (const_string "orig")))
2050    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2051
2052 ;; Convert impossible stores of immediate to existing instructions.
2053 ;; First try to get scratch register and go through it.  In case this
2054 ;; fails, move by 32bit parts.
2055 (define_peephole2
2056   [(match_scratch:DI 2 "r")
2057    (set (match_operand:DI 0 "memory_operand" "")
2058         (match_operand:DI 1 "immediate_operand" ""))]
2059   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2060    && !x86_64_immediate_operand (operands[1], DImode)"
2061   [(set (match_dup 2) (match_dup 1))
2062    (set (match_dup 0) (match_dup 2))])
2063
2064 ;; We need to define this as both peepholer and splitter for case
2065 ;; peephole2 pass is not run.
2066 ;; "&& 1" is needed to keep it from matching the previous pattern.
2067 (define_peephole2
2068   [(set (match_operand:DI 0 "memory_operand" "")
2069         (match_operand:DI 1 "immediate_operand" ""))]
2070   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2072   [(set (match_dup 2) (match_dup 3))
2073    (set (match_dup 4) (match_dup 5))]
2074   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2075
2076 (define_split
2077   [(set (match_operand:DI 0 "memory_operand" "")
2078         (match_operand:DI 1 "immediate_operand" ""))]
2079   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2080                     ? epilogue_completed : reload_completed)
2081    && !symbolic_operand (operands[1], DImode)
2082    && !x86_64_immediate_operand (operands[1], DImode)"
2083   [(set (match_dup 2) (match_dup 3))
2084    (set (match_dup 4) (match_dup 5))]
2085   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2086
2087 (define_insn "*movdi_internal"
2088   [(set (match_operand:DI 0 "nonimmediate_operand"
2089                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2090         (match_operand:DI 1 "general_operand"
2091                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2092   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2093   "@
2094    #
2095    #
2096    pxor\t%0, %0
2097    movq\t{%1, %0|%0, %1}
2098    movq\t{%1, %0|%0, %1}
2099    %vpxor\t%0, %d0
2100    %vmovq\t{%1, %0|%0, %1}
2101    %vmovdqa\t{%1, %0|%0, %1}
2102    %vmovq\t{%1, %0|%0, %1}
2103    xorps\t%0, %0
2104    movlps\t{%1, %0|%0, %1}
2105    movaps\t{%1, %0|%0, %1}
2106    movlps\t{%1, %0|%0, %1}"
2107   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2108    (set (attr "prefix")
2109      (if_then_else (eq_attr "alternative" "5,6,7,8")
2110        (const_string "vex")
2111        (const_string "orig")))
2112    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2113
2114 (define_split
2115   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2116         (match_operand:DI 1 "general_operand" ""))]
2117   "!TARGET_64BIT && reload_completed
2118    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2119    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2120   [(const_int 0)]
2121   "ix86_split_long_move (operands); DONE;")
2122
2123 (define_insn "*movsi_internal"
2124   [(set (match_operand:SI 0 "nonimmediate_operand"
2125                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2126         (match_operand:SI 1 "general_operand"
2127                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2128   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2129 {
2130   switch (get_attr_type (insn))
2131     {
2132     case TYPE_SSELOG1:
2133       if (get_attr_mode (insn) == MODE_TI)
2134         return "%vpxor\t%0, %d0";
2135       return "%vxorps\t%0, %d0";
2136
2137     case TYPE_SSEMOV:
2138       switch (get_attr_mode (insn))
2139         {
2140         case MODE_TI:
2141           return "%vmovdqa\t{%1, %0|%0, %1}";
2142         case MODE_V4SF:
2143           return "%vmovaps\t{%1, %0|%0, %1}";
2144         case MODE_SI:
2145           return "%vmovd\t{%1, %0|%0, %1}";
2146         case MODE_SF:
2147           return "%vmovss\t{%1, %0|%0, %1}";
2148         default:
2149           gcc_unreachable ();
2150         }
2151
2152     case TYPE_MMX:
2153       return "pxor\t%0, %0";
2154
2155     case TYPE_MMXMOV:
2156       if (get_attr_mode (insn) == MODE_DI)
2157         return "movq\t{%1, %0|%0, %1}";
2158       return "movd\t{%1, %0|%0, %1}";
2159
2160     case TYPE_LEA:
2161       return "lea{l}\t{%a1, %0|%0, %a1}";
2162
2163     default:
2164       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2165       return "mov{l}\t{%1, %0|%0, %1}";
2166     }
2167 }
2168   [(set (attr "type")
2169      (cond [(eq_attr "alternative" "2")
2170               (const_string "mmx")
2171             (eq_attr "alternative" "3,4,5")
2172               (const_string "mmxmov")
2173             (eq_attr "alternative" "6")
2174               (const_string "sselog1")
2175             (eq_attr "alternative" "7,8,9,10,11")
2176               (const_string "ssemov")
2177             (match_operand:DI 1 "pic_32bit_operand" "")
2178               (const_string "lea")
2179            ]
2180            (const_string "imov")))
2181    (set (attr "prefix")
2182      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2183        (const_string "orig")
2184        (const_string "maybe_vex")))
2185    (set (attr "prefix_data16")
2186      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2187        (const_string "1")
2188        (const_string "*")))
2189    (set (attr "mode")
2190      (cond [(eq_attr "alternative" "2,3")
2191               (const_string "DI")
2192             (eq_attr "alternative" "6,7")
2193               (if_then_else
2194                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2195                 (const_string "V4SF")
2196                 (const_string "TI"))
2197             (and (eq_attr "alternative" "8,9,10,11")
2198                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2199               (const_string "SF")
2200            ]
2201            (const_string "SI")))])
2202
2203 (define_insn "*movhi_internal"
2204   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2205         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2206   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2207 {
2208   switch (get_attr_type (insn))
2209     {
2210     case TYPE_IMOVX:
2211       /* movzwl is faster than movw on p2 due to partial word stalls,
2212          though not as fast as an aligned movl.  */
2213       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2214     default:
2215       if (get_attr_mode (insn) == MODE_SI)
2216         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2217       else
2218         return "mov{w}\t{%1, %0|%0, %1}";
2219     }
2220 }
2221   [(set (attr "type")
2222      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2223                 (const_int 0))
2224               (const_string "imov")
2225             (and (eq_attr "alternative" "0")
2226                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2227                           (const_int 0))
2228                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2229                           (const_int 0))))
2230               (const_string "imov")
2231             (and (eq_attr "alternative" "1,2")
2232                  (match_operand:HI 1 "aligned_operand" ""))
2233               (const_string "imov")
2234             (and (ne (symbol_ref "TARGET_MOVX")
2235                      (const_int 0))
2236                  (eq_attr "alternative" "0,2"))
2237               (const_string "imovx")
2238            ]
2239            (const_string "imov")))
2240     (set (attr "mode")
2241       (cond [(eq_attr "type" "imovx")
2242                (const_string "SI")
2243              (and (eq_attr "alternative" "1,2")
2244                   (match_operand:HI 1 "aligned_operand" ""))
2245                (const_string "SI")
2246              (and (eq_attr "alternative" "0")
2247                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2248                            (const_int 0))
2249                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2250                            (const_int 0))))
2251                (const_string "SI")
2252             ]
2253             (const_string "HI")))])
2254
2255 ;; Situation is quite tricky about when to choose full sized (SImode) move
2256 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2257 ;; partial register dependency machines (such as AMD Athlon), where QImode
2258 ;; moves issue extra dependency and for partial register stalls machines
2259 ;; that don't use QImode patterns (and QImode move cause stall on the next
2260 ;; instruction).
2261 ;;
2262 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2263 ;; register stall machines with, where we use QImode instructions, since
2264 ;; partial register stall can be caused there.  Then we use movzx.
2265 (define_insn "*movqi_internal"
2266   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2267         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2268   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2269 {
2270   switch (get_attr_type (insn))
2271     {
2272     case TYPE_IMOVX:
2273       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2274       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2275     default:
2276       if (get_attr_mode (insn) == MODE_SI)
2277         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2278       else
2279         return "mov{b}\t{%1, %0|%0, %1}";
2280     }
2281 }
2282   [(set (attr "type")
2283      (cond [(and (eq_attr "alternative" "5")
2284                  (not (match_operand:QI 1 "aligned_operand" "")))
2285               (const_string "imovx")
2286             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2287                 (const_int 0))
2288               (const_string "imov")
2289             (and (eq_attr "alternative" "3")
2290                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2291                           (const_int 0))
2292                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2293                           (const_int 0))))
2294               (const_string "imov")
2295             (eq_attr "alternative" "3,5")
2296               (const_string "imovx")
2297             (and (ne (symbol_ref "TARGET_MOVX")
2298                      (const_int 0))
2299                  (eq_attr "alternative" "2"))
2300               (const_string "imovx")
2301            ]
2302            (const_string "imov")))
2303    (set (attr "mode")
2304       (cond [(eq_attr "alternative" "3,4,5")
2305                (const_string "SI")
2306              (eq_attr "alternative" "6")
2307                (const_string "QI")
2308              (eq_attr "type" "imovx")
2309                (const_string "SI")
2310              (and (eq_attr "type" "imov")
2311                   (and (eq_attr "alternative" "0,1")
2312                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2313                                 (const_int 0))
2314                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2315                                      (const_int 0))
2316                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2317                                      (const_int 0))))))
2318                (const_string "SI")
2319              ;; Avoid partial register stalls when not using QImode arithmetic
2320              (and (eq_attr "type" "imov")
2321                   (and (eq_attr "alternative" "0,1")
2322                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2323                                 (const_int 0))
2324                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2325                                 (const_int 0)))))
2326                (const_string "SI")
2327            ]
2328            (const_string "QI")))])
2329
2330 ;; Stores and loads of ax to arbitrary constant address.
2331 ;; We fake an second form of instruction to force reload to load address
2332 ;; into register when rax is not available
2333 (define_insn "*movabs<mode>_1"
2334   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2335         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2336   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2337   "@
2338    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2339    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2340   [(set_attr "type" "imov")
2341    (set_attr "modrm" "0,*")
2342    (set_attr "length_address" "8,0")
2343    (set_attr "length_immediate" "0,*")
2344    (set_attr "memory" "store")
2345    (set_attr "mode" "<MODE>")])
2346
2347 (define_insn "*movabs<mode>_2"
2348   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2349         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2350   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2351   "@
2352    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2353    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2354   [(set_attr "type" "imov")
2355    (set_attr "modrm" "0,*")
2356    (set_attr "length_address" "8,0")
2357    (set_attr "length_immediate" "0")
2358    (set_attr "memory" "load")
2359    (set_attr "mode" "<MODE>")])
2360
2361 (define_insn "*swap<mode>"
2362   [(set (match_operand:SWI48 0 "register_operand" "+r")
2363         (match_operand:SWI48 1 "register_operand" "+r"))
2364    (set (match_dup 1)
2365         (match_dup 0))]
2366   ""
2367   "xchg{<imodesuffix>}\t%1, %0"
2368   [(set_attr "type" "imov")
2369    (set_attr "mode" "<MODE>")
2370    (set_attr "pent_pair" "np")
2371    (set_attr "athlon_decode" "vector")
2372    (set_attr "amdfam10_decode" "double")
2373    (set_attr "bdver1_decode" "double")])
2374
2375 (define_insn "*swap<mode>_1"
2376   [(set (match_operand:SWI12 0 "register_operand" "+r")
2377         (match_operand:SWI12 1 "register_operand" "+r"))
2378    (set (match_dup 1)
2379         (match_dup 0))]
2380   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2381   "xchg{l}\t%k1, %k0"
2382   [(set_attr "type" "imov")
2383    (set_attr "mode" "SI")
2384    (set_attr "pent_pair" "np")
2385    (set_attr "athlon_decode" "vector")
2386    (set_attr "amdfam10_decode" "double")
2387    (set_attr "bdver1_decode" "double")])
2388
2389 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2390 ;; is disabled for AMDFAM10
2391 (define_insn "*swap<mode>_2"
2392   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2393         (match_operand:SWI12 1 "register_operand" "+<r>"))
2394    (set (match_dup 1)
2395         (match_dup 0))]
2396   "TARGET_PARTIAL_REG_STALL"
2397   "xchg{<imodesuffix>}\t%1, %0"
2398   [(set_attr "type" "imov")
2399    (set_attr "mode" "<MODE>")
2400    (set_attr "pent_pair" "np")
2401    (set_attr "athlon_decode" "vector")])
2402
2403 (define_expand "movstrict<mode>"
2404   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2405         (match_operand:SWI12 1 "general_operand" ""))]
2406   ""
2407 {
2408   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2409     FAIL;
2410   /* Don't generate memory->memory moves, go through a register */
2411   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2412     operands[1] = force_reg (<MODE>mode, operands[1]);
2413 })
2414
2415 (define_insn "*movstrict<mode>_1"
2416   [(set (strict_low_part
2417           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2418         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2419   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2420    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2421   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2422   [(set_attr "type" "imov")
2423    (set_attr "mode" "<MODE>")])
2424
2425 (define_insn "*movstrict<mode>_xor"
2426   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2427         (match_operand:SWI12 1 "const0_operand" ""))
2428    (clobber (reg:CC FLAGS_REG))]
2429   "reload_completed"
2430   "xor{<imodesuffix>}\t%0, %0"
2431   [(set_attr "type" "alu1")
2432    (set_attr "mode" "<MODE>")
2433    (set_attr "length_immediate" "0")])
2434
2435 (define_insn "*mov<mode>_extv_1"
2436   [(set (match_operand:SWI24 0 "register_operand" "=R")
2437         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2438                             (const_int 8)
2439                             (const_int 8)))]
2440   ""
2441   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2442   [(set_attr "type" "imovx")
2443    (set_attr "mode" "SI")])
2444
2445 (define_insn "*movqi_extv_1_rex64"
2446   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2447         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2448                          (const_int 8)
2449                          (const_int 8)))]
2450   "TARGET_64BIT"
2451 {
2452   switch (get_attr_type (insn))
2453     {
2454     case TYPE_IMOVX:
2455       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2456     default:
2457       return "mov{b}\t{%h1, %0|%0, %h1}";
2458     }
2459 }
2460   [(set (attr "type")
2461      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2462                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2463                              (ne (symbol_ref "TARGET_MOVX")
2464                                  (const_int 0))))
2465         (const_string "imovx")
2466         (const_string "imov")))
2467    (set (attr "mode")
2468      (if_then_else (eq_attr "type" "imovx")
2469         (const_string "SI")
2470         (const_string "QI")))])
2471
2472 (define_insn "*movqi_extv_1"
2473   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2474         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2475                          (const_int 8)
2476                          (const_int 8)))]
2477   "!TARGET_64BIT"
2478 {
2479   switch (get_attr_type (insn))
2480     {
2481     case TYPE_IMOVX:
2482       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2483     default:
2484       return "mov{b}\t{%h1, %0|%0, %h1}";
2485     }
2486 }
2487   [(set (attr "type")
2488      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2489                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2490                              (ne (symbol_ref "TARGET_MOVX")
2491                                  (const_int 0))))
2492         (const_string "imovx")
2493         (const_string "imov")))
2494    (set (attr "mode")
2495      (if_then_else (eq_attr "type" "imovx")
2496         (const_string "SI")
2497         (const_string "QI")))])
2498
2499 (define_insn "*mov<mode>_extzv_1"
2500   [(set (match_operand:SWI48 0 "register_operand" "=R")
2501         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2502                             (const_int 8)
2503                             (const_int 8)))]
2504   ""
2505   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2506   [(set_attr "type" "imovx")
2507    (set_attr "mode" "SI")])
2508
2509 (define_insn "*movqi_extzv_2_rex64"
2510   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2511         (subreg:QI
2512           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2513                            (const_int 8)
2514                            (const_int 8)) 0))]
2515   "TARGET_64BIT"
2516 {
2517   switch (get_attr_type (insn))
2518     {
2519     case TYPE_IMOVX:
2520       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2521     default:
2522       return "mov{b}\t{%h1, %0|%0, %h1}";
2523     }
2524 }
2525   [(set (attr "type")
2526      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2527                         (ne (symbol_ref "TARGET_MOVX")
2528                             (const_int 0)))
2529         (const_string "imovx")
2530         (const_string "imov")))
2531    (set (attr "mode")
2532      (if_then_else (eq_attr "type" "imovx")
2533         (const_string "SI")
2534         (const_string "QI")))])
2535
2536 (define_insn "*movqi_extzv_2"
2537   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2538         (subreg:QI
2539           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2540                            (const_int 8)
2541                            (const_int 8)) 0))]
2542   "!TARGET_64BIT"
2543 {
2544   switch (get_attr_type (insn))
2545     {
2546     case TYPE_IMOVX:
2547       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2548     default:
2549       return "mov{b}\t{%h1, %0|%0, %h1}";
2550     }
2551 }
2552   [(set (attr "type")
2553      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2554                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2555                              (ne (symbol_ref "TARGET_MOVX")
2556                                  (const_int 0))))
2557         (const_string "imovx")
2558         (const_string "imov")))
2559    (set (attr "mode")
2560      (if_then_else (eq_attr "type" "imovx")
2561         (const_string "SI")
2562         (const_string "QI")))])
2563
2564 (define_expand "mov<mode>_insv_1"
2565   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2566                             (const_int 8)
2567                             (const_int 8))
2568         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2569
2570 (define_insn "*mov<mode>_insv_1_rex64"
2571   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2572                              (const_int 8)
2573                              (const_int 8))
2574         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2575   "TARGET_64BIT"
2576   "mov{b}\t{%b1, %h0|%h0, %b1}"
2577   [(set_attr "type" "imov")
2578    (set_attr "mode" "QI")])
2579
2580 (define_insn "*movsi_insv_1"
2581   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2582                          (const_int 8)
2583                          (const_int 8))
2584         (match_operand:SI 1 "general_operand" "Qmn"))]
2585   "!TARGET_64BIT"
2586   "mov{b}\t{%b1, %h0|%h0, %b1}"
2587   [(set_attr "type" "imov")
2588    (set_attr "mode" "QI")])
2589
2590 (define_insn "*movqi_insv_2"
2591   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2592                          (const_int 8)
2593                          (const_int 8))
2594         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2595                      (const_int 8)))]
2596   ""
2597   "mov{b}\t{%h1, %h0|%h0, %h1}"
2598   [(set_attr "type" "imov")
2599    (set_attr "mode" "QI")])
2600 \f
2601 ;; Floating point push instructions.
2602
2603 (define_insn "*pushtf"
2604   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2605         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2606   "TARGET_SSE2"
2607 {
2608   /* This insn should be already split before reg-stack.  */
2609   gcc_unreachable ();
2610 }
2611   [(set_attr "type" "multi")
2612    (set_attr "unit" "sse,*,*")
2613    (set_attr "mode" "TF,SI,SI")])
2614
2615 (define_split
2616   [(set (match_operand:TF 0 "push_operand" "")
2617         (match_operand:TF 1 "sse_reg_operand" ""))]
2618   "TARGET_SSE2 && reload_completed"
2619   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2620    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2621
2622 (define_split
2623   [(set (match_operand:TF 0 "push_operand" "")
2624         (match_operand:TF 1 "general_operand" ""))]
2625   "TARGET_SSE2 && reload_completed
2626    && !SSE_REG_P (operands[1])"
2627   [(const_int 0)]
2628   "ix86_split_long_move (operands); DONE;")
2629
2630 (define_insn "*pushxf"
2631   [(set (match_operand:XF 0 "push_operand" "=<,<")
2632         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2633   "optimize_function_for_speed_p (cfun)"
2634 {
2635   /* This insn should be already split before reg-stack.  */
2636   gcc_unreachable ();
2637 }
2638   [(set_attr "type" "multi")
2639    (set_attr "unit" "i387,*")
2640    (set_attr "mode" "XF,SI")])
2641
2642 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2643 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2644 ;; Pushing using integer instructions is longer except for constants
2645 ;; and direct memory references (assuming that any given constant is pushed
2646 ;; only once, but this ought to be handled elsewhere).
2647
2648 (define_insn "*pushxf_nointeger"
2649   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2650         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2651   "optimize_function_for_size_p (cfun)"
2652 {
2653   /* This insn should be already split before reg-stack.  */
2654   gcc_unreachable ();
2655 }
2656   [(set_attr "type" "multi")
2657    (set_attr "unit" "i387,*,*")
2658    (set_attr "mode" "XF,SI,SI")])
2659
2660 (define_split
2661   [(set (match_operand:XF 0 "push_operand" "")
2662         (match_operand:XF 1 "fp_register_operand" ""))]
2663   "reload_completed"
2664   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2665    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2666   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2667
2668 (define_split
2669   [(set (match_operand:XF 0 "push_operand" "")
2670         (match_operand:XF 1 "general_operand" ""))]
2671   "reload_completed
2672    && !FP_REG_P (operands[1])"
2673   [(const_int 0)]
2674   "ix86_split_long_move (operands); DONE;")
2675
2676 (define_insn "*pushdf"
2677   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2678         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2679   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2680 {
2681   /* This insn should be already split before reg-stack.  */
2682   gcc_unreachable ();
2683 }
2684   [(set_attr "type" "multi")
2685    (set_attr "unit" "i387,*,*")
2686    (set_attr "mode" "DF,SI,DF")])
2687
2688 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2689 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2690 ;; On the average, pushdf using integers can be still shorter.  Allow this
2691 ;; pattern for optimize_size too.
2692
2693 (define_insn "*pushdf_nointeger"
2694   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2695         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2696   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2697 {
2698   /* This insn should be already split before reg-stack.  */
2699   gcc_unreachable ();
2700 }
2701   [(set_attr "type" "multi")
2702    (set_attr "unit" "i387,*,*,*")
2703    (set_attr "mode" "DF,SI,SI,DF")])
2704
2705 ;; %%% Kill this when call knows how to work this out.
2706 (define_split
2707   [(set (match_operand:DF 0 "push_operand" "")
2708         (match_operand:DF 1 "any_fp_register_operand" ""))]
2709   "reload_completed"
2710   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2711    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2712
2713 (define_split
2714   [(set (match_operand:DF 0 "push_operand" "")
2715         (match_operand:DF 1 "general_operand" ""))]
2716   "reload_completed
2717    && !ANY_FP_REG_P (operands[1])"
2718   [(const_int 0)]
2719   "ix86_split_long_move (operands); DONE;")
2720
2721 (define_insn "*pushsf_rex64"
2722   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2723         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2724   "TARGET_64BIT"
2725 {
2726   /* Anything else should be already split before reg-stack.  */
2727   gcc_assert (which_alternative == 1);
2728   return "push{q}\t%q1";
2729 }
2730   [(set_attr "type" "multi,push,multi")
2731    (set_attr "unit" "i387,*,*")
2732    (set_attr "mode" "SF,DI,SF")])
2733
2734 (define_insn "*pushsf"
2735   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2736         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2737   "!TARGET_64BIT"
2738 {
2739   /* Anything else should be already split before reg-stack.  */
2740   gcc_assert (which_alternative == 1);
2741   return "push{l}\t%1";
2742 }
2743   [(set_attr "type" "multi,push,multi")
2744    (set_attr "unit" "i387,*,*")
2745    (set_attr "mode" "SF,SI,SF")])
2746
2747 (define_split
2748   [(set (match_operand:SF 0 "push_operand" "")
2749         (match_operand:SF 1 "memory_operand" ""))]
2750   "reload_completed
2751    && MEM_P (operands[1])
2752    && (operands[2] = find_constant_src (insn))"
2753   [(set (match_dup 0)
2754         (match_dup 2))])
2755
2756 ;; %%% Kill this when call knows how to work this out.
2757 (define_split
2758   [(set (match_operand:SF 0 "push_operand" "")
2759         (match_operand:SF 1 "any_fp_register_operand" ""))]
2760   "reload_completed"
2761   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2762    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2763   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2764 \f
2765 ;; Floating point move instructions.
2766
2767 (define_expand "movtf"
2768   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2769         (match_operand:TF 1 "nonimmediate_operand" ""))]
2770   "TARGET_SSE2"
2771 {
2772   ix86_expand_move (TFmode, operands);
2773   DONE;
2774 })
2775
2776 (define_expand "mov<mode>"
2777   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2778         (match_operand:X87MODEF 1 "general_operand" ""))]
2779   ""
2780   "ix86_expand_move (<MODE>mode, operands); DONE;")
2781
2782 (define_insn "*movtf_internal"
2783   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2784         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2785   "TARGET_SSE2
2786    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2787 {
2788   switch (which_alternative)
2789     {
2790     case 0:
2791     case 1:
2792       if (get_attr_mode (insn) == MODE_V4SF)
2793         return "%vmovaps\t{%1, %0|%0, %1}";
2794       else
2795         return "%vmovdqa\t{%1, %0|%0, %1}";
2796     case 2:
2797       if (get_attr_mode (insn) == MODE_V4SF)
2798         return "%vxorps\t%0, %d0";
2799       else
2800         return "%vpxor\t%0, %d0";
2801     case 3:
2802     case 4:
2803         return "#";
2804     default:
2805       gcc_unreachable ();
2806     }
2807 }
2808   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2809    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2810    (set (attr "mode")
2811         (cond [(eq_attr "alternative" "0,2")
2812                  (if_then_else
2813                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2814                        (const_int 0))
2815                    (const_string "V4SF")
2816                    (const_string "TI"))
2817                (eq_attr "alternative" "1")
2818                  (if_then_else
2819                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2820                             (const_int 0))
2821                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2822                             (const_int 0)))
2823                    (const_string "V4SF")
2824                    (const_string "TI"))]
2825                (const_string "DI")))])
2826
2827 (define_split
2828   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2829         (match_operand:TF 1 "general_operand" ""))]
2830   "reload_completed
2831    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2832   [(const_int 0)]
2833   "ix86_split_long_move (operands); DONE;")
2834
2835 (define_insn "*movxf_internal"
2836   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2837         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2838   "optimize_function_for_speed_p (cfun)
2839    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2840    && (reload_in_progress || reload_completed
2841        || GET_CODE (operands[1]) != CONST_DOUBLE
2842        || memory_operand (operands[0], XFmode))"
2843 {
2844   switch (which_alternative)
2845     {
2846     case 0:
2847     case 1:
2848       return output_387_reg_move (insn, operands);
2849
2850     case 2:
2851       return standard_80387_constant_opcode (operands[1]);
2852
2853     case 3: case 4:
2854       return "#";
2855
2856     default:
2857       gcc_unreachable ();
2858     }
2859 }
2860   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2861    (set_attr "mode" "XF,XF,XF,SI,SI")])
2862
2863 ;; Do not use integer registers when optimizing for size
2864 (define_insn "*movxf_internal_nointeger"
2865   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2866         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2867   "optimize_function_for_size_p (cfun)
2868    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2869    && (reload_in_progress || reload_completed
2870        || standard_80387_constant_p (operands[1])
2871        || GET_CODE (operands[1]) != CONST_DOUBLE
2872        || memory_operand (operands[0], XFmode))"
2873 {
2874   switch (which_alternative)
2875     {
2876     case 0:
2877     case 1:
2878       return output_387_reg_move (insn, operands);
2879
2880     case 2:
2881       return standard_80387_constant_opcode (operands[1]);
2882
2883     case 3: case 4:
2884       return "#";
2885     default:
2886       gcc_unreachable ();
2887     }
2888 }
2889   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2890    (set_attr "mode" "XF,XF,XF,SI,SI")])
2891
2892 (define_split
2893   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2894         (match_operand:XF 1 "general_operand" ""))]
2895   "reload_completed
2896    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2897    && ! (FP_REG_P (operands[0]) ||
2898          (GET_CODE (operands[0]) == SUBREG
2899           && FP_REG_P (SUBREG_REG (operands[0]))))
2900    && ! (FP_REG_P (operands[1]) ||
2901          (GET_CODE (operands[1]) == SUBREG
2902           && FP_REG_P (SUBREG_REG (operands[1]))))"
2903   [(const_int 0)]
2904   "ix86_split_long_move (operands); DONE;")
2905
2906 (define_insn "*movdf_internal_rex64"
2907   [(set (match_operand:DF 0 "nonimmediate_operand"
2908                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2909         (match_operand:DF 1 "general_operand"
2910                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2911   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2912    && (reload_in_progress || reload_completed
2913        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2914        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2915            && optimize_function_for_size_p (cfun)
2916            && standard_80387_constant_p (operands[1]))
2917        || GET_CODE (operands[1]) != CONST_DOUBLE
2918        || memory_operand (operands[0], DFmode))"
2919 {
2920   switch (which_alternative)
2921     {
2922     case 0:
2923     case 1:
2924       return output_387_reg_move (insn, operands);
2925
2926     case 2:
2927       return standard_80387_constant_opcode (operands[1]);
2928
2929     case 3:
2930     case 4:
2931       return "#";
2932
2933     case 5:
2934       switch (get_attr_mode (insn))
2935         {
2936         case MODE_V4SF:
2937           return "%vxorps\t%0, %d0";
2938         case MODE_V2DF:
2939           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2940             return "%vxorps\t%0, %d0";
2941           else
2942             return "%vxorpd\t%0, %d0";
2943         case MODE_TI:
2944           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2945             return "%vxorps\t%0, %d0";
2946           else
2947             return "%vpxor\t%0, %d0";
2948         default:
2949           gcc_unreachable ();
2950         }
2951     case 6:
2952     case 7:
2953     case 8:
2954       switch (get_attr_mode (insn))
2955         {
2956         case MODE_V4SF:
2957           return "%vmovaps\t{%1, %0|%0, %1}";
2958         case MODE_V2DF:
2959           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2960             return "%vmovaps\t{%1, %0|%0, %1}";
2961           else
2962             return "%vmovapd\t{%1, %0|%0, %1}";
2963         case MODE_TI:
2964           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2965             return "%vmovaps\t{%1, %0|%0, %1}";
2966           else
2967             return "%vmovdqa\t{%1, %0|%0, %1}";
2968         case MODE_DI:
2969           return "%vmovq\t{%1, %0|%0, %1}";
2970         case MODE_DF:
2971           if (TARGET_AVX)
2972             {
2973               if (REG_P (operands[0]) && REG_P (operands[1]))
2974                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2975               else
2976                 return "vmovsd\t{%1, %0|%0, %1}";
2977             }
2978           else
2979             return "movsd\t{%1, %0|%0, %1}";
2980         case MODE_V1DF:
2981           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2982         case MODE_V2SF:
2983           return "%vmovlps\t{%1, %d0|%d0, %1}";
2984         default:
2985           gcc_unreachable ();
2986         }
2987
2988     case 9:
2989     case 10:
2990     return "%vmovd\t{%1, %0|%0, %1}";
2991
2992     default:
2993       gcc_unreachable();
2994     }
2995 }
2996   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2997    (set (attr "prefix")
2998      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2999        (const_string "orig")
3000        (const_string "maybe_vex")))
3001    (set (attr "prefix_data16")
3002      (if_then_else (eq_attr "mode" "V1DF")
3003        (const_string "1")
3004        (const_string "*")))
3005    (set (attr "mode")
3006         (cond [(eq_attr "alternative" "0,1,2")
3007                  (const_string "DF")
3008                (eq_attr "alternative" "3,4,9,10")
3009                  (const_string "DI")
3010
3011                /* For SSE1, we have many fewer alternatives.  */
3012                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3013                  (cond [(eq_attr "alternative" "5,6")
3014                           (const_string "V4SF")
3015                        ]
3016                    (const_string "V2SF"))
3017
3018                /* xorps is one byte shorter.  */
3019                (eq_attr "alternative" "5")
3020                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3021                             (const_int 0))
3022                           (const_string "V4SF")
3023                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3024                             (const_int 0))
3025                           (const_string "TI")
3026                        ]
3027                        (const_string "V2DF"))
3028
3029                /* For architectures resolving dependencies on
3030                   whole SSE registers use APD move to break dependency
3031                   chains, otherwise use short move to avoid extra work.
3032
3033                   movaps encodes one byte shorter.  */
3034                (eq_attr "alternative" "6")
3035                  (cond
3036                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3037                         (const_int 0))
3038                       (const_string "V4SF")
3039                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3040                         (const_int 0))
3041                       (const_string "V2DF")
3042                    ]
3043                    (const_string "DF"))
3044                /* For architectures resolving dependencies on register
3045                   parts we may avoid extra work to zero out upper part
3046                   of register.  */
3047                (eq_attr "alternative" "7")
3048                  (if_then_else
3049                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3050                        (const_int 0))
3051                    (const_string "V1DF")
3052                    (const_string "DF"))
3053               ]
3054               (const_string "DF")))])
3055
3056 (define_insn "*movdf_internal"
3057   [(set (match_operand:DF 0 "nonimmediate_operand"
3058                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3059         (match_operand:DF 1 "general_operand"
3060                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3061   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3062    && optimize_function_for_speed_p (cfun)
3063    && TARGET_INTEGER_DFMODE_MOVES
3064    && (reload_in_progress || reload_completed
3065        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3066        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3067            && optimize_function_for_size_p (cfun)
3068            && standard_80387_constant_p (operands[1]))
3069        || GET_CODE (operands[1]) != CONST_DOUBLE
3070        || memory_operand (operands[0], DFmode))"
3071 {
3072   switch (which_alternative)
3073     {
3074     case 0:
3075     case 1:
3076       return output_387_reg_move (insn, operands);
3077
3078     case 2:
3079       return standard_80387_constant_opcode (operands[1]);
3080
3081     case 3:
3082     case 4:
3083       return "#";
3084
3085     case 5:
3086       switch (get_attr_mode (insn))
3087         {
3088         case MODE_V4SF:
3089           return "xorps\t%0, %0";
3090         case MODE_V2DF:
3091           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3092             return "xorps\t%0, %0";
3093           else
3094             return "xorpd\t%0, %0";
3095         case MODE_TI:
3096           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3097             return "xorps\t%0, %0";
3098           else
3099             return "pxor\t%0, %0";
3100         default:
3101           gcc_unreachable ();
3102         }
3103     case 6:
3104     case 7:
3105     case 8:
3106       switch (get_attr_mode (insn))
3107         {
3108         case MODE_V4SF:
3109           return "movaps\t{%1, %0|%0, %1}";
3110         case MODE_V2DF:
3111           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3112             return "movaps\t{%1, %0|%0, %1}";
3113           else
3114             return "movapd\t{%1, %0|%0, %1}";
3115         case MODE_TI:
3116           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3117             return "movaps\t{%1, %0|%0, %1}";
3118           else
3119             return "movdqa\t{%1, %0|%0, %1}";
3120         case MODE_DI:
3121           return "movq\t{%1, %0|%0, %1}";
3122         case MODE_DF:
3123           return "movsd\t{%1, %0|%0, %1}";
3124         case MODE_V1DF:
3125           return "movlpd\t{%1, %0|%0, %1}";
3126         case MODE_V2SF:
3127           return "movlps\t{%1, %0|%0, %1}";
3128         default:
3129           gcc_unreachable ();
3130         }
3131
3132     default:
3133       gcc_unreachable();
3134     }
3135 }
3136   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3137    (set (attr "prefix_data16")
3138      (if_then_else (eq_attr "mode" "V1DF")
3139        (const_string "1")
3140        (const_string "*")))
3141    (set (attr "mode")
3142         (cond [(eq_attr "alternative" "0,1,2")
3143                  (const_string "DF")
3144                (eq_attr "alternative" "3,4")
3145                  (const_string "SI")
3146
3147                /* For SSE1, we have many fewer alternatives.  */
3148                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3149                  (cond [(eq_attr "alternative" "5,6")
3150                           (const_string "V4SF")
3151                        ]
3152                    (const_string "V2SF"))
3153
3154                /* xorps is one byte shorter.  */
3155                (eq_attr "alternative" "5")
3156                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3157                             (const_int 0))
3158                           (const_string "V4SF")
3159                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3160                             (const_int 0))
3161                           (const_string "TI")
3162                        ]
3163                        (const_string "V2DF"))
3164
3165                /* For architectures resolving dependencies on
3166                   whole SSE registers use APD move to break dependency
3167                   chains, otherwise use short move to avoid extra work.
3168
3169                   movaps encodes one byte shorter.  */
3170                (eq_attr "alternative" "6")
3171                  (cond
3172                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3173                         (const_int 0))
3174                       (const_string "V4SF")
3175                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3176                         (const_int 0))
3177                       (const_string "V2DF")
3178                    ]
3179                    (const_string "DF"))
3180                /* For architectures resolving dependencies on register
3181                   parts we may avoid extra work to zero out upper part
3182                   of register.  */
3183                (eq_attr "alternative" "7")
3184                  (if_then_else
3185                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3186                        (const_int 0))
3187                    (const_string "V1DF")
3188                    (const_string "DF"))
3189               ]
3190               (const_string "DF")))])
3191
3192 ;; Moving is usually shorter when only FP registers are used. This separate
3193 ;; movdf pattern avoids the use of integer registers for FP operations
3194 ;; when optimizing for size.
3195
3196 (define_insn "*movdf_internal_nointeger"
3197   [(set (match_operand:DF 0 "nonimmediate_operand"
3198                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3199         (match_operand:DF 1 "general_operand"
3200                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3201   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3202    && ((optimize_function_for_size_p (cfun)
3203        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3204    && (reload_in_progress || reload_completed
3205        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3206        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3207            && optimize_function_for_size_p (cfun)
3208            && !memory_operand (operands[0], DFmode)
3209            && standard_80387_constant_p (operands[1]))
3210        || GET_CODE (operands[1]) != CONST_DOUBLE
3211        || ((optimize_function_for_size_p (cfun)
3212             || !TARGET_MEMORY_MISMATCH_STALL
3213             || reload_in_progress || reload_completed)
3214            && memory_operand (operands[0], DFmode)))"
3215 {
3216   switch (which_alternative)
3217     {
3218     case 0:
3219     case 1:
3220       return output_387_reg_move (insn, operands);
3221
3222     case 2:
3223       return standard_80387_constant_opcode (operands[1]);
3224
3225     case 3:
3226     case 4:
3227       return "#";
3228
3229     case 5:
3230       switch (get_attr_mode (insn))
3231         {
3232         case MODE_V4SF:
3233           return "%vxorps\t%0, %d0";
3234         case MODE_V2DF:
3235           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3236             return "%vxorps\t%0, %d0";
3237           else
3238             return "%vxorpd\t%0, %d0";
3239         case MODE_TI:
3240           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3241             return "%vxorps\t%0, %d0";
3242           else
3243             return "%vpxor\t%0, %d0";
3244         default:
3245           gcc_unreachable ();
3246         }
3247     case 6:
3248     case 7:
3249     case 8:
3250       switch (get_attr_mode (insn))
3251         {
3252         case MODE_V4SF:
3253           return "%vmovaps\t{%1, %0|%0, %1}";
3254         case MODE_V2DF:
3255           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3256             return "%vmovaps\t{%1, %0|%0, %1}";
3257           else
3258             return "%vmovapd\t{%1, %0|%0, %1}";
3259         case MODE_TI:
3260           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3261             return "%vmovaps\t{%1, %0|%0, %1}";
3262           else
3263             return "%vmovdqa\t{%1, %0|%0, %1}";
3264         case MODE_DI:
3265           return "%vmovq\t{%1, %0|%0, %1}";
3266         case MODE_DF:
3267           if (TARGET_AVX)
3268             {
3269               if (REG_P (operands[0]) && REG_P (operands[1]))
3270                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3271               else
3272                 return "vmovsd\t{%1, %0|%0, %1}";
3273             }
3274           else
3275             return "movsd\t{%1, %0|%0, %1}";
3276         case MODE_V1DF:
3277           if (TARGET_AVX)
3278             {
3279               if (REG_P (operands[0]))
3280                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3281               else
3282                 return "vmovlpd\t{%1, %0|%0, %1}";
3283             }
3284           else
3285             return "movlpd\t{%1, %0|%0, %1}";
3286         case MODE_V2SF:
3287           if (TARGET_AVX)
3288             {
3289               if (REG_P (operands[0]))
3290                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3291               else
3292                 return "vmovlps\t{%1, %0|%0, %1}";
3293             }
3294           else
3295             return "movlps\t{%1, %0|%0, %1}";
3296         default:
3297           gcc_unreachable ();
3298         }
3299
3300     default:
3301       gcc_unreachable ();
3302     }
3303 }
3304   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3305    (set (attr "prefix")
3306      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3307        (const_string "orig")
3308        (const_string "maybe_vex")))
3309    (set (attr "prefix_data16")
3310      (if_then_else (eq_attr "mode" "V1DF")
3311        (const_string "1")
3312        (const_string "*")))
3313    (set (attr "mode")
3314         (cond [(eq_attr "alternative" "0,1,2")
3315                  (const_string "DF")
3316                (eq_attr "alternative" "3,4")
3317                  (const_string "SI")
3318
3319                /* For SSE1, we have many fewer alternatives.  */
3320                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3321                  (cond [(eq_attr "alternative" "5,6")
3322                           (const_string "V4SF")
3323                        ]
3324                    (const_string "V2SF"))
3325
3326                /* xorps is one byte shorter.  */
3327                (eq_attr "alternative" "5")
3328                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3329                             (const_int 0))
3330                           (const_string "V4SF")
3331                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3332                             (const_int 0))
3333                           (const_string "TI")
3334                        ]
3335                        (const_string "V2DF"))
3336
3337                /* For architectures resolving dependencies on
3338                   whole SSE registers use APD move to break dependency
3339                   chains, otherwise use short move to avoid extra work.
3340
3341                   movaps encodes one byte shorter.  */
3342                (eq_attr "alternative" "6")
3343                  (cond
3344                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3345                         (const_int 0))
3346                       (const_string "V4SF")
3347                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3348                         (const_int 0))
3349                       (const_string "V2DF")
3350                    ]
3351                    (const_string "DF"))
3352                /* For architectures resolving dependencies on register
3353                   parts we may avoid extra work to zero out upper part
3354                   of register.  */
3355                (eq_attr "alternative" "7")
3356                  (if_then_else
3357                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3358                        (const_int 0))
3359                    (const_string "V1DF")
3360                    (const_string "DF"))
3361               ]
3362               (const_string "DF")))])
3363
3364 (define_split
3365   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3366         (match_operand:DF 1 "general_operand" ""))]
3367   "reload_completed
3368    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3369    && ! (ANY_FP_REG_P (operands[0]) ||
3370          (GET_CODE (operands[0]) == SUBREG
3371           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3372    && ! (ANY_FP_REG_P (operands[1]) ||
3373          (GET_CODE (operands[1]) == SUBREG
3374           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3375   [(const_int 0)]
3376   "ix86_split_long_move (operands); DONE;")
3377
3378 (define_insn "*movsf_internal"
3379   [(set (match_operand:SF 0 "nonimmediate_operand"
3380           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3381         (match_operand:SF 1 "general_operand"
3382           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3383   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3384    && (reload_in_progress || reload_completed
3385        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3386        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3387            && standard_80387_constant_p (operands[1]))
3388        || GET_CODE (operands[1]) != CONST_DOUBLE
3389        || memory_operand (operands[0], SFmode))"
3390 {
3391   switch (which_alternative)
3392     {
3393     case 0:
3394     case 1:
3395       return output_387_reg_move (insn, operands);
3396
3397     case 2:
3398       return standard_80387_constant_opcode (operands[1]);
3399
3400     case 3:
3401     case 4:
3402       return "mov{l}\t{%1, %0|%0, %1}";
3403     case 5:
3404       if (get_attr_mode (insn) == MODE_TI)
3405         return "%vpxor\t%0, %d0";
3406       else
3407         return "%vxorps\t%0, %d0";
3408     case 6:
3409       if (get_attr_mode (insn) == MODE_V4SF)
3410         return "%vmovaps\t{%1, %0|%0, %1}";
3411       else
3412         return "%vmovss\t{%1, %d0|%d0, %1}";
3413     case 7:
3414       if (TARGET_AVX)
3415         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3416                                    : "vmovss\t{%1, %0|%0, %1}";
3417       else
3418         return "movss\t{%1, %0|%0, %1}";
3419     case 8:
3420       return "%vmovss\t{%1, %0|%0, %1}";
3421
3422     case 9: case 10: case 14: case 15:
3423       return "movd\t{%1, %0|%0, %1}";
3424     case 12: case 13:
3425       return "%vmovd\t{%1, %0|%0, %1}";
3426
3427     case 11:
3428       return "movq\t{%1, %0|%0, %1}";
3429
3430     default:
3431       gcc_unreachable ();
3432     }
3433 }
3434   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3435    (set (attr "prefix")
3436      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3437        (const_string "maybe_vex")
3438        (const_string "orig")))
3439    (set (attr "mode")
3440         (cond [(eq_attr "alternative" "3,4,9,10")
3441                  (const_string "SI")
3442                (eq_attr "alternative" "5")
3443                  (if_then_else
3444                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3445                                  (const_int 0))
3446                              (ne (symbol_ref "TARGET_SSE2")
3447                                  (const_int 0)))
3448                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3449                             (const_int 0)))
3450                    (const_string "TI")
3451                    (const_string "V4SF"))
3452                /* For architectures resolving dependencies on
3453                   whole SSE registers use APS move to break dependency
3454                   chains, otherwise use short move to avoid extra work.
3455
3456                   Do the same for architectures resolving dependencies on
3457                   the parts.  While in DF mode it is better to always handle
3458                   just register parts, the SF mode is different due to lack
3459                   of instructions to load just part of the register.  It is
3460                   better to maintain the whole registers in single format
3461                   to avoid problems on using packed logical operations.  */
3462                (eq_attr "alternative" "6")
3463                  (if_then_else
3464                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3465                             (const_int 0))
3466                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3467                             (const_int 0)))
3468                    (const_string "V4SF")
3469                    (const_string "SF"))
3470                (eq_attr "alternative" "11")
3471                  (const_string "DI")]
3472                (const_string "SF")))])
3473
3474 (define_split
3475   [(set (match_operand 0 "register_operand" "")
3476         (match_operand 1 "memory_operand" ""))]
3477   "reload_completed
3478    && MEM_P (operands[1])
3479    && (GET_MODE (operands[0]) == TFmode
3480        || GET_MODE (operands[0]) == XFmode
3481        || GET_MODE (operands[0]) == DFmode
3482        || GET_MODE (operands[0]) == SFmode)
3483    && (operands[2] = find_constant_src (insn))"
3484   [(set (match_dup 0) (match_dup 2))]
3485 {
3486   rtx c = operands[2];
3487   rtx r = operands[0];
3488
3489   if (GET_CODE (r) == SUBREG)
3490     r = SUBREG_REG (r);
3491
3492   if (SSE_REG_P (r))
3493     {
3494       if (!standard_sse_constant_p (c))
3495         FAIL;
3496     }
3497   else if (FP_REG_P (r))
3498     {
3499       if (!standard_80387_constant_p (c))
3500         FAIL;
3501     }
3502   else if (MMX_REG_P (r))
3503     FAIL;
3504 })
3505
3506 (define_split
3507   [(set (match_operand 0 "register_operand" "")
3508         (float_extend (match_operand 1 "memory_operand" "")))]
3509   "reload_completed
3510    && MEM_P (operands[1])
3511    && (GET_MODE (operands[0]) == TFmode
3512        || GET_MODE (operands[0]) == XFmode
3513        || GET_MODE (operands[0]) == DFmode
3514        || GET_MODE (operands[0]) == SFmode)
3515    && (operands[2] = find_constant_src (insn))"
3516   [(set (match_dup 0) (match_dup 2))]
3517 {
3518   rtx c = operands[2];
3519   rtx r = operands[0];
3520
3521   if (GET_CODE (r) == SUBREG)
3522     r = SUBREG_REG (r);
3523
3524   if (SSE_REG_P (r))
3525     {
3526       if (!standard_sse_constant_p (c))
3527         FAIL;
3528     }
3529   else if (FP_REG_P (r))
3530     {
3531       if (!standard_80387_constant_p (c))
3532         FAIL;
3533     }
3534   else if (MMX_REG_P (r))
3535     FAIL;
3536 })
3537
3538 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3539 (define_split
3540   [(set (match_operand:X87MODEF 0 "register_operand" "")
3541         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3542   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3543    && (standard_80387_constant_p (operands[1]) == 8
3544        || standard_80387_constant_p (operands[1]) == 9)"
3545   [(set (match_dup 0)(match_dup 1))
3546    (set (match_dup 0)
3547         (neg:X87MODEF (match_dup 0)))]
3548 {
3549   REAL_VALUE_TYPE r;
3550
3551   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3552   if (real_isnegzero (&r))
3553     operands[1] = CONST0_RTX (<MODE>mode);
3554   else
3555     operands[1] = CONST1_RTX (<MODE>mode);
3556 })
3557
3558 (define_insn "swapxf"
3559   [(set (match_operand:XF 0 "register_operand" "+f")
3560         (match_operand:XF 1 "register_operand" "+f"))
3561    (set (match_dup 1)
3562         (match_dup 0))]
3563   "TARGET_80387"
3564 {
3565   if (STACK_TOP_P (operands[0]))
3566     return "fxch\t%1";
3567   else
3568     return "fxch\t%0";
3569 }
3570   [(set_attr "type" "fxch")
3571    (set_attr "mode" "XF")])
3572
3573 (define_insn "*swap<mode>"
3574   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3575         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3576    (set (match_dup 1)
3577         (match_dup 0))]
3578   "TARGET_80387 || reload_completed"
3579 {
3580   if (STACK_TOP_P (operands[0]))
3581     return "fxch\t%1";
3582   else
3583     return "fxch\t%0";
3584 }
3585   [(set_attr "type" "fxch")
3586    (set_attr "mode" "<MODE>")])
3587 \f
3588 ;; Zero extension instructions
3589
3590 (define_expand "zero_extendsidi2"
3591   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3592         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3593   ""
3594 {
3595   if (!TARGET_64BIT)
3596     {
3597       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3598       DONE;
3599     }
3600 })
3601
3602 (define_insn "*zero_extendsidi2_rex64"
3603   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3604         (zero_extend:DI
3605          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3606   "TARGET_64BIT"
3607   "@
3608    mov\t{%k1, %k0|%k0, %k1}
3609    #
3610    movd\t{%1, %0|%0, %1}
3611    movd\t{%1, %0|%0, %1}
3612    %vmovd\t{%1, %0|%0, %1}
3613    %vmovd\t{%1, %0|%0, %1}"
3614   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3615    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3616    (set_attr "prefix_0f" "0,*,*,*,*,*")
3617    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3618
3619 (define_split
3620   [(set (match_operand:DI 0 "memory_operand" "")
3621         (zero_extend:DI (match_dup 0)))]
3622   "TARGET_64BIT"
3623   [(set (match_dup 4) (const_int 0))]
3624   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3625
3626 ;; %%% Kill me once multi-word ops are sane.
3627 (define_insn "zero_extendsidi2_1"
3628   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3629         (zero_extend:DI
3630          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3631    (clobber (reg:CC FLAGS_REG))]
3632   "!TARGET_64BIT"
3633   "@
3634    #
3635    #
3636    #
3637    movd\t{%1, %0|%0, %1}
3638    movd\t{%1, %0|%0, %1}
3639    %vmovd\t{%1, %0|%0, %1}
3640    %vmovd\t{%1, %0|%0, %1}"
3641   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3642    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3643    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3644
3645 (define_split
3646   [(set (match_operand:DI 0 "register_operand" "")
3647         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3648    (clobber (reg:CC FLAGS_REG))]
3649   "!TARGET_64BIT && reload_completed
3650    && true_regnum (operands[0]) == true_regnum (operands[1])"
3651   [(set (match_dup 4) (const_int 0))]
3652   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3653
3654 (define_split
3655   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3656         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3657    (clobber (reg:CC FLAGS_REG))]
3658   "!TARGET_64BIT && reload_completed
3659    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3660   [(set (match_dup 3) (match_dup 1))
3661    (set (match_dup 4) (const_int 0))]
3662   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3663
3664 (define_insn "zero_extend<mode>di2"
3665   [(set (match_operand:DI 0 "register_operand" "=r")
3666         (zero_extend:DI
3667          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3668   "TARGET_64BIT"
3669   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3670   [(set_attr "type" "imovx")
3671    (set_attr "mode" "SI")])
3672
3673 (define_expand "zero_extendhisi2"
3674   [(set (match_operand:SI 0 "register_operand" "")
3675         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3676   ""
3677 {
3678   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3679     {
3680       operands[1] = force_reg (HImode, operands[1]);
3681       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3682       DONE;
3683     }
3684 })
3685
3686 (define_insn_and_split "zero_extendhisi2_and"
3687   [(set (match_operand:SI 0 "register_operand" "=r")
3688         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3689    (clobber (reg:CC FLAGS_REG))]
3690   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3691   "#"
3692   "&& reload_completed"
3693   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3694               (clobber (reg:CC FLAGS_REG))])]
3695   ""
3696   [(set_attr "type" "alu1")
3697    (set_attr "mode" "SI")])
3698
3699 (define_insn "*zero_extendhisi2_movzwl"
3700   [(set (match_operand:SI 0 "register_operand" "=r")
3701         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3702   "!TARGET_ZERO_EXTEND_WITH_AND
3703    || optimize_function_for_size_p (cfun)"
3704   "movz{wl|x}\t{%1, %0|%0, %1}"
3705   [(set_attr "type" "imovx")
3706    (set_attr "mode" "SI")])
3707
3708 (define_expand "zero_extendqi<mode>2"
3709   [(parallel
3710     [(set (match_operand:SWI24 0 "register_operand" "")
3711           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3712      (clobber (reg:CC FLAGS_REG))])])
3713
3714 (define_insn "*zero_extendqi<mode>2_and"
3715   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3716         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3717    (clobber (reg:CC FLAGS_REG))]
3718   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3719   "#"
3720   [(set_attr "type" "alu1")
3721    (set_attr "mode" "<MODE>")])
3722
3723 ;; When source and destination does not overlap, clear destination
3724 ;; first and then do the movb
3725 (define_split
3726   [(set (match_operand:SWI24 0 "register_operand" "")
3727         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3728    (clobber (reg:CC FLAGS_REG))]
3729   "reload_completed
3730    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3731    && ANY_QI_REG_P (operands[0])
3732    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3733    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3734   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3735 {
3736   operands[2] = gen_lowpart (QImode, operands[0]);
3737   ix86_expand_clear (operands[0]);
3738 })
3739
3740 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3741   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3742         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3743    (clobber (reg:CC FLAGS_REG))]
3744   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3745   "#"
3746   [(set_attr "type" "imovx,alu1")
3747    (set_attr "mode" "<MODE>")])
3748
3749 ;; For the movzbl case strip only the clobber
3750 (define_split
3751   [(set (match_operand:SWI24 0 "register_operand" "")
3752         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3753    (clobber (reg:CC FLAGS_REG))]
3754   "reload_completed
3755    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3756    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3757   [(set (match_dup 0)
3758         (zero_extend:SWI24 (match_dup 1)))])
3759
3760 ; zero extend to SImode to avoid partial register stalls
3761 (define_insn "*zero_extendqi<mode>2_movzbl"
3762   [(set (match_operand:SWI24 0 "register_operand" "=r")
3763         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3764   "reload_completed
3765    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3766   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3767   [(set_attr "type" "imovx")
3768    (set_attr "mode" "SI")])
3769
3770 ;; Rest is handled by single and.
3771 (define_split
3772   [(set (match_operand:SWI24 0 "register_operand" "")
3773         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3774    (clobber (reg:CC FLAGS_REG))]
3775   "reload_completed
3776    && true_regnum (operands[0]) == true_regnum (operands[1])"
3777   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3778               (clobber (reg:CC FLAGS_REG))])])
3779 \f
3780 ;; Sign extension instructions
3781
3782 (define_expand "extendsidi2"
3783   [(set (match_operand:DI 0 "register_operand" "")
3784         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3785   ""
3786 {
3787   if (!TARGET_64BIT)
3788     {
3789       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3790       DONE;
3791     }
3792 })
3793
3794 (define_insn "*extendsidi2_rex64"
3795   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3796         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3797   "TARGET_64BIT"
3798   "@
3799    {cltq|cdqe}
3800    movs{lq|x}\t{%1, %0|%0, %1}"
3801   [(set_attr "type" "imovx")
3802    (set_attr "mode" "DI")
3803    (set_attr "prefix_0f" "0")
3804    (set_attr "modrm" "0,1")])
3805
3806 (define_insn "extendsidi2_1"
3807   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3808         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3809    (clobber (reg:CC FLAGS_REG))
3810    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3811   "!TARGET_64BIT"
3812   "#")
3813
3814 ;; Extend to memory case when source register does die.
3815 (define_split
3816   [(set (match_operand:DI 0 "memory_operand" "")
3817         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3818    (clobber (reg:CC FLAGS_REG))
3819    (clobber (match_operand:SI 2 "register_operand" ""))]
3820   "(reload_completed
3821     && dead_or_set_p (insn, operands[1])
3822     && !reg_mentioned_p (operands[1], operands[0]))"
3823   [(set (match_dup 3) (match_dup 1))
3824    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3825               (clobber (reg:CC FLAGS_REG))])
3826    (set (match_dup 4) (match_dup 1))]
3827   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3828
3829 ;; Extend to memory case when source register does not die.
3830 (define_split
3831   [(set (match_operand:DI 0 "memory_operand" "")
3832         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3833    (clobber (reg:CC FLAGS_REG))
3834    (clobber (match_operand:SI 2 "register_operand" ""))]
3835   "reload_completed"
3836   [(const_int 0)]
3837 {
3838   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3839
3840   emit_move_insn (operands[3], operands[1]);
3841
3842   /* Generate a cltd if possible and doing so it profitable.  */
3843   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3844       && true_regnum (operands[1]) == AX_REG
3845       && true_regnum (operands[2]) == DX_REG)
3846     {
3847       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3848     }
3849   else
3850     {
3851       emit_move_insn (operands[2], operands[1]);
3852       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3853     }
3854   emit_move_insn (operands[4], operands[2]);
3855   DONE;
3856 })
3857
3858 ;; Extend to register case.  Optimize case where source and destination
3859 ;; registers match and cases where we can use cltd.
3860 (define_split
3861   [(set (match_operand:DI 0 "register_operand" "")
3862         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3863    (clobber (reg:CC FLAGS_REG))
3864    (clobber (match_scratch:SI 2 ""))]
3865   "reload_completed"
3866   [(const_int 0)]
3867 {
3868   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3869
3870   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3871     emit_move_insn (operands[3], operands[1]);
3872
3873   /* Generate a cltd if possible and doing so it profitable.  */
3874   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3875       && true_regnum (operands[3]) == AX_REG
3876       && true_regnum (operands[4]) == DX_REG)
3877     {
3878       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3879       DONE;
3880     }
3881
3882   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3883     emit_move_insn (operands[4], operands[1]);
3884
3885   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3886   DONE;
3887 })
3888
3889 (define_insn "extend<mode>di2"
3890   [(set (match_operand:DI 0 "register_operand" "=r")
3891         (sign_extend:DI
3892          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3893   "TARGET_64BIT"
3894   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3895   [(set_attr "type" "imovx")
3896    (set_attr "mode" "DI")])
3897
3898 (define_insn "extendhisi2"
3899   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3900         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3901   ""
3902 {
3903   switch (get_attr_prefix_0f (insn))
3904     {
3905     case 0:
3906       return "{cwtl|cwde}";
3907     default:
3908       return "movs{wl|x}\t{%1, %0|%0, %1}";
3909     }
3910 }
3911   [(set_attr "type" "imovx")
3912    (set_attr "mode" "SI")
3913    (set (attr "prefix_0f")
3914      ;; movsx is short decodable while cwtl is vector decoded.
3915      (if_then_else (and (eq_attr "cpu" "!k6")
3916                         (eq_attr "alternative" "0"))
3917         (const_string "0")
3918         (const_string "1")))
3919    (set (attr "modrm")
3920      (if_then_else (eq_attr "prefix_0f" "0")
3921         (const_string "0")
3922         (const_string "1")))])
3923
3924 (define_insn "*extendhisi2_zext"
3925   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3926         (zero_extend:DI
3927          (sign_extend:SI
3928           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3929   "TARGET_64BIT"
3930 {
3931   switch (get_attr_prefix_0f (insn))
3932     {
3933     case 0:
3934       return "{cwtl|cwde}";
3935     default:
3936       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3937     }
3938 }
3939   [(set_attr "type" "imovx")
3940    (set_attr "mode" "SI")
3941    (set (attr "prefix_0f")
3942      ;; movsx is short decodable while cwtl is vector decoded.
3943      (if_then_else (and (eq_attr "cpu" "!k6")
3944                         (eq_attr "alternative" "0"))
3945         (const_string "0")
3946         (const_string "1")))
3947    (set (attr "modrm")
3948      (if_then_else (eq_attr "prefix_0f" "0")
3949         (const_string "0")
3950         (const_string "1")))])
3951
3952 (define_insn "extendqisi2"
3953   [(set (match_operand:SI 0 "register_operand" "=r")
3954         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3955   ""
3956   "movs{bl|x}\t{%1, %0|%0, %1}"
3957    [(set_attr "type" "imovx")
3958     (set_attr "mode" "SI")])
3959
3960 (define_insn "*extendqisi2_zext"
3961   [(set (match_operand:DI 0 "register_operand" "=r")
3962         (zero_extend:DI
3963           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3964   "TARGET_64BIT"
3965   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3966    [(set_attr "type" "imovx")
3967     (set_attr "mode" "SI")])
3968
3969 (define_insn "extendqihi2"
3970   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3971         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3972   ""
3973 {
3974   switch (get_attr_prefix_0f (insn))
3975     {
3976     case 0:
3977       return "{cbtw|cbw}";
3978     default:
3979       return "movs{bw|x}\t{%1, %0|%0, %1}";
3980     }
3981 }
3982   [(set_attr "type" "imovx")
3983    (set_attr "mode" "HI")
3984    (set (attr "prefix_0f")
3985      ;; movsx is short decodable while cwtl is vector decoded.
3986      (if_then_else (and (eq_attr "cpu" "!k6")
3987                         (eq_attr "alternative" "0"))
3988         (const_string "0")
3989         (const_string "1")))
3990    (set (attr "modrm")
3991      (if_then_else (eq_attr "prefix_0f" "0")
3992         (const_string "0")
3993         (const_string "1")))])
3994 \f
3995 ;; Conversions between float and double.
3996
3997 ;; These are all no-ops in the model used for the 80387.
3998 ;; So just emit moves.
3999
4000 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4001 (define_split
4002   [(set (match_operand:DF 0 "push_operand" "")
4003         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4004   "reload_completed"
4005   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4006    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4007
4008 (define_split
4009   [(set (match_operand:XF 0 "push_operand" "")
4010         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4011   "reload_completed"
4012   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4013    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4014   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4015
4016 (define_expand "extendsfdf2"
4017   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4018         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4019   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4020 {
4021   /* ??? Needed for compress_float_constant since all fp constants
4022      are LEGITIMATE_CONSTANT_P.  */
4023   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4024     {
4025       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4026           && standard_80387_constant_p (operands[1]) > 0)
4027         {
4028           operands[1] = simplify_const_unary_operation
4029             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4030           emit_move_insn_1 (operands[0], operands[1]);
4031           DONE;
4032         }
4033       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4034     }
4035 })
4036
4037 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4038    cvtss2sd:
4039       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4040       cvtps2pd xmm2,xmm1
4041    We do the conversion post reload to avoid producing of 128bit spills
4042    that might lead to ICE on 32bit target.  The sequence unlikely combine
4043    anyway.  */
4044 (define_split
4045   [(set (match_operand:DF 0 "register_operand" "")
4046         (float_extend:DF
4047           (match_operand:SF 1 "nonimmediate_operand" "")))]
4048   "TARGET_USE_VECTOR_FP_CONVERTS
4049    && optimize_insn_for_speed_p ()
4050    && reload_completed && SSE_REG_P (operands[0])"
4051    [(set (match_dup 2)
4052          (float_extend:V2DF
4053            (vec_select:V2SF
4054              (match_dup 3)
4055              (parallel [(const_int 0) (const_int 1)]))))]
4056 {
4057   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4058   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4059   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4060      Try to avoid move when unpacking can be done in source.  */
4061   if (REG_P (operands[1]))
4062     {
4063       /* If it is unsafe to overwrite upper half of source, we need
4064          to move to destination and unpack there.  */
4065       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4066            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4067           && true_regnum (operands[0]) != true_regnum (operands[1]))
4068         {
4069           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4070           emit_move_insn (tmp, operands[1]);
4071         }
4072       else
4073         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4074       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4075                                              operands[3]));
4076     }
4077   else
4078     emit_insn (gen_vec_setv4sf_0 (operands[3],
4079                                   CONST0_RTX (V4SFmode), operands[1]));
4080 })
4081
4082 (define_insn "*extendsfdf2_mixed"
4083   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4084         (float_extend:DF
4085           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4086   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4087 {
4088   switch (which_alternative)
4089     {
4090     case 0:
4091     case 1:
4092       return output_387_reg_move (insn, operands);
4093
4094     case 2:
4095       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4096
4097     default:
4098       gcc_unreachable ();
4099     }
4100 }
4101   [(set_attr "type" "fmov,fmov,ssecvt")
4102    (set_attr "prefix" "orig,orig,maybe_vex")
4103    (set_attr "mode" "SF,XF,DF")])
4104
4105 (define_insn "*extendsfdf2_sse"
4106   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4107         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4108   "TARGET_SSE2 && TARGET_SSE_MATH"
4109   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4110   [(set_attr "type" "ssecvt")
4111    (set_attr "prefix" "maybe_vex")
4112    (set_attr "mode" "DF")])
4113
4114 (define_insn "*extendsfdf2_i387"
4115   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4116         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4117   "TARGET_80387"
4118   "* return output_387_reg_move (insn, operands);"
4119   [(set_attr "type" "fmov")
4120    (set_attr "mode" "SF,XF")])
4121
4122 (define_expand "extend<mode>xf2"
4123   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4124         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4125   "TARGET_80387"
4126 {
4127   /* ??? Needed for compress_float_constant since all fp constants
4128      are LEGITIMATE_CONSTANT_P.  */
4129   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4130     {
4131       if (standard_80387_constant_p (operands[1]) > 0)
4132         {
4133           operands[1] = simplify_const_unary_operation
4134             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4135           emit_move_insn_1 (operands[0], operands[1]);
4136           DONE;
4137         }
4138       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4139     }
4140 })
4141
4142 (define_insn "*extend<mode>xf2_i387"
4143   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4144         (float_extend:XF
4145           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4146   "TARGET_80387"
4147   "* return output_387_reg_move (insn, operands);"
4148   [(set_attr "type" "fmov")
4149    (set_attr "mode" "<MODE>,XF")])
4150
4151 ;; %%% This seems bad bad news.
4152 ;; This cannot output into an f-reg because there is no way to be sure
4153 ;; of truncating in that case.  Otherwise this is just like a simple move
4154 ;; insn.  So we pretend we can output to a reg in order to get better
4155 ;; register preferencing, but we really use a stack slot.
4156
4157 ;; Conversion from DFmode to SFmode.
4158
4159 (define_expand "truncdfsf2"
4160   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4161         (float_truncate:SF
4162           (match_operand:DF 1 "nonimmediate_operand" "")))]
4163   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4164 {
4165   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4166     ;
4167   else if (flag_unsafe_math_optimizations)
4168     ;
4169   else
4170     {
4171       enum ix86_stack_slot slot = (virtuals_instantiated
4172                                    ? SLOT_TEMP
4173                                    : SLOT_VIRTUAL);
4174       rtx temp = assign_386_stack_local (SFmode, slot);
4175       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4176       DONE;
4177     }
4178 })
4179
4180 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4181    cvtsd2ss:
4182       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4183       cvtpd2ps xmm2,xmm1
4184    We do the conversion post reload to avoid producing of 128bit spills
4185    that might lead to ICE on 32bit target.  The sequence unlikely combine
4186    anyway.  */
4187 (define_split
4188   [(set (match_operand:SF 0 "register_operand" "")
4189         (float_truncate:SF
4190           (match_operand:DF 1 "nonimmediate_operand" "")))]
4191   "TARGET_USE_VECTOR_FP_CONVERTS
4192    && optimize_insn_for_speed_p ()
4193    && reload_completed && SSE_REG_P (operands[0])"
4194    [(set (match_dup 2)
4195          (vec_concat:V4SF
4196            (float_truncate:V2SF
4197              (match_dup 4))
4198            (match_dup 3)))]
4199 {
4200   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4201   operands[3] = CONST0_RTX (V2SFmode);
4202   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4203   /* Use movsd for loading from memory, unpcklpd for registers.
4204      Try to avoid move when unpacking can be done in source, or SSE3
4205      movddup is available.  */
4206   if (REG_P (operands[1]))
4207     {
4208       if (!TARGET_SSE3
4209           && true_regnum (operands[0]) != true_regnum (operands[1])
4210           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4211               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4212         {
4213           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4214           emit_move_insn (tmp, operands[1]);
4215           operands[1] = tmp;
4216         }
4217       else if (!TARGET_SSE3)
4218         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4219       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4220     }
4221   else
4222     emit_insn (gen_sse2_loadlpd (operands[4],
4223                                  CONST0_RTX (V2DFmode), operands[1]));
4224 })
4225
4226 (define_expand "truncdfsf2_with_temp"
4227   [(parallel [(set (match_operand:SF 0 "" "")
4228                    (float_truncate:SF (match_operand:DF 1 "" "")))
4229               (clobber (match_operand:SF 2 "" ""))])])
4230
4231 (define_insn "*truncdfsf_fast_mixed"
4232   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4233         (float_truncate:SF
4234           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4235   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4236 {
4237   switch (which_alternative)
4238     {
4239     case 0:
4240       return output_387_reg_move (insn, operands);
4241     case 1:
4242       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4243     default:
4244       gcc_unreachable ();
4245     }
4246 }
4247   [(set_attr "type" "fmov,ssecvt")
4248    (set_attr "prefix" "orig,maybe_vex")
4249    (set_attr "mode" "SF")])
4250
4251 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4252 ;; because nothing we do here is unsafe.
4253 (define_insn "*truncdfsf_fast_sse"
4254   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4255         (float_truncate:SF
4256           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4257   "TARGET_SSE2 && TARGET_SSE_MATH"
4258   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4259   [(set_attr "type" "ssecvt")
4260    (set_attr "prefix" "maybe_vex")
4261    (set_attr "mode" "SF")])
4262
4263 (define_insn "*truncdfsf_fast_i387"
4264   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4265         (float_truncate:SF
4266           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4267   "TARGET_80387 && flag_unsafe_math_optimizations"
4268   "* return output_387_reg_move (insn, operands);"
4269   [(set_attr "type" "fmov")
4270    (set_attr "mode" "SF")])
4271
4272 (define_insn "*truncdfsf_mixed"
4273   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4274         (float_truncate:SF
4275           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4276    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4277   "TARGET_MIX_SSE_I387"
4278 {
4279   switch (which_alternative)
4280     {
4281     case 0:
4282       return output_387_reg_move (insn, operands);
4283     case 1:
4284       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4285
4286     default:
4287       return "#";
4288     }
4289 }
4290   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4291    (set_attr "unit" "*,*,i387,i387,i387")
4292    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4293    (set_attr "mode" "SF")])
4294
4295 (define_insn "*truncdfsf_i387"
4296   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4297         (float_truncate:SF
4298           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4299    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4300   "TARGET_80387"
4301 {
4302   switch (which_alternative)
4303     {
4304     case 0:
4305       return output_387_reg_move (insn, operands);
4306
4307     default:
4308       return "#";
4309     }
4310 }
4311   [(set_attr "type" "fmov,multi,multi,multi")
4312    (set_attr "unit" "*,i387,i387,i387")
4313    (set_attr "mode" "SF")])
4314
4315 (define_insn "*truncdfsf2_i387_1"
4316   [(set (match_operand:SF 0 "memory_operand" "=m")
4317         (float_truncate:SF
4318           (match_operand:DF 1 "register_operand" "f")))]
4319   "TARGET_80387
4320    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4321    && !TARGET_MIX_SSE_I387"
4322   "* return output_387_reg_move (insn, operands);"
4323   [(set_attr "type" "fmov")
4324    (set_attr "mode" "SF")])
4325
4326 (define_split
4327   [(set (match_operand:SF 0 "register_operand" "")
4328         (float_truncate:SF
4329          (match_operand:DF 1 "fp_register_operand" "")))
4330    (clobber (match_operand 2 "" ""))]
4331   "reload_completed"
4332   [(set (match_dup 2) (match_dup 1))
4333    (set (match_dup 0) (match_dup 2))]
4334   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4335
4336 ;; Conversion from XFmode to {SF,DF}mode
4337
4338 (define_expand "truncxf<mode>2"
4339   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4340                    (float_truncate:MODEF
4341                      (match_operand:XF 1 "register_operand" "")))
4342               (clobber (match_dup 2))])]
4343   "TARGET_80387"
4344 {
4345   if (flag_unsafe_math_optimizations)
4346     {
4347       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4348       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4349       if (reg != operands[0])
4350         emit_move_insn (operands[0], reg);
4351       DONE;
4352     }
4353   else
4354     {
4355       enum ix86_stack_slot slot = (virtuals_instantiated
4356                                    ? SLOT_TEMP
4357                                    : SLOT_VIRTUAL);
4358       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4359     }
4360 })
4361
4362 (define_insn "*truncxfsf2_mixed"
4363   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4364         (float_truncate:SF
4365           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4366    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4367   "TARGET_80387"
4368 {
4369   gcc_assert (!which_alternative);
4370   return output_387_reg_move (insn, operands);
4371 }
4372   [(set_attr "type" "fmov,multi,multi,multi")
4373    (set_attr "unit" "*,i387,i387,i387")
4374    (set_attr "mode" "SF")])
4375
4376 (define_insn "*truncxfdf2_mixed"
4377   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4378         (float_truncate:DF
4379           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4380    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4381   "TARGET_80387"
4382 {
4383   gcc_assert (!which_alternative);
4384   return output_387_reg_move (insn, operands);
4385 }
4386   [(set_attr "type" "fmov,multi,multi,multi")
4387    (set_attr "unit" "*,i387,i387,i387")
4388    (set_attr "mode" "DF")])
4389
4390 (define_insn "truncxf<mode>2_i387_noop"
4391   [(set (match_operand:MODEF 0 "register_operand" "=f")
4392         (float_truncate:MODEF
4393           (match_operand:XF 1 "register_operand" "f")))]
4394   "TARGET_80387 && flag_unsafe_math_optimizations"
4395   "* return output_387_reg_move (insn, operands);"
4396   [(set_attr "type" "fmov")
4397    (set_attr "mode" "<MODE>")])
4398
4399 (define_insn "*truncxf<mode>2_i387"
4400   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4401         (float_truncate:MODEF
4402           (match_operand:XF 1 "register_operand" "f")))]
4403   "TARGET_80387"
4404   "* return output_387_reg_move (insn, operands);"
4405   [(set_attr "type" "fmov")
4406    (set_attr "mode" "<MODE>")])
4407
4408 (define_split
4409   [(set (match_operand:MODEF 0 "register_operand" "")
4410         (float_truncate:MODEF
4411           (match_operand:XF 1 "register_operand" "")))
4412    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4413   "TARGET_80387 && reload_completed"
4414   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4415    (set (match_dup 0) (match_dup 2))])
4416
4417 (define_split
4418   [(set (match_operand:MODEF 0 "memory_operand" "")
4419         (float_truncate:MODEF
4420           (match_operand:XF 1 "register_operand" "")))
4421    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4422   "TARGET_80387"
4423   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4424 \f
4425 ;; Signed conversion to DImode.
4426
4427 (define_expand "fix_truncxfdi2"
4428   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4429                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4430               (clobber (reg:CC FLAGS_REG))])]
4431   "TARGET_80387"
4432 {
4433   if (TARGET_FISTTP)
4434    {
4435      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4436      DONE;
4437    }
4438 })
4439
4440 (define_expand "fix_trunc<mode>di2"
4441   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4442                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4443               (clobber (reg:CC FLAGS_REG))])]
4444   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4445 {
4446   if (TARGET_FISTTP
4447       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4448    {
4449      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4450      DONE;
4451    }
4452   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4453    {
4454      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4455      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4456      if (out != operands[0])
4457         emit_move_insn (operands[0], out);
4458      DONE;
4459    }
4460 })
4461
4462 ;; Signed conversion to SImode.
4463
4464 (define_expand "fix_truncxfsi2"
4465   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4466                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4467               (clobber (reg:CC FLAGS_REG))])]
4468   "TARGET_80387"
4469 {
4470   if (TARGET_FISTTP)
4471    {
4472      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4473      DONE;
4474    }
4475 })
4476
4477 (define_expand "fix_trunc<mode>si2"
4478   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4479                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4480               (clobber (reg:CC FLAGS_REG))])]
4481   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4482 {
4483   if (TARGET_FISTTP
4484       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4485    {
4486      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4487      DONE;
4488    }
4489   if (SSE_FLOAT_MODE_P (<MODE>mode))
4490    {
4491      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4492      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4493      if (out != operands[0])
4494         emit_move_insn (operands[0], out);
4495      DONE;
4496    }
4497 })
4498
4499 ;; Signed conversion to HImode.
4500
4501 (define_expand "fix_trunc<mode>hi2"
4502   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4503                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4504               (clobber (reg:CC FLAGS_REG))])]
4505   "TARGET_80387
4506    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4507 {
4508   if (TARGET_FISTTP)
4509    {
4510      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4511      DONE;
4512    }
4513 })
4514
4515 ;; Unsigned conversion to SImode.
4516
4517 (define_expand "fixuns_trunc<mode>si2"
4518   [(parallel
4519     [(set (match_operand:SI 0 "register_operand" "")
4520           (unsigned_fix:SI
4521             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4522      (use (match_dup 2))
4523      (clobber (match_scratch:<ssevecmode> 3 ""))
4524      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4525   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4526 {
4527   enum machine_mode mode = <MODE>mode;
4528   enum machine_mode vecmode = <ssevecmode>mode;
4529   REAL_VALUE_TYPE TWO31r;
4530   rtx two31;
4531
4532   if (optimize_insn_for_size_p ())
4533     FAIL;
4534
4535   real_ldexp (&TWO31r, &dconst1, 31);
4536   two31 = const_double_from_real_value (TWO31r, mode);
4537   two31 = ix86_build_const_vector (vecmode, true, two31);
4538   operands[2] = force_reg (vecmode, two31);
4539 })
4540
4541 (define_insn_and_split "*fixuns_trunc<mode>_1"
4542   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4543         (unsigned_fix:SI
4544           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4545    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4546    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4547    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4548   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4549    && optimize_function_for_speed_p (cfun)"
4550   "#"
4551   "&& reload_completed"
4552   [(const_int 0)]
4553 {
4554   ix86_split_convert_uns_si_sse (operands);
4555   DONE;
4556 })
4557
4558 ;; Unsigned conversion to HImode.
4559 ;; Without these patterns, we'll try the unsigned SI conversion which
4560 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4561
4562 (define_expand "fixuns_trunc<mode>hi2"
4563   [(set (match_dup 2)
4564         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4565    (set (match_operand:HI 0 "nonimmediate_operand" "")
4566         (subreg:HI (match_dup 2) 0))]
4567   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4568   "operands[2] = gen_reg_rtx (SImode);")
4569
4570 ;; When SSE is available, it is always faster to use it!
4571 (define_insn "fix_trunc<mode>di_sse"
4572   [(set (match_operand:DI 0 "register_operand" "=r,r")
4573         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4574   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4575    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4576   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4577   [(set_attr "type" "sseicvt")
4578    (set_attr "prefix" "maybe_vex")
4579    (set_attr "prefix_rex" "1")
4580    (set_attr "mode" "<MODE>")
4581    (set_attr "athlon_decode" "double,vector")
4582    (set_attr "amdfam10_decode" "double,double")
4583    (set_attr "bdver1_decode" "double,double")])
4584
4585 (define_insn "fix_trunc<mode>si_sse"
4586   [(set (match_operand:SI 0 "register_operand" "=r,r")
4587         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4588   "SSE_FLOAT_MODE_P (<MODE>mode)
4589    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4590   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4591   [(set_attr "type" "sseicvt")
4592    (set_attr "prefix" "maybe_vex")
4593    (set_attr "mode" "<MODE>")
4594    (set_attr "athlon_decode" "double,vector")
4595    (set_attr "amdfam10_decode" "double,double")
4596    (set_attr "bdver1_decode" "double,double")])
4597
4598 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4599 (define_peephole2
4600   [(set (match_operand:MODEF 0 "register_operand" "")
4601         (match_operand:MODEF 1 "memory_operand" ""))
4602    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4603         (fix:SSEMODEI24 (match_dup 0)))]
4604   "TARGET_SHORTEN_X87_SSE
4605    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4606    && peep2_reg_dead_p (2, operands[0])"
4607   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4608
4609 ;; Avoid vector decoded forms of the instruction.
4610 (define_peephole2
4611   [(match_scratch:DF 2 "Y2")
4612    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4613         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4614   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4615   [(set (match_dup 2) (match_dup 1))
4616    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4617
4618 (define_peephole2
4619   [(match_scratch:SF 2 "x")
4620    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4621         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4622   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4623   [(set (match_dup 2) (match_dup 1))
4624    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4625
4626 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4627   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4628         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4629   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4630    && TARGET_FISTTP
4631    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4632          && (TARGET_64BIT || <MODE>mode != DImode))
4633         && TARGET_SSE_MATH)
4634    && can_create_pseudo_p ()"
4635   "#"
4636   "&& 1"
4637   [(const_int 0)]
4638 {
4639   if (memory_operand (operands[0], VOIDmode))
4640     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4641   else
4642     {
4643       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4644       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4645                                                             operands[1],
4646                                                             operands[2]));
4647     }
4648   DONE;
4649 }
4650   [(set_attr "type" "fisttp")
4651    (set_attr "mode" "<MODE>")])
4652
4653 (define_insn "fix_trunc<mode>_i387_fisttp"
4654   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4655         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4656    (clobber (match_scratch:XF 2 "=&1f"))]
4657   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4658    && TARGET_FISTTP
4659    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4660          && (TARGET_64BIT || <MODE>mode != DImode))
4661         && TARGET_SSE_MATH)"
4662   "* return output_fix_trunc (insn, operands, 1);"
4663   [(set_attr "type" "fisttp")
4664    (set_attr "mode" "<MODE>")])
4665
4666 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4667   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4668         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4669    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4670    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4671   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4672    && TARGET_FISTTP
4673    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4674         && (TARGET_64BIT || <MODE>mode != DImode))
4675         && TARGET_SSE_MATH)"
4676   "#"
4677   [(set_attr "type" "fisttp")
4678    (set_attr "mode" "<MODE>")])
4679
4680 (define_split
4681   [(set (match_operand:X87MODEI 0 "register_operand" "")
4682         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4683    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4684    (clobber (match_scratch 3 ""))]
4685   "reload_completed"
4686   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4687               (clobber (match_dup 3))])
4688    (set (match_dup 0) (match_dup 2))])
4689
4690 (define_split
4691   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4692         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4693    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4694    (clobber (match_scratch 3 ""))]
4695   "reload_completed"
4696   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4697               (clobber (match_dup 3))])])
4698
4699 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4700 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4701 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4702 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4703 ;; function in i386.c.
4704 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4705   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4706         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4707    (clobber (reg:CC FLAGS_REG))]
4708   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4709    && !TARGET_FISTTP
4710    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4711          && (TARGET_64BIT || <MODE>mode != DImode))
4712    && can_create_pseudo_p ()"
4713   "#"
4714   "&& 1"
4715   [(const_int 0)]
4716 {
4717   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4718
4719   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4720   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4721   if (memory_operand (operands[0], VOIDmode))
4722     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4723                                          operands[2], operands[3]));
4724   else
4725     {
4726       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4727       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4728                                                      operands[2], operands[3],
4729                                                      operands[4]));
4730     }
4731   DONE;
4732 }
4733   [(set_attr "type" "fistp")
4734    (set_attr "i387_cw" "trunc")
4735    (set_attr "mode" "<MODE>")])
4736
4737 (define_insn "fix_truncdi_i387"
4738   [(set (match_operand:DI 0 "memory_operand" "=m")
4739         (fix:DI (match_operand 1 "register_operand" "f")))
4740    (use (match_operand:HI 2 "memory_operand" "m"))
4741    (use (match_operand:HI 3 "memory_operand" "m"))
4742    (clobber (match_scratch:XF 4 "=&1f"))]
4743   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4744    && !TARGET_FISTTP
4745    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4746   "* return output_fix_trunc (insn, operands, 0);"
4747   [(set_attr "type" "fistp")
4748    (set_attr "i387_cw" "trunc")
4749    (set_attr "mode" "DI")])
4750
4751 (define_insn "fix_truncdi_i387_with_temp"
4752   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4753         (fix:DI (match_operand 1 "register_operand" "f,f")))
4754    (use (match_operand:HI 2 "memory_operand" "m,m"))
4755    (use (match_operand:HI 3 "memory_operand" "m,m"))
4756    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4757    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4758   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4759    && !TARGET_FISTTP
4760    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4761   "#"
4762   [(set_attr "type" "fistp")
4763    (set_attr "i387_cw" "trunc")
4764    (set_attr "mode" "DI")])
4765
4766 (define_split
4767   [(set (match_operand:DI 0 "register_operand" "")
4768         (fix:DI (match_operand 1 "register_operand" "")))
4769    (use (match_operand:HI 2 "memory_operand" ""))
4770    (use (match_operand:HI 3 "memory_operand" ""))
4771    (clobber (match_operand:DI 4 "memory_operand" ""))
4772    (clobber (match_scratch 5 ""))]
4773   "reload_completed"
4774   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4775               (use (match_dup 2))
4776               (use (match_dup 3))
4777               (clobber (match_dup 5))])
4778    (set (match_dup 0) (match_dup 4))])
4779
4780 (define_split
4781   [(set (match_operand:DI 0 "memory_operand" "")
4782         (fix:DI (match_operand 1 "register_operand" "")))
4783    (use (match_operand:HI 2 "memory_operand" ""))
4784    (use (match_operand:HI 3 "memory_operand" ""))
4785    (clobber (match_operand:DI 4 "memory_operand" ""))
4786    (clobber (match_scratch 5 ""))]
4787   "reload_completed"
4788   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4789               (use (match_dup 2))
4790               (use (match_dup 3))
4791               (clobber (match_dup 5))])])
4792
4793 (define_insn "fix_trunc<mode>_i387"
4794   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4795         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4796    (use (match_operand:HI 2 "memory_operand" "m"))
4797    (use (match_operand:HI 3 "memory_operand" "m"))]
4798   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4799    && !TARGET_FISTTP
4800    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4801   "* return output_fix_trunc (insn, operands, 0);"
4802   [(set_attr "type" "fistp")
4803    (set_attr "i387_cw" "trunc")
4804    (set_attr "mode" "<MODE>")])
4805
4806 (define_insn "fix_trunc<mode>_i387_with_temp"
4807   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4808         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4809    (use (match_operand:HI 2 "memory_operand" "m,m"))
4810    (use (match_operand:HI 3 "memory_operand" "m,m"))
4811    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4812   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4813    && !TARGET_FISTTP
4814    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4815   "#"
4816   [(set_attr "type" "fistp")
4817    (set_attr "i387_cw" "trunc")
4818    (set_attr "mode" "<MODE>")])
4819
4820 (define_split
4821   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4822         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4823    (use (match_operand:HI 2 "memory_operand" ""))
4824    (use (match_operand:HI 3 "memory_operand" ""))
4825    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4826   "reload_completed"
4827   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4828               (use (match_dup 2))
4829               (use (match_dup 3))])
4830    (set (match_dup 0) (match_dup 4))])
4831
4832 (define_split
4833   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4834         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4835    (use (match_operand:HI 2 "memory_operand" ""))
4836    (use (match_operand:HI 3 "memory_operand" ""))
4837    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4838   "reload_completed"
4839   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4840               (use (match_dup 2))
4841               (use (match_dup 3))])])
4842
4843 (define_insn "x86_fnstcw_1"
4844   [(set (match_operand:HI 0 "memory_operand" "=m")
4845         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4846   "TARGET_80387"
4847   "fnstcw\t%0"
4848   [(set (attr "length")
4849         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4850    (set_attr "mode" "HI")
4851    (set_attr "unit" "i387")
4852    (set_attr "bdver1_decode" "vector")])
4853
4854 (define_insn "x86_fldcw_1"
4855   [(set (reg:HI FPCR_REG)
4856         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4857   "TARGET_80387"
4858   "fldcw\t%0"
4859   [(set (attr "length")
4860         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4861    (set_attr "mode" "HI")
4862    (set_attr "unit" "i387")
4863    (set_attr "athlon_decode" "vector")
4864    (set_attr "amdfam10_decode" "vector")
4865    (set_attr "bdver1_decode" "vector")])
4866 \f
4867 ;; Conversion between fixed point and floating point.
4868
4869 ;; Even though we only accept memory inputs, the backend _really_
4870 ;; wants to be able to do this between registers.
4871
4872 (define_expand "floathi<mode>2"
4873   [(set (match_operand:X87MODEF 0 "register_operand" "")
4874         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4875   "TARGET_80387
4876    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4877        || TARGET_MIX_SSE_I387)")
4878
4879 ;; Pre-reload splitter to add memory clobber to the pattern.
4880 (define_insn_and_split "*floathi<mode>2_1"
4881   [(set (match_operand:X87MODEF 0 "register_operand" "")
4882         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4883   "TARGET_80387
4884    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4885        || TARGET_MIX_SSE_I387)
4886    && can_create_pseudo_p ()"
4887   "#"
4888   "&& 1"
4889   [(parallel [(set (match_dup 0)
4890               (float:X87MODEF (match_dup 1)))
4891    (clobber (match_dup 2))])]
4892   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4893
4894 (define_insn "*floathi<mode>2_i387_with_temp"
4895   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4896         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4897   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4898   "TARGET_80387
4899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4900        || TARGET_MIX_SSE_I387)"
4901   "#"
4902   [(set_attr "type" "fmov,multi")
4903    (set_attr "mode" "<MODE>")
4904    (set_attr "unit" "*,i387")
4905    (set_attr "fp_int_src" "true")])
4906
4907 (define_insn "*floathi<mode>2_i387"
4908   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4909         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4910   "TARGET_80387
4911    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4912        || TARGET_MIX_SSE_I387)"
4913   "fild%Z1\t%1"
4914   [(set_attr "type" "fmov")
4915    (set_attr "mode" "<MODE>")
4916    (set_attr "fp_int_src" "true")])
4917
4918 (define_split
4919   [(set (match_operand:X87MODEF 0 "register_operand" "")
4920         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4921    (clobber (match_operand:HI 2 "memory_operand" ""))]
4922   "TARGET_80387
4923    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4924        || TARGET_MIX_SSE_I387)
4925    && reload_completed"
4926   [(set (match_dup 2) (match_dup 1))
4927    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4928
4929 (define_split
4930   [(set (match_operand:X87MODEF 0 "register_operand" "")
4931         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4932    (clobber (match_operand:HI 2 "memory_operand" ""))]
4933    "TARGET_80387
4934     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4935         || TARGET_MIX_SSE_I387)
4936     && reload_completed"
4937   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4938
4939 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4940   [(set (match_operand:X87MODEF 0 "register_operand" "")
4941         (float:X87MODEF
4942           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4943   "TARGET_80387
4944    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4945        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4946 {
4947   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4948         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4949       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4950     {
4951       rtx reg = gen_reg_rtx (XFmode);
4952       rtx insn;
4953
4954       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4955
4956       if (<X87MODEF:MODE>mode == SFmode)
4957         insn = gen_truncxfsf2 (operands[0], reg);
4958       else if (<X87MODEF:MODE>mode == DFmode)
4959         insn = gen_truncxfdf2 (operands[0], reg);
4960       else
4961         gcc_unreachable ();
4962
4963       emit_insn (insn);
4964       DONE;
4965     }
4966 })
4967
4968 ;; Pre-reload splitter to add memory clobber to the pattern.
4969 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4970   [(set (match_operand:X87MODEF 0 "register_operand" "")
4971         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4972   "((TARGET_80387
4973      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4974      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4975            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4976          || TARGET_MIX_SSE_I387))
4977     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4978         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4979         && ((<SSEMODEI24:MODE>mode == SImode
4980              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4981              && optimize_function_for_speed_p (cfun)
4982              && flag_trapping_math)
4983             || !(TARGET_INTER_UNIT_CONVERSIONS
4984                  || optimize_function_for_size_p (cfun)))))
4985    && can_create_pseudo_p ()"
4986   "#"
4987   "&& 1"
4988   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4989               (clobber (match_dup 2))])]
4990 {
4991   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4992
4993   /* Avoid store forwarding (partial memory) stall penalty
4994      by passing DImode value through XMM registers.  */
4995   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4996       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4997       && optimize_function_for_speed_p (cfun))
4998     {
4999       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5000                                                             operands[1],
5001                                                             operands[2]));
5002       DONE;
5003     }
5004 })
5005
5006 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5007   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5008         (float:MODEF
5009           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5010    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5011   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5012    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5013   "#"
5014   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5015    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5016    (set_attr "unit" "*,i387,*,*,*")
5017    (set_attr "athlon_decode" "*,*,double,direct,double")
5018    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5019    (set_attr "bdver1_decode" "*,*,double,direct,double")
5020    (set_attr "fp_int_src" "true")])
5021
5022 (define_insn "*floatsi<mode>2_vector_mixed"
5023   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5024         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5025   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5026    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5027   "@
5028    fild%Z1\t%1
5029    #"
5030   [(set_attr "type" "fmov,sseicvt")
5031    (set_attr "mode" "<MODE>,<ssevecmode>")
5032    (set_attr "unit" "i387,*")
5033    (set_attr "athlon_decode" "*,direct")
5034    (set_attr "amdfam10_decode" "*,double")
5035    (set_attr "bdver1_decode" "*,direct")
5036    (set_attr "fp_int_src" "true")])
5037
5038 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5039   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5040         (float:MODEF
5041           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5042   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5043   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5044    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5045   "#"
5046   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5047    (set_attr "mode" "<MODEF:MODE>")
5048    (set_attr "unit" "*,i387,*,*")
5049    (set_attr "athlon_decode" "*,*,double,direct")
5050    (set_attr "amdfam10_decode" "*,*,vector,double")
5051    (set_attr "bdver1_decode" "*,*,double,direct")
5052    (set_attr "fp_int_src" "true")])
5053
5054 (define_split
5055   [(set (match_operand:MODEF 0 "register_operand" "")
5056         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5057    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5058   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5059    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5060    && TARGET_INTER_UNIT_CONVERSIONS
5061    && reload_completed
5062    && (SSE_REG_P (operands[0])
5063        || (GET_CODE (operands[0]) == SUBREG
5064            && SSE_REG_P (operands[0])))"
5065   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5066
5067 (define_split
5068   [(set (match_operand:MODEF 0 "register_operand" "")
5069         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5070    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5071   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5072    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5073    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5074    && reload_completed
5075    && (SSE_REG_P (operands[0])
5076        || (GET_CODE (operands[0]) == SUBREG
5077            && SSE_REG_P (operands[0])))"
5078   [(set (match_dup 2) (match_dup 1))
5079    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5080
5081 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5082   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5083         (float:MODEF
5084           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5085   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5086    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5087    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5088   "@
5089    fild%Z1\t%1
5090    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5091    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5092   [(set_attr "type" "fmov,sseicvt,sseicvt")
5093    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5094    (set_attr "mode" "<MODEF:MODE>")
5095    (set (attr "prefix_rex")
5096      (if_then_else
5097        (and (eq_attr "prefix" "maybe_vex")
5098             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5099        (const_string "1")
5100        (const_string "*")))
5101    (set_attr "unit" "i387,*,*")
5102    (set_attr "athlon_decode" "*,double,direct")
5103    (set_attr "amdfam10_decode" "*,vector,double")
5104    (set_attr "bdver1_decode" "*,double,direct")
5105    (set_attr "fp_int_src" "true")])
5106
5107 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5108   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5109         (float:MODEF
5110           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5111   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5112    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5113    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5114   "@
5115    fild%Z1\t%1
5116    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5117   [(set_attr "type" "fmov,sseicvt")
5118    (set_attr "prefix" "orig,maybe_vex")
5119    (set_attr "mode" "<MODEF:MODE>")
5120    (set (attr "prefix_rex")
5121      (if_then_else
5122        (and (eq_attr "prefix" "maybe_vex")
5123             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5124        (const_string "1")
5125        (const_string "*")))
5126    (set_attr "athlon_decode" "*,direct")
5127    (set_attr "amdfam10_decode" "*,double")
5128    (set_attr "bdver1_decode" "*,direct")
5129    (set_attr "fp_int_src" "true")])
5130
5131 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5132   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5133         (float:MODEF
5134           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5135    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5136   "TARGET_SSE2 && TARGET_SSE_MATH
5137    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5138   "#"
5139   [(set_attr "type" "sseicvt")
5140    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5141    (set_attr "athlon_decode" "double,direct,double")
5142    (set_attr "amdfam10_decode" "vector,double,double")
5143    (set_attr "bdver1_decode" "double,direct,double")
5144    (set_attr "fp_int_src" "true")])
5145
5146 (define_insn "*floatsi<mode>2_vector_sse"
5147   [(set (match_operand:MODEF 0 "register_operand" "=x")
5148         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5149   "TARGET_SSE2 && TARGET_SSE_MATH
5150    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5151   "#"
5152   [(set_attr "type" "sseicvt")
5153    (set_attr "mode" "<MODE>")
5154    (set_attr "athlon_decode" "direct")
5155    (set_attr "amdfam10_decode" "double")
5156    (set_attr "bdver1_decode" "direct")
5157    (set_attr "fp_int_src" "true")])
5158
5159 (define_split
5160   [(set (match_operand:MODEF 0 "register_operand" "")
5161         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5162    (clobber (match_operand:SI 2 "memory_operand" ""))]
5163   "TARGET_SSE2 && TARGET_SSE_MATH
5164    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5165    && reload_completed
5166    && (SSE_REG_P (operands[0])
5167        || (GET_CODE (operands[0]) == SUBREG
5168            && SSE_REG_P (operands[0])))"
5169   [(const_int 0)]
5170 {
5171   rtx op1 = operands[1];
5172
5173   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5174                                      <MODE>mode, 0);
5175   if (GET_CODE (op1) == SUBREG)
5176     op1 = SUBREG_REG (op1);
5177
5178   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5179     {
5180       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5181       emit_insn (gen_sse2_loadld (operands[4],
5182                                   CONST0_RTX (V4SImode), operands[1]));
5183     }
5184   /* We can ignore possible trapping value in the
5185      high part of SSE register for non-trapping math. */
5186   else if (SSE_REG_P (op1) && !flag_trapping_math)
5187     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5188   else
5189     {
5190       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5191       emit_move_insn (operands[2], operands[1]);
5192       emit_insn (gen_sse2_loadld (operands[4],
5193                                   CONST0_RTX (V4SImode), operands[2]));
5194     }
5195   emit_insn
5196     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5197   DONE;
5198 })
5199
5200 (define_split
5201   [(set (match_operand:MODEF 0 "register_operand" "")
5202         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5203    (clobber (match_operand:SI 2 "memory_operand" ""))]
5204   "TARGET_SSE2 && TARGET_SSE_MATH
5205    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5206    && reload_completed
5207    && (SSE_REG_P (operands[0])
5208        || (GET_CODE (operands[0]) == SUBREG
5209            && SSE_REG_P (operands[0])))"
5210   [(const_int 0)]
5211 {
5212   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5213                                      <MODE>mode, 0);
5214   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5215
5216   emit_insn (gen_sse2_loadld (operands[4],
5217                               CONST0_RTX (V4SImode), operands[1]));
5218   emit_insn
5219     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5220   DONE;
5221 })
5222
5223 (define_split
5224   [(set (match_operand:MODEF 0 "register_operand" "")
5225         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5226   "TARGET_SSE2 && TARGET_SSE_MATH
5227    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5228    && reload_completed
5229    && (SSE_REG_P (operands[0])
5230        || (GET_CODE (operands[0]) == SUBREG
5231            && SSE_REG_P (operands[0])))"
5232   [(const_int 0)]
5233 {
5234   rtx op1 = operands[1];
5235
5236   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5237                                      <MODE>mode, 0);
5238   if (GET_CODE (op1) == SUBREG)
5239     op1 = SUBREG_REG (op1);
5240
5241   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5242     {
5243       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5244       emit_insn (gen_sse2_loadld (operands[4],
5245                                   CONST0_RTX (V4SImode), operands[1]));
5246     }
5247   /* We can ignore possible trapping value in the
5248      high part of SSE register for non-trapping math. */
5249   else if (SSE_REG_P (op1) && !flag_trapping_math)
5250     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5251   else
5252     gcc_unreachable ();
5253   emit_insn
5254     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5255   DONE;
5256 })
5257
5258 (define_split
5259   [(set (match_operand:MODEF 0 "register_operand" "")
5260         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5261   "TARGET_SSE2 && TARGET_SSE_MATH
5262    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5263    && reload_completed
5264    && (SSE_REG_P (operands[0])
5265        || (GET_CODE (operands[0]) == SUBREG
5266            && SSE_REG_P (operands[0])))"
5267   [(const_int 0)]
5268 {
5269   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5270                                      <MODE>mode, 0);
5271   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5272
5273   emit_insn (gen_sse2_loadld (operands[4],
5274                               CONST0_RTX (V4SImode), operands[1]));
5275   emit_insn
5276     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5277   DONE;
5278 })
5279
5280 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5281   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5282         (float:MODEF
5283           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5284   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5285   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5286    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5287   "#"
5288   [(set_attr "type" "sseicvt")
5289    (set_attr "mode" "<MODEF:MODE>")
5290    (set_attr "athlon_decode" "double,direct")
5291    (set_attr "amdfam10_decode" "vector,double")
5292    (set_attr "bdver1_decode" "double,direct")
5293    (set_attr "fp_int_src" "true")])
5294
5295 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5296   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5297         (float:MODEF
5298           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5299   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5301    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5302   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5303   [(set_attr "type" "sseicvt")
5304    (set_attr "prefix" "maybe_vex")
5305    (set_attr "mode" "<MODEF:MODE>")
5306    (set (attr "prefix_rex")
5307      (if_then_else
5308        (and (eq_attr "prefix" "maybe_vex")
5309             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5310        (const_string "1")
5311        (const_string "*")))
5312    (set_attr "athlon_decode" "double,direct")
5313    (set_attr "amdfam10_decode" "vector,double")
5314    (set_attr "bdver1_decode" "double,direct")
5315    (set_attr "fp_int_src" "true")])
5316
5317 (define_split
5318   [(set (match_operand:MODEF 0 "register_operand" "")
5319         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5320    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5321   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5322    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5323    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5324    && reload_completed
5325    && (SSE_REG_P (operands[0])
5326        || (GET_CODE (operands[0]) == SUBREG
5327            && SSE_REG_P (operands[0])))"
5328   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5329
5330 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5331   [(set (match_operand:MODEF 0 "register_operand" "=x")
5332         (float:MODEF
5333           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5334   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5335    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5336    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5337   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5338   [(set_attr "type" "sseicvt")
5339    (set_attr "prefix" "maybe_vex")
5340    (set_attr "mode" "<MODEF:MODE>")
5341    (set (attr "prefix_rex")
5342      (if_then_else
5343        (and (eq_attr "prefix" "maybe_vex")
5344             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5345        (const_string "1")
5346        (const_string "*")))
5347    (set_attr "athlon_decode" "direct")
5348    (set_attr "amdfam10_decode" "double")
5349    (set_attr "bdver1_decode" "direct")
5350    (set_attr "fp_int_src" "true")])
5351
5352 (define_split
5353   [(set (match_operand:MODEF 0 "register_operand" "")
5354         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5355    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5356   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5357    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5358    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5359    && reload_completed
5360    && (SSE_REG_P (operands[0])
5361        || (GET_CODE (operands[0]) == SUBREG
5362            && SSE_REG_P (operands[0])))"
5363   [(set (match_dup 2) (match_dup 1))
5364    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5365
5366 (define_split
5367   [(set (match_operand:MODEF 0 "register_operand" "")
5368         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5369    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5370   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5371    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5372    && reload_completed
5373    && (SSE_REG_P (operands[0])
5374        || (GET_CODE (operands[0]) == SUBREG
5375            && SSE_REG_P (operands[0])))"
5376   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5377
5378 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5379   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5380         (float:X87MODEF
5381           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5382   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5383   "TARGET_80387
5384    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5385   "@
5386    fild%Z1\t%1
5387    #"
5388   [(set_attr "type" "fmov,multi")
5389    (set_attr "mode" "<X87MODEF:MODE>")
5390    (set_attr "unit" "*,i387")
5391    (set_attr "fp_int_src" "true")])
5392
5393 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5394   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5395         (float:X87MODEF
5396           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5397   "TARGET_80387
5398    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5399   "fild%Z1\t%1"
5400   [(set_attr "type" "fmov")
5401    (set_attr "mode" "<X87MODEF:MODE>")
5402    (set_attr "fp_int_src" "true")])
5403
5404 (define_split
5405   [(set (match_operand:X87MODEF 0 "register_operand" "")
5406         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5407    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5408   "TARGET_80387
5409    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5410    && reload_completed
5411    && FP_REG_P (operands[0])"
5412   [(set (match_dup 2) (match_dup 1))
5413    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5414
5415 (define_split
5416   [(set (match_operand:X87MODEF 0 "register_operand" "")
5417         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5418    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5419   "TARGET_80387
5420    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5421    && reload_completed
5422    && FP_REG_P (operands[0])"
5423   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5424
5425 ;; Avoid store forwarding (partial memory) stall penalty
5426 ;; by passing DImode value through XMM registers.  */
5427
5428 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5429   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5430         (float:X87MODEF
5431           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5432    (clobber (match_scratch:V4SI 3 "=X,x"))
5433    (clobber (match_scratch:V4SI 4 "=X,x"))
5434    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5435   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5436    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5437    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5438   "#"
5439   [(set_attr "type" "multi")
5440    (set_attr "mode" "<X87MODEF:MODE>")
5441    (set_attr "unit" "i387")
5442    (set_attr "fp_int_src" "true")])
5443
5444 (define_split
5445   [(set (match_operand:X87MODEF 0 "register_operand" "")
5446         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5447    (clobber (match_scratch:V4SI 3 ""))
5448    (clobber (match_scratch:V4SI 4 ""))
5449    (clobber (match_operand:DI 2 "memory_operand" ""))]
5450   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5451    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5452    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5453    && reload_completed
5454    && FP_REG_P (operands[0])"
5455   [(set (match_dup 2) (match_dup 3))
5456    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5457 {
5458   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5459      Assemble the 64-bit DImode value in an xmm register.  */
5460   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5461                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5462   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5463                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5464   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5465                                          operands[4]));
5466
5467   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5468 })
5469
5470 (define_split
5471   [(set (match_operand:X87MODEF 0 "register_operand" "")
5472         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5473    (clobber (match_scratch:V4SI 3 ""))
5474    (clobber (match_scratch:V4SI 4 ""))
5475    (clobber (match_operand:DI 2 "memory_operand" ""))]
5476   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5477    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5478    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5479    && reload_completed
5480    && FP_REG_P (operands[0])"
5481   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5482
5483 ;; Avoid store forwarding (partial memory) stall penalty by extending
5484 ;; SImode value to DImode through XMM register instead of pushing two
5485 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5486 ;; targets benefit from this optimization. Also note that fild
5487 ;; loads from memory only.
5488
5489 (define_insn "*floatunssi<mode>2_1"
5490   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5491         (unsigned_float:X87MODEF
5492           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5493    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5494    (clobber (match_scratch:SI 3 "=X,x"))]
5495   "!TARGET_64BIT
5496    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5497    && TARGET_SSE"
5498   "#"
5499   [(set_attr "type" "multi")
5500    (set_attr "mode" "<MODE>")])
5501
5502 (define_split
5503   [(set (match_operand:X87MODEF 0 "register_operand" "")
5504         (unsigned_float:X87MODEF
5505           (match_operand:SI 1 "register_operand" "")))
5506    (clobber (match_operand:DI 2 "memory_operand" ""))
5507    (clobber (match_scratch:SI 3 ""))]
5508   "!TARGET_64BIT
5509    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5510    && TARGET_SSE
5511    && reload_completed"
5512   [(set (match_dup 2) (match_dup 1))
5513    (set (match_dup 0)
5514         (float:X87MODEF (match_dup 2)))]
5515   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5516
5517 (define_split
5518   [(set (match_operand:X87MODEF 0 "register_operand" "")
5519         (unsigned_float:X87MODEF
5520           (match_operand:SI 1 "memory_operand" "")))
5521    (clobber (match_operand:DI 2 "memory_operand" ""))
5522    (clobber (match_scratch:SI 3 ""))]
5523   "!TARGET_64BIT
5524    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5525    && TARGET_SSE
5526    && reload_completed"
5527   [(set (match_dup 2) (match_dup 3))
5528    (set (match_dup 0)
5529         (float:X87MODEF (match_dup 2)))]
5530 {
5531   emit_move_insn (operands[3], operands[1]);
5532   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5533 })
5534
5535 (define_expand "floatunssi<mode>2"
5536   [(parallel
5537      [(set (match_operand:X87MODEF 0 "register_operand" "")
5538            (unsigned_float:X87MODEF
5539              (match_operand:SI 1 "nonimmediate_operand" "")))
5540       (clobber (match_dup 2))
5541       (clobber (match_scratch:SI 3 ""))])]
5542   "!TARGET_64BIT
5543    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5544         && TARGET_SSE)
5545        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5546 {
5547   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5548     {
5549       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5550       DONE;
5551     }
5552   else
5553     {
5554       enum ix86_stack_slot slot = (virtuals_instantiated
5555                                    ? SLOT_TEMP
5556                                    : SLOT_VIRTUAL);
5557       operands[2] = assign_386_stack_local (DImode, slot);
5558     }
5559 })
5560
5561 (define_expand "floatunsdisf2"
5562   [(use (match_operand:SF 0 "register_operand" ""))
5563    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5564   "TARGET_64BIT && TARGET_SSE_MATH"
5565   "x86_emit_floatuns (operands); DONE;")
5566
5567 (define_expand "floatunsdidf2"
5568   [(use (match_operand:DF 0 "register_operand" ""))
5569    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5570   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5571    && TARGET_SSE2 && TARGET_SSE_MATH"
5572 {
5573   if (TARGET_64BIT)
5574     x86_emit_floatuns (operands);
5575   else
5576     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5577   DONE;
5578 })
5579 \f
5580 ;; Add instructions
5581
5582 (define_expand "add<mode>3"
5583   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5584         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5585                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5586   ""
5587   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5588
5589 (define_insn_and_split "*add<dwi>3_doubleword"
5590   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5591         (plus:<DWI>
5592           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5593           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5594    (clobber (reg:CC FLAGS_REG))]
5595   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5596   "#"
5597   "reload_completed"
5598   [(parallel [(set (reg:CC FLAGS_REG)
5599                    (unspec:CC [(match_dup 1) (match_dup 2)]
5600                               UNSPEC_ADD_CARRY))
5601               (set (match_dup 0)
5602                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5603    (parallel [(set (match_dup 3)
5604                    (plus:DWIH
5605                      (match_dup 4)
5606                      (plus:DWIH
5607                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5608                        (match_dup 5))))
5609               (clobber (reg:CC FLAGS_REG))])]
5610   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5611
5612 (define_insn "*add<mode>3_cc"
5613   [(set (reg:CC FLAGS_REG)
5614         (unspec:CC
5615           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5616            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5617           UNSPEC_ADD_CARRY))
5618    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5619         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5620   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5621   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5622   [(set_attr "type" "alu")
5623    (set_attr "mode" "<MODE>")])
5624
5625 (define_insn "addqi3_cc"
5626   [(set (reg:CC FLAGS_REG)
5627         (unspec:CC
5628           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5629            (match_operand:QI 2 "general_operand" "qn,qm")]
5630           UNSPEC_ADD_CARRY))
5631    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5632         (plus:QI (match_dup 1) (match_dup 2)))]
5633   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5634   "add{b}\t{%2, %0|%0, %2}"
5635   [(set_attr "type" "alu")
5636    (set_attr "mode" "QI")])
5637
5638 (define_insn "*lea_1"
5639   [(set (match_operand:P 0 "register_operand" "=r")
5640         (match_operand:P 1 "no_seg_address_operand" "p"))]
5641   ""
5642   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5643   [(set_attr "type" "lea")
5644    (set_attr "mode" "<MODE>")])
5645
5646 (define_insn "*lea_2"
5647   [(set (match_operand:SI 0 "register_operand" "=r")
5648         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5649   "TARGET_64BIT"
5650   "lea{l}\t{%a1, %0|%0, %a1}"
5651   [(set_attr "type" "lea")
5652    (set_attr "mode" "SI")])
5653
5654 (define_insn "*lea_2_zext"
5655   [(set (match_operand:DI 0 "register_operand" "=r")
5656         (zero_extend:DI
5657           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5658   "TARGET_64BIT"
5659   "lea{l}\t{%a1, %k0|%k0, %a1}"
5660   [(set_attr "type" "lea")
5661    (set_attr "mode" "SI")])
5662
5663 (define_insn "*add<mode>_1"
5664   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5665         (plus:SWI48
5666           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5667           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5668    (clobber (reg:CC FLAGS_REG))]
5669   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5670 {
5671   switch (get_attr_type (insn))
5672     {
5673     case TYPE_LEA:
5674       return "#";
5675
5676     case TYPE_INCDEC:
5677       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5678       if (operands[2] == const1_rtx)
5679         return "inc{<imodesuffix>}\t%0";
5680       else
5681         {
5682           gcc_assert (operands[2] == constm1_rtx);
5683           return "dec{<imodesuffix>}\t%0";
5684         }
5685
5686     default:
5687       /* For most processors, ADD is faster than LEA.  This alternative
5688          was added to use ADD as much as possible.  */
5689       if (which_alternative == 2)
5690         {
5691           rtx tmp;
5692           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5693         }
5694         
5695       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5696       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5697         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5698
5699       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5700     }
5701 }
5702   [(set (attr "type")
5703      (cond [(eq_attr "alternative" "3")
5704               (const_string "lea")
5705             (match_operand:SWI48 2 "incdec_operand" "")
5706               (const_string "incdec")
5707            ]
5708            (const_string "alu")))
5709    (set (attr "length_immediate")
5710       (if_then_else
5711         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5712         (const_string "1")
5713         (const_string "*")))
5714    (set_attr "mode" "<MODE>")])
5715
5716 ;; It may seem that nonimmediate operand is proper one for operand 1.
5717 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5718 ;; we take care in ix86_binary_operator_ok to not allow two memory
5719 ;; operands so proper swapping will be done in reload.  This allow
5720 ;; patterns constructed from addsi_1 to match.
5721
5722 (define_insn "*addsi_1_zext"
5723   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5724         (zero_extend:DI
5725           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5726                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5727    (clobber (reg:CC FLAGS_REG))]
5728   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5729 {
5730   switch (get_attr_type (insn))
5731     {
5732     case TYPE_LEA:
5733       return "#";
5734
5735     case TYPE_INCDEC:
5736       if (operands[2] == const1_rtx)
5737         return "inc{l}\t%k0";
5738       else
5739         {
5740           gcc_assert (operands[2] == constm1_rtx);
5741           return "dec{l}\t%k0";
5742         }
5743
5744     default:
5745       /* For most processors, ADD is faster than LEA.  This alternative
5746          was added to use ADD as much as possible.  */
5747       if (which_alternative == 1)
5748         {
5749           rtx tmp;
5750           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5751         }
5752
5753       if (x86_maybe_negate_const_int (&operands[2], SImode))
5754         return "sub{l}\t{%2, %k0|%k0, %2}";
5755
5756       return "add{l}\t{%2, %k0|%k0, %2}";
5757     }
5758 }
5759   [(set (attr "type")
5760      (cond [(eq_attr "alternative" "2")
5761               (const_string "lea")
5762             (match_operand:SI 2 "incdec_operand" "")
5763               (const_string "incdec")
5764            ]
5765            (const_string "alu")))
5766    (set (attr "length_immediate")
5767       (if_then_else
5768         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5769         (const_string "1")
5770         (const_string "*")))
5771    (set_attr "mode" "SI")])
5772
5773 (define_insn "*addhi_1"
5774   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5775         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5776                  (match_operand:HI 2 "general_operand" "rn,rm")))
5777    (clobber (reg:CC FLAGS_REG))]
5778   "TARGET_PARTIAL_REG_STALL
5779    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5780 {
5781   switch (get_attr_type (insn))
5782     {
5783     case TYPE_INCDEC:
5784       if (operands[2] == const1_rtx)
5785         return "inc{w}\t%0";
5786       else
5787         {
5788           gcc_assert (operands[2] == constm1_rtx);
5789           return "dec{w}\t%0";
5790         }
5791
5792     default:
5793       if (x86_maybe_negate_const_int (&operands[2], HImode))
5794         return "sub{w}\t{%2, %0|%0, %2}";
5795
5796       return "add{w}\t{%2, %0|%0, %2}";
5797     }
5798 }
5799   [(set (attr "type")
5800      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5801         (const_string "incdec")
5802         (const_string "alu")))
5803    (set (attr "length_immediate")
5804       (if_then_else
5805         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5806         (const_string "1")
5807         (const_string "*")))
5808    (set_attr "mode" "HI")])
5809
5810 (define_insn "*addhi_1_lea"
5811   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5812         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5813                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5814    (clobber (reg:CC FLAGS_REG))]
5815   "!TARGET_PARTIAL_REG_STALL
5816    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5817 {
5818   switch (get_attr_type (insn))
5819     {
5820     case TYPE_LEA:
5821       return "#";
5822
5823     case TYPE_INCDEC:
5824       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5825       if (operands[2] == const1_rtx)
5826         return "inc{w}\t%0";
5827       else
5828         {
5829           gcc_assert (operands[2] == constm1_rtx);
5830           return "dec{w}\t%0";
5831         }
5832
5833     default:
5834       /* For most processors, ADD is faster than LEA.  This alternative
5835          was added to use ADD as much as possible.  */
5836       if (which_alternative == 2)
5837         {
5838           rtx tmp;
5839           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5840         }
5841
5842       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5843       if (x86_maybe_negate_const_int (&operands[2], HImode))
5844         return "sub{w}\t{%2, %0|%0, %2}";
5845
5846       return "add{w}\t{%2, %0|%0, %2}";
5847     }
5848 }
5849   [(set (attr "type")
5850      (cond [(eq_attr "alternative" "3")
5851               (const_string "lea")
5852             (match_operand:HI 2 "incdec_operand" "")
5853               (const_string "incdec")
5854            ]
5855            (const_string "alu")))
5856    (set (attr "length_immediate")
5857       (if_then_else
5858         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5859         (const_string "1")
5860         (const_string "*")))
5861    (set_attr "mode" "HI,HI,HI,SI")])
5862
5863 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5864 (define_insn "*addqi_1"
5865   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5866         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5867                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5868    (clobber (reg:CC FLAGS_REG))]
5869   "TARGET_PARTIAL_REG_STALL
5870    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5871 {
5872   int widen = (which_alternative == 2);
5873   switch (get_attr_type (insn))
5874     {
5875     case TYPE_INCDEC:
5876       if (operands[2] == const1_rtx)
5877         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5878       else
5879         {
5880           gcc_assert (operands[2] == constm1_rtx);
5881           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5882         }
5883
5884     default:
5885       if (x86_maybe_negate_const_int (&operands[2], QImode))
5886         {
5887           if (widen)
5888             return "sub{l}\t{%2, %k0|%k0, %2}";
5889           else
5890             return "sub{b}\t{%2, %0|%0, %2}";
5891         }
5892       if (widen)
5893         return "add{l}\t{%k2, %k0|%k0, %k2}";
5894       else
5895         return "add{b}\t{%2, %0|%0, %2}";
5896     }
5897 }
5898   [(set (attr "type")
5899      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5900         (const_string "incdec")
5901         (const_string "alu")))
5902    (set (attr "length_immediate")
5903       (if_then_else
5904         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5905         (const_string "1")
5906         (const_string "*")))
5907    (set_attr "mode" "QI,QI,SI")])
5908
5909 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5910 (define_insn "*addqi_1_lea"
5911   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5912         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5913                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5914    (clobber (reg:CC FLAGS_REG))]
5915   "!TARGET_PARTIAL_REG_STALL
5916    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5917 {
5918   int widen = (which_alternative == 3 || which_alternative == 4);
5919
5920   switch (get_attr_type (insn))
5921     {
5922     case TYPE_LEA:
5923       return "#";
5924
5925     case TYPE_INCDEC:
5926       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5927       if (operands[2] == const1_rtx)
5928         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5929       else
5930         {
5931           gcc_assert (operands[2] == constm1_rtx);
5932           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5933         }
5934
5935     default:
5936       /* For most processors, ADD is faster than LEA.  These alternatives
5937          were added to use ADD as much as possible.  */
5938       if (which_alternative == 2 || which_alternative == 4)
5939         {
5940           rtx tmp;
5941           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5942         }
5943
5944       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5945       if (x86_maybe_negate_const_int (&operands[2], QImode))
5946         {
5947           if (widen)
5948             return "sub{l}\t{%2, %k0|%k0, %2}";
5949           else
5950             return "sub{b}\t{%2, %0|%0, %2}";
5951         }
5952       if (widen)
5953         return "add{l}\t{%k2, %k0|%k0, %k2}";
5954       else
5955         return "add{b}\t{%2, %0|%0, %2}";
5956     }
5957 }
5958   [(set (attr "type")
5959      (cond [(eq_attr "alternative" "5")
5960               (const_string "lea")
5961             (match_operand:QI 2 "incdec_operand" "")
5962               (const_string "incdec")
5963            ]
5964            (const_string "alu")))
5965    (set (attr "length_immediate")
5966       (if_then_else
5967         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5968         (const_string "1")
5969         (const_string "*")))
5970    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5971
5972 (define_insn "*addqi_1_slp"
5973   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5974         (plus:QI (match_dup 0)
5975                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5976    (clobber (reg:CC FLAGS_REG))]
5977   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5978    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5979 {
5980   switch (get_attr_type (insn))
5981     {
5982     case TYPE_INCDEC:
5983       if (operands[1] == const1_rtx)
5984         return "inc{b}\t%0";
5985       else
5986         {
5987           gcc_assert (operands[1] == constm1_rtx);
5988           return "dec{b}\t%0";
5989         }
5990
5991     default:
5992       if (x86_maybe_negate_const_int (&operands[1], QImode))
5993         return "sub{b}\t{%1, %0|%0, %1}";
5994
5995       return "add{b}\t{%1, %0|%0, %1}";
5996     }
5997 }
5998   [(set (attr "type")
5999      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6000         (const_string "incdec")
6001         (const_string "alu1")))
6002    (set (attr "memory")
6003      (if_then_else (match_operand 1 "memory_operand" "")
6004         (const_string "load")
6005         (const_string "none")))
6006    (set_attr "mode" "QI")])
6007
6008 ;; Convert lea to the lea pattern to avoid flags dependency.
6009 (define_split
6010   [(set (match_operand 0 "register_operand" "")
6011         (plus (match_operand 1 "register_operand" "")
6012               (match_operand 2 "nonmemory_operand" "")))
6013    (clobber (reg:CC FLAGS_REG))]
6014   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6015   [(const_int 0)]
6016 {
6017   rtx pat;
6018   enum machine_mode mode = GET_MODE (operands[0]);
6019
6020   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6021      may confuse gen_lowpart.  */
6022   if (mode != Pmode)
6023     {
6024       operands[1] = gen_lowpart (Pmode, operands[1]);
6025       operands[2] = gen_lowpart (Pmode, operands[2]);
6026     }
6027
6028   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6029
6030   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6031     operands[0] = gen_lowpart (SImode, operands[0]);
6032
6033   if (TARGET_64BIT && mode != Pmode)
6034     pat = gen_rtx_SUBREG (SImode, pat, 0);
6035
6036   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6037   DONE;
6038 })
6039
6040 ;; Convert lea to the lea pattern to avoid flags dependency.
6041 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6042 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6043 (define_split
6044   [(set (match_operand:DI 0 "register_operand" "")
6045         (plus:DI (match_operand:DI 1 "register_operand" "")
6046                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6047    (clobber (reg:CC FLAGS_REG))]
6048   "TARGET_64BIT && reload_completed 
6049    && true_regnum (operands[0]) != true_regnum (operands[1])"
6050   [(set (match_dup 0)
6051         (plus:DI (match_dup 1) (match_dup 2)))])
6052
6053 ;; Convert lea to the lea pattern to avoid flags dependency.
6054 (define_split
6055   [(set (match_operand:DI 0 "register_operand" "")
6056         (zero_extend:DI
6057           (plus:SI (match_operand:SI 1 "register_operand" "")
6058                    (match_operand:SI 2 "nonmemory_operand" ""))))
6059    (clobber (reg:CC FLAGS_REG))]
6060   "TARGET_64BIT && reload_completed
6061    && ix86_lea_for_add_ok (insn, operands)"
6062   [(set (match_dup 0)
6063         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6064 {
6065   operands[1] = gen_lowpart (DImode, operands[1]);
6066   operands[2] = gen_lowpart (DImode, operands[2]);
6067 })
6068
6069 (define_insn "*add<mode>_2"
6070   [(set (reg FLAGS_REG)
6071         (compare
6072           (plus:SWI
6073             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6074             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6075           (const_int 0)))
6076    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6077         (plus:SWI (match_dup 1) (match_dup 2)))]
6078   "ix86_match_ccmode (insn, CCGOCmode)
6079    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6080 {
6081   switch (get_attr_type (insn))
6082     {
6083     case TYPE_INCDEC:
6084       if (operands[2] == const1_rtx)
6085         return "inc{<imodesuffix>}\t%0";
6086       else
6087         {
6088           gcc_assert (operands[2] == constm1_rtx);
6089           return "dec{<imodesuffix>}\t%0";
6090         }
6091
6092     default:
6093       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6094         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6095
6096       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6097     }
6098 }
6099   [(set (attr "type")
6100      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6101         (const_string "incdec")
6102         (const_string "alu")))
6103    (set (attr "length_immediate")
6104       (if_then_else
6105         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6106         (const_string "1")
6107         (const_string "*")))
6108    (set_attr "mode" "<MODE>")])
6109
6110 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6111 (define_insn "*addsi_2_zext"
6112   [(set (reg FLAGS_REG)
6113         (compare
6114           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6115                    (match_operand:SI 2 "general_operand" "g"))
6116           (const_int 0)))
6117    (set (match_operand:DI 0 "register_operand" "=r")
6118         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6119   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6120    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6121 {
6122   switch (get_attr_type (insn))
6123     {
6124     case TYPE_INCDEC:
6125       if (operands[2] == const1_rtx)
6126         return "inc{l}\t%k0";
6127       else
6128         {
6129           gcc_assert (operands[2] == constm1_rtx);
6130           return "dec{l}\t%k0";
6131         }
6132
6133     default:
6134       if (x86_maybe_negate_const_int (&operands[2], SImode))
6135         return "sub{l}\t{%2, %k0|%k0, %2}";
6136
6137       return "add{l}\t{%2, %k0|%k0, %2}";
6138     }
6139 }
6140   [(set (attr "type")
6141      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6142         (const_string "incdec")
6143         (const_string "alu")))
6144    (set (attr "length_immediate")
6145       (if_then_else
6146         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6147         (const_string "1")
6148         (const_string "*")))
6149    (set_attr "mode" "SI")])
6150
6151 (define_insn "*add<mode>_3"
6152   [(set (reg FLAGS_REG)
6153         (compare
6154           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6155           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6156    (clobber (match_scratch:SWI 0 "=<r>"))]
6157   "ix86_match_ccmode (insn, CCZmode)
6158    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6159 {
6160   switch (get_attr_type (insn))
6161     {
6162     case TYPE_INCDEC:
6163       if (operands[2] == const1_rtx)
6164         return "inc{<imodesuffix>}\t%0";
6165       else
6166         {
6167           gcc_assert (operands[2] == constm1_rtx);
6168           return "dec{<imodesuffix>}\t%0";
6169         }
6170
6171     default:
6172       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6173         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6174
6175       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6176     }
6177 }
6178   [(set (attr "type")
6179      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6180         (const_string "incdec")
6181         (const_string "alu")))
6182    (set (attr "length_immediate")
6183       (if_then_else
6184         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6185         (const_string "1")
6186         (const_string "*")))
6187    (set_attr "mode" "<MODE>")])
6188
6189 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6190 (define_insn "*addsi_3_zext"
6191   [(set (reg FLAGS_REG)
6192         (compare
6193           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6194           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6195    (set (match_operand:DI 0 "register_operand" "=r")
6196         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6197   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6198    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6199 {
6200   switch (get_attr_type (insn))
6201     {
6202     case TYPE_INCDEC:
6203       if (operands[2] == const1_rtx)
6204         return "inc{l}\t%k0";
6205       else
6206         {
6207           gcc_assert (operands[2] == constm1_rtx);
6208           return "dec{l}\t%k0";
6209         }
6210
6211     default:
6212       if (x86_maybe_negate_const_int (&operands[2], SImode))
6213         return "sub{l}\t{%2, %k0|%k0, %2}";
6214
6215       return "add{l}\t{%2, %k0|%k0, %2}";
6216     }
6217 }
6218   [(set (attr "type")
6219      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6220         (const_string "incdec")
6221         (const_string "alu")))
6222    (set (attr "length_immediate")
6223       (if_then_else
6224         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6225         (const_string "1")
6226         (const_string "*")))
6227    (set_attr "mode" "SI")])
6228
6229 ; For comparisons against 1, -1 and 128, we may generate better code
6230 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6231 ; is matched then.  We can't accept general immediate, because for
6232 ; case of overflows,  the result is messed up.
6233 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6234 ; only for comparisons not depending on it.
6235
6236 (define_insn "*adddi_4"
6237   [(set (reg FLAGS_REG)
6238         (compare
6239           (match_operand:DI 1 "nonimmediate_operand" "0")
6240           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6241    (clobber (match_scratch:DI 0 "=rm"))]
6242   "TARGET_64BIT
6243    && ix86_match_ccmode (insn, CCGCmode)"
6244 {
6245   switch (get_attr_type (insn))
6246     {
6247     case TYPE_INCDEC:
6248       if (operands[2] == constm1_rtx)
6249         return "inc{q}\t%0";
6250       else
6251         {
6252           gcc_assert (operands[2] == const1_rtx);
6253           return "dec{q}\t%0";
6254         }
6255
6256     default:
6257       if (x86_maybe_negate_const_int (&operands[2], DImode))
6258         return "add{q}\t{%2, %0|%0, %2}";
6259
6260       return "sub{q}\t{%2, %0|%0, %2}";
6261     }
6262 }
6263   [(set (attr "type")
6264      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6265         (const_string "incdec")
6266         (const_string "alu")))
6267    (set (attr "length_immediate")
6268       (if_then_else
6269         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6270         (const_string "1")
6271         (const_string "*")))
6272    (set_attr "mode" "DI")])
6273
6274 ; For comparisons against 1, -1 and 128, we may generate better code
6275 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6276 ; is matched then.  We can't accept general immediate, because for
6277 ; case of overflows,  the result is messed up.
6278 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6279 ; only for comparisons not depending on it.
6280
6281 (define_insn "*add<mode>_4"
6282   [(set (reg FLAGS_REG)
6283         (compare
6284           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6285           (match_operand:SWI124 2 "const_int_operand" "n")))
6286    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6287   "ix86_match_ccmode (insn, CCGCmode)"
6288 {
6289   switch (get_attr_type (insn))
6290     {
6291     case TYPE_INCDEC:
6292       if (operands[2] == constm1_rtx)
6293         return "inc{<imodesuffix>}\t%0";
6294       else
6295         {
6296           gcc_assert (operands[2] == const1_rtx);
6297           return "dec{<imodesuffix>}\t%0";
6298         }
6299
6300     default:
6301       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6302         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6303
6304       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6305     }
6306 }
6307   [(set (attr "type")
6308      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6309         (const_string "incdec")
6310         (const_string "alu")))
6311    (set (attr "length_immediate")
6312       (if_then_else
6313         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6314         (const_string "1")
6315         (const_string "*")))
6316    (set_attr "mode" "<MODE>")])
6317
6318 (define_insn "*add<mode>_5"
6319   [(set (reg FLAGS_REG)
6320         (compare
6321           (plus:SWI
6322             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6323             (match_operand:SWI 2 "<general_operand>" "<g>"))
6324           (const_int 0)))
6325    (clobber (match_scratch:SWI 0 "=<r>"))]
6326   "ix86_match_ccmode (insn, CCGOCmode)
6327    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6328 {
6329   switch (get_attr_type (insn))
6330     {
6331     case TYPE_INCDEC:
6332       if (operands[2] == const1_rtx)
6333         return "inc{<imodesuffix>}\t%0";
6334       else
6335         {
6336           gcc_assert (operands[2] == constm1_rtx);
6337           return "dec{<imodesuffix>}\t%0";
6338         }
6339
6340     default:
6341       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6342         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6343
6344       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6345     }
6346 }
6347   [(set (attr "type")
6348      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6349         (const_string "incdec")
6350         (const_string "alu")))
6351    (set (attr "length_immediate")
6352       (if_then_else
6353         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6354         (const_string "1")
6355         (const_string "*")))
6356    (set_attr "mode" "<MODE>")])
6357
6358 (define_insn "*addqi_ext_1_rex64"
6359   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6360                          (const_int 8)
6361                          (const_int 8))
6362         (plus:SI
6363           (zero_extract:SI
6364             (match_operand 1 "ext_register_operand" "0")
6365             (const_int 8)
6366             (const_int 8))
6367           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6368    (clobber (reg:CC FLAGS_REG))]
6369   "TARGET_64BIT"
6370 {
6371   switch (get_attr_type (insn))
6372     {
6373     case TYPE_INCDEC:
6374       if (operands[2] == const1_rtx)
6375         return "inc{b}\t%h0";
6376       else
6377         {
6378           gcc_assert (operands[2] == constm1_rtx);
6379           return "dec{b}\t%h0";
6380         }
6381
6382     default:
6383       return "add{b}\t{%2, %h0|%h0, %2}";
6384     }
6385 }
6386   [(set (attr "type")
6387      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6388         (const_string "incdec")
6389         (const_string "alu")))
6390    (set_attr "modrm" "1")
6391    (set_attr "mode" "QI")])
6392
6393 (define_insn "addqi_ext_1"
6394   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6395                          (const_int 8)
6396                          (const_int 8))
6397         (plus:SI
6398           (zero_extract:SI
6399             (match_operand 1 "ext_register_operand" "0")
6400             (const_int 8)
6401             (const_int 8))
6402           (match_operand:QI 2 "general_operand" "Qmn")))
6403    (clobber (reg:CC FLAGS_REG))]
6404   "!TARGET_64BIT"
6405 {
6406   switch (get_attr_type (insn))
6407     {
6408     case TYPE_INCDEC:
6409       if (operands[2] == const1_rtx)
6410         return "inc{b}\t%h0";
6411       else
6412         {
6413           gcc_assert (operands[2] == constm1_rtx);
6414           return "dec{b}\t%h0";
6415         }
6416
6417     default:
6418       return "add{b}\t{%2, %h0|%h0, %2}";
6419     }
6420 }
6421   [(set (attr "type")
6422      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6423         (const_string "incdec")
6424         (const_string "alu")))
6425    (set_attr "modrm" "1")
6426    (set_attr "mode" "QI")])
6427
6428 (define_insn "*addqi_ext_2"
6429   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6430                          (const_int 8)
6431                          (const_int 8))
6432         (plus:SI
6433           (zero_extract:SI
6434             (match_operand 1 "ext_register_operand" "%0")
6435             (const_int 8)
6436             (const_int 8))
6437           (zero_extract:SI
6438             (match_operand 2 "ext_register_operand" "Q")
6439             (const_int 8)
6440             (const_int 8))))
6441    (clobber (reg:CC FLAGS_REG))]
6442   ""
6443   "add{b}\t{%h2, %h0|%h0, %h2}"
6444   [(set_attr "type" "alu")
6445    (set_attr "mode" "QI")])
6446
6447 ;; The lea patterns for non-Pmodes needs to be matched by
6448 ;; several insns converted to real lea by splitters.
6449
6450 (define_insn_and_split "*lea_general_1"
6451   [(set (match_operand 0 "register_operand" "=r")
6452         (plus (plus (match_operand 1 "index_register_operand" "l")
6453                     (match_operand 2 "register_operand" "r"))
6454               (match_operand 3 "immediate_operand" "i")))]
6455   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6456     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6457    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6458    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6459    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6460    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6461        || GET_MODE (operands[3]) == VOIDmode)"
6462   "#"
6463   "&& reload_completed"
6464   [(const_int 0)]
6465 {
6466   rtx pat;
6467   operands[0] = gen_lowpart (SImode, operands[0]);
6468   operands[1] = gen_lowpart (Pmode, operands[1]);
6469   operands[2] = gen_lowpart (Pmode, operands[2]);
6470   operands[3] = gen_lowpart (Pmode, operands[3]);
6471   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6472                       operands[3]);
6473   if (Pmode != SImode)
6474     pat = gen_rtx_SUBREG (SImode, pat, 0);
6475   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6476   DONE;
6477 }
6478   [(set_attr "type" "lea")
6479    (set_attr "mode" "SI")])
6480
6481 (define_insn_and_split "*lea_general_1_zext"
6482   [(set (match_operand:DI 0 "register_operand" "=r")
6483         (zero_extend:DI
6484           (plus:SI (plus:SI
6485                      (match_operand:SI 1 "index_register_operand" "l")
6486                      (match_operand:SI 2 "register_operand" "r"))
6487                    (match_operand:SI 3 "immediate_operand" "i"))))]
6488   "TARGET_64BIT"
6489   "#"
6490   "&& reload_completed"
6491   [(set (match_dup 0)
6492         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6493                                                      (match_dup 2))
6494                                             (match_dup 3)) 0)))]
6495 {
6496   operands[1] = gen_lowpart (Pmode, operands[1]);
6497   operands[2] = gen_lowpart (Pmode, operands[2]);
6498   operands[3] = gen_lowpart (Pmode, operands[3]);
6499 }
6500   [(set_attr "type" "lea")
6501    (set_attr "mode" "SI")])
6502
6503 (define_insn_and_split "*lea_general_2"
6504   [(set (match_operand 0 "register_operand" "=r")
6505         (plus (mult (match_operand 1 "index_register_operand" "l")
6506                     (match_operand 2 "const248_operand" "i"))
6507               (match_operand 3 "nonmemory_operand" "ri")))]
6508   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6509     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6510    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6511    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6512    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6513        || GET_MODE (operands[3]) == VOIDmode)"
6514   "#"
6515   "&& reload_completed"
6516   [(const_int 0)]
6517 {
6518   rtx pat;
6519   operands[0] = gen_lowpart (SImode, operands[0]);
6520   operands[1] = gen_lowpart (Pmode, operands[1]);
6521   operands[3] = gen_lowpart (Pmode, operands[3]);
6522   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6523                       operands[3]);
6524   if (Pmode != SImode)
6525     pat = gen_rtx_SUBREG (SImode, pat, 0);
6526   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6527   DONE;
6528 }
6529   [(set_attr "type" "lea")
6530    (set_attr "mode" "SI")])
6531
6532 (define_insn_and_split "*lea_general_2_zext"
6533   [(set (match_operand:DI 0 "register_operand" "=r")
6534         (zero_extend:DI
6535           (plus:SI (mult:SI
6536                      (match_operand:SI 1 "index_register_operand" "l")
6537                      (match_operand:SI 2 "const248_operand" "n"))
6538                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6539   "TARGET_64BIT"
6540   "#"
6541   "&& reload_completed"
6542   [(set (match_dup 0)
6543         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6544                                                      (match_dup 2))
6545                                             (match_dup 3)) 0)))]
6546 {
6547   operands[1] = gen_lowpart (Pmode, operands[1]);
6548   operands[3] = gen_lowpart (Pmode, operands[3]);
6549 }
6550   [(set_attr "type" "lea")
6551    (set_attr "mode" "SI")])
6552
6553 (define_insn_and_split "*lea_general_3"
6554   [(set (match_operand 0 "register_operand" "=r")
6555         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6556                           (match_operand 2 "const248_operand" "i"))
6557                     (match_operand 3 "register_operand" "r"))
6558               (match_operand 4 "immediate_operand" "i")))]
6559   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6560     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6561    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6562    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6563    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6564   "#"
6565   "&& reload_completed"
6566   [(const_int 0)]
6567 {
6568   rtx pat;
6569   operands[0] = gen_lowpart (SImode, operands[0]);
6570   operands[1] = gen_lowpart (Pmode, operands[1]);
6571   operands[3] = gen_lowpart (Pmode, operands[3]);
6572   operands[4] = gen_lowpart (Pmode, operands[4]);
6573   pat = gen_rtx_PLUS (Pmode,
6574                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6575                                                          operands[2]),
6576                                     operands[3]),
6577                       operands[4]);
6578   if (Pmode != SImode)
6579     pat = gen_rtx_SUBREG (SImode, pat, 0);
6580   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6581   DONE;
6582 }
6583   [(set_attr "type" "lea")
6584    (set_attr "mode" "SI")])
6585
6586 (define_insn_and_split "*lea_general_3_zext"
6587   [(set (match_operand:DI 0 "register_operand" "=r")
6588         (zero_extend:DI
6589           (plus:SI (plus:SI
6590                      (mult:SI
6591                        (match_operand:SI 1 "index_register_operand" "l")
6592                        (match_operand:SI 2 "const248_operand" "n"))
6593                      (match_operand:SI 3 "register_operand" "r"))
6594                    (match_operand:SI 4 "immediate_operand" "i"))))]
6595   "TARGET_64BIT"
6596   "#"
6597   "&& reload_completed"
6598   [(set (match_dup 0)
6599         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6600                                                               (match_dup 2))
6601                                                      (match_dup 3))
6602                                             (match_dup 4)) 0)))]
6603 {
6604   operands[1] = gen_lowpart (Pmode, operands[1]);
6605   operands[3] = gen_lowpart (Pmode, operands[3]);
6606   operands[4] = gen_lowpart (Pmode, operands[4]);
6607 }
6608   [(set_attr "type" "lea")
6609    (set_attr "mode" "SI")])
6610 \f
6611 ;; Subtract instructions
6612
6613 (define_expand "sub<mode>3"
6614   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6615         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6616                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6617   ""
6618   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6619
6620 (define_insn_and_split "*sub<dwi>3_doubleword"
6621   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6622         (minus:<DWI>
6623           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6624           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6625    (clobber (reg:CC FLAGS_REG))]
6626   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6627   "#"
6628   "reload_completed"
6629   [(parallel [(set (reg:CC FLAGS_REG)
6630                    (compare:CC (match_dup 1) (match_dup 2)))
6631               (set (match_dup 0)
6632                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6633    (parallel [(set (match_dup 3)
6634                    (minus:DWIH
6635                      (match_dup 4)
6636                      (plus:DWIH
6637                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6638                        (match_dup 5))))
6639               (clobber (reg:CC FLAGS_REG))])]
6640   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6641
6642 (define_insn "*sub<mode>_1"
6643   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6644         (minus:SWI
6645           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6646           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6647    (clobber (reg:CC FLAGS_REG))]
6648   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6649   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6650   [(set_attr "type" "alu")
6651    (set_attr "mode" "<MODE>")])
6652
6653 (define_insn "*subsi_1_zext"
6654   [(set (match_operand:DI 0 "register_operand" "=r")
6655         (zero_extend:DI
6656           (minus:SI (match_operand:SI 1 "register_operand" "0")
6657                     (match_operand:SI 2 "general_operand" "g"))))
6658    (clobber (reg:CC FLAGS_REG))]
6659   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6660   "sub{l}\t{%2, %k0|%k0, %2}"
6661   [(set_attr "type" "alu")
6662    (set_attr "mode" "SI")])
6663
6664 (define_insn "*subqi_1_slp"
6665   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6666         (minus:QI (match_dup 0)
6667                   (match_operand:QI 1 "general_operand" "qn,qm")))
6668    (clobber (reg:CC FLAGS_REG))]
6669   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6670    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6671   "sub{b}\t{%1, %0|%0, %1}"
6672   [(set_attr "type" "alu1")
6673    (set_attr "mode" "QI")])
6674
6675 (define_insn "*sub<mode>_2"
6676   [(set (reg FLAGS_REG)
6677         (compare
6678           (minus:SWI
6679             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6680             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6681           (const_int 0)))
6682    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6683         (minus:SWI (match_dup 1) (match_dup 2)))]
6684   "ix86_match_ccmode (insn, CCGOCmode)
6685    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6686   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "<MODE>")])
6689
6690 (define_insn "*subsi_2_zext"
6691   [(set (reg FLAGS_REG)
6692         (compare
6693           (minus:SI (match_operand:SI 1 "register_operand" "0")
6694                     (match_operand:SI 2 "general_operand" "g"))
6695           (const_int 0)))
6696    (set (match_operand:DI 0 "register_operand" "=r")
6697         (zero_extend:DI
6698           (minus:SI (match_dup 1)
6699                     (match_dup 2))))]
6700   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6701    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6702   "sub{l}\t{%2, %k0|%k0, %2}"
6703   [(set_attr "type" "alu")
6704    (set_attr "mode" "SI")])
6705
6706 (define_insn "*sub<mode>_3"
6707   [(set (reg FLAGS_REG)
6708         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6709                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6710    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6711         (minus:SWI (match_dup 1) (match_dup 2)))]
6712   "ix86_match_ccmode (insn, CCmode)
6713    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6714   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6715   [(set_attr "type" "alu")
6716    (set_attr "mode" "<MODE>")])
6717
6718 (define_insn "*subsi_3_zext"
6719   [(set (reg FLAGS_REG)
6720         (compare (match_operand:SI 1 "register_operand" "0")
6721                  (match_operand:SI 2 "general_operand" "g")))
6722    (set (match_operand:DI 0 "register_operand" "=r")
6723         (zero_extend:DI
6724           (minus:SI (match_dup 1)
6725                     (match_dup 2))))]
6726   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6727    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728   "sub{l}\t{%2, %1|%1, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "SI")])
6731 \f
6732 ;; Add with carry and subtract with borrow
6733
6734 (define_expand "<plusminus_insn><mode>3_carry"
6735   [(parallel
6736     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6737           (plusminus:SWI
6738             (match_operand:SWI 1 "nonimmediate_operand" "")
6739             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6740                        [(match_operand 3 "flags_reg_operand" "")
6741                         (const_int 0)])
6742                       (match_operand:SWI 2 "<general_operand>" ""))))
6743      (clobber (reg:CC FLAGS_REG))])]
6744   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6745
6746 (define_insn "*<plusminus_insn><mode>3_carry"
6747   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6748         (plusminus:SWI
6749           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6750           (plus:SWI
6751             (match_operator 3 "ix86_carry_flag_operator"
6752              [(reg FLAGS_REG) (const_int 0)])
6753             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6754    (clobber (reg:CC FLAGS_REG))]
6755   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6756   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6757   [(set_attr "type" "alu")
6758    (set_attr "use_carry" "1")
6759    (set_attr "pent_pair" "pu")
6760    (set_attr "mode" "<MODE>")])
6761
6762 (define_insn "*addsi3_carry_zext"
6763   [(set (match_operand:DI 0 "register_operand" "=r")
6764         (zero_extend:DI
6765           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6766                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6767                              [(reg FLAGS_REG) (const_int 0)])
6768                             (match_operand:SI 2 "general_operand" "g")))))
6769    (clobber (reg:CC FLAGS_REG))]
6770   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6771   "adc{l}\t{%2, %k0|%k0, %2}"
6772   [(set_attr "type" "alu")
6773    (set_attr "use_carry" "1")
6774    (set_attr "pent_pair" "pu")
6775    (set_attr "mode" "SI")])
6776
6777 (define_insn "*subsi3_carry_zext"
6778   [(set (match_operand:DI 0 "register_operand" "=r")
6779         (zero_extend:DI
6780           (minus:SI (match_operand:SI 1 "register_operand" "0")
6781                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6782                               [(reg FLAGS_REG) (const_int 0)])
6783                              (match_operand:SI 2 "general_operand" "g")))))
6784    (clobber (reg:CC FLAGS_REG))]
6785   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6786   "sbb{l}\t{%2, %k0|%k0, %2}"
6787   [(set_attr "type" "alu")
6788    (set_attr "pent_pair" "pu")
6789    (set_attr "mode" "SI")])
6790 \f
6791 ;; Overflow setting add and subtract instructions
6792
6793 (define_insn "*add<mode>3_cconly_overflow"
6794   [(set (reg:CCC FLAGS_REG)
6795         (compare:CCC
6796           (plus:SWI
6797             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6798             (match_operand:SWI 2 "<general_operand>" "<g>"))
6799           (match_dup 1)))
6800    (clobber (match_scratch:SWI 0 "=<r>"))]
6801   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6802   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6803   [(set_attr "type" "alu")
6804    (set_attr "mode" "<MODE>")])
6805
6806 (define_insn "*sub<mode>3_cconly_overflow"
6807   [(set (reg:CCC FLAGS_REG)
6808         (compare:CCC
6809           (minus:SWI
6810             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6811             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6812           (match_dup 0)))]
6813   ""
6814   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6815   [(set_attr "type" "icmp")
6816    (set_attr "mode" "<MODE>")])
6817
6818 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6819   [(set (reg:CCC FLAGS_REG)
6820         (compare:CCC
6821             (plusminus:SWI
6822                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6823                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6824             (match_dup 1)))
6825    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6826         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6827   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6828   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6829   [(set_attr "type" "alu")
6830    (set_attr "mode" "<MODE>")])
6831
6832 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6833   [(set (reg:CCC FLAGS_REG)
6834         (compare:CCC
6835           (plusminus:SI
6836             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6837             (match_operand:SI 2 "general_operand" "g"))
6838           (match_dup 1)))
6839    (set (match_operand:DI 0 "register_operand" "=r")
6840         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6841   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6842   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6843   [(set_attr "type" "alu")
6844    (set_attr "mode" "SI")])
6845
6846 ;; The patterns that match these are at the end of this file.
6847
6848 (define_expand "<plusminus_insn>xf3"
6849   [(set (match_operand:XF 0 "register_operand" "")
6850         (plusminus:XF
6851           (match_operand:XF 1 "register_operand" "")
6852           (match_operand:XF 2 "register_operand" "")))]
6853   "TARGET_80387")
6854
6855 (define_expand "<plusminus_insn><mode>3"
6856   [(set (match_operand:MODEF 0 "register_operand" "")
6857         (plusminus:MODEF
6858           (match_operand:MODEF 1 "register_operand" "")
6859           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6860   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6861     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6862 \f
6863 ;; Multiply instructions
6864
6865 (define_expand "mul<mode>3"
6866   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6867                    (mult:SWIM248
6868                      (match_operand:SWIM248 1 "register_operand" "")
6869                      (match_operand:SWIM248 2 "<general_operand>" "")))
6870               (clobber (reg:CC FLAGS_REG))])])
6871
6872 (define_expand "mulqi3"
6873   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6874                    (mult:QI
6875                      (match_operand:QI 1 "register_operand" "")
6876                      (match_operand:QI 2 "nonimmediate_operand" "")))
6877               (clobber (reg:CC FLAGS_REG))])]
6878   "TARGET_QIMODE_MATH")
6879
6880 ;; On AMDFAM10
6881 ;; IMUL reg32/64, reg32/64, imm8        Direct
6882 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6883 ;; IMUL reg32/64, reg32/64, imm32       Direct
6884 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6885 ;; IMUL reg32/64, reg32/64              Direct
6886 ;; IMUL reg32/64, mem32/64              Direct
6887 ;;
6888 ;; On BDVER1, all above IMULs use DirectPath
6889
6890 (define_insn "*mul<mode>3_1"
6891   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6892         (mult:SWI48
6893           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6894           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6895    (clobber (reg:CC FLAGS_REG))]
6896   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6897   "@
6898    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6899    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6900    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6901   [(set_attr "type" "imul")
6902    (set_attr "prefix_0f" "0,0,1")
6903    (set (attr "athlon_decode")
6904         (cond [(eq_attr "cpu" "athlon")
6905                   (const_string "vector")
6906                (eq_attr "alternative" "1")
6907                   (const_string "vector")
6908                (and (eq_attr "alternative" "2")
6909                     (match_operand 1 "memory_operand" ""))
6910                   (const_string "vector")]
6911               (const_string "direct")))
6912    (set (attr "amdfam10_decode")
6913         (cond [(and (eq_attr "alternative" "0,1")
6914                     (match_operand 1 "memory_operand" ""))
6915                   (const_string "vector")]
6916               (const_string "direct")))
6917    (set_attr "bdver1_decode" "direct")
6918    (set_attr "mode" "<MODE>")])
6919
6920 (define_insn "*mulsi3_1_zext"
6921   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6922         (zero_extend:DI
6923           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6924                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6925    (clobber (reg:CC FLAGS_REG))]
6926   "TARGET_64BIT
6927    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928   "@
6929    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6930    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6931    imul{l}\t{%2, %k0|%k0, %2}"
6932   [(set_attr "type" "imul")
6933    (set_attr "prefix_0f" "0,0,1")
6934    (set (attr "athlon_decode")
6935         (cond [(eq_attr "cpu" "athlon")
6936                   (const_string "vector")
6937                (eq_attr "alternative" "1")
6938                   (const_string "vector")
6939                (and (eq_attr "alternative" "2")
6940                     (match_operand 1 "memory_operand" ""))
6941                   (const_string "vector")]
6942               (const_string "direct")))
6943    (set (attr "amdfam10_decode")
6944         (cond [(and (eq_attr "alternative" "0,1")
6945                     (match_operand 1 "memory_operand" ""))
6946                   (const_string "vector")]
6947               (const_string "direct")))
6948    (set_attr "bdver1_decode" "direct")
6949    (set_attr "mode" "SI")])
6950
6951 ;; On AMDFAM10
6952 ;; IMUL reg16, reg16, imm8      VectorPath
6953 ;; IMUL reg16, mem16, imm8      VectorPath
6954 ;; IMUL reg16, reg16, imm16     VectorPath
6955 ;; IMUL reg16, mem16, imm16     VectorPath
6956 ;; IMUL reg16, reg16            Direct
6957 ;; IMUL reg16, mem16            Direct
6958 ;;
6959 ;; On BDVER1, all HI MULs use DoublePath
6960
6961 (define_insn "*mulhi3_1"
6962   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6963         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6964                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "TARGET_HIMODE_MATH
6967    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6968   "@
6969    imul{w}\t{%2, %1, %0|%0, %1, %2}
6970    imul{w}\t{%2, %1, %0|%0, %1, %2}
6971    imul{w}\t{%2, %0|%0, %2}"
6972   [(set_attr "type" "imul")
6973    (set_attr "prefix_0f" "0,0,1")
6974    (set (attr "athlon_decode")
6975         (cond [(eq_attr "cpu" "athlon")
6976                   (const_string "vector")
6977                (eq_attr "alternative" "1,2")
6978                   (const_string "vector")]
6979               (const_string "direct")))
6980    (set (attr "amdfam10_decode")
6981         (cond [(eq_attr "alternative" "0,1")
6982                   (const_string "vector")]
6983               (const_string "direct")))
6984    (set_attr "bdver1_decode" "double")
6985    (set_attr "mode" "HI")])
6986
6987 ;;On AMDFAM10 and BDVER1
6988 ;; MUL reg8     Direct
6989 ;; MUL mem8     Direct
6990
6991 (define_insn "*mulqi3_1"
6992   [(set (match_operand:QI 0 "register_operand" "=a")
6993         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6994                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6995    (clobber (reg:CC FLAGS_REG))]
6996   "TARGET_QIMODE_MATH
6997    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998   "mul{b}\t%2"
6999   [(set_attr "type" "imul")
7000    (set_attr "length_immediate" "0")
7001    (set (attr "athlon_decode")
7002      (if_then_else (eq_attr "cpu" "athlon")
7003         (const_string "vector")
7004         (const_string "direct")))
7005    (set_attr "amdfam10_decode" "direct")
7006    (set_attr "bdver1_decode" "direct")
7007    (set_attr "mode" "QI")])
7008
7009 (define_expand "<u>mul<mode><dwi>3"
7010   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7011                    (mult:<DWI>
7012                      (any_extend:<DWI>
7013                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7014                      (any_extend:<DWI>
7015                        (match_operand:DWIH 2 "register_operand" ""))))
7016               (clobber (reg:CC FLAGS_REG))])])
7017
7018 (define_expand "<u>mulqihi3"
7019   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7020                    (mult:HI
7021                      (any_extend:HI
7022                        (match_operand:QI 1 "nonimmediate_operand" ""))
7023                      (any_extend:HI
7024                        (match_operand:QI 2 "register_operand" ""))))
7025               (clobber (reg:CC FLAGS_REG))])]
7026   "TARGET_QIMODE_MATH")
7027
7028 (define_insn "*<u>mul<mode><dwi>3_1"
7029   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7030         (mult:<DWI>
7031           (any_extend:<DWI>
7032             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7033           (any_extend:<DWI>
7034             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7035    (clobber (reg:CC FLAGS_REG))]
7036   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7037   "<sgnprefix>mul{<imodesuffix>}\t%2"
7038   [(set_attr "type" "imul")
7039    (set_attr "length_immediate" "0")
7040    (set (attr "athlon_decode")
7041      (if_then_else (eq_attr "cpu" "athlon")
7042         (const_string "vector")
7043         (const_string "double")))
7044    (set_attr "amdfam10_decode" "double")
7045    (set_attr "bdver1_decode" "direct")
7046    (set_attr "mode" "<MODE>")])
7047
7048 (define_insn "*<u>mulqihi3_1"
7049   [(set (match_operand:HI 0 "register_operand" "=a")
7050         (mult:HI
7051           (any_extend:HI
7052             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7053           (any_extend:HI
7054             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7055    (clobber (reg:CC FLAGS_REG))]
7056   "TARGET_QIMODE_MATH
7057    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7058   "<sgnprefix>mul{b}\t%2"
7059   [(set_attr "type" "imul")
7060    (set_attr "length_immediate" "0")
7061    (set (attr "athlon_decode")
7062      (if_then_else (eq_attr "cpu" "athlon")
7063         (const_string "vector")
7064         (const_string "direct")))
7065    (set_attr "amdfam10_decode" "direct")
7066    (set_attr "bdver1_decode" "direct")
7067    (set_attr "mode" "QI")])
7068
7069 (define_expand "<s>mul<mode>3_highpart"
7070   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7071                    (truncate:SWI48
7072                      (lshiftrt:<DWI>
7073                        (mult:<DWI>
7074                          (any_extend:<DWI>
7075                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7076                          (any_extend:<DWI>
7077                            (match_operand:SWI48 2 "register_operand" "")))
7078                        (match_dup 4))))
7079               (clobber (match_scratch:SWI48 3 ""))
7080               (clobber (reg:CC FLAGS_REG))])]
7081   ""
7082   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7083
7084 (define_insn "*<s>muldi3_highpart_1"
7085   [(set (match_operand:DI 0 "register_operand" "=d")
7086         (truncate:DI
7087           (lshiftrt:TI
7088             (mult:TI
7089               (any_extend:TI
7090                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7091               (any_extend:TI
7092                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7093             (const_int 64))))
7094    (clobber (match_scratch:DI 3 "=1"))
7095    (clobber (reg:CC FLAGS_REG))]
7096   "TARGET_64BIT
7097    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7098   "<sgnprefix>mul{q}\t%2"
7099   [(set_attr "type" "imul")
7100    (set_attr "length_immediate" "0")
7101    (set (attr "athlon_decode")
7102      (if_then_else (eq_attr "cpu" "athlon")
7103         (const_string "vector")
7104         (const_string "double")))
7105    (set_attr "amdfam10_decode" "double")
7106    (set_attr "bdver1_decode" "direct")
7107    (set_attr "mode" "DI")])
7108
7109 (define_insn "*<s>mulsi3_highpart_1"
7110   [(set (match_operand:SI 0 "register_operand" "=d")
7111         (truncate:SI
7112           (lshiftrt:DI
7113             (mult:DI
7114               (any_extend:DI
7115                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7116               (any_extend:DI
7117                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7118             (const_int 32))))
7119    (clobber (match_scratch:SI 3 "=1"))
7120    (clobber (reg:CC FLAGS_REG))]
7121   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7122   "<sgnprefix>mul{l}\t%2"
7123   [(set_attr "type" "imul")
7124    (set_attr "length_immediate" "0")
7125    (set (attr "athlon_decode")
7126      (if_then_else (eq_attr "cpu" "athlon")
7127         (const_string "vector")
7128         (const_string "double")))
7129    (set_attr "amdfam10_decode" "double")
7130    (set_attr "bdver1_decode" "direct")
7131    (set_attr "mode" "SI")])
7132
7133 (define_insn "*<s>mulsi3_highpart_zext"
7134   [(set (match_operand:DI 0 "register_operand" "=d")
7135         (zero_extend:DI (truncate:SI
7136           (lshiftrt:DI
7137             (mult:DI (any_extend:DI
7138                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7139                      (any_extend:DI
7140                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7141             (const_int 32)))))
7142    (clobber (match_scratch:SI 3 "=1"))
7143    (clobber (reg:CC FLAGS_REG))]
7144   "TARGET_64BIT
7145    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7146   "<sgnprefix>mul{l}\t%2"
7147   [(set_attr "type" "imul")
7148    (set_attr "length_immediate" "0")
7149    (set (attr "athlon_decode")
7150      (if_then_else (eq_attr "cpu" "athlon")
7151         (const_string "vector")
7152         (const_string "double")))
7153    (set_attr "amdfam10_decode" "double")
7154    (set_attr "bdver1_decode" "direct")
7155    (set_attr "mode" "SI")])
7156
7157 ;; The patterns that match these are at the end of this file.
7158
7159 (define_expand "mulxf3"
7160   [(set (match_operand:XF 0 "register_operand" "")
7161         (mult:XF (match_operand:XF 1 "register_operand" "")
7162                  (match_operand:XF 2 "register_operand" "")))]
7163   "TARGET_80387")
7164
7165 (define_expand "mul<mode>3"
7166   [(set (match_operand:MODEF 0 "register_operand" "")
7167         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7168                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7169   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7170     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7171 \f
7172 ;; Divide instructions
7173
7174 ;; The patterns that match these are at the end of this file.
7175
7176 (define_expand "divxf3"
7177   [(set (match_operand:XF 0 "register_operand" "")
7178         (div:XF (match_operand:XF 1 "register_operand" "")
7179                 (match_operand:XF 2 "register_operand" "")))]
7180   "TARGET_80387")
7181
7182 (define_expand "divdf3"
7183   [(set (match_operand:DF 0 "register_operand" "")
7184         (div:DF (match_operand:DF 1 "register_operand" "")
7185                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7186    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7187     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7188
7189 (define_expand "divsf3"
7190   [(set (match_operand:SF 0 "register_operand" "")
7191         (div:SF (match_operand:SF 1 "register_operand" "")
7192                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7193   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7194     || TARGET_SSE_MATH"
7195 {
7196   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7197       && flag_finite_math_only && !flag_trapping_math
7198       && flag_unsafe_math_optimizations)
7199     {
7200       ix86_emit_swdivsf (operands[0], operands[1],
7201                          operands[2], SFmode);
7202       DONE;
7203     }
7204 })
7205 \f
7206 ;; Divmod instructions.
7207
7208 (define_expand "divmod<mode>4"
7209   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7210                    (div:SWIM248
7211                      (match_operand:SWIM248 1 "register_operand" "")
7212                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7213               (set (match_operand:SWIM248 3 "register_operand" "")
7214                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7215               (clobber (reg:CC FLAGS_REG))])])
7216
7217 ;; Split with 8bit unsigned divide:
7218 ;;      if (dividend an divisor are in [0-255])
7219 ;;         use 8bit unsigned integer divide
7220 ;;       else
7221 ;;         use original integer divide
7222 (define_split
7223   [(set (match_operand:SWI48 0 "register_operand" "")
7224         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7225                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7226    (set (match_operand:SWI48 1 "register_operand" "")
7227         (mod:SWI48 (match_dup 2) (match_dup 3)))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_USE_8BIT_IDIV
7230    && TARGET_QIMODE_MATH
7231    && can_create_pseudo_p ()
7232    && !optimize_insn_for_size_p ()"
7233   [(const_int 0)]
7234   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7235
7236 (define_insn_and_split "divmod<mode>4_1"
7237   [(set (match_operand:SWI48 0 "register_operand" "=a")
7238         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7239                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7240    (set (match_operand:SWI48 1 "register_operand" "=&d")
7241         (mod:SWI48 (match_dup 2) (match_dup 3)))
7242    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7243    (clobber (reg:CC FLAGS_REG))]
7244   ""
7245   "#"
7246   "reload_completed"
7247   [(parallel [(set (match_dup 1)
7248                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7249               (clobber (reg:CC FLAGS_REG))])
7250    (parallel [(set (match_dup 0)
7251                    (div:SWI48 (match_dup 2) (match_dup 3)))
7252               (set (match_dup 1)
7253                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7254               (use (match_dup 1))
7255               (clobber (reg:CC FLAGS_REG))])]
7256 {
7257   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7258
7259   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7260     operands[4] = operands[2];
7261   else
7262     {
7263       /* Avoid use of cltd in favor of a mov+shift.  */
7264       emit_move_insn (operands[1], operands[2]);
7265       operands[4] = operands[1];
7266     }
7267 }
7268   [(set_attr "type" "multi")
7269    (set_attr "mode" "<MODE>")])
7270
7271 (define_insn_and_split "*divmod<mode>4"
7272   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7273         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7274                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7275    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7276         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7277    (clobber (reg:CC FLAGS_REG))]
7278   ""
7279   "#"
7280   "reload_completed"
7281   [(parallel [(set (match_dup 1)
7282                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7283               (clobber (reg:CC FLAGS_REG))])
7284    (parallel [(set (match_dup 0)
7285                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7286               (set (match_dup 1)
7287                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7288               (use (match_dup 1))
7289               (clobber (reg:CC FLAGS_REG))])]
7290 {
7291   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7292
7293   if (<MODE>mode != HImode
7294       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7295     operands[4] = operands[2];
7296   else
7297     {
7298       /* Avoid use of cltd in favor of a mov+shift.  */
7299       emit_move_insn (operands[1], operands[2]);
7300       operands[4] = operands[1];
7301     }
7302 }
7303   [(set_attr "type" "multi")
7304    (set_attr "mode" "<MODE>")])
7305
7306 (define_insn "*divmod<mode>4_noext"
7307   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7308         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7309                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7310    (set (match_operand:SWIM248 1 "register_operand" "=d")
7311         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7312    (use (match_operand:SWIM248 4 "register_operand" "1"))
7313    (clobber (reg:CC FLAGS_REG))]
7314   ""
7315   "idiv{<imodesuffix>}\t%3"
7316   [(set_attr "type" "idiv")
7317    (set_attr "mode" "<MODE>")])
7318
7319 (define_expand "divmodqi4"
7320   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7321                    (div:QI
7322                      (match_operand:QI 1 "register_operand" "")
7323                      (match_operand:QI 2 "nonimmediate_operand" "")))
7324               (set (match_operand:QI 3 "register_operand" "")
7325                    (mod:QI (match_dup 1) (match_dup 2)))
7326               (clobber (reg:CC FLAGS_REG))])]
7327   "TARGET_QIMODE_MATH"
7328 {
7329   rtx div, mod, insn;
7330   rtx tmp0, tmp1;
7331   
7332   tmp0 = gen_reg_rtx (HImode);
7333   tmp1 = gen_reg_rtx (HImode);
7334
7335   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7336      in AX.  */
7337   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7338   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7339
7340   /* Extract remainder from AH.  */
7341   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7342   insn = emit_move_insn (operands[3], tmp1);
7343
7344   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7345   set_unique_reg_note (insn, REG_EQUAL, mod);
7346
7347   /* Extract quotient from AL.  */
7348   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7349
7350   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7351   set_unique_reg_note (insn, REG_EQUAL, div);
7352
7353   DONE;
7354 })
7355
7356 ;; Divide AX by r/m8, with result stored in
7357 ;; AL <- Quotient
7358 ;; AH <- Remainder
7359 ;; Change div/mod to HImode and extend the second argument to HImode
7360 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7361 ;; combine may fail.
7362 (define_insn "divmodhiqi3"
7363   [(set (match_operand:HI 0 "register_operand" "=a")
7364         (ior:HI
7365           (ashift:HI
7366             (zero_extend:HI
7367               (truncate:QI
7368                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7369                         (sign_extend:HI
7370                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7371             (const_int 8))
7372           (zero_extend:HI
7373             (truncate:QI
7374               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7375    (clobber (reg:CC FLAGS_REG))]
7376   "TARGET_QIMODE_MATH"
7377   "idiv{b}\t%2"
7378   [(set_attr "type" "idiv")
7379    (set_attr "mode" "QI")])
7380
7381 (define_expand "udivmod<mode>4"
7382   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7383                    (udiv:SWIM248
7384                      (match_operand:SWIM248 1 "register_operand" "")
7385                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7386               (set (match_operand:SWIM248 3 "register_operand" "")
7387                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7388               (clobber (reg:CC FLAGS_REG))])])
7389
7390 ;; Split with 8bit unsigned divide:
7391 ;;      if (dividend an divisor are in [0-255])
7392 ;;         use 8bit unsigned integer divide
7393 ;;       else
7394 ;;         use original integer divide
7395 (define_split
7396   [(set (match_operand:SWI48 0 "register_operand" "")
7397         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7398                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7399    (set (match_operand:SWI48 1 "register_operand" "")
7400         (umod:SWI48 (match_dup 2) (match_dup 3)))
7401    (clobber (reg:CC FLAGS_REG))]
7402   "TARGET_USE_8BIT_IDIV
7403    && TARGET_QIMODE_MATH
7404    && can_create_pseudo_p ()
7405    && !optimize_insn_for_size_p ()"
7406   [(const_int 0)]
7407   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7408
7409 (define_insn_and_split "udivmod<mode>4_1"
7410   [(set (match_operand:SWI48 0 "register_operand" "=a")
7411         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7412                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7413    (set (match_operand:SWI48 1 "register_operand" "=&d")
7414         (umod:SWI48 (match_dup 2) (match_dup 3)))
7415    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7416    (clobber (reg:CC FLAGS_REG))]
7417   ""
7418   "#"
7419   "reload_completed"
7420   [(set (match_dup 1) (const_int 0))
7421    (parallel [(set (match_dup 0)
7422                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7423               (set (match_dup 1)
7424                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7425               (use (match_dup 1))
7426               (clobber (reg:CC FLAGS_REG))])]
7427   ""
7428   [(set_attr "type" "multi")
7429    (set_attr "mode" "<MODE>")])
7430
7431 (define_insn_and_split "*udivmod<mode>4"
7432   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7433         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7434                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7435    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7436         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7437    (clobber (reg:CC FLAGS_REG))]
7438   ""
7439   "#"
7440   "reload_completed"
7441   [(set (match_dup 1) (const_int 0))
7442    (parallel [(set (match_dup 0)
7443                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7444               (set (match_dup 1)
7445                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7446               (use (match_dup 1))
7447               (clobber (reg:CC FLAGS_REG))])]
7448   ""
7449   [(set_attr "type" "multi")
7450    (set_attr "mode" "<MODE>")])
7451
7452 (define_insn "*udivmod<mode>4_noext"
7453   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7454         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7455                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7456    (set (match_operand:SWIM248 1 "register_operand" "=d")
7457         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7458    (use (match_operand:SWIM248 4 "register_operand" "1"))
7459    (clobber (reg:CC FLAGS_REG))]
7460   ""
7461   "div{<imodesuffix>}\t%3"
7462   [(set_attr "type" "idiv")
7463    (set_attr "mode" "<MODE>")])
7464
7465 (define_expand "udivmodqi4"
7466   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7467                    (udiv:QI
7468                      (match_operand:QI 1 "register_operand" "")
7469                      (match_operand:QI 2 "nonimmediate_operand" "")))
7470               (set (match_operand:QI 3 "register_operand" "")
7471                    (umod:QI (match_dup 1) (match_dup 2)))
7472               (clobber (reg:CC FLAGS_REG))])]
7473   "TARGET_QIMODE_MATH"
7474 {
7475   rtx div, mod, insn;
7476   rtx tmp0, tmp1;
7477   
7478   tmp0 = gen_reg_rtx (HImode);
7479   tmp1 = gen_reg_rtx (HImode);
7480
7481   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7482      in AX.  */
7483   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7484   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7485
7486   /* Extract remainder from AH.  */
7487   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7488   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7489   insn = emit_move_insn (operands[3], tmp1);
7490
7491   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7492   set_unique_reg_note (insn, REG_EQUAL, mod);
7493
7494   /* Extract quotient from AL.  */
7495   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7496
7497   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7498   set_unique_reg_note (insn, REG_EQUAL, div);
7499
7500   DONE;
7501 })
7502
7503 (define_insn "udivmodhiqi3"
7504   [(set (match_operand:HI 0 "register_operand" "=a")
7505         (ior:HI
7506           (ashift:HI
7507             (zero_extend:HI
7508               (truncate:QI
7509                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7510                         (zero_extend:HI
7511                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7512             (const_int 8))
7513           (zero_extend:HI
7514             (truncate:QI
7515               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7516    (clobber (reg:CC FLAGS_REG))]
7517   "TARGET_QIMODE_MATH"
7518   "div{b}\t%2"
7519   [(set_attr "type" "idiv")
7520    (set_attr "mode" "QI")])
7521
7522 ;; We cannot use div/idiv for double division, because it causes
7523 ;; "division by zero" on the overflow and that's not what we expect
7524 ;; from truncate.  Because true (non truncating) double division is
7525 ;; never generated, we can't create this insn anyway.
7526 ;
7527 ;(define_insn ""
7528 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7529 ;       (truncate:SI
7530 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7531 ;                  (zero_extend:DI
7532 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7533 ;   (set (match_operand:SI 3 "register_operand" "=d")
7534 ;       (truncate:SI
7535 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7536 ;   (clobber (reg:CC FLAGS_REG))]
7537 ;  ""
7538 ;  "div{l}\t{%2, %0|%0, %2}"
7539 ;  [(set_attr "type" "idiv")])
7540 \f
7541 ;;- Logical AND instructions
7542
7543 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7544 ;; Note that this excludes ah.
7545
7546 (define_expand "testsi_ccno_1"
7547   [(set (reg:CCNO FLAGS_REG)
7548         (compare:CCNO
7549           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7550                   (match_operand:SI 1 "nonmemory_operand" ""))
7551           (const_int 0)))])
7552
7553 (define_expand "testqi_ccz_1"
7554   [(set (reg:CCZ FLAGS_REG)
7555         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7556                              (match_operand:QI 1 "nonmemory_operand" ""))
7557                  (const_int 0)))])
7558
7559 (define_expand "testdi_ccno_1"
7560   [(set (reg:CCNO FLAGS_REG)
7561         (compare:CCNO
7562           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7563                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7564           (const_int 0)))]
7565   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7566
7567 (define_insn "*testdi_1"
7568   [(set (reg FLAGS_REG)
7569         (compare
7570          (and:DI
7571           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7572           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7573          (const_int 0)))]
7574   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7575    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7576   "@
7577    test{l}\t{%k1, %k0|%k0, %k1}
7578    test{l}\t{%k1, %k0|%k0, %k1}
7579    test{q}\t{%1, %0|%0, %1}
7580    test{q}\t{%1, %0|%0, %1}
7581    test{q}\t{%1, %0|%0, %1}"
7582   [(set_attr "type" "test")
7583    (set_attr "modrm" "0,1,0,1,1")
7584    (set_attr "mode" "SI,SI,DI,DI,DI")])
7585
7586 (define_insn "*testqi_1_maybe_si"
7587   [(set (reg FLAGS_REG)
7588         (compare
7589           (and:QI
7590             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7591             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7592           (const_int 0)))]
7593    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7594     && ix86_match_ccmode (insn,
7595                          CONST_INT_P (operands[1])
7596                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7597 {
7598   if (which_alternative == 3)
7599     {
7600       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7601         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7602       return "test{l}\t{%1, %k0|%k0, %1}";
7603     }
7604   return "test{b}\t{%1, %0|%0, %1}";
7605 }
7606   [(set_attr "type" "test")
7607    (set_attr "modrm" "0,1,1,1")
7608    (set_attr "mode" "QI,QI,QI,SI")
7609    (set_attr "pent_pair" "uv,np,uv,np")])
7610
7611 (define_insn "*test<mode>_1"
7612   [(set (reg FLAGS_REG)
7613         (compare
7614          (and:SWI124
7615           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7616           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7617          (const_int 0)))]
7618   "ix86_match_ccmode (insn, CCNOmode)
7619    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7620   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7621   [(set_attr "type" "test")
7622    (set_attr "modrm" "0,1,1")
7623    (set_attr "mode" "<MODE>")
7624    (set_attr "pent_pair" "uv,np,uv")])
7625
7626 (define_expand "testqi_ext_ccno_0"
7627   [(set (reg:CCNO FLAGS_REG)
7628         (compare:CCNO
7629           (and:SI
7630             (zero_extract:SI
7631               (match_operand 0 "ext_register_operand" "")
7632               (const_int 8)
7633               (const_int 8))
7634             (match_operand 1 "const_int_operand" ""))
7635           (const_int 0)))])
7636
7637 (define_insn "*testqi_ext_0"
7638   [(set (reg FLAGS_REG)
7639         (compare
7640           (and:SI
7641             (zero_extract:SI
7642               (match_operand 0 "ext_register_operand" "Q")
7643               (const_int 8)
7644               (const_int 8))
7645             (match_operand 1 "const_int_operand" "n"))
7646           (const_int 0)))]
7647   "ix86_match_ccmode (insn, CCNOmode)"
7648   "test{b}\t{%1, %h0|%h0, %1}"
7649   [(set_attr "type" "test")
7650    (set_attr "mode" "QI")
7651    (set_attr "length_immediate" "1")
7652    (set_attr "modrm" "1")
7653    (set_attr "pent_pair" "np")])
7654
7655 (define_insn "*testqi_ext_1_rex64"
7656   [(set (reg FLAGS_REG)
7657         (compare
7658           (and:SI
7659             (zero_extract:SI
7660               (match_operand 0 "ext_register_operand" "Q")
7661               (const_int 8)
7662               (const_int 8))
7663             (zero_extend:SI
7664               (match_operand:QI 1 "register_operand" "Q")))
7665           (const_int 0)))]
7666   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7667   "test{b}\t{%1, %h0|%h0, %1}"
7668   [(set_attr "type" "test")
7669    (set_attr "mode" "QI")])
7670
7671 (define_insn "*testqi_ext_1"
7672   [(set (reg FLAGS_REG)
7673         (compare
7674           (and:SI
7675             (zero_extract:SI
7676               (match_operand 0 "ext_register_operand" "Q")
7677               (const_int 8)
7678               (const_int 8))
7679             (zero_extend:SI
7680               (match_operand:QI 1 "general_operand" "Qm")))
7681           (const_int 0)))]
7682   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7683   "test{b}\t{%1, %h0|%h0, %1}"
7684   [(set_attr "type" "test")
7685    (set_attr "mode" "QI")])
7686
7687 (define_insn "*testqi_ext_2"
7688   [(set (reg FLAGS_REG)
7689         (compare
7690           (and:SI
7691             (zero_extract:SI
7692               (match_operand 0 "ext_register_operand" "Q")
7693               (const_int 8)
7694               (const_int 8))
7695             (zero_extract:SI
7696               (match_operand 1 "ext_register_operand" "Q")
7697               (const_int 8)
7698               (const_int 8)))
7699           (const_int 0)))]
7700   "ix86_match_ccmode (insn, CCNOmode)"
7701   "test{b}\t{%h1, %h0|%h0, %h1}"
7702   [(set_attr "type" "test")
7703    (set_attr "mode" "QI")])
7704
7705 (define_insn "*testqi_ext_3_rex64"
7706   [(set (reg FLAGS_REG)
7707         (compare (zero_extract:DI
7708                    (match_operand 0 "nonimmediate_operand" "rm")
7709                    (match_operand:DI 1 "const_int_operand" "")
7710                    (match_operand:DI 2 "const_int_operand" ""))
7711                  (const_int 0)))]
7712   "TARGET_64BIT
7713    && ix86_match_ccmode (insn, CCNOmode)
7714    && INTVAL (operands[1]) > 0
7715    && INTVAL (operands[2]) >= 0
7716    /* Ensure that resulting mask is zero or sign extended operand.  */
7717    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7718        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7719            && INTVAL (operands[1]) > 32))
7720    && (GET_MODE (operands[0]) == SImode
7721        || GET_MODE (operands[0]) == DImode
7722        || GET_MODE (operands[0]) == HImode
7723        || GET_MODE (operands[0]) == QImode)"
7724   "#")
7725
7726 ;; Combine likes to form bit extractions for some tests.  Humor it.
7727 (define_insn "*testqi_ext_3"
7728   [(set (reg FLAGS_REG)
7729         (compare (zero_extract:SI
7730                    (match_operand 0 "nonimmediate_operand" "rm")
7731                    (match_operand:SI 1 "const_int_operand" "")
7732                    (match_operand:SI 2 "const_int_operand" ""))
7733                  (const_int 0)))]
7734   "ix86_match_ccmode (insn, CCNOmode)
7735    && INTVAL (operands[1]) > 0
7736    && INTVAL (operands[2]) >= 0
7737    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7738    && (GET_MODE (operands[0]) == SImode
7739        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7740        || GET_MODE (operands[0]) == HImode
7741        || GET_MODE (operands[0]) == QImode)"
7742   "#")
7743
7744 (define_split
7745   [(set (match_operand 0 "flags_reg_operand" "")
7746         (match_operator 1 "compare_operator"
7747           [(zero_extract
7748              (match_operand 2 "nonimmediate_operand" "")
7749              (match_operand 3 "const_int_operand" "")
7750              (match_operand 4 "const_int_operand" ""))
7751            (const_int 0)]))]
7752   "ix86_match_ccmode (insn, CCNOmode)"
7753   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7754 {
7755   rtx val = operands[2];
7756   HOST_WIDE_INT len = INTVAL (operands[3]);
7757   HOST_WIDE_INT pos = INTVAL (operands[4]);
7758   HOST_WIDE_INT mask;
7759   enum machine_mode mode, submode;
7760
7761   mode = GET_MODE (val);
7762   if (MEM_P (val))
7763     {
7764       /* ??? Combine likes to put non-volatile mem extractions in QImode
7765          no matter the size of the test.  So find a mode that works.  */
7766       if (! MEM_VOLATILE_P (val))
7767         {
7768           mode = smallest_mode_for_size (pos + len, MODE_INT);
7769           val = adjust_address (val, mode, 0);
7770         }
7771     }
7772   else if (GET_CODE (val) == SUBREG
7773            && (submode = GET_MODE (SUBREG_REG (val)),
7774                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7775            && pos + len <= GET_MODE_BITSIZE (submode)
7776            && GET_MODE_CLASS (submode) == MODE_INT)
7777     {
7778       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7779       mode = submode;
7780       val = SUBREG_REG (val);
7781     }
7782   else if (mode == HImode && pos + len <= 8)
7783     {
7784       /* Small HImode tests can be converted to QImode.  */
7785       mode = QImode;
7786       val = gen_lowpart (QImode, val);
7787     }
7788
7789   if (len == HOST_BITS_PER_WIDE_INT)
7790     mask = -1;
7791   else
7792     mask = ((HOST_WIDE_INT)1 << len) - 1;
7793   mask <<= pos;
7794
7795   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7796 })
7797
7798 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7799 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7800 ;; this is relatively important trick.
7801 ;; Do the conversion only post-reload to avoid limiting of the register class
7802 ;; to QI regs.
7803 (define_split
7804   [(set (match_operand 0 "flags_reg_operand" "")
7805         (match_operator 1 "compare_operator"
7806           [(and (match_operand 2 "register_operand" "")
7807                 (match_operand 3 "const_int_operand" ""))
7808            (const_int 0)]))]
7809    "reload_completed
7810     && QI_REG_P (operands[2])
7811     && GET_MODE (operands[2]) != QImode
7812     && ((ix86_match_ccmode (insn, CCZmode)
7813          && !(INTVAL (operands[3]) & ~(255 << 8)))
7814         || (ix86_match_ccmode (insn, CCNOmode)
7815             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7816   [(set (match_dup 0)
7817         (match_op_dup 1
7818           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7819                    (match_dup 3))
7820            (const_int 0)]))]
7821   "operands[2] = gen_lowpart (SImode, operands[2]);
7822    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7823
7824 (define_split
7825   [(set (match_operand 0 "flags_reg_operand" "")
7826         (match_operator 1 "compare_operator"
7827           [(and (match_operand 2 "nonimmediate_operand" "")
7828                 (match_operand 3 "const_int_operand" ""))
7829            (const_int 0)]))]
7830    "reload_completed
7831     && GET_MODE (operands[2]) != QImode
7832     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7833     && ((ix86_match_ccmode (insn, CCZmode)
7834          && !(INTVAL (operands[3]) & ~255))
7835         || (ix86_match_ccmode (insn, CCNOmode)
7836             && !(INTVAL (operands[3]) & ~127)))"
7837   [(set (match_dup 0)
7838         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7839                          (const_int 0)]))]
7840   "operands[2] = gen_lowpart (QImode, operands[2]);
7841    operands[3] = gen_lowpart (QImode, operands[3]);")
7842
7843 ;; %%% This used to optimize known byte-wide and operations to memory,
7844 ;; and sometimes to QImode registers.  If this is considered useful,
7845 ;; it should be done with splitters.
7846
7847 (define_expand "and<mode>3"
7848   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7849         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7850                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7851   ""
7852   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7853
7854 (define_insn "*anddi_1"
7855   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7856         (and:DI
7857          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7858          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7859    (clobber (reg:CC FLAGS_REG))]
7860   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7861 {
7862   switch (get_attr_type (insn))
7863     {
7864     case TYPE_IMOVX:
7865       {
7866         enum machine_mode mode;
7867
7868         gcc_assert (CONST_INT_P (operands[2]));
7869         if (INTVAL (operands[2]) == 0xff)
7870           mode = QImode;
7871         else
7872           {
7873             gcc_assert (INTVAL (operands[2]) == 0xffff);
7874             mode = HImode;
7875           }
7876
7877         operands[1] = gen_lowpart (mode, operands[1]);
7878         if (mode == QImode)
7879           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7880         else
7881           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7882       }
7883
7884     default:
7885       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7886       if (get_attr_mode (insn) == MODE_SI)
7887         return "and{l}\t{%k2, %k0|%k0, %k2}";
7888       else
7889         return "and{q}\t{%2, %0|%0, %2}";
7890     }
7891 }
7892   [(set_attr "type" "alu,alu,alu,imovx")
7893    (set_attr "length_immediate" "*,*,*,0")
7894    (set (attr "prefix_rex")
7895      (if_then_else
7896        (and (eq_attr "type" "imovx")
7897             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7898                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7899        (const_string "1")
7900        (const_string "*")))
7901    (set_attr "mode" "SI,DI,DI,SI")])
7902
7903 (define_insn "*andsi_1"
7904   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7905         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7906                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7907    (clobber (reg:CC FLAGS_REG))]
7908   "ix86_binary_operator_ok (AND, SImode, operands)"
7909 {
7910   switch (get_attr_type (insn))
7911     {
7912     case TYPE_IMOVX:
7913       {
7914         enum machine_mode mode;
7915
7916         gcc_assert (CONST_INT_P (operands[2]));
7917         if (INTVAL (operands[2]) == 0xff)
7918           mode = QImode;
7919         else
7920           {
7921             gcc_assert (INTVAL (operands[2]) == 0xffff);
7922             mode = HImode;
7923           }
7924
7925         operands[1] = gen_lowpart (mode, operands[1]);
7926         if (mode == QImode)
7927           return "movz{bl|x}\t{%1, %0|%0, %1}";
7928         else
7929           return "movz{wl|x}\t{%1, %0|%0, %1}";
7930       }
7931
7932     default:
7933       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7934       return "and{l}\t{%2, %0|%0, %2}";
7935     }
7936 }
7937   [(set_attr "type" "alu,alu,imovx")
7938    (set (attr "prefix_rex")
7939      (if_then_else
7940        (and (eq_attr "type" "imovx")
7941             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7942                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7943        (const_string "1")
7944        (const_string "*")))
7945    (set_attr "length_immediate" "*,*,0")
7946    (set_attr "mode" "SI")])
7947
7948 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7949 (define_insn "*andsi_1_zext"
7950   [(set (match_operand:DI 0 "register_operand" "=r")
7951         (zero_extend:DI
7952           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7953                   (match_operand:SI 2 "general_operand" "g"))))
7954    (clobber (reg:CC FLAGS_REG))]
7955   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7956   "and{l}\t{%2, %k0|%k0, %2}"
7957   [(set_attr "type" "alu")
7958    (set_attr "mode" "SI")])
7959
7960 (define_insn "*andhi_1"
7961   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7962         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7963                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7964    (clobber (reg:CC FLAGS_REG))]
7965   "ix86_binary_operator_ok (AND, HImode, operands)"
7966 {
7967   switch (get_attr_type (insn))
7968     {
7969     case TYPE_IMOVX:
7970       gcc_assert (CONST_INT_P (operands[2]));
7971       gcc_assert (INTVAL (operands[2]) == 0xff);
7972       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7973
7974     default:
7975       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7976
7977       return "and{w}\t{%2, %0|%0, %2}";
7978     }
7979 }
7980   [(set_attr "type" "alu,alu,imovx")
7981    (set_attr "length_immediate" "*,*,0")
7982    (set (attr "prefix_rex")
7983      (if_then_else
7984        (and (eq_attr "type" "imovx")
7985             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7986        (const_string "1")
7987        (const_string "*")))
7988    (set_attr "mode" "HI,HI,SI")])
7989
7990 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7991 (define_insn "*andqi_1"
7992   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7993         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7994                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7995    (clobber (reg:CC FLAGS_REG))]
7996   "ix86_binary_operator_ok (AND, QImode, operands)"
7997   "@
7998    and{b}\t{%2, %0|%0, %2}
7999    and{b}\t{%2, %0|%0, %2}
8000    and{l}\t{%k2, %k0|%k0, %k2}"
8001   [(set_attr "type" "alu")
8002    (set_attr "mode" "QI,QI,SI")])
8003
8004 (define_insn "*andqi_1_slp"
8005   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8006         (and:QI (match_dup 0)
8007                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8008    (clobber (reg:CC FLAGS_REG))]
8009   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8010    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8011   "and{b}\t{%1, %0|%0, %1}"
8012   [(set_attr "type" "alu1")
8013    (set_attr "mode" "QI")])
8014
8015 (define_split
8016   [(set (match_operand 0 "register_operand" "")
8017         (and (match_dup 0)
8018              (const_int -65536)))
8019    (clobber (reg:CC FLAGS_REG))]
8020   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8021     || optimize_function_for_size_p (cfun)"
8022   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8023   "operands[1] = gen_lowpart (HImode, operands[0]);")
8024
8025 (define_split
8026   [(set (match_operand 0 "ext_register_operand" "")
8027         (and (match_dup 0)
8028              (const_int -256)))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8031    && reload_completed"
8032   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8033   "operands[1] = gen_lowpart (QImode, operands[0]);")
8034
8035 (define_split
8036   [(set (match_operand 0 "ext_register_operand" "")
8037         (and (match_dup 0)
8038              (const_int -65281)))
8039    (clobber (reg:CC FLAGS_REG))]
8040   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8041    && reload_completed"
8042   [(parallel [(set (zero_extract:SI (match_dup 0)
8043                                     (const_int 8)
8044                                     (const_int 8))
8045                    (xor:SI
8046                      (zero_extract:SI (match_dup 0)
8047                                       (const_int 8)
8048                                       (const_int 8))
8049                      (zero_extract:SI (match_dup 0)
8050                                       (const_int 8)
8051                                       (const_int 8))))
8052               (clobber (reg:CC FLAGS_REG))])]
8053   "operands[0] = gen_lowpart (SImode, operands[0]);")
8054
8055 (define_insn "*anddi_2"
8056   [(set (reg FLAGS_REG)
8057         (compare
8058          (and:DI
8059           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8060           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8061          (const_int 0)))
8062    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8063         (and:DI (match_dup 1) (match_dup 2)))]
8064   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8065    && ix86_binary_operator_ok (AND, DImode, operands)"
8066   "@
8067    and{l}\t{%k2, %k0|%k0, %k2}
8068    and{q}\t{%2, %0|%0, %2}
8069    and{q}\t{%2, %0|%0, %2}"
8070   [(set_attr "type" "alu")
8071    (set_attr "mode" "SI,DI,DI")])
8072
8073 (define_insn "*andqi_2_maybe_si"
8074   [(set (reg FLAGS_REG)
8075         (compare (and:QI
8076                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8077                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8078                  (const_int 0)))
8079    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8080         (and:QI (match_dup 1) (match_dup 2)))]
8081   "ix86_binary_operator_ok (AND, QImode, operands)
8082    && ix86_match_ccmode (insn,
8083                          CONST_INT_P (operands[2])
8084                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8085 {
8086   if (which_alternative == 2)
8087     {
8088       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8089         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8090       return "and{l}\t{%2, %k0|%k0, %2}";
8091     }
8092   return "and{b}\t{%2, %0|%0, %2}";
8093 }
8094   [(set_attr "type" "alu")
8095    (set_attr "mode" "QI,QI,SI")])
8096
8097 (define_insn "*and<mode>_2"
8098   [(set (reg FLAGS_REG)
8099         (compare (and:SWI124
8100                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8101                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8102                  (const_int 0)))
8103    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8104         (and:SWI124 (match_dup 1) (match_dup 2)))]
8105   "ix86_match_ccmode (insn, CCNOmode)
8106    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8107   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8108   [(set_attr "type" "alu")
8109    (set_attr "mode" "<MODE>")])
8110
8111 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8112 (define_insn "*andsi_2_zext"
8113   [(set (reg FLAGS_REG)
8114         (compare (and:SI
8115                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8116                   (match_operand:SI 2 "general_operand" "g"))
8117                  (const_int 0)))
8118    (set (match_operand:DI 0 "register_operand" "=r")
8119         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8120   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8121    && ix86_binary_operator_ok (AND, SImode, operands)"
8122   "and{l}\t{%2, %k0|%k0, %2}"
8123   [(set_attr "type" "alu")
8124    (set_attr "mode" "SI")])
8125
8126 (define_insn "*andqi_2_slp"
8127   [(set (reg FLAGS_REG)
8128         (compare (and:QI
8129                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8130                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8131                  (const_int 0)))
8132    (set (strict_low_part (match_dup 0))
8133         (and:QI (match_dup 0) (match_dup 1)))]
8134   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8135    && ix86_match_ccmode (insn, CCNOmode)
8136    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8137   "and{b}\t{%1, %0|%0, %1}"
8138   [(set_attr "type" "alu1")
8139    (set_attr "mode" "QI")])
8140
8141 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8142 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8143 ;; for a QImode operand, which of course failed.
8144 (define_insn "andqi_ext_0"
8145   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8146                          (const_int 8)
8147                          (const_int 8))
8148         (and:SI
8149           (zero_extract:SI
8150             (match_operand 1 "ext_register_operand" "0")
8151             (const_int 8)
8152             (const_int 8))
8153           (match_operand 2 "const_int_operand" "n")))
8154    (clobber (reg:CC FLAGS_REG))]
8155   ""
8156   "and{b}\t{%2, %h0|%h0, %2}"
8157   [(set_attr "type" "alu")
8158    (set_attr "length_immediate" "1")
8159    (set_attr "modrm" "1")
8160    (set_attr "mode" "QI")])
8161
8162 ;; Generated by peephole translating test to and.  This shows up
8163 ;; often in fp comparisons.
8164 (define_insn "*andqi_ext_0_cc"
8165   [(set (reg FLAGS_REG)
8166         (compare
8167           (and:SI
8168             (zero_extract:SI
8169               (match_operand 1 "ext_register_operand" "0")
8170               (const_int 8)
8171               (const_int 8))
8172             (match_operand 2 "const_int_operand" "n"))
8173           (const_int 0)))
8174    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8175                          (const_int 8)
8176                          (const_int 8))
8177         (and:SI
8178           (zero_extract:SI
8179             (match_dup 1)
8180             (const_int 8)
8181             (const_int 8))
8182           (match_dup 2)))]
8183   "ix86_match_ccmode (insn, CCNOmode)"
8184   "and{b}\t{%2, %h0|%h0, %2}"
8185   [(set_attr "type" "alu")
8186    (set_attr "length_immediate" "1")
8187    (set_attr "modrm" "1")
8188    (set_attr "mode" "QI")])
8189
8190 (define_insn "*andqi_ext_1_rex64"
8191   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8192                          (const_int 8)
8193                          (const_int 8))
8194         (and:SI
8195           (zero_extract:SI
8196             (match_operand 1 "ext_register_operand" "0")
8197             (const_int 8)
8198             (const_int 8))
8199           (zero_extend:SI
8200             (match_operand 2 "ext_register_operand" "Q"))))
8201    (clobber (reg:CC FLAGS_REG))]
8202   "TARGET_64BIT"
8203   "and{b}\t{%2, %h0|%h0, %2}"
8204   [(set_attr "type" "alu")
8205    (set_attr "length_immediate" "0")
8206    (set_attr "mode" "QI")])
8207
8208 (define_insn "*andqi_ext_1"
8209   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8210                          (const_int 8)
8211                          (const_int 8))
8212         (and:SI
8213           (zero_extract:SI
8214             (match_operand 1 "ext_register_operand" "0")
8215             (const_int 8)
8216             (const_int 8))
8217           (zero_extend:SI
8218             (match_operand:QI 2 "general_operand" "Qm"))))
8219    (clobber (reg:CC FLAGS_REG))]
8220   "!TARGET_64BIT"
8221   "and{b}\t{%2, %h0|%h0, %2}"
8222   [(set_attr "type" "alu")
8223    (set_attr "length_immediate" "0")
8224    (set_attr "mode" "QI")])
8225
8226 (define_insn "*andqi_ext_2"
8227   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8228                          (const_int 8)
8229                          (const_int 8))
8230         (and:SI
8231           (zero_extract:SI
8232             (match_operand 1 "ext_register_operand" "%0")
8233             (const_int 8)
8234             (const_int 8))
8235           (zero_extract:SI
8236             (match_operand 2 "ext_register_operand" "Q")
8237             (const_int 8)
8238             (const_int 8))))
8239    (clobber (reg:CC FLAGS_REG))]
8240   ""
8241   "and{b}\t{%h2, %h0|%h0, %h2}"
8242   [(set_attr "type" "alu")
8243    (set_attr "length_immediate" "0")
8244    (set_attr "mode" "QI")])
8245
8246 ;; Convert wide AND instructions with immediate operand to shorter QImode
8247 ;; equivalents when possible.
8248 ;; Don't do the splitting with memory operands, since it introduces risk
8249 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8250 ;; for size, but that can (should?) be handled by generic code instead.
8251 (define_split
8252   [(set (match_operand 0 "register_operand" "")
8253         (and (match_operand 1 "register_operand" "")
8254              (match_operand 2 "const_int_operand" "")))
8255    (clobber (reg:CC FLAGS_REG))]
8256    "reload_completed
8257     && QI_REG_P (operands[0])
8258     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8259     && !(~INTVAL (operands[2]) & ~(255 << 8))
8260     && GET_MODE (operands[0]) != QImode"
8261   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8262                    (and:SI (zero_extract:SI (match_dup 1)
8263                                             (const_int 8) (const_int 8))
8264                            (match_dup 2)))
8265               (clobber (reg:CC FLAGS_REG))])]
8266   "operands[0] = gen_lowpart (SImode, operands[0]);
8267    operands[1] = gen_lowpart (SImode, operands[1]);
8268    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8269
8270 ;; Since AND can be encoded with sign extended immediate, this is only
8271 ;; profitable when 7th bit is not set.
8272 (define_split
8273   [(set (match_operand 0 "register_operand" "")
8274         (and (match_operand 1 "general_operand" "")
8275              (match_operand 2 "const_int_operand" "")))
8276    (clobber (reg:CC FLAGS_REG))]
8277    "reload_completed
8278     && ANY_QI_REG_P (operands[0])
8279     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8280     && !(~INTVAL (operands[2]) & ~255)
8281     && !(INTVAL (operands[2]) & 128)
8282     && GET_MODE (operands[0]) != QImode"
8283   [(parallel [(set (strict_low_part (match_dup 0))
8284                    (and:QI (match_dup 1)
8285                            (match_dup 2)))
8286               (clobber (reg:CC FLAGS_REG))])]
8287   "operands[0] = gen_lowpart (QImode, operands[0]);
8288    operands[1] = gen_lowpart (QImode, operands[1]);
8289    operands[2] = gen_lowpart (QImode, operands[2]);")
8290 \f
8291 ;; Logical inclusive and exclusive OR instructions
8292
8293 ;; %%% This used to optimize known byte-wide and operations to memory.
8294 ;; If this is considered useful, it should be done with splitters.
8295
8296 (define_expand "<code><mode>3"
8297   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8298         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8299                      (match_operand:SWIM 2 "<general_operand>" "")))]
8300   ""
8301   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8302
8303 (define_insn "*<code><mode>_1"
8304   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8305         (any_or:SWI248
8306          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8307          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8308    (clobber (reg:CC FLAGS_REG))]
8309   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8310   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8311   [(set_attr "type" "alu")
8312    (set_attr "mode" "<MODE>")])
8313
8314 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8315 (define_insn "*<code>qi_1"
8316   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8317         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8318                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8319    (clobber (reg:CC FLAGS_REG))]
8320   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8321   "@
8322    <logic>{b}\t{%2, %0|%0, %2}
8323    <logic>{b}\t{%2, %0|%0, %2}
8324    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8325   [(set_attr "type" "alu")
8326    (set_attr "mode" "QI,QI,SI")])
8327
8328 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8329 (define_insn "*<code>si_1_zext"
8330   [(set (match_operand:DI 0 "register_operand" "=r")
8331         (zero_extend:DI
8332          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8333                     (match_operand:SI 2 "general_operand" "g"))))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8336   "<logic>{l}\t{%2, %k0|%k0, %2}"
8337   [(set_attr "type" "alu")
8338    (set_attr "mode" "SI")])
8339
8340 (define_insn "*<code>si_1_zext_imm"
8341   [(set (match_operand:DI 0 "register_operand" "=r")
8342         (any_or:DI
8343          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8344          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8347   "<logic>{l}\t{%2, %k0|%k0, %2}"
8348   [(set_attr "type" "alu")
8349    (set_attr "mode" "SI")])
8350
8351 (define_insn "*<code>qi_1_slp"
8352   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8353         (any_or:QI (match_dup 0)
8354                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8355    (clobber (reg:CC FLAGS_REG))]
8356   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8357    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8358   "<logic>{b}\t{%1, %0|%0, %1}"
8359   [(set_attr "type" "alu1")
8360    (set_attr "mode" "QI")])
8361
8362 (define_insn "*<code><mode>_2"
8363   [(set (reg FLAGS_REG)
8364         (compare (any_or:SWI
8365                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8366                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8367                  (const_int 0)))
8368    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8369         (any_or:SWI (match_dup 1) (match_dup 2)))]
8370   "ix86_match_ccmode (insn, CCNOmode)
8371    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8372   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8373   [(set_attr "type" "alu")
8374    (set_attr "mode" "<MODE>")])
8375
8376 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8377 ;; ??? Special case for immediate operand is missing - it is tricky.
8378 (define_insn "*<code>si_2_zext"
8379   [(set (reg FLAGS_REG)
8380         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8381                             (match_operand:SI 2 "general_operand" "g"))
8382                  (const_int 0)))
8383    (set (match_operand:DI 0 "register_operand" "=r")
8384         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8385   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8386    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8387   "<logic>{l}\t{%2, %k0|%k0, %2}"
8388   [(set_attr "type" "alu")
8389    (set_attr "mode" "SI")])
8390
8391 (define_insn "*<code>si_2_zext_imm"
8392   [(set (reg FLAGS_REG)
8393         (compare (any_or:SI
8394                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8395                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8396                  (const_int 0)))
8397    (set (match_operand:DI 0 "register_operand" "=r")
8398         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8399   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8400    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8401   "<logic>{l}\t{%2, %k0|%k0, %2}"
8402   [(set_attr "type" "alu")
8403    (set_attr "mode" "SI")])
8404
8405 (define_insn "*<code>qi_2_slp"
8406   [(set (reg FLAGS_REG)
8407         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8408                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8409                  (const_int 0)))
8410    (set (strict_low_part (match_dup 0))
8411         (any_or:QI (match_dup 0) (match_dup 1)))]
8412   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413    && ix86_match_ccmode (insn, CCNOmode)
8414    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8415   "<logic>{b}\t{%1, %0|%0, %1}"
8416   [(set_attr "type" "alu1")
8417    (set_attr "mode" "QI")])
8418
8419 (define_insn "*<code><mode>_3"
8420   [(set (reg FLAGS_REG)
8421         (compare (any_or:SWI
8422                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8423                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8424                  (const_int 0)))
8425    (clobber (match_scratch:SWI 0 "=<r>"))]
8426   "ix86_match_ccmode (insn, CCNOmode)
8427    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8428   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8429   [(set_attr "type" "alu")
8430    (set_attr "mode" "<MODE>")])
8431
8432 (define_insn "*<code>qi_ext_0"
8433   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8434                          (const_int 8)
8435                          (const_int 8))
8436         (any_or:SI
8437           (zero_extract:SI
8438             (match_operand 1 "ext_register_operand" "0")
8439             (const_int 8)
8440             (const_int 8))
8441           (match_operand 2 "const_int_operand" "n")))
8442    (clobber (reg:CC FLAGS_REG))]
8443   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8444   "<logic>{b}\t{%2, %h0|%h0, %2}"
8445   [(set_attr "type" "alu")
8446    (set_attr "length_immediate" "1")
8447    (set_attr "modrm" "1")
8448    (set_attr "mode" "QI")])
8449
8450 (define_insn "*<code>qi_ext_1_rex64"
8451   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8452                          (const_int 8)
8453                          (const_int 8))
8454         (any_or:SI
8455           (zero_extract:SI
8456             (match_operand 1 "ext_register_operand" "0")
8457             (const_int 8)
8458             (const_int 8))
8459           (zero_extend:SI
8460             (match_operand 2 "ext_register_operand" "Q"))))
8461    (clobber (reg:CC FLAGS_REG))]
8462   "TARGET_64BIT
8463    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8464   "<logic>{b}\t{%2, %h0|%h0, %2}"
8465   [(set_attr "type" "alu")
8466    (set_attr "length_immediate" "0")
8467    (set_attr "mode" "QI")])
8468
8469 (define_insn "*<code>qi_ext_1"
8470   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8471                          (const_int 8)
8472                          (const_int 8))
8473         (any_or:SI
8474           (zero_extract:SI
8475             (match_operand 1 "ext_register_operand" "0")
8476             (const_int 8)
8477             (const_int 8))
8478           (zero_extend:SI
8479             (match_operand:QI 2 "general_operand" "Qm"))))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "!TARGET_64BIT
8482    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8483   "<logic>{b}\t{%2, %h0|%h0, %2}"
8484   [(set_attr "type" "alu")
8485    (set_attr "length_immediate" "0")
8486    (set_attr "mode" "QI")])
8487
8488 (define_insn "*<code>qi_ext_2"
8489   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8490                          (const_int 8)
8491                          (const_int 8))
8492         (any_or:SI
8493           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8494                            (const_int 8)
8495                            (const_int 8))
8496           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8497                            (const_int 8)
8498                            (const_int 8))))
8499    (clobber (reg:CC FLAGS_REG))]
8500   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8501   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8502   [(set_attr "type" "alu")
8503    (set_attr "length_immediate" "0")
8504    (set_attr "mode" "QI")])
8505
8506 (define_split
8507   [(set (match_operand 0 "register_operand" "")
8508         (any_or (match_operand 1 "register_operand" "")
8509                 (match_operand 2 "const_int_operand" "")))
8510    (clobber (reg:CC FLAGS_REG))]
8511    "reload_completed
8512     && QI_REG_P (operands[0])
8513     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8514     && !(INTVAL (operands[2]) & ~(255 << 8))
8515     && GET_MODE (operands[0]) != QImode"
8516   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8517                    (any_or:SI (zero_extract:SI (match_dup 1)
8518                                                (const_int 8) (const_int 8))
8519                               (match_dup 2)))
8520               (clobber (reg:CC FLAGS_REG))])]
8521   "operands[0] = gen_lowpart (SImode, operands[0]);
8522    operands[1] = gen_lowpart (SImode, operands[1]);
8523    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8524
8525 ;; Since OR can be encoded with sign extended immediate, this is only
8526 ;; profitable when 7th bit is set.
8527 (define_split
8528   [(set (match_operand 0 "register_operand" "")
8529         (any_or (match_operand 1 "general_operand" "")
8530                 (match_operand 2 "const_int_operand" "")))
8531    (clobber (reg:CC FLAGS_REG))]
8532    "reload_completed
8533     && ANY_QI_REG_P (operands[0])
8534     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8535     && !(INTVAL (operands[2]) & ~255)
8536     && (INTVAL (operands[2]) & 128)
8537     && GET_MODE (operands[0]) != QImode"
8538   [(parallel [(set (strict_low_part (match_dup 0))
8539                    (any_or:QI (match_dup 1)
8540                               (match_dup 2)))
8541               (clobber (reg:CC FLAGS_REG))])]
8542   "operands[0] = gen_lowpart (QImode, operands[0]);
8543    operands[1] = gen_lowpart (QImode, operands[1]);
8544    operands[2] = gen_lowpart (QImode, operands[2]);")
8545
8546 (define_expand "xorqi_cc_ext_1"
8547   [(parallel [
8548      (set (reg:CCNO FLAGS_REG)
8549           (compare:CCNO
8550             (xor:SI
8551               (zero_extract:SI
8552                 (match_operand 1 "ext_register_operand" "")
8553                 (const_int 8)
8554                 (const_int 8))
8555               (match_operand:QI 2 "general_operand" ""))
8556             (const_int 0)))
8557      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8558                            (const_int 8)
8559                            (const_int 8))
8560           (xor:SI
8561             (zero_extract:SI
8562              (match_dup 1)
8563              (const_int 8)
8564              (const_int 8))
8565             (match_dup 2)))])])
8566
8567 (define_insn "*xorqi_cc_ext_1_rex64"
8568   [(set (reg FLAGS_REG)
8569         (compare
8570           (xor:SI
8571             (zero_extract:SI
8572               (match_operand 1 "ext_register_operand" "0")
8573               (const_int 8)
8574               (const_int 8))
8575             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8576           (const_int 0)))
8577    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8578                          (const_int 8)
8579                          (const_int 8))
8580         (xor:SI
8581           (zero_extract:SI
8582            (match_dup 1)
8583            (const_int 8)
8584            (const_int 8))
8585           (match_dup 2)))]
8586   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8587   "xor{b}\t{%2, %h0|%h0, %2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "modrm" "1")
8590    (set_attr "mode" "QI")])
8591
8592 (define_insn "*xorqi_cc_ext_1"
8593   [(set (reg FLAGS_REG)
8594         (compare
8595           (xor:SI
8596             (zero_extract:SI
8597               (match_operand 1 "ext_register_operand" "0")
8598               (const_int 8)
8599               (const_int 8))
8600             (match_operand:QI 2 "general_operand" "qmn"))
8601           (const_int 0)))
8602    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8603                          (const_int 8)
8604                          (const_int 8))
8605         (xor:SI
8606           (zero_extract:SI
8607            (match_dup 1)
8608            (const_int 8)
8609            (const_int 8))
8610           (match_dup 2)))]
8611   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8612   "xor{b}\t{%2, %h0|%h0, %2}"
8613   [(set_attr "type" "alu")
8614    (set_attr "modrm" "1")
8615    (set_attr "mode" "QI")])
8616 \f
8617 ;; Negation instructions
8618
8619 (define_expand "neg<mode>2"
8620   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8621         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8622   ""
8623   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8624
8625 (define_insn_and_split "*neg<dwi>2_doubleword"
8626   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8627         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8628    (clobber (reg:CC FLAGS_REG))]
8629   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8630   "#"
8631   "reload_completed"
8632   [(parallel
8633     [(set (reg:CCZ FLAGS_REG)
8634           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8635      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8636    (parallel
8637     [(set (match_dup 2)
8638           (plus:DWIH (match_dup 3)
8639                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8640                                 (const_int 0))))
8641      (clobber (reg:CC FLAGS_REG))])
8642    (parallel
8643     [(set (match_dup 2)
8644           (neg:DWIH (match_dup 2)))
8645      (clobber (reg:CC FLAGS_REG))])]
8646   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8647
8648 (define_insn "*neg<mode>2_1"
8649   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8650         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8651    (clobber (reg:CC FLAGS_REG))]
8652   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8653   "neg{<imodesuffix>}\t%0"
8654   [(set_attr "type" "negnot")
8655    (set_attr "mode" "<MODE>")])
8656
8657 ;; Combine is quite creative about this pattern.
8658 (define_insn "*negsi2_1_zext"
8659   [(set (match_operand:DI 0 "register_operand" "=r")
8660         (lshiftrt:DI
8661           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8662                              (const_int 32)))
8663         (const_int 32)))
8664    (clobber (reg:CC FLAGS_REG))]
8665   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8666   "neg{l}\t%k0"
8667   [(set_attr "type" "negnot")
8668    (set_attr "mode" "SI")])
8669
8670 ;; The problem with neg is that it does not perform (compare x 0),
8671 ;; it really performs (compare 0 x), which leaves us with the zero
8672 ;; flag being the only useful item.
8673
8674 (define_insn "*neg<mode>2_cmpz"
8675   [(set (reg:CCZ FLAGS_REG)
8676         (compare:CCZ
8677           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8678                    (const_int 0)))
8679    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8680         (neg:SWI (match_dup 1)))]
8681   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8682   "neg{<imodesuffix>}\t%0"
8683   [(set_attr "type" "negnot")
8684    (set_attr "mode" "<MODE>")])
8685
8686 (define_insn "*negsi2_cmpz_zext"
8687   [(set (reg:CCZ FLAGS_REG)
8688         (compare:CCZ
8689           (lshiftrt:DI
8690             (neg:DI (ashift:DI
8691                       (match_operand:DI 1 "register_operand" "0")
8692                       (const_int 32)))
8693             (const_int 32))
8694           (const_int 0)))
8695    (set (match_operand:DI 0 "register_operand" "=r")
8696         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8697                                         (const_int 32)))
8698                      (const_int 32)))]
8699   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8700   "neg{l}\t%k0"
8701   [(set_attr "type" "negnot")
8702    (set_attr "mode" "SI")])
8703
8704 ;; Changing of sign for FP values is doable using integer unit too.
8705
8706 (define_expand "<code><mode>2"
8707   [(set (match_operand:X87MODEF 0 "register_operand" "")
8708         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8709   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8710   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8711
8712 (define_insn "*absneg<mode>2_mixed"
8713   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8714         (match_operator:MODEF 3 "absneg_operator"
8715           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8716    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8719   "#")
8720
8721 (define_insn "*absneg<mode>2_sse"
8722   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8723         (match_operator:MODEF 3 "absneg_operator"
8724           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8725    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8726    (clobber (reg:CC FLAGS_REG))]
8727   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8728   "#")
8729
8730 (define_insn "*absneg<mode>2_i387"
8731   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8732         (match_operator:X87MODEF 3 "absneg_operator"
8733           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8734    (use (match_operand 2 "" ""))
8735    (clobber (reg:CC FLAGS_REG))]
8736   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8737   "#")
8738
8739 (define_expand "<code>tf2"
8740   [(set (match_operand:TF 0 "register_operand" "")
8741         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8742   "TARGET_SSE2"
8743   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8744
8745 (define_insn "*absnegtf2_sse"
8746   [(set (match_operand:TF 0 "register_operand" "=x,x")
8747         (match_operator:TF 3 "absneg_operator"
8748           [(match_operand:TF 1 "register_operand" "0,x")]))
8749    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8750    (clobber (reg:CC FLAGS_REG))]
8751   "TARGET_SSE2"
8752   "#")
8753
8754 ;; Splitters for fp abs and neg.
8755
8756 (define_split
8757   [(set (match_operand 0 "fp_register_operand" "")
8758         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8759    (use (match_operand 2 "" ""))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "reload_completed"
8762   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8763
8764 (define_split
8765   [(set (match_operand 0 "register_operand" "")
8766         (match_operator 3 "absneg_operator"
8767           [(match_operand 1 "register_operand" "")]))
8768    (use (match_operand 2 "nonimmediate_operand" ""))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "reload_completed && SSE_REG_P (operands[0])"
8771   [(set (match_dup 0) (match_dup 3))]
8772 {
8773   enum machine_mode mode = GET_MODE (operands[0]);
8774   enum machine_mode vmode = GET_MODE (operands[2]);
8775   rtx tmp;
8776
8777   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8778   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8779   if (operands_match_p (operands[0], operands[2]))
8780     {
8781       tmp = operands[1];
8782       operands[1] = operands[2];
8783       operands[2] = tmp;
8784     }
8785   if (GET_CODE (operands[3]) == ABS)
8786     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8787   else
8788     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8789   operands[3] = tmp;
8790 })
8791
8792 (define_split
8793   [(set (match_operand:SF 0 "register_operand" "")
8794         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8795    (use (match_operand:V4SF 2 "" ""))
8796    (clobber (reg:CC FLAGS_REG))]
8797   "reload_completed"
8798   [(parallel [(set (match_dup 0) (match_dup 1))
8799               (clobber (reg:CC FLAGS_REG))])]
8800 {
8801   rtx tmp;
8802   operands[0] = gen_lowpart (SImode, operands[0]);
8803   if (GET_CODE (operands[1]) == ABS)
8804     {
8805       tmp = gen_int_mode (0x7fffffff, SImode);
8806       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8807     }
8808   else
8809     {
8810       tmp = gen_int_mode (0x80000000, SImode);
8811       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8812     }
8813   operands[1] = tmp;
8814 })
8815
8816 (define_split
8817   [(set (match_operand:DF 0 "register_operand" "")
8818         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8819    (use (match_operand 2 "" ""))
8820    (clobber (reg:CC FLAGS_REG))]
8821   "reload_completed"
8822   [(parallel [(set (match_dup 0) (match_dup 1))
8823               (clobber (reg:CC FLAGS_REG))])]
8824 {
8825   rtx tmp;
8826   if (TARGET_64BIT)
8827     {
8828       tmp = gen_lowpart (DImode, operands[0]);
8829       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8830       operands[0] = tmp;
8831
8832       if (GET_CODE (operands[1]) == ABS)
8833         tmp = const0_rtx;
8834       else
8835         tmp = gen_rtx_NOT (DImode, tmp);
8836     }
8837   else
8838     {
8839       operands[0] = gen_highpart (SImode, operands[0]);
8840       if (GET_CODE (operands[1]) == ABS)
8841         {
8842           tmp = gen_int_mode (0x7fffffff, SImode);
8843           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8844         }
8845       else
8846         {
8847           tmp = gen_int_mode (0x80000000, SImode);
8848           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8849         }
8850     }
8851   operands[1] = tmp;
8852 })
8853
8854 (define_split
8855   [(set (match_operand:XF 0 "register_operand" "")
8856         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8857    (use (match_operand 2 "" ""))
8858    (clobber (reg:CC FLAGS_REG))]
8859   "reload_completed"
8860   [(parallel [(set (match_dup 0) (match_dup 1))
8861               (clobber (reg:CC FLAGS_REG))])]
8862 {
8863   rtx tmp;
8864   operands[0] = gen_rtx_REG (SImode,
8865                              true_regnum (operands[0])
8866                              + (TARGET_64BIT ? 1 : 2));
8867   if (GET_CODE (operands[1]) == ABS)
8868     {
8869       tmp = GEN_INT (0x7fff);
8870       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8871     }
8872   else
8873     {
8874       tmp = GEN_INT (0x8000);
8875       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8876     }
8877   operands[1] = tmp;
8878 })
8879
8880 ;; Conditionalize these after reload. If they match before reload, we
8881 ;; lose the clobber and ability to use integer instructions.
8882
8883 (define_insn "*<code><mode>2_1"
8884   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8885         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8886   "TARGET_80387
8887    && (reload_completed
8888        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8889   "f<absneg_mnemonic>"
8890   [(set_attr "type" "fsgn")
8891    (set_attr "mode" "<MODE>")])
8892
8893 (define_insn "*<code>extendsfdf2"
8894   [(set (match_operand:DF 0 "register_operand" "=f")
8895         (absneg:DF (float_extend:DF
8896                      (match_operand:SF 1 "register_operand" "0"))))]
8897   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8898   "f<absneg_mnemonic>"
8899   [(set_attr "type" "fsgn")
8900    (set_attr "mode" "DF")])
8901
8902 (define_insn "*<code>extendsfxf2"
8903   [(set (match_operand:XF 0 "register_operand" "=f")
8904         (absneg:XF (float_extend:XF
8905                      (match_operand:SF 1 "register_operand" "0"))))]
8906   "TARGET_80387"
8907   "f<absneg_mnemonic>"
8908   [(set_attr "type" "fsgn")
8909    (set_attr "mode" "XF")])
8910
8911 (define_insn "*<code>extenddfxf2"
8912   [(set (match_operand:XF 0 "register_operand" "=f")
8913         (absneg:XF (float_extend:XF
8914                      (match_operand:DF 1 "register_operand" "0"))))]
8915   "TARGET_80387"
8916   "f<absneg_mnemonic>"
8917   [(set_attr "type" "fsgn")
8918    (set_attr "mode" "XF")])
8919
8920 ;; Copysign instructions
8921
8922 (define_mode_iterator CSGNMODE [SF DF TF])
8923 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8924
8925 (define_expand "copysign<mode>3"
8926   [(match_operand:CSGNMODE 0 "register_operand" "")
8927    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8928    (match_operand:CSGNMODE 2 "register_operand" "")]
8929   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8930    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8931   "ix86_expand_copysign (operands); DONE;")
8932
8933 (define_insn_and_split "copysign<mode>3_const"
8934   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8935         (unspec:CSGNMODE
8936           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8937            (match_operand:CSGNMODE 2 "register_operand" "0")
8938            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8939           UNSPEC_COPYSIGN))]
8940   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8942   "#"
8943   "&& reload_completed"
8944   [(const_int 0)]
8945   "ix86_split_copysign_const (operands); DONE;")
8946
8947 (define_insn "copysign<mode>3_var"
8948   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8949         (unspec:CSGNMODE
8950           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8951            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8952            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8953            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8954           UNSPEC_COPYSIGN))
8955    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8956   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8957    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8958   "#")
8959
8960 (define_split
8961   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8962         (unspec:CSGNMODE
8963           [(match_operand:CSGNMODE 2 "register_operand" "")
8964            (match_operand:CSGNMODE 3 "register_operand" "")
8965            (match_operand:<CSGNVMODE> 4 "" "")
8966            (match_operand:<CSGNVMODE> 5 "" "")]
8967           UNSPEC_COPYSIGN))
8968    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8969   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8970     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8971    && reload_completed"
8972   [(const_int 0)]
8973   "ix86_split_copysign_var (operands); DONE;")
8974 \f
8975 ;; One complement instructions
8976
8977 (define_expand "one_cmpl<mode>2"
8978   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8979         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8980   ""
8981   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8982
8983 (define_insn "*one_cmpl<mode>2_1"
8984   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8985         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8986   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8987   "not{<imodesuffix>}\t%0"
8988   [(set_attr "type" "negnot")
8989    (set_attr "mode" "<MODE>")])
8990
8991 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8992 (define_insn "*one_cmplqi2_1"
8993   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8994         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8995   "ix86_unary_operator_ok (NOT, QImode, operands)"
8996   "@
8997    not{b}\t%0
8998    not{l}\t%k0"
8999   [(set_attr "type" "negnot")
9000    (set_attr "mode" "QI,SI")])
9001
9002 ;; ??? Currently never generated - xor is used instead.
9003 (define_insn "*one_cmplsi2_1_zext"
9004   [(set (match_operand:DI 0 "register_operand" "=r")
9005         (zero_extend:DI
9006           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9007   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9008   "not{l}\t%k0"
9009   [(set_attr "type" "negnot")
9010    (set_attr "mode" "SI")])
9011
9012 (define_insn "*one_cmpl<mode>2_2"
9013   [(set (reg FLAGS_REG)
9014         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9015                  (const_int 0)))
9016    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9017         (not:SWI (match_dup 1)))]
9018   "ix86_match_ccmode (insn, CCNOmode)
9019    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9020   "#"
9021   [(set_attr "type" "alu1")
9022    (set_attr "mode" "<MODE>")])
9023
9024 (define_split
9025   [(set (match_operand 0 "flags_reg_operand" "")
9026         (match_operator 2 "compare_operator"
9027           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9028            (const_int 0)]))
9029    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9030         (not:SWI (match_dup 3)))]
9031   "ix86_match_ccmode (insn, CCNOmode)"
9032   [(parallel [(set (match_dup 0)
9033                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9034                                     (const_int 0)]))
9035               (set (match_dup 1)
9036                    (xor:SWI (match_dup 3) (const_int -1)))])])
9037
9038 ;; ??? Currently never generated - xor is used instead.
9039 (define_insn "*one_cmplsi2_2_zext"
9040   [(set (reg FLAGS_REG)
9041         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9042                  (const_int 0)))
9043    (set (match_operand:DI 0 "register_operand" "=r")
9044         (zero_extend:DI (not:SI (match_dup 1))))]
9045   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046    && ix86_unary_operator_ok (NOT, SImode, operands)"
9047   "#"
9048   [(set_attr "type" "alu1")
9049    (set_attr "mode" "SI")])
9050
9051 (define_split
9052   [(set (match_operand 0 "flags_reg_operand" "")
9053         (match_operator 2 "compare_operator"
9054           [(not:SI (match_operand:SI 3 "register_operand" ""))
9055            (const_int 0)]))
9056    (set (match_operand:DI 1 "register_operand" "")
9057         (zero_extend:DI (not:SI (match_dup 3))))]
9058   "ix86_match_ccmode (insn, CCNOmode)"
9059   [(parallel [(set (match_dup 0)
9060                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9061                                     (const_int 0)]))
9062               (set (match_dup 1)
9063                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9064 \f
9065 ;; Shift instructions
9066
9067 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9068 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9069 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9070 ;; from the assembler input.
9071 ;;
9072 ;; This instruction shifts the target reg/mem as usual, but instead of
9073 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9074 ;; is a left shift double, bits are taken from the high order bits of
9075 ;; reg, else if the insn is a shift right double, bits are taken from the
9076 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9077 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9078 ;;
9079 ;; Since sh[lr]d does not change the `reg' operand, that is done
9080 ;; separately, making all shifts emit pairs of shift double and normal
9081 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9082 ;; support a 63 bit shift, each shift where the count is in a reg expands
9083 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9084 ;;
9085 ;; If the shift count is a constant, we need never emit more than one
9086 ;; shift pair, instead using moves and sign extension for counts greater
9087 ;; than 31.
9088
9089 (define_expand "ashl<mode>3"
9090   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9091         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9092                       (match_operand:QI 2 "nonmemory_operand" "")))]
9093   ""
9094   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9095
9096 (define_insn "*ashl<mode>3_doubleword"
9097   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9098         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9099                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9100    (clobber (reg:CC FLAGS_REG))]
9101   ""
9102   "#"
9103   [(set_attr "type" "multi")])
9104
9105 (define_split
9106   [(set (match_operand:DWI 0 "register_operand" "")
9107         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9108                     (match_operand:QI 2 "nonmemory_operand" "")))
9109    (clobber (reg:CC FLAGS_REG))]
9110   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9111   [(const_int 0)]
9112   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9113
9114 ;; By default we don't ask for a scratch register, because when DWImode
9115 ;; values are manipulated, registers are already at a premium.  But if
9116 ;; we have one handy, we won't turn it away.
9117
9118 (define_peephole2
9119   [(match_scratch:DWIH 3 "r")
9120    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9121                    (ashift:<DWI>
9122                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9123                      (match_operand:QI 2 "nonmemory_operand" "")))
9124               (clobber (reg:CC FLAGS_REG))])
9125    (match_dup 3)]
9126   "TARGET_CMOVE"
9127   [(const_int 0)]
9128   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9129
9130 (define_insn "x86_64_shld"
9131   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9132         (ior:DI (ashift:DI (match_dup 0)
9133                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9134                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9135                   (minus:QI (const_int 64) (match_dup 2)))))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "TARGET_64BIT"
9138   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9139   [(set_attr "type" "ishift")
9140    (set_attr "prefix_0f" "1")
9141    (set_attr "mode" "DI")
9142    (set_attr "athlon_decode" "vector")
9143    (set_attr "amdfam10_decode" "vector")
9144    (set_attr "bdver1_decode" "vector")])
9145
9146 (define_insn "x86_shld"
9147   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9148         (ior:SI (ashift:SI (match_dup 0)
9149                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9150                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9151                   (minus:QI (const_int 32) (match_dup 2)))))
9152    (clobber (reg:CC FLAGS_REG))]
9153   ""
9154   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9155   [(set_attr "type" "ishift")
9156    (set_attr "prefix_0f" "1")
9157    (set_attr "mode" "SI")
9158    (set_attr "pent_pair" "np")
9159    (set_attr "athlon_decode" "vector")
9160    (set_attr "amdfam10_decode" "vector")
9161    (set_attr "bdver1_decode" "vector")])
9162
9163 (define_expand "x86_shift<mode>_adj_1"
9164   [(set (reg:CCZ FLAGS_REG)
9165         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9166                              (match_dup 4))
9167                      (const_int 0)))
9168    (set (match_operand:SWI48 0 "register_operand" "")
9169         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9170                             (match_operand:SWI48 1 "register_operand" "")
9171                             (match_dup 0)))
9172    (set (match_dup 1)
9173         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9174                             (match_operand:SWI48 3 "register_operand" "r")
9175                             (match_dup 1)))]
9176   "TARGET_CMOVE"
9177   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9178
9179 (define_expand "x86_shift<mode>_adj_2"
9180   [(use (match_operand:SWI48 0 "register_operand" ""))
9181    (use (match_operand:SWI48 1 "register_operand" ""))
9182    (use (match_operand:QI 2 "register_operand" ""))]
9183   ""
9184 {
9185   rtx label = gen_label_rtx ();
9186   rtx tmp;
9187
9188   emit_insn (gen_testqi_ccz_1 (operands[2],
9189                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9190
9191   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9192   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9193   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9194                               gen_rtx_LABEL_REF (VOIDmode, label),
9195                               pc_rtx);
9196   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9197   JUMP_LABEL (tmp) = label;
9198
9199   emit_move_insn (operands[0], operands[1]);
9200   ix86_expand_clear (operands[1]);
9201
9202   emit_label (label);
9203   LABEL_NUSES (label) = 1;
9204
9205   DONE;
9206 })
9207
9208 ;; Avoid useless masking of count operand.
9209 (define_insn_and_split "*ashl<mode>3_mask"
9210   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9211         (ashift:SWI48
9212           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9213           (subreg:QI
9214             (and:SI
9215               (match_operand:SI 2 "nonimmediate_operand" "c")
9216               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9217    (clobber (reg:CC FLAGS_REG))]
9218   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9219    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9220       == GET_MODE_BITSIZE (<MODE>mode)-1"
9221   "#"
9222   "&& 1"
9223   [(parallel [(set (match_dup 0)
9224                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9225               (clobber (reg:CC FLAGS_REG))])]
9226 {
9227   if (can_create_pseudo_p ())
9228     operands [2] = force_reg (SImode, operands[2]);
9229
9230   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9231 }
9232   [(set_attr "type" "ishift")
9233    (set_attr "mode" "<MODE>")])
9234
9235 (define_insn "*ashl<mode>3_1"
9236   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9237         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9238                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9241 {
9242   switch (get_attr_type (insn))
9243     {
9244     case TYPE_LEA:
9245       return "#";
9246
9247     case TYPE_ALU:
9248       gcc_assert (operands[2] == const1_rtx);
9249       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9250       return "add{<imodesuffix>}\t%0, %0";
9251
9252     default:
9253       if (operands[2] == const1_rtx
9254           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9255         return "sal{<imodesuffix>}\t%0";
9256       else
9257         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9258     }
9259 }
9260   [(set (attr "type")
9261      (cond [(eq_attr "alternative" "1")
9262               (const_string "lea")
9263             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9264                           (const_int 0))
9265                       (match_operand 0 "register_operand" ""))
9266                  (match_operand 2 "const1_operand" ""))
9267               (const_string "alu")
9268            ]
9269            (const_string "ishift")))
9270    (set (attr "length_immediate")
9271      (if_then_else
9272        (ior (eq_attr "type" "alu")
9273             (and (eq_attr "type" "ishift")
9274                  (and (match_operand 2 "const1_operand" "")
9275                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9276                           (const_int 0)))))
9277        (const_string "0")
9278        (const_string "*")))
9279    (set_attr "mode" "<MODE>")])
9280
9281 (define_insn "*ashlsi3_1_zext"
9282   [(set (match_operand:DI 0 "register_operand" "=r,r")
9283         (zero_extend:DI
9284           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9285                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9286    (clobber (reg:CC FLAGS_REG))]
9287   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9288 {
9289   switch (get_attr_type (insn))
9290     {
9291     case TYPE_LEA:
9292       return "#";
9293
9294     case TYPE_ALU:
9295       gcc_assert (operands[2] == const1_rtx);
9296       return "add{l}\t%k0, %k0";
9297
9298     default:
9299       if (operands[2] == const1_rtx
9300           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9301         return "sal{l}\t%k0";
9302       else
9303         return "sal{l}\t{%2, %k0|%k0, %2}";
9304     }
9305 }
9306   [(set (attr "type")
9307      (cond [(eq_attr "alternative" "1")
9308               (const_string "lea")
9309             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9310                      (const_int 0))
9311                  (match_operand 2 "const1_operand" ""))
9312               (const_string "alu")
9313            ]
9314            (const_string "ishift")))
9315    (set (attr "length_immediate")
9316      (if_then_else
9317        (ior (eq_attr "type" "alu")
9318             (and (eq_attr "type" "ishift")
9319                  (and (match_operand 2 "const1_operand" "")
9320                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9321                           (const_int 0)))))
9322        (const_string "0")
9323        (const_string "*")))
9324    (set_attr "mode" "SI")])
9325
9326 (define_insn "*ashlhi3_1"
9327   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9328         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9329                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9330    (clobber (reg:CC FLAGS_REG))]
9331   "TARGET_PARTIAL_REG_STALL
9332    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9333 {
9334   switch (get_attr_type (insn))
9335     {
9336     case TYPE_ALU:
9337       gcc_assert (operands[2] == const1_rtx);
9338       return "add{w}\t%0, %0";
9339
9340     default:
9341       if (operands[2] == const1_rtx
9342           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9343         return "sal{w}\t%0";
9344       else
9345         return "sal{w}\t{%2, %0|%0, %2}";
9346     }
9347 }
9348   [(set (attr "type")
9349      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9350                           (const_int 0))
9351                       (match_operand 0 "register_operand" ""))
9352                  (match_operand 2 "const1_operand" ""))
9353               (const_string "alu")
9354            ]
9355            (const_string "ishift")))
9356    (set (attr "length_immediate")
9357      (if_then_else
9358        (ior (eq_attr "type" "alu")
9359             (and (eq_attr "type" "ishift")
9360                  (and (match_operand 2 "const1_operand" "")
9361                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9362                           (const_int 0)))))
9363        (const_string "0")
9364        (const_string "*")))
9365    (set_attr "mode" "HI")])
9366
9367 (define_insn "*ashlhi3_1_lea"
9368   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9369         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9370                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9371    (clobber (reg:CC FLAGS_REG))]
9372   "!TARGET_PARTIAL_REG_STALL
9373    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9374 {
9375   switch (get_attr_type (insn))
9376     {
9377     case TYPE_LEA:
9378       return "#";
9379
9380     case TYPE_ALU:
9381       gcc_assert (operands[2] == const1_rtx);
9382       return "add{w}\t%0, %0";
9383
9384     default:
9385       if (operands[2] == const1_rtx
9386           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9387         return "sal{w}\t%0";
9388       else
9389         return "sal{w}\t{%2, %0|%0, %2}";
9390     }
9391 }
9392   [(set (attr "type")
9393      (cond [(eq_attr "alternative" "1")
9394               (const_string "lea")
9395             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9396                           (const_int 0))
9397                       (match_operand 0 "register_operand" ""))
9398                  (match_operand 2 "const1_operand" ""))
9399               (const_string "alu")
9400            ]
9401            (const_string "ishift")))
9402    (set (attr "length_immediate")
9403      (if_then_else
9404        (ior (eq_attr "type" "alu")
9405             (and (eq_attr "type" "ishift")
9406                  (and (match_operand 2 "const1_operand" "")
9407                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9408                           (const_int 0)))))
9409        (const_string "0")
9410        (const_string "*")))
9411    (set_attr "mode" "HI,SI")])
9412
9413 (define_insn "*ashlqi3_1"
9414   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9415         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9416                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9417    (clobber (reg:CC FLAGS_REG))]
9418   "TARGET_PARTIAL_REG_STALL
9419    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9420 {
9421   switch (get_attr_type (insn))
9422     {
9423     case TYPE_ALU:
9424       gcc_assert (operands[2] == const1_rtx);
9425       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9426         return "add{l}\t%k0, %k0";
9427       else
9428         return "add{b}\t%0, %0";
9429
9430     default:
9431       if (operands[2] == const1_rtx
9432           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9433         {
9434           if (get_attr_mode (insn) == MODE_SI)
9435             return "sal{l}\t%k0";
9436           else
9437             return "sal{b}\t%0";
9438         }
9439       else
9440         {
9441           if (get_attr_mode (insn) == MODE_SI)
9442             return "sal{l}\t{%2, %k0|%k0, %2}";
9443           else
9444             return "sal{b}\t{%2, %0|%0, %2}";
9445         }
9446     }
9447 }
9448   [(set (attr "type")
9449      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9450                           (const_int 0))
9451                       (match_operand 0 "register_operand" ""))
9452                  (match_operand 2 "const1_operand" ""))
9453               (const_string "alu")
9454            ]
9455            (const_string "ishift")))
9456    (set (attr "length_immediate")
9457      (if_then_else
9458        (ior (eq_attr "type" "alu")
9459             (and (eq_attr "type" "ishift")
9460                  (and (match_operand 2 "const1_operand" "")
9461                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9462                           (const_int 0)))))
9463        (const_string "0")
9464        (const_string "*")))
9465    (set_attr "mode" "QI,SI")])
9466
9467 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9468 (define_insn "*ashlqi3_1_lea"
9469   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9470         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9471                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9472    (clobber (reg:CC FLAGS_REG))]
9473   "!TARGET_PARTIAL_REG_STALL
9474    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9475 {
9476   switch (get_attr_type (insn))
9477     {
9478     case TYPE_LEA:
9479       return "#";
9480
9481     case TYPE_ALU:
9482       gcc_assert (operands[2] == const1_rtx);
9483       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9484         return "add{l}\t%k0, %k0";
9485       else
9486         return "add{b}\t%0, %0";
9487
9488     default:
9489       if (operands[2] == const1_rtx
9490           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9491         {
9492           if (get_attr_mode (insn) == MODE_SI)
9493             return "sal{l}\t%k0";
9494           else
9495             return "sal{b}\t%0";
9496         }
9497       else
9498         {
9499           if (get_attr_mode (insn) == MODE_SI)
9500             return "sal{l}\t{%2, %k0|%k0, %2}";
9501           else
9502             return "sal{b}\t{%2, %0|%0, %2}";
9503         }
9504     }
9505 }
9506   [(set (attr "type")
9507      (cond [(eq_attr "alternative" "2")
9508               (const_string "lea")
9509             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9510                           (const_int 0))
9511                       (match_operand 0 "register_operand" ""))
9512                  (match_operand 2 "const1_operand" ""))
9513               (const_string "alu")
9514            ]
9515            (const_string "ishift")))
9516    (set (attr "length_immediate")
9517      (if_then_else
9518        (ior (eq_attr "type" "alu")
9519             (and (eq_attr "type" "ishift")
9520                  (and (match_operand 2 "const1_operand" "")
9521                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9522                           (const_int 0)))))
9523        (const_string "0")
9524        (const_string "*")))
9525    (set_attr "mode" "QI,SI,SI")])
9526
9527 (define_insn "*ashlqi3_1_slp"
9528   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9529         (ashift:QI (match_dup 0)
9530                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "(optimize_function_for_size_p (cfun)
9533     || !TARGET_PARTIAL_FLAG_REG_STALL
9534     || (operands[1] == const1_rtx
9535         && (TARGET_SHIFT1
9536             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9537 {
9538   switch (get_attr_type (insn))
9539     {
9540     case TYPE_ALU:
9541       gcc_assert (operands[1] == const1_rtx);
9542       return "add{b}\t%0, %0";
9543
9544     default:
9545       if (operands[1] == const1_rtx
9546           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9547         return "sal{b}\t%0";
9548       else
9549         return "sal{b}\t{%1, %0|%0, %1}";
9550     }
9551 }
9552   [(set (attr "type")
9553      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9554                           (const_int 0))
9555                       (match_operand 0 "register_operand" ""))
9556                  (match_operand 1 "const1_operand" ""))
9557               (const_string "alu")
9558            ]
9559            (const_string "ishift1")))
9560    (set (attr "length_immediate")
9561      (if_then_else
9562        (ior (eq_attr "type" "alu")
9563             (and (eq_attr "type" "ishift1")
9564                  (and (match_operand 1 "const1_operand" "")
9565                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9566                           (const_int 0)))))
9567        (const_string "0")
9568        (const_string "*")))
9569    (set_attr "mode" "QI")])
9570
9571 ;; Convert lea to the lea pattern to avoid flags dependency.
9572 (define_split
9573   [(set (match_operand 0 "register_operand" "")
9574         (ashift (match_operand 1 "index_register_operand" "")
9575                 (match_operand:QI 2 "const_int_operand" "")))
9576    (clobber (reg:CC FLAGS_REG))]
9577   "reload_completed
9578    && true_regnum (operands[0]) != true_regnum (operands[1])"
9579   [(const_int 0)]
9580 {
9581   rtx pat;
9582   enum machine_mode mode = GET_MODE (operands[0]);
9583
9584   if (mode != Pmode)
9585     operands[1] = gen_lowpart (Pmode, operands[1]);
9586   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9587
9588   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9589
9590   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9591     operands[0] = gen_lowpart (SImode, operands[0]);
9592
9593   if (TARGET_64BIT && mode != Pmode)
9594     pat = gen_rtx_SUBREG (SImode, pat, 0);
9595
9596   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9597   DONE;
9598 })
9599
9600 ;; Convert lea to the lea pattern to avoid flags dependency.
9601 (define_split
9602   [(set (match_operand:DI 0 "register_operand" "")
9603         (zero_extend:DI
9604           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9605                      (match_operand:QI 2 "const_int_operand" ""))))
9606    (clobber (reg:CC FLAGS_REG))]
9607   "TARGET_64BIT && reload_completed
9608    && true_regnum (operands[0]) != true_regnum (operands[1])"
9609   [(set (match_dup 0)
9610         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9611 {
9612   operands[1] = gen_lowpart (DImode, operands[1]);
9613   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9614 })
9615
9616 ;; This pattern can't accept a variable shift count, since shifts by
9617 ;; zero don't affect the flags.  We assume that shifts by constant
9618 ;; zero are optimized away.
9619 (define_insn "*ashl<mode>3_cmp"
9620   [(set (reg FLAGS_REG)
9621         (compare
9622           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9623                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9624           (const_int 0)))
9625    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9626         (ashift:SWI (match_dup 1) (match_dup 2)))]
9627   "(optimize_function_for_size_p (cfun)
9628     || !TARGET_PARTIAL_FLAG_REG_STALL
9629     || (operands[2] == const1_rtx
9630         && (TARGET_SHIFT1
9631             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9632    && ix86_match_ccmode (insn, CCGOCmode)
9633    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9634 {
9635   switch (get_attr_type (insn))
9636     {
9637     case TYPE_ALU:
9638       gcc_assert (operands[2] == const1_rtx);
9639       return "add{<imodesuffix>}\t%0, %0";
9640
9641     default:
9642       if (operands[2] == const1_rtx
9643           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9644         return "sal{<imodesuffix>}\t%0";
9645       else
9646         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9647     }
9648 }
9649   [(set (attr "type")
9650      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9651                           (const_int 0))
9652                       (match_operand 0 "register_operand" ""))
9653                  (match_operand 2 "const1_operand" ""))
9654               (const_string "alu")
9655            ]
9656            (const_string "ishift")))
9657    (set (attr "length_immediate")
9658      (if_then_else
9659        (ior (eq_attr "type" "alu")
9660             (and (eq_attr "type" "ishift")
9661                  (and (match_operand 2 "const1_operand" "")
9662                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9663                           (const_int 0)))))
9664        (const_string "0")
9665        (const_string "*")))
9666    (set_attr "mode" "<MODE>")])
9667
9668 (define_insn "*ashlsi3_cmp_zext"
9669   [(set (reg FLAGS_REG)
9670         (compare
9671           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9672                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9673           (const_int 0)))
9674    (set (match_operand:DI 0 "register_operand" "=r")
9675         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9676   "TARGET_64BIT
9677    && (optimize_function_for_size_p (cfun)
9678        || !TARGET_PARTIAL_FLAG_REG_STALL
9679        || (operands[2] == const1_rtx
9680            && (TARGET_SHIFT1
9681                || TARGET_DOUBLE_WITH_ADD)))
9682    && ix86_match_ccmode (insn, CCGOCmode)
9683    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9684 {
9685   switch (get_attr_type (insn))
9686     {
9687     case TYPE_ALU:
9688       gcc_assert (operands[2] == const1_rtx);
9689       return "add{l}\t%k0, %k0";
9690
9691     default:
9692       if (operands[2] == const1_rtx
9693           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9694         return "sal{l}\t%k0";
9695       else
9696         return "sal{l}\t{%2, %k0|%k0, %2}";
9697     }
9698 }
9699   [(set (attr "type")
9700      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9701                      (const_int 0))
9702                  (match_operand 2 "const1_operand" ""))
9703               (const_string "alu")
9704            ]
9705            (const_string "ishift")))
9706    (set (attr "length_immediate")
9707      (if_then_else
9708        (ior (eq_attr "type" "alu")
9709             (and (eq_attr "type" "ishift")
9710                  (and (match_operand 2 "const1_operand" "")
9711                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9712                           (const_int 0)))))
9713        (const_string "0")
9714        (const_string "*")))
9715    (set_attr "mode" "SI")])
9716
9717 (define_insn "*ashl<mode>3_cconly"
9718   [(set (reg FLAGS_REG)
9719         (compare
9720           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9721                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9722           (const_int 0)))
9723    (clobber (match_scratch:SWI 0 "=<r>"))]
9724   "(optimize_function_for_size_p (cfun)
9725     || !TARGET_PARTIAL_FLAG_REG_STALL
9726     || (operands[2] == const1_rtx
9727         && (TARGET_SHIFT1
9728             || TARGET_DOUBLE_WITH_ADD)))
9729    && ix86_match_ccmode (insn, CCGOCmode)"
9730 {
9731   switch (get_attr_type (insn))
9732     {
9733     case TYPE_ALU:
9734       gcc_assert (operands[2] == const1_rtx);
9735       return "add{<imodesuffix>}\t%0, %0";
9736
9737     default:
9738       if (operands[2] == const1_rtx
9739           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9740         return "sal{<imodesuffix>}\t%0";
9741       else
9742         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9743     }
9744 }
9745   [(set (attr "type")
9746      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9747                           (const_int 0))
9748                       (match_operand 0 "register_operand" ""))
9749                  (match_operand 2 "const1_operand" ""))
9750               (const_string "alu")
9751            ]
9752            (const_string "ishift")))
9753    (set (attr "length_immediate")
9754      (if_then_else
9755        (ior (eq_attr "type" "alu")
9756             (and (eq_attr "type" "ishift")
9757                  (and (match_operand 2 "const1_operand" "")
9758                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9759                           (const_int 0)))))
9760        (const_string "0")
9761        (const_string "*")))
9762    (set_attr "mode" "<MODE>")])
9763
9764 ;; See comment above `ashl<mode>3' about how this works.
9765
9766 (define_expand "<shiftrt_insn><mode>3"
9767   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9768         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9769                            (match_operand:QI 2 "nonmemory_operand" "")))]
9770   ""
9771   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9772
9773 ;; Avoid useless masking of count operand.
9774 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9775   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9776         (any_shiftrt:SWI48
9777           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9778           (subreg:QI
9779             (and:SI
9780               (match_operand:SI 2 "nonimmediate_operand" "c")
9781               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9782    (clobber (reg:CC FLAGS_REG))]
9783   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9784    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9785       == GET_MODE_BITSIZE (<MODE>mode)-1"
9786   "#"
9787   "&& 1"
9788   [(parallel [(set (match_dup 0)
9789                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9790               (clobber (reg:CC FLAGS_REG))])]
9791 {
9792   if (can_create_pseudo_p ())
9793     operands [2] = force_reg (SImode, operands[2]);
9794
9795   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9796 }
9797   [(set_attr "type" "ishift")
9798    (set_attr "mode" "<MODE>")])
9799
9800 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9801   [(set (match_operand:DWI 0 "register_operand" "=r")
9802         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9803                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9804    (clobber (reg:CC FLAGS_REG))]
9805   ""
9806   "#"
9807   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9808   [(const_int 0)]
9809   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9810   [(set_attr "type" "multi")])
9811
9812 ;; By default we don't ask for a scratch register, because when DWImode
9813 ;; values are manipulated, registers are already at a premium.  But if
9814 ;; we have one handy, we won't turn it away.
9815
9816 (define_peephole2
9817   [(match_scratch:DWIH 3 "r")
9818    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9819                    (any_shiftrt:<DWI>
9820                      (match_operand:<DWI> 1 "register_operand" "")
9821                      (match_operand:QI 2 "nonmemory_operand" "")))
9822               (clobber (reg:CC FLAGS_REG))])
9823    (match_dup 3)]
9824   "TARGET_CMOVE"
9825   [(const_int 0)]
9826   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9827
9828 (define_insn "x86_64_shrd"
9829   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9830         (ior:DI (ashiftrt:DI (match_dup 0)
9831                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9832                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9833                   (minus:QI (const_int 64) (match_dup 2)))))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "TARGET_64BIT"
9836   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9837   [(set_attr "type" "ishift")
9838    (set_attr "prefix_0f" "1")
9839    (set_attr "mode" "DI")
9840    (set_attr "athlon_decode" "vector")
9841    (set_attr "amdfam10_decode" "vector")
9842    (set_attr "bdver1_decode" "vector")])
9843
9844 (define_insn "x86_shrd"
9845   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9846         (ior:SI (ashiftrt:SI (match_dup 0)
9847                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9848                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9849                   (minus:QI (const_int 32) (match_dup 2)))))
9850    (clobber (reg:CC FLAGS_REG))]
9851   ""
9852   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9853   [(set_attr "type" "ishift")
9854    (set_attr "prefix_0f" "1")
9855    (set_attr "mode" "SI")
9856    (set_attr "pent_pair" "np")
9857    (set_attr "athlon_decode" "vector")
9858    (set_attr "amdfam10_decode" "vector")
9859    (set_attr "bdver1_decode" "vector")])
9860
9861 (define_insn "ashrdi3_cvt"
9862   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9863         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9864                      (match_operand:QI 2 "const_int_operand" "")))
9865    (clobber (reg:CC FLAGS_REG))]
9866   "TARGET_64BIT && INTVAL (operands[2]) == 63
9867    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9868    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9869   "@
9870    {cqto|cqo}
9871    sar{q}\t{%2, %0|%0, %2}"
9872   [(set_attr "type" "imovx,ishift")
9873    (set_attr "prefix_0f" "0,*")
9874    (set_attr "length_immediate" "0,*")
9875    (set_attr "modrm" "0,1")
9876    (set_attr "mode" "DI")])
9877
9878 (define_insn "ashrsi3_cvt"
9879   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9880         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9881                      (match_operand:QI 2 "const_int_operand" "")))
9882    (clobber (reg:CC FLAGS_REG))]
9883   "INTVAL (operands[2]) == 31
9884    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9885    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9886   "@
9887    {cltd|cdq}
9888    sar{l}\t{%2, %0|%0, %2}"
9889   [(set_attr "type" "imovx,ishift")
9890    (set_attr "prefix_0f" "0,*")
9891    (set_attr "length_immediate" "0,*")
9892    (set_attr "modrm" "0,1")
9893    (set_attr "mode" "SI")])
9894
9895 (define_insn "*ashrsi3_cvt_zext"
9896   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9897         (zero_extend:DI
9898           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9899                        (match_operand:QI 2 "const_int_operand" ""))))
9900    (clobber (reg:CC FLAGS_REG))]
9901   "TARGET_64BIT && INTVAL (operands[2]) == 31
9902    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9903    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9904   "@
9905    {cltd|cdq}
9906    sar{l}\t{%2, %k0|%k0, %2}"
9907   [(set_attr "type" "imovx,ishift")
9908    (set_attr "prefix_0f" "0,*")
9909    (set_attr "length_immediate" "0,*")
9910    (set_attr "modrm" "0,1")
9911    (set_attr "mode" "SI")])
9912
9913 (define_expand "x86_shift<mode>_adj_3"
9914   [(use (match_operand:SWI48 0 "register_operand" ""))
9915    (use (match_operand:SWI48 1 "register_operand" ""))
9916    (use (match_operand:QI 2 "register_operand" ""))]
9917   ""
9918 {
9919   rtx label = gen_label_rtx ();
9920   rtx tmp;
9921
9922   emit_insn (gen_testqi_ccz_1 (operands[2],
9923                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9924
9925   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9926   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9927   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9928                               gen_rtx_LABEL_REF (VOIDmode, label),
9929                               pc_rtx);
9930   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9931   JUMP_LABEL (tmp) = label;
9932
9933   emit_move_insn (operands[0], operands[1]);
9934   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9935                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9936   emit_label (label);
9937   LABEL_NUSES (label) = 1;
9938
9939   DONE;
9940 })
9941
9942 (define_insn "*<shiftrt_insn><mode>3_1"
9943   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9944         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9945                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9946    (clobber (reg:CC FLAGS_REG))]
9947   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9948 {
9949   if (operands[2] == const1_rtx
9950       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9951     return "<shiftrt>{<imodesuffix>}\t%0";
9952   else
9953     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9954 }
9955   [(set_attr "type" "ishift")
9956    (set (attr "length_immediate")
9957      (if_then_else
9958        (and (match_operand 2 "const1_operand" "")
9959             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9960                 (const_int 0)))
9961        (const_string "0")
9962        (const_string "*")))
9963    (set_attr "mode" "<MODE>")])
9964
9965 (define_insn "*<shiftrt_insn>si3_1_zext"
9966   [(set (match_operand:DI 0 "register_operand" "=r")
9967         (zero_extend:DI
9968           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9969                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9970    (clobber (reg:CC FLAGS_REG))]
9971   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9972 {
9973   if (operands[2] == const1_rtx
9974       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9975     return "<shiftrt>{l}\t%k0";
9976   else
9977     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9978 }
9979   [(set_attr "type" "ishift")
9980    (set (attr "length_immediate")
9981      (if_then_else
9982        (and (match_operand 2 "const1_operand" "")
9983             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9984                 (const_int 0)))
9985        (const_string "0")
9986        (const_string "*")))
9987    (set_attr "mode" "SI")])
9988
9989 (define_insn "*<shiftrt_insn>qi3_1_slp"
9990   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9991         (any_shiftrt:QI (match_dup 0)
9992                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9993    (clobber (reg:CC FLAGS_REG))]
9994   "(optimize_function_for_size_p (cfun)
9995     || !TARGET_PARTIAL_REG_STALL
9996     || (operands[1] == const1_rtx
9997         && TARGET_SHIFT1))"
9998 {
9999   if (operands[1] == const1_rtx
10000       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10001     return "<shiftrt>{b}\t%0";
10002   else
10003     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10004 }
10005   [(set_attr "type" "ishift1")
10006    (set (attr "length_immediate")
10007      (if_then_else
10008        (and (match_operand 1 "const1_operand" "")
10009             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10010                 (const_int 0)))
10011        (const_string "0")
10012        (const_string "*")))
10013    (set_attr "mode" "QI")])
10014
10015 ;; This pattern can't accept a variable shift count, since shifts by
10016 ;; zero don't affect the flags.  We assume that shifts by constant
10017 ;; zero are optimized away.
10018 (define_insn "*<shiftrt_insn><mode>3_cmp"
10019   [(set (reg FLAGS_REG)
10020         (compare
10021           (any_shiftrt:SWI
10022             (match_operand:SWI 1 "nonimmediate_operand" "0")
10023             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10024           (const_int 0)))
10025    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10026         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10027   "(optimize_function_for_size_p (cfun)
10028     || !TARGET_PARTIAL_FLAG_REG_STALL
10029     || (operands[2] == const1_rtx
10030         && TARGET_SHIFT1))
10031    && ix86_match_ccmode (insn, CCGOCmode)
10032    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10033 {
10034   if (operands[2] == const1_rtx
10035       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036     return "<shiftrt>{<imodesuffix>}\t%0";
10037   else
10038     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10039 }
10040   [(set_attr "type" "ishift")
10041    (set (attr "length_immediate")
10042      (if_then_else
10043        (and (match_operand 2 "const1_operand" "")
10044             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10045                 (const_int 0)))
10046        (const_string "0")
10047        (const_string "*")))
10048    (set_attr "mode" "<MODE>")])
10049
10050 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10051   [(set (reg FLAGS_REG)
10052         (compare
10053           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10054                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10055           (const_int 0)))
10056    (set (match_operand:DI 0 "register_operand" "=r")
10057         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10058   "TARGET_64BIT
10059    && (optimize_function_for_size_p (cfun)
10060        || !TARGET_PARTIAL_FLAG_REG_STALL
10061        || (operands[2] == const1_rtx
10062            && TARGET_SHIFT1))
10063    && ix86_match_ccmode (insn, CCGOCmode)
10064    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10065 {
10066   if (operands[2] == const1_rtx
10067       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10068     return "<shiftrt>{l}\t%k0";
10069   else
10070     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10071 }
10072   [(set_attr "type" "ishift")
10073    (set (attr "length_immediate")
10074      (if_then_else
10075        (and (match_operand 2 "const1_operand" "")
10076             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10077                 (const_int 0)))
10078        (const_string "0")
10079        (const_string "*")))
10080    (set_attr "mode" "SI")])
10081
10082 (define_insn "*<shiftrt_insn><mode>3_cconly"
10083   [(set (reg FLAGS_REG)
10084         (compare
10085           (any_shiftrt:SWI
10086             (match_operand:SWI 1 "register_operand" "0")
10087             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10088           (const_int 0)))
10089    (clobber (match_scratch:SWI 0 "=<r>"))]
10090   "(optimize_function_for_size_p (cfun)
10091     || !TARGET_PARTIAL_FLAG_REG_STALL
10092     || (operands[2] == const1_rtx
10093         && TARGET_SHIFT1))
10094    && ix86_match_ccmode (insn, CCGOCmode)"
10095 {
10096   if (operands[2] == const1_rtx
10097       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10098     return "<shiftrt>{<imodesuffix>}\t%0";
10099   else
10100     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10101 }
10102   [(set_attr "type" "ishift")
10103    (set (attr "length_immediate")
10104      (if_then_else
10105        (and (match_operand 2 "const1_operand" "")
10106             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10107                 (const_int 0)))
10108        (const_string "0")
10109        (const_string "*")))
10110    (set_attr "mode" "<MODE>")])
10111 \f
10112 ;; Rotate instructions
10113
10114 (define_expand "<rotate_insn>ti3"
10115   [(set (match_operand:TI 0 "register_operand" "")
10116         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10117                        (match_operand:QI 2 "nonmemory_operand" "")))]
10118   "TARGET_64BIT"
10119 {
10120   if (const_1_to_63_operand (operands[2], VOIDmode))
10121     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10122                 (operands[0], operands[1], operands[2]));
10123   else
10124     FAIL;
10125
10126   DONE;
10127 })
10128
10129 (define_expand "<rotate_insn>di3"
10130   [(set (match_operand:DI 0 "shiftdi_operand" "")
10131         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10132                        (match_operand:QI 2 "nonmemory_operand" "")))]
10133  ""
10134 {
10135   if (TARGET_64BIT)
10136     ix86_expand_binary_operator (<CODE>, DImode, operands);
10137   else if (const_1_to_31_operand (operands[2], VOIDmode))
10138     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10139                 (operands[0], operands[1], operands[2]));
10140   else
10141     FAIL;
10142
10143   DONE;
10144 })
10145
10146 (define_expand "<rotate_insn><mode>3"
10147   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10148         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10149                             (match_operand:QI 2 "nonmemory_operand" "")))]
10150   ""
10151   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10152
10153 ;; Avoid useless masking of count operand.
10154 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10155   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10156         (any_rotate:SWI48
10157           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10158           (subreg:QI
10159             (and:SI
10160               (match_operand:SI 2 "nonimmediate_operand" "c")
10161               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10162    (clobber (reg:CC FLAGS_REG))]
10163   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10164    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10165       == GET_MODE_BITSIZE (<MODE>mode)-1"
10166   "#"
10167   "&& 1"
10168   [(parallel [(set (match_dup 0)
10169                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10170               (clobber (reg:CC FLAGS_REG))])]
10171 {
10172   if (can_create_pseudo_p ())
10173     operands [2] = force_reg (SImode, operands[2]);
10174
10175   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10176 }
10177   [(set_attr "type" "rotate")
10178    (set_attr "mode" "<MODE>")])
10179
10180 ;; Implement rotation using two double-precision
10181 ;; shift instructions and a scratch register.
10182
10183 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10184  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10185        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10186                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10187   (clobber (reg:CC FLAGS_REG))
10188   (clobber (match_scratch:DWIH 3 "=&r"))]
10189  ""
10190  "#"
10191  "reload_completed"
10192  [(set (match_dup 3) (match_dup 4))
10193   (parallel
10194    [(set (match_dup 4)
10195          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10196                    (lshiftrt:DWIH (match_dup 5)
10197                                   (minus:QI (match_dup 6) (match_dup 2)))))
10198     (clobber (reg:CC FLAGS_REG))])
10199   (parallel
10200    [(set (match_dup 5)
10201          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10202                    (lshiftrt:DWIH (match_dup 3)
10203                                   (minus:QI (match_dup 6) (match_dup 2)))))
10204     (clobber (reg:CC FLAGS_REG))])]
10205 {
10206   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10207
10208   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10209 })
10210
10211 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10212  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10213        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10214                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10215   (clobber (reg:CC FLAGS_REG))
10216   (clobber (match_scratch:DWIH 3 "=&r"))]
10217  ""
10218  "#"
10219  "reload_completed"
10220  [(set (match_dup 3) (match_dup 4))
10221   (parallel
10222    [(set (match_dup 4)
10223          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10224                    (ashift:DWIH (match_dup 5)
10225                                 (minus:QI (match_dup 6) (match_dup 2)))))
10226     (clobber (reg:CC FLAGS_REG))])
10227   (parallel
10228    [(set (match_dup 5)
10229          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10230                    (ashift:DWIH (match_dup 3)
10231                                 (minus:QI (match_dup 6) (match_dup 2)))))
10232     (clobber (reg:CC FLAGS_REG))])]
10233 {
10234   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10235
10236   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10237 })
10238
10239 (define_insn "*<rotate_insn><mode>3_1"
10240   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10241         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10242                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10243    (clobber (reg:CC FLAGS_REG))]
10244   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10245 {
10246   if (operands[2] == const1_rtx
10247       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10248     return "<rotate>{<imodesuffix>}\t%0";
10249   else
10250     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10251 }
10252   [(set_attr "type" "rotate")
10253    (set (attr "length_immediate")
10254      (if_then_else
10255        (and (match_operand 2 "const1_operand" "")
10256             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10257                 (const_int 0)))
10258        (const_string "0")
10259        (const_string "*")))
10260    (set_attr "mode" "<MODE>")])
10261
10262 (define_insn "*<rotate_insn>si3_1_zext"
10263   [(set (match_operand:DI 0 "register_operand" "=r")
10264         (zero_extend:DI
10265           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10266                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10267    (clobber (reg:CC FLAGS_REG))]
10268   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10269 {
10270     if (operands[2] == const1_rtx
10271         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10272     return "<rotate>{l}\t%k0";
10273   else
10274     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10275 }
10276   [(set_attr "type" "rotate")
10277    (set (attr "length_immediate")
10278      (if_then_else
10279        (and (match_operand 2 "const1_operand" "")
10280             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10281                 (const_int 0)))
10282        (const_string "0")
10283        (const_string "*")))
10284    (set_attr "mode" "SI")])
10285
10286 (define_insn "*<rotate_insn>qi3_1_slp"
10287   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10288         (any_rotate:QI (match_dup 0)
10289                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10290    (clobber (reg:CC FLAGS_REG))]
10291   "(optimize_function_for_size_p (cfun)
10292     || !TARGET_PARTIAL_REG_STALL
10293     || (operands[1] == const1_rtx
10294         && TARGET_SHIFT1))"
10295 {
10296   if (operands[1] == const1_rtx
10297       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10298     return "<rotate>{b}\t%0";
10299   else
10300     return "<rotate>{b}\t{%1, %0|%0, %1}";
10301 }
10302   [(set_attr "type" "rotate1")
10303    (set (attr "length_immediate")
10304      (if_then_else
10305        (and (match_operand 1 "const1_operand" "")
10306             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10307                 (const_int 0)))
10308        (const_string "0")
10309        (const_string "*")))
10310    (set_attr "mode" "QI")])
10311
10312 (define_split
10313  [(set (match_operand:HI 0 "register_operand" "")
10314        (any_rotate:HI (match_dup 0) (const_int 8)))
10315   (clobber (reg:CC FLAGS_REG))]
10316  "reload_completed
10317   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10318  [(parallel [(set (strict_low_part (match_dup 0))
10319                   (bswap:HI (match_dup 0)))
10320              (clobber (reg:CC FLAGS_REG))])])
10321 \f
10322 ;; Bit set / bit test instructions
10323
10324 (define_expand "extv"
10325   [(set (match_operand:SI 0 "register_operand" "")
10326         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10327                          (match_operand:SI 2 "const8_operand" "")
10328                          (match_operand:SI 3 "const8_operand" "")))]
10329   ""
10330 {
10331   /* Handle extractions from %ah et al.  */
10332   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10333     FAIL;
10334
10335   /* From mips.md: extract_bit_field doesn't verify that our source
10336      matches the predicate, so check it again here.  */
10337   if (! ext_register_operand (operands[1], VOIDmode))
10338     FAIL;
10339 })
10340
10341 (define_expand "extzv"
10342   [(set (match_operand:SI 0 "register_operand" "")
10343         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10344                          (match_operand:SI 2 "const8_operand" "")
10345                          (match_operand:SI 3 "const8_operand" "")))]
10346   ""
10347 {
10348   /* Handle extractions from %ah et al.  */
10349   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10350     FAIL;
10351
10352   /* From mips.md: extract_bit_field doesn't verify that our source
10353      matches the predicate, so check it again here.  */
10354   if (! ext_register_operand (operands[1], VOIDmode))
10355     FAIL;
10356 })
10357
10358 (define_expand "insv"
10359   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10360                       (match_operand 1 "const8_operand" "")
10361                       (match_operand 2 "const8_operand" ""))
10362         (match_operand 3 "register_operand" ""))]
10363   ""
10364 {
10365   rtx (*gen_mov_insv_1) (rtx, rtx);
10366
10367   /* Handle insertions to %ah et al.  */
10368   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10369     FAIL;
10370
10371   /* From mips.md: insert_bit_field doesn't verify that our source
10372      matches the predicate, so check it again here.  */
10373   if (! ext_register_operand (operands[0], VOIDmode))
10374     FAIL;
10375
10376   gen_mov_insv_1 = (TARGET_64BIT
10377                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10378
10379   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10380   DONE;
10381 })
10382
10383 ;; %%% bts, btr, btc, bt.
10384 ;; In general these instructions are *slow* when applied to memory,
10385 ;; since they enforce atomic operation.  When applied to registers,
10386 ;; it depends on the cpu implementation.  They're never faster than
10387 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10388 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10389 ;; within the instruction itself, so operating on bits in the high
10390 ;; 32-bits of a register becomes easier.
10391 ;;
10392 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10393 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10394 ;; negdf respectively, so they can never be disabled entirely.
10395
10396 (define_insn "*btsq"
10397   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10398                          (const_int 1)
10399                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10400         (const_int 1))
10401    (clobber (reg:CC FLAGS_REG))]
10402   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10403   "bts{q}\t{%1, %0|%0, %1}"
10404   [(set_attr "type" "alu1")
10405    (set_attr "prefix_0f" "1")
10406    (set_attr "mode" "DI")])
10407
10408 (define_insn "*btrq"
10409   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10410                          (const_int 1)
10411                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10412         (const_int 0))
10413    (clobber (reg:CC FLAGS_REG))]
10414   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10415   "btr{q}\t{%1, %0|%0, %1}"
10416   [(set_attr "type" "alu1")
10417    (set_attr "prefix_0f" "1")
10418    (set_attr "mode" "DI")])
10419
10420 (define_insn "*btcq"
10421   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10422                          (const_int 1)
10423                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10424         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10425    (clobber (reg:CC FLAGS_REG))]
10426   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10427   "btc{q}\t{%1, %0|%0, %1}"
10428   [(set_attr "type" "alu1")
10429    (set_attr "prefix_0f" "1")
10430    (set_attr "mode" "DI")])
10431
10432 ;; Allow Nocona to avoid these instructions if a register is available.
10433
10434 (define_peephole2
10435   [(match_scratch:DI 2 "r")
10436    (parallel [(set (zero_extract:DI
10437                      (match_operand:DI 0 "register_operand" "")
10438                      (const_int 1)
10439                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10440                    (const_int 1))
10441               (clobber (reg:CC FLAGS_REG))])]
10442   "TARGET_64BIT && !TARGET_USE_BT"
10443   [(const_int 0)]
10444 {
10445   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10446   rtx op1;
10447
10448   if (HOST_BITS_PER_WIDE_INT >= 64)
10449     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10450   else if (i < HOST_BITS_PER_WIDE_INT)
10451     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10452   else
10453     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10454
10455   op1 = immed_double_const (lo, hi, DImode);
10456   if (i >= 31)
10457     {
10458       emit_move_insn (operands[2], op1);
10459       op1 = operands[2];
10460     }
10461
10462   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10463   DONE;
10464 })
10465
10466 (define_peephole2
10467   [(match_scratch:DI 2 "r")
10468    (parallel [(set (zero_extract:DI
10469                      (match_operand:DI 0 "register_operand" "")
10470                      (const_int 1)
10471                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10472                    (const_int 0))
10473               (clobber (reg:CC FLAGS_REG))])]
10474   "TARGET_64BIT && !TARGET_USE_BT"
10475   [(const_int 0)]
10476 {
10477   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10478   rtx op1;
10479
10480   if (HOST_BITS_PER_WIDE_INT >= 64)
10481     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10482   else if (i < HOST_BITS_PER_WIDE_INT)
10483     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10484   else
10485     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10486
10487   op1 = immed_double_const (~lo, ~hi, DImode);
10488   if (i >= 32)
10489     {
10490       emit_move_insn (operands[2], op1);
10491       op1 = operands[2];
10492     }
10493
10494   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10495   DONE;
10496 })
10497
10498 (define_peephole2
10499   [(match_scratch:DI 2 "r")
10500    (parallel [(set (zero_extract:DI
10501                      (match_operand:DI 0 "register_operand" "")
10502                      (const_int 1)
10503                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10504               (not:DI (zero_extract:DI
10505                         (match_dup 0) (const_int 1) (match_dup 1))))
10506               (clobber (reg:CC FLAGS_REG))])]
10507   "TARGET_64BIT && !TARGET_USE_BT"
10508   [(const_int 0)]
10509 {
10510   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10511   rtx op1;
10512
10513   if (HOST_BITS_PER_WIDE_INT >= 64)
10514     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10515   else if (i < HOST_BITS_PER_WIDE_INT)
10516     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10517   else
10518     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10519
10520   op1 = immed_double_const (lo, hi, DImode);
10521   if (i >= 31)
10522     {
10523       emit_move_insn (operands[2], op1);
10524       op1 = operands[2];
10525     }
10526
10527   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10528   DONE;
10529 })
10530
10531 (define_insn "*bt<mode>"
10532   [(set (reg:CCC FLAGS_REG)
10533         (compare:CCC
10534           (zero_extract:SWI48
10535             (match_operand:SWI48 0 "register_operand" "r")
10536             (const_int 1)
10537             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10538           (const_int 0)))]
10539   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10540   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10541   [(set_attr "type" "alu1")
10542    (set_attr "prefix_0f" "1")
10543    (set_attr "mode" "<MODE>")])
10544 \f
10545 ;; Store-flag instructions.
10546
10547 ;; For all sCOND expanders, also expand the compare or test insn that
10548 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10549
10550 (define_insn_and_split "*setcc_di_1"
10551   [(set (match_operand:DI 0 "register_operand" "=q")
10552         (match_operator:DI 1 "ix86_comparison_operator"
10553           [(reg FLAGS_REG) (const_int 0)]))]
10554   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10555   "#"
10556   "&& reload_completed"
10557   [(set (match_dup 2) (match_dup 1))
10558    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10559 {
10560   PUT_MODE (operands[1], QImode);
10561   operands[2] = gen_lowpart (QImode, operands[0]);
10562 })
10563
10564 (define_insn_and_split "*setcc_si_1_and"
10565   [(set (match_operand:SI 0 "register_operand" "=q")
10566         (match_operator:SI 1 "ix86_comparison_operator"
10567           [(reg FLAGS_REG) (const_int 0)]))
10568    (clobber (reg:CC FLAGS_REG))]
10569   "!TARGET_PARTIAL_REG_STALL
10570    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10571   "#"
10572   "&& reload_completed"
10573   [(set (match_dup 2) (match_dup 1))
10574    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10575               (clobber (reg:CC FLAGS_REG))])]
10576 {
10577   PUT_MODE (operands[1], QImode);
10578   operands[2] = gen_lowpart (QImode, operands[0]);
10579 })
10580
10581 (define_insn_and_split "*setcc_si_1_movzbl"
10582   [(set (match_operand:SI 0 "register_operand" "=q")
10583         (match_operator:SI 1 "ix86_comparison_operator"
10584           [(reg FLAGS_REG) (const_int 0)]))]
10585   "!TARGET_PARTIAL_REG_STALL
10586    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10587   "#"
10588   "&& reload_completed"
10589   [(set (match_dup 2) (match_dup 1))
10590    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10591 {
10592   PUT_MODE (operands[1], QImode);
10593   operands[2] = gen_lowpart (QImode, operands[0]);
10594 })
10595
10596 (define_insn "*setcc_qi"
10597   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10598         (match_operator:QI 1 "ix86_comparison_operator"
10599           [(reg FLAGS_REG) (const_int 0)]))]
10600   ""
10601   "set%C1\t%0"
10602   [(set_attr "type" "setcc")
10603    (set_attr "mode" "QI")])
10604
10605 (define_insn "*setcc_qi_slp"
10606   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10607         (match_operator:QI 1 "ix86_comparison_operator"
10608           [(reg FLAGS_REG) (const_int 0)]))]
10609   ""
10610   "set%C1\t%0"
10611   [(set_attr "type" "setcc")
10612    (set_attr "mode" "QI")])
10613
10614 ;; In general it is not safe to assume too much about CCmode registers,
10615 ;; so simplify-rtx stops when it sees a second one.  Under certain
10616 ;; conditions this is safe on x86, so help combine not create
10617 ;;
10618 ;;      seta    %al
10619 ;;      testb   %al, %al
10620 ;;      sete    %al
10621
10622 (define_split
10623   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10624         (ne:QI (match_operator 1 "ix86_comparison_operator"
10625                  [(reg FLAGS_REG) (const_int 0)])
10626             (const_int 0)))]
10627   ""
10628   [(set (match_dup 0) (match_dup 1))]
10629   "PUT_MODE (operands[1], QImode);")
10630
10631 (define_split
10632   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10633         (ne:QI (match_operator 1 "ix86_comparison_operator"
10634                  [(reg FLAGS_REG) (const_int 0)])
10635             (const_int 0)))]
10636   ""
10637   [(set (match_dup 0) (match_dup 1))]
10638   "PUT_MODE (operands[1], QImode);")
10639
10640 (define_split
10641   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10642         (eq:QI (match_operator 1 "ix86_comparison_operator"
10643                  [(reg FLAGS_REG) (const_int 0)])
10644             (const_int 0)))]
10645   ""
10646   [(set (match_dup 0) (match_dup 1))]
10647 {
10648   rtx new_op1 = copy_rtx (operands[1]);
10649   operands[1] = new_op1;
10650   PUT_MODE (new_op1, QImode);
10651   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10652                                              GET_MODE (XEXP (new_op1, 0))));
10653
10654   /* Make sure that (a) the CCmode we have for the flags is strong
10655      enough for the reversed compare or (b) we have a valid FP compare.  */
10656   if (! ix86_comparison_operator (new_op1, VOIDmode))
10657     FAIL;
10658 })
10659
10660 (define_split
10661   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10662         (eq:QI (match_operator 1 "ix86_comparison_operator"
10663                  [(reg FLAGS_REG) (const_int 0)])
10664             (const_int 0)))]
10665   ""
10666   [(set (match_dup 0) (match_dup 1))]
10667 {
10668   rtx new_op1 = copy_rtx (operands[1]);
10669   operands[1] = new_op1;
10670   PUT_MODE (new_op1, QImode);
10671   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10672                                              GET_MODE (XEXP (new_op1, 0))));
10673
10674   /* Make sure that (a) the CCmode we have for the flags is strong
10675      enough for the reversed compare or (b) we have a valid FP compare.  */
10676   if (! ix86_comparison_operator (new_op1, VOIDmode))
10677     FAIL;
10678 })
10679
10680 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10681 ;; subsequent logical operations are used to imitate conditional moves.
10682 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10683 ;; it directly.
10684
10685 (define_insn "*avx_setcc<mode>"
10686   [(set (match_operand:MODEF 0 "register_operand" "=x")
10687         (match_operator:MODEF 1 "avx_comparison_float_operator"
10688           [(match_operand:MODEF 2 "register_operand" "x")
10689            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10690   "TARGET_AVX"
10691   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10692   [(set_attr "type" "ssecmp")
10693    (set_attr "prefix" "vex")
10694    (set_attr "length_immediate" "1")
10695    (set_attr "mode" "<MODE>")])
10696
10697 (define_insn "*sse_setcc<mode>"
10698   [(set (match_operand:MODEF 0 "register_operand" "=x")
10699         (match_operator:MODEF 1 "sse_comparison_operator"
10700           [(match_operand:MODEF 2 "register_operand" "0")
10701            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10702   "SSE_FLOAT_MODE_P (<MODE>mode)"
10703   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10704   [(set_attr "type" "ssecmp")
10705    (set_attr "length_immediate" "1")
10706    (set_attr "mode" "<MODE>")])
10707 \f
10708 ;; Basic conditional jump instructions.
10709 ;; We ignore the overflow flag for signed branch instructions.
10710
10711 (define_insn "*jcc_1"
10712   [(set (pc)
10713         (if_then_else (match_operator 1 "ix86_comparison_operator"
10714                                       [(reg FLAGS_REG) (const_int 0)])
10715                       (label_ref (match_operand 0 "" ""))
10716                       (pc)))]
10717   ""
10718   "%+j%C1\t%l0"
10719   [(set_attr "type" "ibr")
10720    (set_attr "modrm" "0")
10721    (set (attr "length")
10722            (if_then_else (and (ge (minus (match_dup 0) (pc))
10723                                   (const_int -126))
10724                               (lt (minus (match_dup 0) (pc))
10725                                   (const_int 128)))
10726              (const_int 2)
10727              (const_int 6)))])
10728
10729 (define_insn "*jcc_2"
10730   [(set (pc)
10731         (if_then_else (match_operator 1 "ix86_comparison_operator"
10732                                       [(reg FLAGS_REG) (const_int 0)])
10733                       (pc)
10734                       (label_ref (match_operand 0 "" ""))))]
10735   ""
10736   "%+j%c1\t%l0"
10737   [(set_attr "type" "ibr")
10738    (set_attr "modrm" "0")
10739    (set (attr "length")
10740            (if_then_else (and (ge (minus (match_dup 0) (pc))
10741                                   (const_int -126))
10742                               (lt (minus (match_dup 0) (pc))
10743                                   (const_int 128)))
10744              (const_int 2)
10745              (const_int 6)))])
10746
10747 ;; In general it is not safe to assume too much about CCmode registers,
10748 ;; so simplify-rtx stops when it sees a second one.  Under certain
10749 ;; conditions this is safe on x86, so help combine not create
10750 ;;
10751 ;;      seta    %al
10752 ;;      testb   %al, %al
10753 ;;      je      Lfoo
10754
10755 (define_split
10756   [(set (pc)
10757         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10758                                       [(reg FLAGS_REG) (const_int 0)])
10759                           (const_int 0))
10760                       (label_ref (match_operand 1 "" ""))
10761                       (pc)))]
10762   ""
10763   [(set (pc)
10764         (if_then_else (match_dup 0)
10765                       (label_ref (match_dup 1))
10766                       (pc)))]
10767   "PUT_MODE (operands[0], VOIDmode);")
10768
10769 (define_split
10770   [(set (pc)
10771         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10772                                       [(reg FLAGS_REG) (const_int 0)])
10773                           (const_int 0))
10774                       (label_ref (match_operand 1 "" ""))
10775                       (pc)))]
10776   ""
10777   [(set (pc)
10778         (if_then_else (match_dup 0)
10779                       (label_ref (match_dup 1))
10780                       (pc)))]
10781 {
10782   rtx new_op0 = copy_rtx (operands[0]);
10783   operands[0] = new_op0;
10784   PUT_MODE (new_op0, VOIDmode);
10785   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10786                                              GET_MODE (XEXP (new_op0, 0))));
10787
10788   /* Make sure that (a) the CCmode we have for the flags is strong
10789      enough for the reversed compare or (b) we have a valid FP compare.  */
10790   if (! ix86_comparison_operator (new_op0, VOIDmode))
10791     FAIL;
10792 })
10793
10794 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10795 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10796 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10797 ;; appropriate modulo of the bit offset value.
10798
10799 (define_insn_and_split "*jcc_bt<mode>"
10800   [(set (pc)
10801         (if_then_else (match_operator 0 "bt_comparison_operator"
10802                         [(zero_extract:SWI48
10803                            (match_operand:SWI48 1 "register_operand" "r")
10804                            (const_int 1)
10805                            (zero_extend:SI
10806                              (match_operand:QI 2 "register_operand" "r")))
10807                          (const_int 0)])
10808                       (label_ref (match_operand 3 "" ""))
10809                       (pc)))
10810    (clobber (reg:CC FLAGS_REG))]
10811   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10812   "#"
10813   "&& 1"
10814   [(set (reg:CCC FLAGS_REG)
10815         (compare:CCC
10816           (zero_extract:SWI48
10817             (match_dup 1)
10818             (const_int 1)
10819             (match_dup 2))
10820           (const_int 0)))
10821    (set (pc)
10822         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10823                       (label_ref (match_dup 3))
10824                       (pc)))]
10825 {
10826   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10827
10828   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10829 })
10830
10831 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10832 ;; also for DImode, this is what combine produces.
10833 (define_insn_and_split "*jcc_bt<mode>_mask"
10834   [(set (pc)
10835         (if_then_else (match_operator 0 "bt_comparison_operator"
10836                         [(zero_extract:SWI48
10837                            (match_operand:SWI48 1 "register_operand" "r")
10838                            (const_int 1)
10839                            (and:SI
10840                              (match_operand:SI 2 "register_operand" "r")
10841                              (match_operand:SI 3 "const_int_operand" "n")))])
10842                       (label_ref (match_operand 4 "" ""))
10843                       (pc)))
10844    (clobber (reg:CC FLAGS_REG))]
10845   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10846    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10847       == GET_MODE_BITSIZE (<MODE>mode)-1"
10848   "#"
10849   "&& 1"
10850   [(set (reg:CCC FLAGS_REG)
10851         (compare:CCC
10852           (zero_extract:SWI48
10853             (match_dup 1)
10854             (const_int 1)
10855             (match_dup 2))
10856           (const_int 0)))
10857    (set (pc)
10858         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10859                       (label_ref (match_dup 4))
10860                       (pc)))]
10861 {
10862   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10863
10864   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10865 })
10866
10867 (define_insn_and_split "*jcc_btsi_1"
10868   [(set (pc)
10869         (if_then_else (match_operator 0 "bt_comparison_operator"
10870                         [(and:SI
10871                            (lshiftrt:SI
10872                              (match_operand:SI 1 "register_operand" "r")
10873                              (match_operand:QI 2 "register_operand" "r"))
10874                            (const_int 1))
10875                          (const_int 0)])
10876                       (label_ref (match_operand 3 "" ""))
10877                       (pc)))
10878    (clobber (reg:CC FLAGS_REG))]
10879   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10880   "#"
10881   "&& 1"
10882   [(set (reg:CCC FLAGS_REG)
10883         (compare:CCC
10884           (zero_extract:SI
10885             (match_dup 1)
10886             (const_int 1)
10887             (match_dup 2))
10888           (const_int 0)))
10889    (set (pc)
10890         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10891                       (label_ref (match_dup 3))
10892                       (pc)))]
10893 {
10894   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10895
10896   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10897 })
10898
10899 ;; avoid useless masking of bit offset operand
10900 (define_insn_and_split "*jcc_btsi_mask_1"
10901   [(set (pc)
10902         (if_then_else
10903           (match_operator 0 "bt_comparison_operator"
10904             [(and:SI
10905                (lshiftrt:SI
10906                  (match_operand:SI 1 "register_operand" "r")
10907                  (subreg:QI
10908                    (and:SI
10909                      (match_operand:SI 2 "register_operand" "r")
10910                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10911                (const_int 1))
10912              (const_int 0)])
10913           (label_ref (match_operand 4 "" ""))
10914           (pc)))
10915    (clobber (reg:CC FLAGS_REG))]
10916   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10917    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10918   "#"
10919   "&& 1"
10920   [(set (reg:CCC FLAGS_REG)
10921         (compare:CCC
10922           (zero_extract:SI
10923             (match_dup 1)
10924             (const_int 1)
10925             (match_dup 2))
10926           (const_int 0)))
10927    (set (pc)
10928         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10929                       (label_ref (match_dup 4))
10930                       (pc)))]
10931   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10932
10933 ;; Define combination compare-and-branch fp compare instructions to help
10934 ;; combine.
10935
10936 (define_insn "*fp_jcc_1_387"
10937   [(set (pc)
10938         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10939                         [(match_operand 1 "register_operand" "f")
10940                          (match_operand 2 "nonimmediate_operand" "fm")])
10941           (label_ref (match_operand 3 "" ""))
10942           (pc)))
10943    (clobber (reg:CCFP FPSR_REG))
10944    (clobber (reg:CCFP FLAGS_REG))
10945    (clobber (match_scratch:HI 4 "=a"))]
10946   "TARGET_80387
10947    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10948    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10949    && SELECT_CC_MODE (GET_CODE (operands[0]),
10950                       operands[1], operands[2]) == CCFPmode
10951    && !TARGET_CMOVE"
10952   "#")
10953
10954 (define_insn "*fp_jcc_1r_387"
10955   [(set (pc)
10956         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10957                         [(match_operand 1 "register_operand" "f")
10958                          (match_operand 2 "nonimmediate_operand" "fm")])
10959           (pc)
10960           (label_ref (match_operand 3 "" ""))))
10961    (clobber (reg:CCFP FPSR_REG))
10962    (clobber (reg:CCFP FLAGS_REG))
10963    (clobber (match_scratch:HI 4 "=a"))]
10964   "TARGET_80387
10965    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10966    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10967    && SELECT_CC_MODE (GET_CODE (operands[0]),
10968                       operands[1], operands[2]) == CCFPmode
10969    && !TARGET_CMOVE"
10970   "#")
10971
10972 (define_insn "*fp_jcc_2_387"
10973   [(set (pc)
10974         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10975                         [(match_operand 1 "register_operand" "f")
10976                          (match_operand 2 "register_operand" "f")])
10977           (label_ref (match_operand 3 "" ""))
10978           (pc)))
10979    (clobber (reg:CCFP FPSR_REG))
10980    (clobber (reg:CCFP FLAGS_REG))
10981    (clobber (match_scratch:HI 4 "=a"))]
10982   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10983    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10984    && !TARGET_CMOVE"
10985   "#")
10986
10987 (define_insn "*fp_jcc_2r_387"
10988   [(set (pc)
10989         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990                         [(match_operand 1 "register_operand" "f")
10991                          (match_operand 2 "register_operand" "f")])
10992           (pc)
10993           (label_ref (match_operand 3 "" ""))))
10994    (clobber (reg:CCFP FPSR_REG))
10995    (clobber (reg:CCFP FLAGS_REG))
10996    (clobber (match_scratch:HI 4 "=a"))]
10997   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10998    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10999    && !TARGET_CMOVE"
11000   "#")
11001
11002 (define_insn "*fp_jcc_3_387"
11003   [(set (pc)
11004         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11005                         [(match_operand 1 "register_operand" "f")
11006                          (match_operand 2 "const0_operand" "")])
11007           (label_ref (match_operand 3 "" ""))
11008           (pc)))
11009    (clobber (reg:CCFP FPSR_REG))
11010    (clobber (reg:CCFP FLAGS_REG))
11011    (clobber (match_scratch:HI 4 "=a"))]
11012   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11013    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11014    && SELECT_CC_MODE (GET_CODE (operands[0]),
11015                       operands[1], operands[2]) == CCFPmode
11016    && !TARGET_CMOVE"
11017   "#")
11018
11019 (define_split
11020   [(set (pc)
11021         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11022                         [(match_operand 1 "register_operand" "")
11023                          (match_operand 2 "nonimmediate_operand" "")])
11024           (match_operand 3 "" "")
11025           (match_operand 4 "" "")))
11026    (clobber (reg:CCFP FPSR_REG))
11027    (clobber (reg:CCFP FLAGS_REG))]
11028   "reload_completed"
11029   [(const_int 0)]
11030 {
11031   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11032                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11033   DONE;
11034 })
11035
11036 (define_split
11037   [(set (pc)
11038         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11039                         [(match_operand 1 "register_operand" "")
11040                          (match_operand 2 "general_operand" "")])
11041           (match_operand 3 "" "")
11042           (match_operand 4 "" "")))
11043    (clobber (reg:CCFP FPSR_REG))
11044    (clobber (reg:CCFP FLAGS_REG))
11045    (clobber (match_scratch:HI 5 "=a"))]
11046   "reload_completed"
11047   [(const_int 0)]
11048 {
11049   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11050                         operands[3], operands[4], operands[5], NULL_RTX);
11051   DONE;
11052 })
11053
11054 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11055 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11056 ;; with a precedence over other operators and is always put in the first
11057 ;; place. Swap condition and operands to match ficom instruction.
11058
11059 (define_insn "*fp_jcc_4_<mode>_387"
11060   [(set (pc)
11061         (if_then_else
11062           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11063             [(match_operator 1 "float_operator"
11064               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11065              (match_operand 3 "register_operand" "f,f")])
11066           (label_ref (match_operand 4 "" ""))
11067           (pc)))
11068    (clobber (reg:CCFP FPSR_REG))
11069    (clobber (reg:CCFP FLAGS_REG))
11070    (clobber (match_scratch:HI 5 "=a,a"))]
11071   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11072    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11073    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11074    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11075    && !TARGET_CMOVE"
11076   "#")
11077
11078 (define_split
11079   [(set (pc)
11080         (if_then_else
11081           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11082             [(match_operator 1 "float_operator"
11083               [(match_operand:X87MODEI12 2 "memory_operand" "")])
11084              (match_operand 3 "register_operand" "")])
11085           (match_operand 4 "" "")
11086           (match_operand 5 "" "")))
11087    (clobber (reg:CCFP FPSR_REG))
11088    (clobber (reg:CCFP FLAGS_REG))
11089    (clobber (match_scratch:HI 6 "=a"))]
11090   "reload_completed"
11091   [(const_int 0)]
11092 {
11093   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11094
11095   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11096                         operands[3], operands[7],
11097                         operands[4], operands[5], operands[6], NULL_RTX);
11098   DONE;
11099 })
11100
11101 ;; %%% Kill this when reload knows how to do it.
11102 (define_split
11103   [(set (pc)
11104         (if_then_else
11105           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11106             [(match_operator 1 "float_operator"
11107               [(match_operand:X87MODEI12 2 "register_operand" "")])
11108              (match_operand 3 "register_operand" "")])
11109           (match_operand 4 "" "")
11110           (match_operand 5 "" "")))
11111    (clobber (reg:CCFP FPSR_REG))
11112    (clobber (reg:CCFP FLAGS_REG))
11113    (clobber (match_scratch:HI 6 "=a"))]
11114   "reload_completed"
11115   [(const_int 0)]
11116 {
11117   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11118   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11119
11120   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11121                         operands[3], operands[7],
11122                         operands[4], operands[5], operands[6], operands[2]);
11123   DONE;
11124 })
11125 \f
11126 ;; Unconditional and other jump instructions
11127
11128 (define_insn "jump"
11129   [(set (pc)
11130         (label_ref (match_operand 0 "" "")))]
11131   ""
11132   "jmp\t%l0"
11133   [(set_attr "type" "ibr")
11134    (set (attr "length")
11135            (if_then_else (and (ge (minus (match_dup 0) (pc))
11136                                   (const_int -126))
11137                               (lt (minus (match_dup 0) (pc))
11138                                   (const_int 128)))
11139              (const_int 2)
11140              (const_int 5)))
11141    (set_attr "modrm" "0")])
11142
11143 (define_expand "indirect_jump"
11144   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11145   ""
11146   "")
11147
11148 (define_insn "*indirect_jump"
11149   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11150   ""
11151   "jmp\t%A0"
11152   [(set_attr "type" "ibr")
11153    (set_attr "length_immediate" "0")])
11154
11155 (define_expand "tablejump"
11156   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11157               (use (label_ref (match_operand 1 "" "")))])]
11158   ""
11159 {
11160   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11161      relative.  Convert the relative address to an absolute address.  */
11162   if (flag_pic)
11163     {
11164       rtx op0, op1;
11165       enum rtx_code code;
11166
11167       /* We can't use @GOTOFF for text labels on VxWorks;
11168          see gotoff_operand.  */
11169       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11170         {
11171           code = PLUS;
11172           op0 = operands[0];
11173           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11174         }
11175       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11176         {
11177           code = PLUS;
11178           op0 = operands[0];
11179           op1 = pic_offset_table_rtx;
11180         }
11181       else
11182         {
11183           code = MINUS;
11184           op0 = pic_offset_table_rtx;
11185           op1 = operands[0];
11186         }
11187
11188       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11189                                          OPTAB_DIRECT);
11190     }
11191 })
11192
11193 (define_insn "*tablejump_1"
11194   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11195    (use (label_ref (match_operand 1 "" "")))]
11196   ""
11197   "jmp\t%A0"
11198   [(set_attr "type" "ibr")
11199    (set_attr "length_immediate" "0")])
11200 \f
11201 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11202
11203 (define_peephole2
11204   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11205    (set (match_operand:QI 1 "register_operand" "")
11206         (match_operator:QI 2 "ix86_comparison_operator"
11207           [(reg FLAGS_REG) (const_int 0)]))
11208    (set (match_operand 3 "q_regs_operand" "")
11209         (zero_extend (match_dup 1)))]
11210   "(peep2_reg_dead_p (3, operands[1])
11211     || operands_match_p (operands[1], operands[3]))
11212    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11213   [(set (match_dup 4) (match_dup 0))
11214    (set (strict_low_part (match_dup 5))
11215         (match_dup 2))]
11216 {
11217   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11218   operands[5] = gen_lowpart (QImode, operands[3]);
11219   ix86_expand_clear (operands[3]);
11220 })
11221
11222 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11223
11224 (define_peephole2
11225   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11226    (set (match_operand:QI 1 "register_operand" "")
11227         (match_operator:QI 2 "ix86_comparison_operator"
11228           [(reg FLAGS_REG) (const_int 0)]))
11229    (parallel [(set (match_operand 3 "q_regs_operand" "")
11230                    (zero_extend (match_dup 1)))
11231               (clobber (reg:CC FLAGS_REG))])]
11232   "(peep2_reg_dead_p (3, operands[1])
11233     || operands_match_p (operands[1], operands[3]))
11234    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11235   [(set (match_dup 4) (match_dup 0))
11236    (set (strict_low_part (match_dup 5))
11237         (match_dup 2))]
11238 {
11239   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11240   operands[5] = gen_lowpart (QImode, operands[3]);
11241   ix86_expand_clear (operands[3]);
11242 })
11243 \f
11244 ;; Call instructions.
11245
11246 ;; The predicates normally associated with named expanders are not properly
11247 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11248 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11249
11250 ;; P6 processors will jump to the address after the decrement when %esp
11251 ;; is used as a call operand, so they will execute return address as a code.
11252 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11253  
11254 ;; Call subroutine returning no value.
11255
11256 (define_expand "call_pop"
11257   [(parallel [(call (match_operand:QI 0 "" "")
11258                     (match_operand:SI 1 "" ""))
11259               (set (reg:SI SP_REG)
11260                    (plus:SI (reg:SI SP_REG)
11261                             (match_operand:SI 3 "" "")))])]
11262   "!TARGET_64BIT"
11263 {
11264   ix86_expand_call (NULL, operands[0], operands[1],
11265                     operands[2], operands[3], 0);
11266   DONE;
11267 })
11268
11269 (define_insn_and_split "*call_pop_0_vzeroupper"
11270   [(parallel
11271     [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11272            (match_operand:SI 1 "" ""))
11273      (set (reg:SI SP_REG)
11274           (plus:SI (reg:SI SP_REG)
11275                    (match_operand:SI 2 "immediate_operand" "")))])
11276    (unspec [(match_operand 3 "const_int_operand" "")]
11277            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11278   "TARGET_VZEROUPPER && !TARGET_64BIT"
11279   "#"
11280   "&& reload_completed"
11281   [(const_int 0)]
11282   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11283   [(set_attr "type" "call")])
11284
11285 (define_insn "*call_pop_0"
11286   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11287          (match_operand:SI 1 "" ""))
11288    (set (reg:SI SP_REG)
11289         (plus:SI (reg:SI SP_REG)
11290                  (match_operand:SI 2 "immediate_operand" "")))]
11291   "!TARGET_64BIT"
11292 {
11293   if (SIBLING_CALL_P (insn))
11294     return "jmp\t%P0";
11295   else
11296     return "call\t%P0";
11297 }
11298   [(set_attr "type" "call")])
11299
11300 (define_insn_and_split "*call_pop_1_vzeroupper"
11301   [(parallel
11302     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11303            (match_operand:SI 1 "" ""))
11304      (set (reg:SI SP_REG)
11305           (plus:SI (reg:SI SP_REG)
11306                    (match_operand:SI 2 "immediate_operand" "i")))])
11307    (unspec [(match_operand 3 "const_int_operand" "")]
11308            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11309   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11310   "#"
11311   "&& reload_completed"
11312   [(const_int 0)]
11313   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11314   [(set_attr "type" "call")])
11315
11316 (define_insn "*call_pop_1"
11317   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11318          (match_operand:SI 1 "" ""))
11319    (set (reg:SI SP_REG)
11320         (plus:SI (reg:SI SP_REG)
11321                  (match_operand:SI 2 "immediate_operand" "i")))]
11322   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11323 {
11324   if (constant_call_address_operand (operands[0], Pmode))
11325     return "call\t%P0";
11326   return "call\t%A0";
11327 }
11328   [(set_attr "type" "call")])
11329
11330 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11331  [(parallel
11332    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11333            (match_operand:SI 1 "" ""))
11334      (set (reg:SI SP_REG)
11335           (plus:SI (reg:SI SP_REG)
11336                    (match_operand:SI 2 "immediate_operand" "i,i")))])
11337    (unspec [(match_operand 3 "const_int_operand" "")]
11338            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11339   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11340   "#"
11341   "&& reload_completed"
11342   [(const_int 0)]
11343   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11344   [(set_attr "type" "call")])
11345
11346 (define_insn "*sibcall_pop_1"
11347   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11348          (match_operand:SI 1 "" ""))
11349    (set (reg:SI SP_REG)
11350         (plus:SI (reg:SI SP_REG)
11351                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11352   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11353   "@
11354    jmp\t%P0
11355    jmp\t%A0"
11356   [(set_attr "type" "call")])
11357
11358 (define_expand "call"
11359   [(call (match_operand:QI 0 "" "")
11360          (match_operand 1 "" ""))
11361    (use (match_operand 2 "" ""))]
11362   ""
11363 {
11364   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11365   DONE;
11366 })
11367
11368 (define_expand "sibcall"
11369   [(call (match_operand:QI 0 "" "")
11370          (match_operand 1 "" ""))
11371    (use (match_operand 2 "" ""))]
11372   ""
11373 {
11374   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11375   DONE;
11376 })
11377
11378 (define_insn_and_split "*call_0_vzeroupper"
11379   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11380          (match_operand 1 "" ""))
11381    (unspec [(match_operand 2 "const_int_operand" "")]
11382            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11383   "TARGET_VZEROUPPER"
11384   "#"
11385   "&& reload_completed"
11386   [(const_int 0)]
11387   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11388   [(set_attr "type" "call")])
11389
11390 (define_insn "*call_0"
11391   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11392          (match_operand 1 "" ""))]
11393   ""
11394   { return ix86_output_call_insn (insn, operands[0], 0); }
11395   [(set_attr "type" "call")])
11396
11397 (define_insn_and_split "*call_1_vzeroupper"
11398   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11399          (match_operand 1 "" ""))
11400    (unspec [(match_operand 2 "const_int_operand" "")]
11401            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11402   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11403   "#"
11404   "&& reload_completed"
11405   [(const_int 0)]
11406   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11407   [(set_attr "type" "call")])
11408
11409 (define_insn "*call_1"
11410   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11411          (match_operand 1 "" ""))]
11412   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11413   { return ix86_output_call_insn (insn, operands[0], 0); }
11414   [(set_attr "type" "call")])
11415
11416 (define_insn_and_split "*sibcall_1_vzeroupper"
11417   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11418          (match_operand 1 "" ""))
11419    (unspec [(match_operand 2 "const_int_operand" "")]
11420            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11421   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11422   "#"
11423   "&& reload_completed"
11424   [(const_int 0)]
11425   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11426   [(set_attr "type" "call")])
11427
11428 (define_insn "*sibcall_1"
11429   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11430          (match_operand 1 "" ""))]
11431   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11432   { return ix86_output_call_insn (insn, operands[0], 0); }
11433   [(set_attr "type" "call")])
11434
11435 (define_insn_and_split "*call_1_rex64_vzeroupper"
11436   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11437          (match_operand 1 "" ""))
11438    (unspec [(match_operand 2 "const_int_operand" "")]
11439            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11440   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11441    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11442   "#"
11443   "&& reload_completed"
11444   [(const_int 0)]
11445   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11446   [(set_attr "type" "call")])
11447
11448 (define_insn "*call_1_rex64"
11449   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11450          (match_operand 1 "" ""))]
11451   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11452    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11453   { return ix86_output_call_insn (insn, operands[0], 0); }
11454   [(set_attr "type" "call")])
11455
11456 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11457   [(parallel
11458     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11459            (match_operand 1 "" ""))
11460      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11461      (clobber (reg:TI XMM6_REG))
11462      (clobber (reg:TI XMM7_REG))
11463      (clobber (reg:TI XMM8_REG))
11464      (clobber (reg:TI XMM9_REG))
11465      (clobber (reg:TI XMM10_REG))
11466      (clobber (reg:TI XMM11_REG))
11467      (clobber (reg:TI XMM12_REG))
11468      (clobber (reg:TI XMM13_REG))
11469      (clobber (reg:TI XMM14_REG))
11470      (clobber (reg:TI XMM15_REG))
11471      (clobber (reg:DI SI_REG))
11472      (clobber (reg:DI DI_REG))])
11473    (unspec [(match_operand 2 "const_int_operand" "")]
11474            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11475   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11476   "#"
11477   "&& reload_completed"
11478   [(const_int 0)]
11479   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11480   [(set_attr "type" "call")])
11481
11482 (define_insn "*call_1_rex64_ms_sysv"
11483   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11484          (match_operand 1 "" ""))
11485    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11486    (clobber (reg:TI XMM6_REG))
11487    (clobber (reg:TI XMM7_REG))
11488    (clobber (reg:TI XMM8_REG))
11489    (clobber (reg:TI XMM9_REG))
11490    (clobber (reg:TI XMM10_REG))
11491    (clobber (reg:TI XMM11_REG))
11492    (clobber (reg:TI XMM12_REG))
11493    (clobber (reg:TI XMM13_REG))
11494    (clobber (reg:TI XMM14_REG))
11495    (clobber (reg:TI XMM15_REG))
11496    (clobber (reg:DI SI_REG))
11497    (clobber (reg:DI DI_REG))]
11498   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11499   { return ix86_output_call_insn (insn, operands[0], 0); }
11500   [(set_attr "type" "call")])
11501
11502 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11503   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11504          (match_operand 1 "" ""))
11505    (unspec [(match_operand 2 "const_int_operand" "")]
11506            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11507   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11508   "#"
11509   "&& reload_completed"
11510   [(const_int 0)]
11511   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11512   [(set_attr "type" "call")])
11513
11514 (define_insn "*call_1_rex64_large"
11515   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11516          (match_operand 1 "" ""))]
11517   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11518   { return ix86_output_call_insn (insn, operands[0], 0); }
11519   [(set_attr "type" "call")])
11520
11521 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11522   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11523          (match_operand 1 "" ""))
11524    (unspec [(match_operand 2 "const_int_operand" "")]
11525            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11526   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11527   "#"
11528   "&& reload_completed"
11529   [(const_int 0)]
11530   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11531   [(set_attr "type" "call")])
11532
11533 (define_insn "*sibcall_1_rex64"
11534   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11535          (match_operand 1 "" ""))]
11536   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11537   { return ix86_output_call_insn (insn, operands[0], 0); }
11538   [(set_attr "type" "call")])
11539
11540 ;; Call subroutine, returning value in operand 0
11541 (define_expand "call_value_pop"
11542   [(parallel [(set (match_operand 0 "" "")
11543                    (call (match_operand:QI 1 "" "")
11544                          (match_operand:SI 2 "" "")))
11545               (set (reg:SI SP_REG)
11546                    (plus:SI (reg:SI SP_REG)
11547                             (match_operand:SI 4 "" "")))])]
11548   "!TARGET_64BIT"
11549 {
11550   ix86_expand_call (operands[0], operands[1], operands[2],
11551                     operands[3], operands[4], 0);
11552   DONE;
11553 })
11554
11555 (define_expand "call_value"
11556   [(set (match_operand 0 "" "")
11557         (call (match_operand:QI 1 "" "")
11558               (match_operand:SI 2 "" "")))
11559    (use (match_operand:SI 3 "" ""))]
11560   ;; Operand 3 is not used on the i386.
11561   ""
11562 {
11563   ix86_expand_call (operands[0], operands[1], operands[2],
11564                     operands[3], NULL, 0);
11565   DONE;
11566 })
11567
11568 (define_expand "sibcall_value"
11569   [(set (match_operand 0 "" "")
11570         (call (match_operand:QI 1 "" "")
11571               (match_operand:SI 2 "" "")))
11572    (use (match_operand:SI 3 "" ""))]
11573   ;; Operand 3 is not used on the i386.
11574   ""
11575 {
11576   ix86_expand_call (operands[0], operands[1], operands[2],
11577                     operands[3], NULL, 1);
11578   DONE;
11579 })
11580
11581 ;; Call subroutine returning any type.
11582
11583 (define_expand "untyped_call"
11584   [(parallel [(call (match_operand 0 "" "")
11585                     (const_int 0))
11586               (match_operand 1 "" "")
11587               (match_operand 2 "" "")])]
11588   ""
11589 {
11590   int i;
11591
11592   /* In order to give reg-stack an easier job in validating two
11593      coprocessor registers as containing a possible return value,
11594      simply pretend the untyped call returns a complex long double
11595      value. 
11596
11597      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11598      and should have the default ABI.  */
11599
11600   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11601                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11602                     operands[0], const0_rtx,
11603                     GEN_INT ((TARGET_64BIT
11604                               ? (ix86_abi == SYSV_ABI
11605                                  ? X86_64_SSE_REGPARM_MAX
11606                                  : X86_64_MS_SSE_REGPARM_MAX)
11607                               : X86_32_SSE_REGPARM_MAX)
11608                              - 1),
11609                     NULL, 0);
11610
11611   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11612     {
11613       rtx set = XVECEXP (operands[2], 0, i);
11614       emit_move_insn (SET_DEST (set), SET_SRC (set));
11615     }
11616
11617   /* The optimizer does not know that the call sets the function value
11618      registers we stored in the result block.  We avoid problems by
11619      claiming that all hard registers are used and clobbered at this
11620      point.  */
11621   emit_insn (gen_blockage ());
11622
11623   DONE;
11624 })
11625 \f
11626 ;; Prologue and epilogue instructions
11627
11628 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11629 ;; all of memory.  This blocks insns from being moved across this point.
11630
11631 (define_insn "blockage"
11632   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11633   ""
11634   ""
11635   [(set_attr "length" "0")])
11636
11637 ;; Do not schedule instructions accessing memory across this point.
11638
11639 (define_expand "memory_blockage"
11640   [(set (match_dup 0)
11641         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11642   ""
11643 {
11644   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11645   MEM_VOLATILE_P (operands[0]) = 1;
11646 })
11647
11648 (define_insn "*memory_blockage"
11649   [(set (match_operand:BLK 0 "" "")
11650         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11651   ""
11652   ""
11653   [(set_attr "length" "0")])
11654
11655 ;; As USE insns aren't meaningful after reload, this is used instead
11656 ;; to prevent deleting instructions setting registers for PIC code
11657 (define_insn "prologue_use"
11658   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11659   ""
11660   ""
11661   [(set_attr "length" "0")])
11662
11663 ;; Insn emitted into the body of a function to return from a function.
11664 ;; This is only done if the function's epilogue is known to be simple.
11665 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11666
11667 (define_expand "return"
11668   [(return)]
11669   "ix86_can_use_return_insn_p ()"
11670 {
11671   if (crtl->args.pops_args)
11672     {
11673       rtx popc = GEN_INT (crtl->args.pops_args);
11674       emit_jump_insn (gen_return_pop_internal (popc));
11675       DONE;
11676     }
11677 })
11678
11679 (define_insn "return_internal"
11680   [(return)]
11681   "reload_completed"
11682   "ret"
11683   [(set_attr "length" "1")
11684    (set_attr "atom_unit" "jeu")
11685    (set_attr "length_immediate" "0")
11686    (set_attr "modrm" "0")])
11687
11688 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11689 ;; instruction Athlon and K8 have.
11690
11691 (define_insn "return_internal_long"
11692   [(return)
11693    (unspec [(const_int 0)] UNSPEC_REP)]
11694   "reload_completed"
11695   "rep\;ret"
11696   [(set_attr "length" "2")
11697    (set_attr "atom_unit" "jeu")
11698    (set_attr "length_immediate" "0")
11699    (set_attr "prefix_rep" "1")
11700    (set_attr "modrm" "0")])
11701
11702 (define_insn "return_pop_internal"
11703   [(return)
11704    (use (match_operand:SI 0 "const_int_operand" ""))]
11705   "reload_completed"
11706   "ret\t%0"
11707   [(set_attr "length" "3")
11708    (set_attr "atom_unit" "jeu")
11709    (set_attr "length_immediate" "2")
11710    (set_attr "modrm" "0")])
11711
11712 (define_insn "return_indirect_internal"
11713   [(return)
11714    (use (match_operand:SI 0 "register_operand" "r"))]
11715   "reload_completed"
11716   "jmp\t%A0"
11717   [(set_attr "type" "ibr")
11718    (set_attr "length_immediate" "0")])
11719
11720 (define_insn "nop"
11721   [(const_int 0)]
11722   ""
11723   "nop"
11724   [(set_attr "length" "1")
11725    (set_attr "length_immediate" "0")
11726    (set_attr "modrm" "0")])
11727
11728 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11729 (define_insn "nops"
11730   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11731                     UNSPECV_NOPS)]
11732   "reload_completed"
11733 {
11734   int num = INTVAL (operands[0]);
11735
11736   gcc_assert (num >= 1 && num <= 8);
11737
11738   while (num--)
11739     fputs ("\tnop\n", asm_out_file);
11740
11741   return "";
11742 }
11743   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11744    (set_attr "length_immediate" "0")
11745    (set_attr "modrm" "0")])
11746
11747 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11748 ;; branch prediction penalty for the third jump in a 16-byte
11749 ;; block on K8.
11750
11751 (define_insn "pad"
11752   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11753   ""
11754 {
11755 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11756   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11757 #else
11758   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11759      The align insn is used to avoid 3 jump instructions in the row to improve
11760      branch prediction and the benefits hardly outweigh the cost of extra 8
11761      nops on the average inserted by full alignment pseudo operation.  */
11762 #endif
11763   return "";
11764 }
11765   [(set_attr "length" "16")])
11766
11767 (define_expand "prologue"
11768   [(const_int 0)]
11769   ""
11770   "ix86_expand_prologue (); DONE;")
11771
11772 (define_insn "set_got"
11773   [(set (match_operand:SI 0 "register_operand" "=r")
11774         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11775    (clobber (reg:CC FLAGS_REG))]
11776   "!TARGET_64BIT"
11777   "* return output_set_got (operands[0], NULL_RTX);"
11778   [(set_attr "type" "multi")
11779    (set_attr "length" "12")])
11780
11781 (define_insn "set_got_labelled"
11782   [(set (match_operand:SI 0 "register_operand" "=r")
11783         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11784          UNSPEC_SET_GOT))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "!TARGET_64BIT"
11787   "* return output_set_got (operands[0], operands[1]);"
11788   [(set_attr "type" "multi")
11789    (set_attr "length" "12")])
11790
11791 (define_insn "set_got_rex64"
11792   [(set (match_operand:DI 0 "register_operand" "=r")
11793         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11794   "TARGET_64BIT"
11795   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11796   [(set_attr "type" "lea")
11797    (set_attr "length_address" "4")
11798    (set_attr "mode" "DI")])
11799
11800 (define_insn "set_rip_rex64"
11801   [(set (match_operand:DI 0 "register_operand" "=r")
11802         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11803   "TARGET_64BIT"
11804   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11805   [(set_attr "type" "lea")
11806    (set_attr "length_address" "4")
11807    (set_attr "mode" "DI")])
11808
11809 (define_insn "set_got_offset_rex64"
11810   [(set (match_operand:DI 0 "register_operand" "=r")
11811         (unspec:DI
11812           [(label_ref (match_operand 1 "" ""))]
11813           UNSPEC_SET_GOT_OFFSET))]
11814   "TARGET_64BIT"
11815   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11816   [(set_attr "type" "imov")
11817    (set_attr "length_immediate" "0")
11818    (set_attr "length_address" "8")
11819    (set_attr "mode" "DI")])
11820
11821 (define_expand "epilogue"
11822   [(const_int 0)]
11823   ""
11824   "ix86_expand_epilogue (1); DONE;")
11825
11826 (define_expand "sibcall_epilogue"
11827   [(const_int 0)]
11828   ""
11829   "ix86_expand_epilogue (0); DONE;")
11830
11831 (define_expand "eh_return"
11832   [(use (match_operand 0 "register_operand" ""))]
11833   ""
11834 {
11835   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11836
11837   /* Tricky bit: we write the address of the handler to which we will
11838      be returning into someone else's stack frame, one word below the
11839      stack address we wish to restore.  */
11840   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11841   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11842   tmp = gen_rtx_MEM (Pmode, tmp);
11843   emit_move_insn (tmp, ra);
11844
11845   emit_jump_insn (gen_eh_return_internal ());
11846   emit_barrier ();
11847   DONE;
11848 })
11849
11850 (define_insn_and_split "eh_return_internal"
11851   [(eh_return)]
11852   ""
11853   "#"
11854   "epilogue_completed"
11855   [(const_int 0)]
11856   "ix86_expand_epilogue (2); DONE;")
11857
11858 (define_insn "leave"
11859   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11860    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11861    (clobber (mem:BLK (scratch)))]
11862   "!TARGET_64BIT"
11863   "leave"
11864   [(set_attr "type" "leave")])
11865
11866 (define_insn "leave_rex64"
11867   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11868    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11869    (clobber (mem:BLK (scratch)))]
11870   "TARGET_64BIT"
11871   "leave"
11872   [(set_attr "type" "leave")])
11873 \f
11874 ;; Handle -fsplit-stack.
11875
11876 (define_expand "split_stack_prologue"
11877   [(const_int 0)]
11878   ""
11879 {
11880   ix86_expand_split_stack_prologue ();
11881   DONE;
11882 })
11883
11884 ;; In order to support the call/return predictor, we use a return
11885 ;; instruction which the middle-end doesn't see.
11886 (define_insn "split_stack_return"
11887   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11888                      UNSPECV_SPLIT_STACK_RETURN)]
11889   ""
11890 {
11891   if (operands[0] == const0_rtx)
11892     return "ret";
11893   else
11894     return "ret\t%0";
11895 }
11896   [(set_attr "atom_unit" "jeu")
11897    (set_attr "modrm" "0")
11898    (set (attr "length")
11899         (if_then_else (match_operand:SI 0 "const0_operand" "")
11900                       (const_int 1)
11901                       (const_int 3)))
11902    (set (attr "length_immediate")
11903         (if_then_else (match_operand:SI 0 "const0_operand" "")
11904                       (const_int 0)
11905                       (const_int 2)))])
11906
11907 ;; If there are operand 0 bytes available on the stack, jump to
11908 ;; operand 1.
11909
11910 (define_expand "split_stack_space_check"
11911   [(set (pc) (if_then_else
11912               (ltu (minus (reg SP_REG)
11913                           (match_operand 0 "register_operand" ""))
11914                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11915               (label_ref (match_operand 1 "" ""))
11916               (pc)))]
11917   ""
11918 {
11919   rtx reg, size, limit;
11920
11921   reg = gen_reg_rtx (Pmode);
11922   size = force_reg (Pmode, operands[0]);
11923   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11924   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11925                           UNSPEC_STACK_CHECK);
11926   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11927   ix86_expand_branch (GEU, reg, limit, operands[1]);
11928
11929   DONE;
11930 })
11931 \f
11932 ;; Bit manipulation instructions.
11933
11934 (define_expand "ffs<mode>2"
11935   [(set (match_dup 2) (const_int -1))
11936    (parallel [(set (reg:CCZ FLAGS_REG)
11937                    (compare:CCZ
11938                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11939                      (const_int 0)))
11940               (set (match_operand:SWI48 0 "register_operand" "")
11941                    (ctz:SWI48 (match_dup 1)))])
11942    (set (match_dup 0) (if_then_else:SWI48
11943                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11944                         (match_dup 2)
11945                         (match_dup 0)))
11946    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11947               (clobber (reg:CC FLAGS_REG))])]
11948   ""
11949 {
11950   if (<MODE>mode == SImode && !TARGET_CMOVE)
11951     {
11952       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11953       DONE;
11954     }
11955   operands[2] = gen_reg_rtx (<MODE>mode);
11956 })
11957
11958 (define_insn_and_split "ffssi2_no_cmove"
11959   [(set (match_operand:SI 0 "register_operand" "=r")
11960         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11961    (clobber (match_scratch:SI 2 "=&q"))
11962    (clobber (reg:CC FLAGS_REG))]
11963   "!TARGET_CMOVE"
11964   "#"
11965   "&& reload_completed"
11966   [(parallel [(set (reg:CCZ FLAGS_REG)
11967                    (compare:CCZ (match_dup 1) (const_int 0)))
11968               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11969    (set (strict_low_part (match_dup 3))
11970         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11971    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11972               (clobber (reg:CC FLAGS_REG))])
11973    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11974               (clobber (reg:CC FLAGS_REG))])
11975    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11976               (clobber (reg:CC FLAGS_REG))])]
11977 {
11978   operands[3] = gen_lowpart (QImode, operands[2]);
11979   ix86_expand_clear (operands[2]);
11980 })
11981
11982 (define_insn "*ffs<mode>_1"
11983   [(set (reg:CCZ FLAGS_REG)
11984         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11985                      (const_int 0)))
11986    (set (match_operand:SWI48 0 "register_operand" "=r")
11987         (ctz:SWI48 (match_dup 1)))]
11988   ""
11989   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11990   [(set_attr "type" "alu1")
11991    (set_attr "prefix_0f" "1")
11992    (set_attr "mode" "<MODE>")])
11993
11994 (define_insn "ctz<mode>2"
11995   [(set (match_operand:SWI248 0 "register_operand" "=r")
11996         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11997    (clobber (reg:CC FLAGS_REG))]
11998   ""
11999 {
12000   if (TARGET_BMI)
12001     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12002   else
12003     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12004 }
12005   [(set_attr "type" "alu1")
12006    (set_attr "prefix_0f" "1")
12007    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12008    (set_attr "mode" "<MODE>")])
12009
12010 (define_expand "clz<mode>2"
12011   [(parallel
12012      [(set (match_operand:SWI248 0 "register_operand" "")
12013            (minus:SWI248
12014              (match_dup 2)
12015              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12016       (clobber (reg:CC FLAGS_REG))])
12017    (parallel
12018      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12019       (clobber (reg:CC FLAGS_REG))])]
12020   ""
12021 {
12022   if (TARGET_ABM)
12023     {
12024       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12025       DONE;
12026     }
12027   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12028 })
12029
12030 (define_insn "clz<mode>2_abm"
12031   [(set (match_operand:SWI248 0 "register_operand" "=r")
12032         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12033    (clobber (reg:CC FLAGS_REG))]
12034   "TARGET_ABM || TARGET_BMI"
12035   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12036   [(set_attr "prefix_rep" "1")
12037    (set_attr "type" "bitmanip")
12038    (set_attr "mode" "<MODE>")])
12039
12040 ;; BMI instructions.
12041 (define_insn "*bmi_andn_<mode>"
12042   [(set (match_operand:SWI48 0 "register_operand" "=r")
12043         (and:SWI48
12044           (not:SWI48
12045             (match_operand:SWI48 1 "register_operand" "r"))
12046             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12047    (clobber (reg:CC FLAGS_REG))]
12048   "TARGET_BMI"
12049   "andn\t{%2, %1, %0|%0, %1, %2}"
12050   [(set_attr "type" "bitmanip")
12051    (set_attr "mode" "<MODE>")])
12052
12053 (define_insn "bmi_bextr_<mode>"
12054   [(set (match_operand:SWI48 0 "register_operand" "=r")
12055         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12056                        (match_operand:SWI48 2 "register_operand" "r")]
12057                        UNSPEC_BEXTR))
12058    (clobber (reg:CC FLAGS_REG))]
12059   "TARGET_BMI"
12060   "bextr\t{%2, %1, %0|%0, %1, %2}"
12061   [(set_attr "type" "bitmanip")
12062    (set_attr "mode" "<MODE>")])
12063
12064 (define_insn "*bmi_blsi_<mode>"
12065   [(set (match_operand:SWI48 0 "register_operand" "=r")
12066         (and:SWI48
12067           (neg:SWI48
12068             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12069           (match_dup 1)))
12070    (clobber (reg:CC FLAGS_REG))]
12071   "TARGET_BMI"
12072   "blsi\t{%1, %0|%0, %1}"
12073   [(set_attr "type" "bitmanip")
12074    (set_attr "mode" "<MODE>")])
12075
12076 (define_insn "*bmi_blsmsk_<mode>"
12077   [(set (match_operand:SWI48 0 "register_operand" "=r")
12078         (xor:SWI48
12079           (plus:SWI48
12080             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12081             (const_int -1))
12082           (match_dup 1)))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "TARGET_BMI"
12085   "blsmsk\t{%1, %0|%0, %1}"
12086   [(set_attr "type" "bitmanip")
12087    (set_attr "mode" "<MODE>")])
12088
12089 (define_insn "*bmi_blsr_<mode>"
12090   [(set (match_operand:SWI48 0 "register_operand" "=r")
12091         (and:SWI48
12092           (plus:SWI48
12093             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12094             (const_int -1))
12095           (match_dup 1)))
12096    (clobber (reg:CC FLAGS_REG))]
12097    "TARGET_BMI"
12098    "blsr\t{%1, %0|%0, %1}"
12099   [(set_attr "type" "bitmanip")
12100    (set_attr "mode" "<MODE>")])
12101
12102 ;; TBM instructions.
12103 (define_insn "tbm_bextri_<mode>"
12104   [(set (match_operand:SWI48 0 "register_operand" "=r")
12105         (zero_extract:SWI48
12106           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12107           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12108           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12109    (clobber (reg:CC FLAGS_REG))]
12110    "TARGET_TBM"
12111 {
12112   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12113   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12114 }
12115   [(set_attr "type" "bitmanip")
12116    (set_attr "mode" "<MODE>")])
12117
12118 (define_insn "*tbm_blcfill_<mode>"
12119   [(set (match_operand:SWI48 0 "register_operand" "=r")
12120         (and:SWI48
12121           (plus:SWI48
12122             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12123             (const_int 1))
12124           (match_dup 1)))
12125    (clobber (reg:CC FLAGS_REG))]
12126    "TARGET_TBM"
12127    "blcfill\t{%1, %0|%0, %1}"
12128   [(set_attr "type" "bitmanip")
12129    (set_attr "mode" "<MODE>")])
12130
12131 (define_insn "*tbm_blci_<mode>"
12132   [(set (match_operand:SWI48 0 "register_operand" "=r")
12133         (ior:SWI48
12134           (not:SWI48
12135             (plus:SWI48
12136               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12137               (const_int 1)))
12138           (match_dup 1)))
12139    (clobber (reg:CC FLAGS_REG))]
12140    "TARGET_TBM"
12141    "blci\t{%1, %0|%0, %1}"
12142   [(set_attr "type" "bitmanip")
12143    (set_attr "mode" "<MODE>")])
12144
12145 (define_insn "*tbm_blcic_<mode>"
12146   [(set (match_operand:SWI48 0 "register_operand" "=r")
12147         (and:SWI48
12148           (plus:SWI48
12149             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12150             (const_int 1))
12151           (not:SWI48
12152             (match_dup 1))))
12153    (clobber (reg:CC FLAGS_REG))]
12154    "TARGET_TBM"
12155    "blcic\t{%1, %0|%0, %1}"
12156   [(set_attr "type" "bitmanip")
12157    (set_attr "mode" "<MODE>")])
12158
12159 (define_insn "*tbm_blcmsk_<mode>"
12160   [(set (match_operand:SWI48 0 "register_operand" "=r")
12161         (xor:SWI48
12162           (plus:SWI48
12163             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12164             (const_int 1))
12165           (match_dup 1)))
12166    (clobber (reg:CC FLAGS_REG))]
12167    "TARGET_TBM"
12168    "blcmsk\t{%1, %0|%0, %1}"
12169   [(set_attr "type" "bitmanip")
12170    (set_attr "mode" "<MODE>")])
12171
12172 (define_insn "*tbm_blcs_<mode>"
12173   [(set (match_operand:SWI48 0 "register_operand" "=r")
12174         (ior:SWI48
12175           (plus:SWI48
12176             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12177             (const_int 1))
12178           (match_dup 1)))
12179    (clobber (reg:CC FLAGS_REG))]
12180    "TARGET_TBM"
12181    "blcs\t{%1, %0|%0, %1}"
12182   [(set_attr "type" "bitmanip")
12183    (set_attr "mode" "<MODE>")])
12184
12185 (define_insn "*tbm_blsfill_<mode>"
12186   [(set (match_operand:SWI48 0 "register_operand" "=r")
12187         (ior:SWI48
12188           (plus:SWI48
12189             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12190             (const_int -1))
12191           (match_dup 1)))
12192    (clobber (reg:CC FLAGS_REG))]
12193    "TARGET_TBM"
12194    "blsfill\t{%1, %0|%0, %1}"
12195   [(set_attr "type" "bitmanip")
12196    (set_attr "mode" "<MODE>")])
12197
12198 (define_insn "*tbm_blsic_<mode>"
12199   [(set (match_operand:SWI48 0 "register_operand" "=r")
12200         (ior:SWI48
12201           (plus:SWI48
12202             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12203             (const_int -1))
12204           (not:SWI48
12205             (match_dup 1))))
12206    (clobber (reg:CC FLAGS_REG))]
12207    "TARGET_TBM"
12208    "blsic\t{%1, %0|%0, %1}"
12209   [(set_attr "type" "bitmanip")
12210    (set_attr "mode" "<MODE>")])
12211
12212 (define_insn "*tbm_t1mskc_<mode>"
12213   [(set (match_operand:SWI48 0 "register_operand" "=r")
12214         (ior:SWI48
12215           (plus:SWI48
12216             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12217             (const_int 1))
12218           (not:SWI48
12219             (match_dup 1))))
12220    (clobber (reg:CC FLAGS_REG))]
12221    "TARGET_TBM"
12222    "t1mskc\t{%1, %0|%0, %1}"
12223   [(set_attr "type" "bitmanip")
12224    (set_attr "mode" "<MODE>")])
12225
12226 (define_insn "*tbm_tzmsk_<mode>"
12227   [(set (match_operand:SWI48 0 "register_operand" "=r")
12228         (and:SWI48
12229           (plus:SWI48
12230             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12231             (const_int -1))
12232           (not:SWI48
12233             (match_dup 1))))
12234    (clobber (reg:CC FLAGS_REG))]
12235    "TARGET_TBM"
12236    "tzmsk\t{%1, %0|%0, %1}"
12237   [(set_attr "type" "bitmanip")
12238    (set_attr "mode" "<MODE>")])
12239
12240 (define_insn "bsr_rex64"
12241   [(set (match_operand:DI 0 "register_operand" "=r")
12242         (minus:DI (const_int 63)
12243                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12244    (clobber (reg:CC FLAGS_REG))]
12245   "TARGET_64BIT"
12246   "bsr{q}\t{%1, %0|%0, %1}"
12247   [(set_attr "type" "alu1")
12248    (set_attr "prefix_0f" "1")
12249    (set_attr "mode" "DI")])
12250
12251 (define_insn "bsr"
12252   [(set (match_operand:SI 0 "register_operand" "=r")
12253         (minus:SI (const_int 31)
12254                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12255    (clobber (reg:CC FLAGS_REG))]
12256   ""
12257   "bsr{l}\t{%1, %0|%0, %1}"
12258   [(set_attr "type" "alu1")
12259    (set_attr "prefix_0f" "1")
12260    (set_attr "mode" "SI")])
12261
12262 (define_insn "*bsrhi"
12263   [(set (match_operand:HI 0 "register_operand" "=r")
12264         (minus:HI (const_int 15)
12265                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12266    (clobber (reg:CC FLAGS_REG))]
12267   ""
12268   "bsr{w}\t{%1, %0|%0, %1}"
12269   [(set_attr "type" "alu1")
12270    (set_attr "prefix_0f" "1")
12271    (set_attr "mode" "HI")])
12272
12273 (define_insn "popcount<mode>2"
12274   [(set (match_operand:SWI248 0 "register_operand" "=r")
12275         (popcount:SWI248
12276           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12277    (clobber (reg:CC FLAGS_REG))]
12278   "TARGET_POPCNT"
12279 {
12280 #if TARGET_MACHO
12281   return "popcnt\t{%1, %0|%0, %1}";
12282 #else
12283   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12284 #endif
12285 }
12286   [(set_attr "prefix_rep" "1")
12287    (set_attr "type" "bitmanip")
12288    (set_attr "mode" "<MODE>")])
12289
12290 (define_insn "*popcount<mode>2_cmp"
12291   [(set (reg FLAGS_REG)
12292         (compare
12293           (popcount:SWI248
12294             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12295           (const_int 0)))
12296    (set (match_operand:SWI248 0 "register_operand" "=r")
12297         (popcount:SWI248 (match_dup 1)))]
12298   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12299 {
12300 #if TARGET_MACHO
12301   return "popcnt\t{%1, %0|%0, %1}";
12302 #else
12303   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12304 #endif
12305 }
12306   [(set_attr "prefix_rep" "1")
12307    (set_attr "type" "bitmanip")
12308    (set_attr "mode" "<MODE>")])
12309
12310 (define_insn "*popcountsi2_cmp_zext"
12311   [(set (reg FLAGS_REG)
12312         (compare
12313           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12314           (const_int 0)))
12315    (set (match_operand:DI 0 "register_operand" "=r")
12316         (zero_extend:DI(popcount:SI (match_dup 1))))]
12317   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12318 {
12319 #if TARGET_MACHO
12320   return "popcnt\t{%1, %0|%0, %1}";
12321 #else
12322   return "popcnt{l}\t{%1, %0|%0, %1}";
12323 #endif
12324 }
12325   [(set_attr "prefix_rep" "1")
12326    (set_attr "type" "bitmanip")
12327    (set_attr "mode" "SI")])
12328
12329 (define_expand "bswap<mode>2"
12330   [(set (match_operand:SWI48 0 "register_operand" "")
12331         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12332   ""
12333 {
12334   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12335     {
12336       rtx x = operands[0];
12337
12338       emit_move_insn (x, operands[1]);
12339       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12340       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12341       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12342       DONE;
12343     }
12344 })
12345
12346 (define_insn "*bswap<mode>2_movbe"
12347   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12348         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12349   "TARGET_MOVBE
12350    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12351   "@
12352     bswap\t%0
12353     movbe\t{%1, %0|%0, %1}
12354     movbe\t{%1, %0|%0, %1}"
12355   [(set_attr "type" "bitmanip,imov,imov")
12356    (set_attr "modrm" "0,1,1")
12357    (set_attr "prefix_0f" "*,1,1")
12358    (set_attr "prefix_extra" "*,1,1")
12359    (set_attr "mode" "<MODE>")])
12360
12361 (define_insn "*bswap<mode>2_1"
12362   [(set (match_operand:SWI48 0 "register_operand" "=r")
12363         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12364   "TARGET_BSWAP"
12365   "bswap\t%0"
12366   [(set_attr "type" "bitmanip")
12367    (set_attr "modrm" "0")
12368    (set_attr "mode" "<MODE>")])
12369
12370 (define_insn "*bswaphi_lowpart_1"
12371   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12372         (bswap:HI (match_dup 0)))
12373    (clobber (reg:CC FLAGS_REG))]
12374   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12375   "@
12376     xchg{b}\t{%h0, %b0|%b0, %h0}
12377     rol{w}\t{$8, %0|%0, 8}"
12378   [(set_attr "length" "2,4")
12379    (set_attr "mode" "QI,HI")])
12380
12381 (define_insn "bswaphi_lowpart"
12382   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12383         (bswap:HI (match_dup 0)))
12384    (clobber (reg:CC FLAGS_REG))]
12385   ""
12386   "rol{w}\t{$8, %0|%0, 8}"
12387   [(set_attr "length" "4")
12388    (set_attr "mode" "HI")])
12389
12390 (define_expand "paritydi2"
12391   [(set (match_operand:DI 0 "register_operand" "")
12392         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12393   "! TARGET_POPCNT"
12394 {
12395   rtx scratch = gen_reg_rtx (QImode);
12396   rtx cond;
12397
12398   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12399                                 NULL_RTX, operands[1]));
12400
12401   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12402                          gen_rtx_REG (CCmode, FLAGS_REG),
12403                          const0_rtx);
12404   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12405
12406   if (TARGET_64BIT)
12407     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12408   else
12409     {
12410       rtx tmp = gen_reg_rtx (SImode);
12411
12412       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12413       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12414     }
12415   DONE;
12416 })
12417
12418 (define_expand "paritysi2"
12419   [(set (match_operand:SI 0 "register_operand" "")
12420         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12421   "! TARGET_POPCNT"
12422 {
12423   rtx scratch = gen_reg_rtx (QImode);
12424   rtx cond;
12425
12426   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12427
12428   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12429                          gen_rtx_REG (CCmode, FLAGS_REG),
12430                          const0_rtx);
12431   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12432
12433   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12434   DONE;
12435 })
12436
12437 (define_insn_and_split "paritydi2_cmp"
12438   [(set (reg:CC FLAGS_REG)
12439         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12440                    UNSPEC_PARITY))
12441    (clobber (match_scratch:DI 0 "=r"))
12442    (clobber (match_scratch:SI 1 "=&r"))
12443    (clobber (match_scratch:HI 2 "=Q"))]
12444   "! TARGET_POPCNT"
12445   "#"
12446   "&& reload_completed"
12447   [(parallel
12448      [(set (match_dup 1)
12449            (xor:SI (match_dup 1) (match_dup 4)))
12450       (clobber (reg:CC FLAGS_REG))])
12451    (parallel
12452      [(set (reg:CC FLAGS_REG)
12453            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12454       (clobber (match_dup 1))
12455       (clobber (match_dup 2))])]
12456 {
12457   operands[4] = gen_lowpart (SImode, operands[3]);
12458
12459   if (TARGET_64BIT)
12460     {
12461       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12462       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12463     }
12464   else
12465     operands[1] = gen_highpart (SImode, operands[3]);
12466 })
12467
12468 (define_insn_and_split "paritysi2_cmp"
12469   [(set (reg:CC FLAGS_REG)
12470         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12471                    UNSPEC_PARITY))
12472    (clobber (match_scratch:SI 0 "=r"))
12473    (clobber (match_scratch:HI 1 "=&Q"))]
12474   "! TARGET_POPCNT"
12475   "#"
12476   "&& reload_completed"
12477   [(parallel
12478      [(set (match_dup 1)
12479            (xor:HI (match_dup 1) (match_dup 3)))
12480       (clobber (reg:CC FLAGS_REG))])
12481    (parallel
12482      [(set (reg:CC FLAGS_REG)
12483            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12484       (clobber (match_dup 1))])]
12485 {
12486   operands[3] = gen_lowpart (HImode, operands[2]);
12487
12488   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12489   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12490 })
12491
12492 (define_insn "*parityhi2_cmp"
12493   [(set (reg:CC FLAGS_REG)
12494         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12495                    UNSPEC_PARITY))
12496    (clobber (match_scratch:HI 0 "=Q"))]
12497   "! TARGET_POPCNT"
12498   "xor{b}\t{%h0, %b0|%b0, %h0}"
12499   [(set_attr "length" "2")
12500    (set_attr "mode" "HI")])
12501 \f
12502 ;; Thread-local storage patterns for ELF.
12503 ;;
12504 ;; Note that these code sequences must appear exactly as shown
12505 ;; in order to allow linker relaxation.
12506
12507 (define_insn "*tls_global_dynamic_32_gnu"
12508   [(set (match_operand:SI 0 "register_operand" "=a")
12509         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12510                     (match_operand:SI 2 "tls_symbolic_operand" "")
12511                     (match_operand:SI 3 "call_insn_operand" "")]
12512                     UNSPEC_TLS_GD))
12513    (clobber (match_scratch:SI 4 "=d"))
12514    (clobber (match_scratch:SI 5 "=c"))
12515    (clobber (reg:CC FLAGS_REG))]
12516   "!TARGET_64BIT && TARGET_GNU_TLS"
12517   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12518   [(set_attr "type" "multi")
12519    (set_attr "length" "12")])
12520
12521 (define_expand "tls_global_dynamic_32"
12522   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12523                    (unspec:SI
12524                     [(match_dup 2)
12525                      (match_operand:SI 1 "tls_symbolic_operand" "")
12526                      (match_dup 3)]
12527                     UNSPEC_TLS_GD))
12528               (clobber (match_scratch:SI 4 ""))
12529               (clobber (match_scratch:SI 5 ""))
12530               (clobber (reg:CC FLAGS_REG))])]
12531   ""
12532 {
12533   if (flag_pic)
12534     operands[2] = pic_offset_table_rtx;
12535   else
12536     {
12537       operands[2] = gen_reg_rtx (Pmode);
12538       emit_insn (gen_set_got (operands[2]));
12539     }
12540   if (TARGET_GNU2_TLS)
12541     {
12542        emit_insn (gen_tls_dynamic_gnu2_32
12543                   (operands[0], operands[1], operands[2]));
12544        DONE;
12545     }
12546   operands[3] = ix86_tls_get_addr ();
12547 })
12548
12549 (define_insn "*tls_global_dynamic_64"
12550   [(set (match_operand:DI 0 "register_operand" "=a")
12551         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12552                  (match_operand:DI 3 "" "")))
12553    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12554               UNSPEC_TLS_GD)]
12555   "TARGET_64BIT"
12556   { 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"; }
12557   [(set_attr "type" "multi")
12558    (set_attr "length" "16")])
12559
12560 (define_expand "tls_global_dynamic_64"
12561   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12562                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12563               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12564                          UNSPEC_TLS_GD)])]
12565   ""
12566 {
12567   if (TARGET_GNU2_TLS)
12568     {
12569        emit_insn (gen_tls_dynamic_gnu2_64
12570                   (operands[0], operands[1]));
12571        DONE;
12572     }
12573   operands[2] = ix86_tls_get_addr ();
12574 })
12575
12576 (define_insn "*tls_local_dynamic_base_32_gnu"
12577   [(set (match_operand:SI 0 "register_operand" "=a")
12578         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12579                     (match_operand:SI 2 "call_insn_operand" "")]
12580                    UNSPEC_TLS_LD_BASE))
12581    (clobber (match_scratch:SI 3 "=d"))
12582    (clobber (match_scratch:SI 4 "=c"))
12583    (clobber (reg:CC FLAGS_REG))]
12584   "!TARGET_64BIT && TARGET_GNU_TLS"
12585   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12586   [(set_attr "type" "multi")
12587    (set_attr "length" "11")])
12588
12589 (define_expand "tls_local_dynamic_base_32"
12590   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12591                    (unspec:SI [(match_dup 1) (match_dup 2)]
12592                               UNSPEC_TLS_LD_BASE))
12593               (clobber (match_scratch:SI 3 ""))
12594               (clobber (match_scratch:SI 4 ""))
12595               (clobber (reg:CC FLAGS_REG))])]
12596   ""
12597 {
12598   if (flag_pic)
12599     operands[1] = pic_offset_table_rtx;
12600   else
12601     {
12602       operands[1] = gen_reg_rtx (Pmode);
12603       emit_insn (gen_set_got (operands[1]));
12604     }
12605   if (TARGET_GNU2_TLS)
12606     {
12607        emit_insn (gen_tls_dynamic_gnu2_32
12608                   (operands[0], ix86_tls_module_base (), operands[1]));
12609        DONE;
12610     }
12611   operands[2] = ix86_tls_get_addr ();
12612 })
12613
12614 (define_insn "*tls_local_dynamic_base_64"
12615   [(set (match_operand:DI 0 "register_operand" "=a")
12616         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12617                  (match_operand:DI 2 "" "")))
12618    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12619   "TARGET_64BIT"
12620   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12621   [(set_attr "type" "multi")
12622    (set_attr "length" "12")])
12623
12624 (define_expand "tls_local_dynamic_base_64"
12625   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12626                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12627               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12628   ""
12629 {
12630   if (TARGET_GNU2_TLS)
12631     {
12632        emit_insn (gen_tls_dynamic_gnu2_64
12633                   (operands[0], ix86_tls_module_base ()));
12634        DONE;
12635     }
12636   operands[1] = ix86_tls_get_addr ();
12637 })
12638
12639 ;; Local dynamic of a single variable is a lose.  Show combine how
12640 ;; to convert that back to global dynamic.
12641
12642 (define_insn_and_split "*tls_local_dynamic_32_once"
12643   [(set (match_operand:SI 0 "register_operand" "=a")
12644         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12645                              (match_operand:SI 2 "call_insn_operand" "")]
12646                             UNSPEC_TLS_LD_BASE)
12647                  (const:SI (unspec:SI
12648                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12649                             UNSPEC_DTPOFF))))
12650    (clobber (match_scratch:SI 4 "=d"))
12651    (clobber (match_scratch:SI 5 "=c"))
12652    (clobber (reg:CC FLAGS_REG))]
12653   ""
12654   "#"
12655   ""
12656   [(parallel [(set (match_dup 0)
12657                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12658                               UNSPEC_TLS_GD))
12659               (clobber (match_dup 4))
12660               (clobber (match_dup 5))
12661               (clobber (reg:CC FLAGS_REG))])])
12662
12663 ;; Segment register for the thread base ptr load
12664 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12665
12666 ;; Load and add the thread base pointer from %gs:0.
12667 (define_insn "*load_tp_<mode>"
12668   [(set (match_operand:P 0 "register_operand" "=r")
12669         (unspec:P [(const_int 0)] UNSPEC_TP))]
12670   ""
12671   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12672   [(set_attr "type" "imov")
12673    (set_attr "modrm" "0")
12674    (set_attr "length" "7")
12675    (set_attr "memory" "load")
12676    (set_attr "imm_disp" "false")])
12677
12678 (define_insn "*add_tp_<mode>"
12679   [(set (match_operand:P 0 "register_operand" "=r")
12680         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12681                 (match_operand:P 1 "register_operand" "0")))
12682    (clobber (reg:CC FLAGS_REG))]
12683   ""
12684   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12685   [(set_attr "type" "alu")
12686    (set_attr "modrm" "0")
12687    (set_attr "length" "7")
12688    (set_attr "memory" "load")
12689    (set_attr "imm_disp" "false")])
12690
12691 ;; GNU2 TLS patterns can be split.
12692
12693 (define_expand "tls_dynamic_gnu2_32"
12694   [(set (match_dup 3)
12695         (plus:SI (match_operand:SI 2 "register_operand" "")
12696                  (const:SI
12697                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12698                              UNSPEC_TLSDESC))))
12699    (parallel
12700     [(set (match_operand:SI 0 "register_operand" "")
12701           (unspec:SI [(match_dup 1) (match_dup 3)
12702                       (match_dup 2) (reg:SI SP_REG)]
12703                       UNSPEC_TLSDESC))
12704      (clobber (reg:CC FLAGS_REG))])]
12705   "!TARGET_64BIT && TARGET_GNU2_TLS"
12706 {
12707   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12708   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12709 })
12710
12711 (define_insn "*tls_dynamic_lea_32"
12712   [(set (match_operand:SI 0 "register_operand" "=r")
12713         (plus:SI (match_operand:SI 1 "register_operand" "b")
12714                  (const:SI
12715                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12716                               UNSPEC_TLSDESC))))]
12717   "!TARGET_64BIT && TARGET_GNU2_TLS"
12718   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12719   [(set_attr "type" "lea")
12720    (set_attr "mode" "SI")
12721    (set_attr "length" "6")
12722    (set_attr "length_address" "4")])
12723
12724 (define_insn "*tls_dynamic_call_32"
12725   [(set (match_operand:SI 0 "register_operand" "=a")
12726         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12727                     (match_operand:SI 2 "register_operand" "0")
12728                     ;; we have to make sure %ebx still points to the GOT
12729                     (match_operand:SI 3 "register_operand" "b")
12730                     (reg:SI SP_REG)]
12731                    UNSPEC_TLSDESC))
12732    (clobber (reg:CC FLAGS_REG))]
12733   "!TARGET_64BIT && TARGET_GNU2_TLS"
12734   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12735   [(set_attr "type" "call")
12736    (set_attr "length" "2")
12737    (set_attr "length_address" "0")])
12738
12739 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12740   [(set (match_operand:SI 0 "register_operand" "=&a")
12741         (plus:SI
12742          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12743                      (match_operand:SI 4 "" "")
12744                      (match_operand:SI 2 "register_operand" "b")
12745                      (reg:SI SP_REG)]
12746                     UNSPEC_TLSDESC)
12747          (const:SI (unspec:SI
12748                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12749                     UNSPEC_DTPOFF))))
12750    (clobber (reg:CC FLAGS_REG))]
12751   "!TARGET_64BIT && TARGET_GNU2_TLS"
12752   "#"
12753   ""
12754   [(set (match_dup 0) (match_dup 5))]
12755 {
12756   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12757   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12758 })
12759
12760 (define_expand "tls_dynamic_gnu2_64"
12761   [(set (match_dup 2)
12762         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12763                    UNSPEC_TLSDESC))
12764    (parallel
12765     [(set (match_operand:DI 0 "register_operand" "")
12766           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12767                      UNSPEC_TLSDESC))
12768      (clobber (reg:CC FLAGS_REG))])]
12769   "TARGET_64BIT && TARGET_GNU2_TLS"
12770 {
12771   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12772   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12773 })
12774
12775 (define_insn "*tls_dynamic_lea_64"
12776   [(set (match_operand:DI 0 "register_operand" "=r")
12777         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12778                    UNSPEC_TLSDESC))]
12779   "TARGET_64BIT && TARGET_GNU2_TLS"
12780   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12781   [(set_attr "type" "lea")
12782    (set_attr "mode" "DI")
12783    (set_attr "length" "7")
12784    (set_attr "length_address" "4")])
12785
12786 (define_insn "*tls_dynamic_call_64"
12787   [(set (match_operand:DI 0 "register_operand" "=a")
12788         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12789                     (match_operand:DI 2 "register_operand" "0")
12790                     (reg:DI SP_REG)]
12791                    UNSPEC_TLSDESC))
12792    (clobber (reg:CC FLAGS_REG))]
12793   "TARGET_64BIT && TARGET_GNU2_TLS"
12794   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12795   [(set_attr "type" "call")
12796    (set_attr "length" "2")
12797    (set_attr "length_address" "0")])
12798
12799 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12800   [(set (match_operand:DI 0 "register_operand" "=&a")
12801         (plus:DI
12802          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12803                      (match_operand:DI 3 "" "")
12804                      (reg:DI SP_REG)]
12805                     UNSPEC_TLSDESC)
12806          (const:DI (unspec:DI
12807                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12808                     UNSPEC_DTPOFF))))
12809    (clobber (reg:CC FLAGS_REG))]
12810   "TARGET_64BIT && TARGET_GNU2_TLS"
12811   "#"
12812   ""
12813   [(set (match_dup 0) (match_dup 4))]
12814 {
12815   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12816   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12817 })
12818 \f
12819 ;; These patterns match the binary 387 instructions for addM3, subM3,
12820 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12821 ;; SFmode.  The first is the normal insn, the second the same insn but
12822 ;; with one operand a conversion, and the third the same insn but with
12823 ;; the other operand a conversion.  The conversion may be SFmode or
12824 ;; SImode if the target mode DFmode, but only SImode if the target mode
12825 ;; is SFmode.
12826
12827 ;; Gcc is slightly more smart about handling normal two address instructions
12828 ;; so use special patterns for add and mull.
12829
12830 (define_insn "*fop_<mode>_comm_mixed_avx"
12831   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12832         (match_operator:MODEF 3 "binary_fp_operator"
12833           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12834            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12835   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12836    && COMMUTATIVE_ARITH_P (operands[3])
12837    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12838   "* return output_387_binary_op (insn, operands);"
12839   [(set (attr "type")
12840         (if_then_else (eq_attr "alternative" "1")
12841            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12842               (const_string "ssemul")
12843               (const_string "sseadd"))
12844            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12845               (const_string "fmul")
12846               (const_string "fop"))))
12847    (set_attr "prefix" "orig,maybe_vex")
12848    (set_attr "mode" "<MODE>")])
12849
12850 (define_insn "*fop_<mode>_comm_mixed"
12851   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12852         (match_operator:MODEF 3 "binary_fp_operator"
12853           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12854            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12855   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12856    && COMMUTATIVE_ARITH_P (operands[3])
12857    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12858   "* return output_387_binary_op (insn, operands);"
12859   [(set (attr "type")
12860         (if_then_else (eq_attr "alternative" "1")
12861            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12862               (const_string "ssemul")
12863               (const_string "sseadd"))
12864            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12865               (const_string "fmul")
12866               (const_string "fop"))))
12867    (set_attr "mode" "<MODE>")])
12868
12869 (define_insn "*fop_<mode>_comm_avx"
12870   [(set (match_operand:MODEF 0 "register_operand" "=x")
12871         (match_operator:MODEF 3 "binary_fp_operator"
12872           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12873            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12874   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12875    && COMMUTATIVE_ARITH_P (operands[3])
12876    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12877   "* return output_387_binary_op (insn, operands);"
12878   [(set (attr "type")
12879         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12880            (const_string "ssemul")
12881            (const_string "sseadd")))
12882    (set_attr "prefix" "vex")
12883    (set_attr "mode" "<MODE>")])
12884
12885 (define_insn "*fop_<mode>_comm_sse"
12886   [(set (match_operand:MODEF 0 "register_operand" "=x")
12887         (match_operator:MODEF 3 "binary_fp_operator"
12888           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12889            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12890   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12891    && COMMUTATIVE_ARITH_P (operands[3])
12892    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12893   "* return output_387_binary_op (insn, operands);"
12894   [(set (attr "type")
12895         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12896            (const_string "ssemul")
12897            (const_string "sseadd")))
12898    (set_attr "mode" "<MODE>")])
12899
12900 (define_insn "*fop_<mode>_comm_i387"
12901   [(set (match_operand:MODEF 0 "register_operand" "=f")
12902         (match_operator:MODEF 3 "binary_fp_operator"
12903           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12904            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12905   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12906    && COMMUTATIVE_ARITH_P (operands[3])
12907    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12908   "* return output_387_binary_op (insn, operands);"
12909   [(set (attr "type")
12910         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12911            (const_string "fmul")
12912            (const_string "fop")))
12913    (set_attr "mode" "<MODE>")])
12914
12915 (define_insn "*fop_<mode>_1_mixed_avx"
12916   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12917         (match_operator:MODEF 3 "binary_fp_operator"
12918           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12919            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12920   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12921    && !COMMUTATIVE_ARITH_P (operands[3])
12922    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12923   "* return output_387_binary_op (insn, operands);"
12924   [(set (attr "type")
12925         (cond [(and (eq_attr "alternative" "2")
12926                     (match_operand:MODEF 3 "mult_operator" ""))
12927                  (const_string "ssemul")
12928                (and (eq_attr "alternative" "2")
12929                     (match_operand:MODEF 3 "div_operator" ""))
12930                  (const_string "ssediv")
12931                (eq_attr "alternative" "2")
12932                  (const_string "sseadd")
12933                (match_operand:MODEF 3 "mult_operator" "")
12934                  (const_string "fmul")
12935                (match_operand:MODEF 3 "div_operator" "")
12936                  (const_string "fdiv")
12937               ]
12938               (const_string "fop")))
12939    (set_attr "prefix" "orig,orig,maybe_vex")
12940    (set_attr "mode" "<MODE>")])
12941
12942 (define_insn "*fop_<mode>_1_mixed"
12943   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12944         (match_operator:MODEF 3 "binary_fp_operator"
12945           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12946            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12947   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12948    && !COMMUTATIVE_ARITH_P (operands[3])
12949    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12950   "* return output_387_binary_op (insn, operands);"
12951   [(set (attr "type")
12952         (cond [(and (eq_attr "alternative" "2")
12953                     (match_operand:MODEF 3 "mult_operator" ""))
12954                  (const_string "ssemul")
12955                (and (eq_attr "alternative" "2")
12956                     (match_operand:MODEF 3 "div_operator" ""))
12957                  (const_string "ssediv")
12958                (eq_attr "alternative" "2")
12959                  (const_string "sseadd")
12960                (match_operand:MODEF 3 "mult_operator" "")
12961                  (const_string "fmul")
12962                (match_operand:MODEF 3 "div_operator" "")
12963                  (const_string "fdiv")
12964               ]
12965               (const_string "fop")))
12966    (set_attr "mode" "<MODE>")])
12967
12968 (define_insn "*rcpsf2_sse"
12969   [(set (match_operand:SF 0 "register_operand" "=x")
12970         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12971                    UNSPEC_RCP))]
12972   "TARGET_SSE_MATH"
12973   "%vrcpss\t{%1, %d0|%d0, %1}"
12974   [(set_attr "type" "sse")
12975    (set_attr "atom_sse_attr" "rcp")
12976    (set_attr "prefix" "maybe_vex")
12977    (set_attr "mode" "SF")])
12978
12979 (define_insn "*fop_<mode>_1_avx"
12980   [(set (match_operand:MODEF 0 "register_operand" "=x")
12981         (match_operator:MODEF 3 "binary_fp_operator"
12982           [(match_operand:MODEF 1 "register_operand" "x")
12983            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12984   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12985    && !COMMUTATIVE_ARITH_P (operands[3])"
12986   "* return output_387_binary_op (insn, operands);"
12987   [(set (attr "type")
12988         (cond [(match_operand:MODEF 3 "mult_operator" "")
12989                  (const_string "ssemul")
12990                (match_operand:MODEF 3 "div_operator" "")
12991                  (const_string "ssediv")
12992               ]
12993               (const_string "sseadd")))
12994    (set_attr "prefix" "vex")
12995    (set_attr "mode" "<MODE>")])
12996
12997 (define_insn "*fop_<mode>_1_sse"
12998   [(set (match_operand:MODEF 0 "register_operand" "=x")
12999         (match_operator:MODEF 3 "binary_fp_operator"
13000           [(match_operand:MODEF 1 "register_operand" "0")
13001            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13002   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13003    && !COMMUTATIVE_ARITH_P (operands[3])"
13004   "* return output_387_binary_op (insn, operands);"
13005   [(set (attr "type")
13006         (cond [(match_operand:MODEF 3 "mult_operator" "")
13007                  (const_string "ssemul")
13008                (match_operand:MODEF 3 "div_operator" "")
13009                  (const_string "ssediv")
13010               ]
13011               (const_string "sseadd")))
13012    (set_attr "mode" "<MODE>")])
13013
13014 ;; This pattern is not fully shadowed by the pattern above.
13015 (define_insn "*fop_<mode>_1_i387"
13016   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13017         (match_operator:MODEF 3 "binary_fp_operator"
13018           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13019            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13020   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13021    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13022    && !COMMUTATIVE_ARITH_P (operands[3])
13023    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13024   "* return output_387_binary_op (insn, operands);"
13025   [(set (attr "type")
13026         (cond [(match_operand:MODEF 3 "mult_operator" "")
13027                  (const_string "fmul")
13028                (match_operand:MODEF 3 "div_operator" "")
13029                  (const_string "fdiv")
13030               ]
13031               (const_string "fop")))
13032    (set_attr "mode" "<MODE>")])
13033
13034 ;; ??? Add SSE splitters for these!
13035 (define_insn "*fop_<MODEF:mode>_2_i387"
13036   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13037         (match_operator:MODEF 3 "binary_fp_operator"
13038           [(float:MODEF
13039              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13040            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13041   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13042    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13043    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13044   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13045   [(set (attr "type")
13046         (cond [(match_operand:MODEF 3 "mult_operator" "")
13047                  (const_string "fmul")
13048                (match_operand:MODEF 3 "div_operator" "")
13049                  (const_string "fdiv")
13050               ]
13051               (const_string "fop")))
13052    (set_attr "fp_int_src" "true")
13053    (set_attr "mode" "<X87MODEI12:MODE>")])
13054
13055 (define_insn "*fop_<MODEF:mode>_3_i387"
13056   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13057         (match_operator:MODEF 3 "binary_fp_operator"
13058           [(match_operand:MODEF 1 "register_operand" "0,0")
13059            (float:MODEF
13060              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13061   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13062    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13063    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13064   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13065   [(set (attr "type")
13066         (cond [(match_operand:MODEF 3 "mult_operator" "")
13067                  (const_string "fmul")
13068                (match_operand:MODEF 3 "div_operator" "")
13069                  (const_string "fdiv")
13070               ]
13071               (const_string "fop")))
13072    (set_attr "fp_int_src" "true")
13073    (set_attr "mode" "<MODE>")])
13074
13075 (define_insn "*fop_df_4_i387"
13076   [(set (match_operand:DF 0 "register_operand" "=f,f")
13077         (match_operator:DF 3 "binary_fp_operator"
13078            [(float_extend:DF
13079              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13080             (match_operand:DF 2 "register_operand" "0,f")]))]
13081   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13082    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13084   "* return output_387_binary_op (insn, operands);"
13085   [(set (attr "type")
13086         (cond [(match_operand:DF 3 "mult_operator" "")
13087                  (const_string "fmul")
13088                (match_operand:DF 3 "div_operator" "")
13089                  (const_string "fdiv")
13090               ]
13091               (const_string "fop")))
13092    (set_attr "mode" "SF")])
13093
13094 (define_insn "*fop_df_5_i387"
13095   [(set (match_operand:DF 0 "register_operand" "=f,f")
13096         (match_operator:DF 3 "binary_fp_operator"
13097           [(match_operand:DF 1 "register_operand" "0,f")
13098            (float_extend:DF
13099             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13100   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13101    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13102   "* return output_387_binary_op (insn, operands);"
13103   [(set (attr "type")
13104         (cond [(match_operand:DF 3 "mult_operator" "")
13105                  (const_string "fmul")
13106                (match_operand:DF 3 "div_operator" "")
13107                  (const_string "fdiv")
13108               ]
13109               (const_string "fop")))
13110    (set_attr "mode" "SF")])
13111
13112 (define_insn "*fop_df_6_i387"
13113   [(set (match_operand:DF 0 "register_operand" "=f,f")
13114         (match_operator:DF 3 "binary_fp_operator"
13115           [(float_extend:DF
13116             (match_operand:SF 1 "register_operand" "0,f"))
13117            (float_extend:DF
13118             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13119   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13120    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13121   "* return output_387_binary_op (insn, operands);"
13122   [(set (attr "type")
13123         (cond [(match_operand:DF 3 "mult_operator" "")
13124                  (const_string "fmul")
13125                (match_operand:DF 3 "div_operator" "")
13126                  (const_string "fdiv")
13127               ]
13128               (const_string "fop")))
13129    (set_attr "mode" "SF")])
13130
13131 (define_insn "*fop_xf_comm_i387"
13132   [(set (match_operand:XF 0 "register_operand" "=f")
13133         (match_operator:XF 3 "binary_fp_operator"
13134                         [(match_operand:XF 1 "register_operand" "%0")
13135                          (match_operand:XF 2 "register_operand" "f")]))]
13136   "TARGET_80387
13137    && COMMUTATIVE_ARITH_P (operands[3])"
13138   "* return output_387_binary_op (insn, operands);"
13139   [(set (attr "type")
13140         (if_then_else (match_operand:XF 3 "mult_operator" "")
13141            (const_string "fmul")
13142            (const_string "fop")))
13143    (set_attr "mode" "XF")])
13144
13145 (define_insn "*fop_xf_1_i387"
13146   [(set (match_operand:XF 0 "register_operand" "=f,f")
13147         (match_operator:XF 3 "binary_fp_operator"
13148                         [(match_operand:XF 1 "register_operand" "0,f")
13149                          (match_operand:XF 2 "register_operand" "f,0")]))]
13150   "TARGET_80387
13151    && !COMMUTATIVE_ARITH_P (operands[3])"
13152   "* return output_387_binary_op (insn, operands);"
13153   [(set (attr "type")
13154         (cond [(match_operand:XF 3 "mult_operator" "")
13155                  (const_string "fmul")
13156                (match_operand:XF 3 "div_operator" "")
13157                  (const_string "fdiv")
13158               ]
13159               (const_string "fop")))
13160    (set_attr "mode" "XF")])
13161
13162 (define_insn "*fop_xf_2_i387"
13163   [(set (match_operand:XF 0 "register_operand" "=f,f")
13164         (match_operator:XF 3 "binary_fp_operator"
13165           [(float:XF
13166              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13167            (match_operand:XF 2 "register_operand" "0,0")]))]
13168   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13169   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13170   [(set (attr "type")
13171         (cond [(match_operand:XF 3 "mult_operator" "")
13172                  (const_string "fmul")
13173                (match_operand:XF 3 "div_operator" "")
13174                  (const_string "fdiv")
13175               ]
13176               (const_string "fop")))
13177    (set_attr "fp_int_src" "true")
13178    (set_attr "mode" "<MODE>")])
13179
13180 (define_insn "*fop_xf_3_i387"
13181   [(set (match_operand:XF 0 "register_operand" "=f,f")
13182         (match_operator:XF 3 "binary_fp_operator"
13183           [(match_operand:XF 1 "register_operand" "0,0")
13184            (float:XF
13185              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13186   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13187   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13188   [(set (attr "type")
13189         (cond [(match_operand:XF 3 "mult_operator" "")
13190                  (const_string "fmul")
13191                (match_operand:XF 3 "div_operator" "")
13192                  (const_string "fdiv")
13193               ]
13194               (const_string "fop")))
13195    (set_attr "fp_int_src" "true")
13196    (set_attr "mode" "<MODE>")])
13197
13198 (define_insn "*fop_xf_4_i387"
13199   [(set (match_operand:XF 0 "register_operand" "=f,f")
13200         (match_operator:XF 3 "binary_fp_operator"
13201            [(float_extend:XF
13202               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13203             (match_operand:XF 2 "register_operand" "0,f")]))]
13204   "TARGET_80387"
13205   "* return output_387_binary_op (insn, operands);"
13206   [(set (attr "type")
13207         (cond [(match_operand:XF 3 "mult_operator" "")
13208                  (const_string "fmul")
13209                (match_operand:XF 3 "div_operator" "")
13210                  (const_string "fdiv")
13211               ]
13212               (const_string "fop")))
13213    (set_attr "mode" "<MODE>")])
13214
13215 (define_insn "*fop_xf_5_i387"
13216   [(set (match_operand:XF 0 "register_operand" "=f,f")
13217         (match_operator:XF 3 "binary_fp_operator"
13218           [(match_operand:XF 1 "register_operand" "0,f")
13219            (float_extend:XF
13220              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13221   "TARGET_80387"
13222   "* return output_387_binary_op (insn, operands);"
13223   [(set (attr "type")
13224         (cond [(match_operand:XF 3 "mult_operator" "")
13225                  (const_string "fmul")
13226                (match_operand:XF 3 "div_operator" "")
13227                  (const_string "fdiv")
13228               ]
13229               (const_string "fop")))
13230    (set_attr "mode" "<MODE>")])
13231
13232 (define_insn "*fop_xf_6_i387"
13233   [(set (match_operand:XF 0 "register_operand" "=f,f")
13234         (match_operator:XF 3 "binary_fp_operator"
13235           [(float_extend:XF
13236              (match_operand:MODEF 1 "register_operand" "0,f"))
13237            (float_extend:XF
13238              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13239   "TARGET_80387"
13240   "* return output_387_binary_op (insn, operands);"
13241   [(set (attr "type")
13242         (cond [(match_operand:XF 3 "mult_operator" "")
13243                  (const_string "fmul")
13244                (match_operand:XF 3 "div_operator" "")
13245                  (const_string "fdiv")
13246               ]
13247               (const_string "fop")))
13248    (set_attr "mode" "<MODE>")])
13249
13250 (define_split
13251   [(set (match_operand 0 "register_operand" "")
13252         (match_operator 3 "binary_fp_operator"
13253            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13254             (match_operand 2 "register_operand" "")]))]
13255   "reload_completed
13256    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13257    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13258   [(const_int 0)]
13259 {
13260   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13261   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13262   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13263                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13264                                           GET_MODE (operands[3]),
13265                                           operands[4],
13266                                           operands[2])));
13267   ix86_free_from_memory (GET_MODE (operands[1]));
13268   DONE;
13269 })
13270
13271 (define_split
13272   [(set (match_operand 0 "register_operand" "")
13273         (match_operator 3 "binary_fp_operator"
13274            [(match_operand 1 "register_operand" "")
13275             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13276   "reload_completed
13277    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13278    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13279   [(const_int 0)]
13280 {
13281   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13282   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13283   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13284                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13285                                           GET_MODE (operands[3]),
13286                                           operands[1],
13287                                           operands[4])));
13288   ix86_free_from_memory (GET_MODE (operands[2]));
13289   DONE;
13290 })
13291 \f
13292 ;; FPU special functions.
13293
13294 ;; This pattern implements a no-op XFmode truncation for
13295 ;; all fancy i386 XFmode math functions.
13296
13297 (define_insn "truncxf<mode>2_i387_noop_unspec"
13298   [(set (match_operand:MODEF 0 "register_operand" "=f")
13299         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13300         UNSPEC_TRUNC_NOOP))]
13301   "TARGET_USE_FANCY_MATH_387"
13302   "* return output_387_reg_move (insn, operands);"
13303   [(set_attr "type" "fmov")
13304    (set_attr "mode" "<MODE>")])
13305
13306 (define_insn "sqrtxf2"
13307   [(set (match_operand:XF 0 "register_operand" "=f")
13308         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13309   "TARGET_USE_FANCY_MATH_387"
13310   "fsqrt"
13311   [(set_attr "type" "fpspc")
13312    (set_attr "mode" "XF")
13313    (set_attr "athlon_decode" "direct")
13314    (set_attr "amdfam10_decode" "direct")
13315    (set_attr "bdver1_decode" "direct")])
13316
13317 (define_insn "sqrt_extend<mode>xf2_i387"
13318   [(set (match_operand:XF 0 "register_operand" "=f")
13319         (sqrt:XF
13320           (float_extend:XF
13321             (match_operand:MODEF 1 "register_operand" "0"))))]
13322   "TARGET_USE_FANCY_MATH_387"
13323   "fsqrt"
13324   [(set_attr "type" "fpspc")
13325    (set_attr "mode" "XF")
13326    (set_attr "athlon_decode" "direct")
13327    (set_attr "amdfam10_decode" "direct")
13328    (set_attr "bdver1_decode" "direct")])
13329
13330 (define_insn "*rsqrtsf2_sse"
13331   [(set (match_operand:SF 0 "register_operand" "=x")
13332         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13333                    UNSPEC_RSQRT))]
13334   "TARGET_SSE_MATH"
13335   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13336   [(set_attr "type" "sse")
13337    (set_attr "atom_sse_attr" "rcp")
13338    (set_attr "prefix" "maybe_vex")
13339    (set_attr "mode" "SF")])
13340
13341 (define_expand "rsqrtsf2"
13342   [(set (match_operand:SF 0 "register_operand" "")
13343         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13344                    UNSPEC_RSQRT))]
13345   "TARGET_SSE_MATH"
13346 {
13347   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13348   DONE;
13349 })
13350
13351 (define_insn "*sqrt<mode>2_sse"
13352   [(set (match_operand:MODEF 0 "register_operand" "=x")
13353         (sqrt:MODEF
13354           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13355   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13356   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13357   [(set_attr "type" "sse")
13358    (set_attr "atom_sse_attr" "sqrt")
13359    (set_attr "prefix" "maybe_vex")
13360    (set_attr "mode" "<MODE>")
13361    (set_attr "athlon_decode" "*")
13362    (set_attr "amdfam10_decode" "*")
13363    (set_attr "bdver1_decode" "*")])
13364
13365 (define_expand "sqrt<mode>2"
13366   [(set (match_operand:MODEF 0 "register_operand" "")
13367         (sqrt:MODEF
13368           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13369   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13370    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13371 {
13372   if (<MODE>mode == SFmode
13373       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13374       && flag_finite_math_only && !flag_trapping_math
13375       && flag_unsafe_math_optimizations)
13376     {
13377       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13378       DONE;
13379     }
13380
13381   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13382     {
13383       rtx op0 = gen_reg_rtx (XFmode);
13384       rtx op1 = force_reg (<MODE>mode, operands[1]);
13385
13386       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13387       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13388       DONE;
13389    }
13390 })
13391
13392 (define_insn "fpremxf4_i387"
13393   [(set (match_operand:XF 0 "register_operand" "=f")
13394         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13395                     (match_operand:XF 3 "register_operand" "1")]
13396                    UNSPEC_FPREM_F))
13397    (set (match_operand:XF 1 "register_operand" "=u")
13398         (unspec:XF [(match_dup 2) (match_dup 3)]
13399                    UNSPEC_FPREM_U))
13400    (set (reg:CCFP FPSR_REG)
13401         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13402                      UNSPEC_C2_FLAG))]
13403   "TARGET_USE_FANCY_MATH_387"
13404   "fprem"
13405   [(set_attr "type" "fpspc")
13406    (set_attr "mode" "XF")])
13407
13408 (define_expand "fmodxf3"
13409   [(use (match_operand:XF 0 "register_operand" ""))
13410    (use (match_operand:XF 1 "general_operand" ""))
13411    (use (match_operand:XF 2 "general_operand" ""))]
13412   "TARGET_USE_FANCY_MATH_387"
13413 {
13414   rtx label = gen_label_rtx ();
13415
13416   rtx op1 = gen_reg_rtx (XFmode);
13417   rtx op2 = gen_reg_rtx (XFmode);
13418
13419   emit_move_insn (op2, operands[2]);
13420   emit_move_insn (op1, operands[1]);
13421
13422   emit_label (label);
13423   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13424   ix86_emit_fp_unordered_jump (label);
13425   LABEL_NUSES (label) = 1;
13426
13427   emit_move_insn (operands[0], op1);
13428   DONE;
13429 })
13430
13431 (define_expand "fmod<mode>3"
13432   [(use (match_operand:MODEF 0 "register_operand" ""))
13433    (use (match_operand:MODEF 1 "general_operand" ""))
13434    (use (match_operand:MODEF 2 "general_operand" ""))]
13435   "TARGET_USE_FANCY_MATH_387"
13436 {
13437   rtx (*gen_truncxf) (rtx, rtx);
13438
13439   rtx label = gen_label_rtx ();
13440
13441   rtx op1 = gen_reg_rtx (XFmode);
13442   rtx op2 = gen_reg_rtx (XFmode);
13443
13444   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13445   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13446
13447   emit_label (label);
13448   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13449   ix86_emit_fp_unordered_jump (label);
13450   LABEL_NUSES (label) = 1;
13451
13452   /* Truncate the result properly for strict SSE math.  */
13453   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13454       && !TARGET_MIX_SSE_I387)
13455     gen_truncxf = gen_truncxf<mode>2;
13456   else
13457     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13458
13459   emit_insn (gen_truncxf (operands[0], op1));
13460   DONE;
13461 })
13462
13463 (define_insn "fprem1xf4_i387"
13464   [(set (match_operand:XF 0 "register_operand" "=f")
13465         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13466                     (match_operand:XF 3 "register_operand" "1")]
13467                    UNSPEC_FPREM1_F))
13468    (set (match_operand:XF 1 "register_operand" "=u")
13469         (unspec:XF [(match_dup 2) (match_dup 3)]
13470                    UNSPEC_FPREM1_U))
13471    (set (reg:CCFP FPSR_REG)
13472         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13473                      UNSPEC_C2_FLAG))]
13474   "TARGET_USE_FANCY_MATH_387"
13475   "fprem1"
13476   [(set_attr "type" "fpspc")
13477    (set_attr "mode" "XF")])
13478
13479 (define_expand "remainderxf3"
13480   [(use (match_operand:XF 0 "register_operand" ""))
13481    (use (match_operand:XF 1 "general_operand" ""))
13482    (use (match_operand:XF 2 "general_operand" ""))]
13483   "TARGET_USE_FANCY_MATH_387"
13484 {
13485   rtx label = gen_label_rtx ();
13486
13487   rtx op1 = gen_reg_rtx (XFmode);
13488   rtx op2 = gen_reg_rtx (XFmode);
13489
13490   emit_move_insn (op2, operands[2]);
13491   emit_move_insn (op1, operands[1]);
13492
13493   emit_label (label);
13494   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13495   ix86_emit_fp_unordered_jump (label);
13496   LABEL_NUSES (label) = 1;
13497
13498   emit_move_insn (operands[0], op1);
13499   DONE;
13500 })
13501
13502 (define_expand "remainder<mode>3"
13503   [(use (match_operand:MODEF 0 "register_operand" ""))
13504    (use (match_operand:MODEF 1 "general_operand" ""))
13505    (use (match_operand:MODEF 2 "general_operand" ""))]
13506   "TARGET_USE_FANCY_MATH_387"
13507 {
13508   rtx (*gen_truncxf) (rtx, rtx);
13509
13510   rtx label = gen_label_rtx ();
13511
13512   rtx op1 = gen_reg_rtx (XFmode);
13513   rtx op2 = gen_reg_rtx (XFmode);
13514
13515   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13516   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13517
13518   emit_label (label);
13519
13520   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13521   ix86_emit_fp_unordered_jump (label);
13522   LABEL_NUSES (label) = 1;
13523
13524   /* Truncate the result properly for strict SSE math.  */
13525   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13526       && !TARGET_MIX_SSE_I387)
13527     gen_truncxf = gen_truncxf<mode>2;
13528   else
13529     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13530
13531   emit_insn (gen_truncxf (operands[0], op1));
13532   DONE;
13533 })
13534
13535 (define_insn "*sinxf2_i387"
13536   [(set (match_operand:XF 0 "register_operand" "=f")
13537         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13538   "TARGET_USE_FANCY_MATH_387
13539    && flag_unsafe_math_optimizations"
13540   "fsin"
13541   [(set_attr "type" "fpspc")
13542    (set_attr "mode" "XF")])
13543
13544 (define_insn "*sin_extend<mode>xf2_i387"
13545   [(set (match_operand:XF 0 "register_operand" "=f")
13546         (unspec:XF [(float_extend:XF
13547                       (match_operand:MODEF 1 "register_operand" "0"))]
13548                    UNSPEC_SIN))]
13549   "TARGET_USE_FANCY_MATH_387
13550    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13551        || TARGET_MIX_SSE_I387)
13552    && flag_unsafe_math_optimizations"
13553   "fsin"
13554   [(set_attr "type" "fpspc")
13555    (set_attr "mode" "XF")])
13556
13557 (define_insn "*cosxf2_i387"
13558   [(set (match_operand:XF 0 "register_operand" "=f")
13559         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13560   "TARGET_USE_FANCY_MATH_387
13561    && flag_unsafe_math_optimizations"
13562   "fcos"
13563   [(set_attr "type" "fpspc")
13564    (set_attr "mode" "XF")])
13565
13566 (define_insn "*cos_extend<mode>xf2_i387"
13567   [(set (match_operand:XF 0 "register_operand" "=f")
13568         (unspec:XF [(float_extend:XF
13569                       (match_operand:MODEF 1 "register_operand" "0"))]
13570                    UNSPEC_COS))]
13571   "TARGET_USE_FANCY_MATH_387
13572    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13573        || TARGET_MIX_SSE_I387)
13574    && flag_unsafe_math_optimizations"
13575   "fcos"
13576   [(set_attr "type" "fpspc")
13577    (set_attr "mode" "XF")])
13578
13579 ;; When sincos pattern is defined, sin and cos builtin functions will be
13580 ;; expanded to sincos pattern with one of its outputs left unused.
13581 ;; CSE pass will figure out if two sincos patterns can be combined,
13582 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13583 ;; depending on the unused output.
13584
13585 (define_insn "sincosxf3"
13586   [(set (match_operand:XF 0 "register_operand" "=f")
13587         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13588                    UNSPEC_SINCOS_COS))
13589    (set (match_operand:XF 1 "register_operand" "=u")
13590         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13591   "TARGET_USE_FANCY_MATH_387
13592    && flag_unsafe_math_optimizations"
13593   "fsincos"
13594   [(set_attr "type" "fpspc")
13595    (set_attr "mode" "XF")])
13596
13597 (define_split
13598   [(set (match_operand:XF 0 "register_operand" "")
13599         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13600                    UNSPEC_SINCOS_COS))
13601    (set (match_operand:XF 1 "register_operand" "")
13602         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13603   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13604    && !(reload_completed || reload_in_progress)"
13605   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13606
13607 (define_split
13608   [(set (match_operand:XF 0 "register_operand" "")
13609         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13610                    UNSPEC_SINCOS_COS))
13611    (set (match_operand:XF 1 "register_operand" "")
13612         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13613   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13614    && !(reload_completed || reload_in_progress)"
13615   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13616
13617 (define_insn "sincos_extend<mode>xf3_i387"
13618   [(set (match_operand:XF 0 "register_operand" "=f")
13619         (unspec:XF [(float_extend:XF
13620                       (match_operand:MODEF 2 "register_operand" "0"))]
13621                    UNSPEC_SINCOS_COS))
13622    (set (match_operand:XF 1 "register_operand" "=u")
13623         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13624   "TARGET_USE_FANCY_MATH_387
13625    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13626        || TARGET_MIX_SSE_I387)
13627    && flag_unsafe_math_optimizations"
13628   "fsincos"
13629   [(set_attr "type" "fpspc")
13630    (set_attr "mode" "XF")])
13631
13632 (define_split
13633   [(set (match_operand:XF 0 "register_operand" "")
13634         (unspec:XF [(float_extend:XF
13635                       (match_operand:MODEF 2 "register_operand" ""))]
13636                    UNSPEC_SINCOS_COS))
13637    (set (match_operand:XF 1 "register_operand" "")
13638         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13639   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13640    && !(reload_completed || reload_in_progress)"
13641   [(set (match_dup 1)
13642         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13643
13644 (define_split
13645   [(set (match_operand:XF 0 "register_operand" "")
13646         (unspec:XF [(float_extend:XF
13647                       (match_operand:MODEF 2 "register_operand" ""))]
13648                    UNSPEC_SINCOS_COS))
13649    (set (match_operand:XF 1 "register_operand" "")
13650         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13651   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13652    && !(reload_completed || reload_in_progress)"
13653   [(set (match_dup 0)
13654         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13655
13656 (define_expand "sincos<mode>3"
13657   [(use (match_operand:MODEF 0 "register_operand" ""))
13658    (use (match_operand:MODEF 1 "register_operand" ""))
13659    (use (match_operand:MODEF 2 "register_operand" ""))]
13660   "TARGET_USE_FANCY_MATH_387
13661    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662        || TARGET_MIX_SSE_I387)
13663    && flag_unsafe_math_optimizations"
13664 {
13665   rtx op0 = gen_reg_rtx (XFmode);
13666   rtx op1 = gen_reg_rtx (XFmode);
13667
13668   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13669   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13670   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13671   DONE;
13672 })
13673
13674 (define_insn "fptanxf4_i387"
13675   [(set (match_operand:XF 0 "register_operand" "=f")
13676         (match_operand:XF 3 "const_double_operand" "F"))
13677    (set (match_operand:XF 1 "register_operand" "=u")
13678         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13679                    UNSPEC_TAN))]
13680   "TARGET_USE_FANCY_MATH_387
13681    && flag_unsafe_math_optimizations
13682    && standard_80387_constant_p (operands[3]) == 2"
13683   "fptan"
13684   [(set_attr "type" "fpspc")
13685    (set_attr "mode" "XF")])
13686
13687 (define_insn "fptan_extend<mode>xf4_i387"
13688   [(set (match_operand:MODEF 0 "register_operand" "=f")
13689         (match_operand:MODEF 3 "const_double_operand" "F"))
13690    (set (match_operand:XF 1 "register_operand" "=u")
13691         (unspec:XF [(float_extend:XF
13692                       (match_operand:MODEF 2 "register_operand" "0"))]
13693                    UNSPEC_TAN))]
13694   "TARGET_USE_FANCY_MATH_387
13695    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13696        || TARGET_MIX_SSE_I387)
13697    && flag_unsafe_math_optimizations
13698    && standard_80387_constant_p (operands[3]) == 2"
13699   "fptan"
13700   [(set_attr "type" "fpspc")
13701    (set_attr "mode" "XF")])
13702
13703 (define_expand "tanxf2"
13704   [(use (match_operand:XF 0 "register_operand" ""))
13705    (use (match_operand:XF 1 "register_operand" ""))]
13706   "TARGET_USE_FANCY_MATH_387
13707    && flag_unsafe_math_optimizations"
13708 {
13709   rtx one = gen_reg_rtx (XFmode);
13710   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13711
13712   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13713   DONE;
13714 })
13715
13716 (define_expand "tan<mode>2"
13717   [(use (match_operand:MODEF 0 "register_operand" ""))
13718    (use (match_operand:MODEF 1 "register_operand" ""))]
13719   "TARGET_USE_FANCY_MATH_387
13720    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13721        || TARGET_MIX_SSE_I387)
13722    && flag_unsafe_math_optimizations"
13723 {
13724   rtx op0 = gen_reg_rtx (XFmode);
13725
13726   rtx one = gen_reg_rtx (<MODE>mode);
13727   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13728
13729   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13730                                              operands[1], op2));
13731   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13732   DONE;
13733 })
13734
13735 (define_insn "*fpatanxf3_i387"
13736   [(set (match_operand:XF 0 "register_operand" "=f")
13737         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13738                     (match_operand:XF 2 "register_operand" "u")]
13739                    UNSPEC_FPATAN))
13740    (clobber (match_scratch:XF 3 "=2"))]
13741   "TARGET_USE_FANCY_MATH_387
13742    && flag_unsafe_math_optimizations"
13743   "fpatan"
13744   [(set_attr "type" "fpspc")
13745    (set_attr "mode" "XF")])
13746
13747 (define_insn "fpatan_extend<mode>xf3_i387"
13748   [(set (match_operand:XF 0 "register_operand" "=f")
13749         (unspec:XF [(float_extend:XF
13750                       (match_operand:MODEF 1 "register_operand" "0"))
13751                     (float_extend:XF
13752                       (match_operand:MODEF 2 "register_operand" "u"))]
13753                    UNSPEC_FPATAN))
13754    (clobber (match_scratch:XF 3 "=2"))]
13755   "TARGET_USE_FANCY_MATH_387
13756    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13757        || TARGET_MIX_SSE_I387)
13758    && flag_unsafe_math_optimizations"
13759   "fpatan"
13760   [(set_attr "type" "fpspc")
13761    (set_attr "mode" "XF")])
13762
13763 (define_expand "atan2xf3"
13764   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13765                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13766                                (match_operand:XF 1 "register_operand" "")]
13767                               UNSPEC_FPATAN))
13768               (clobber (match_scratch:XF 3 ""))])]
13769   "TARGET_USE_FANCY_MATH_387
13770    && flag_unsafe_math_optimizations")
13771
13772 (define_expand "atan2<mode>3"
13773   [(use (match_operand:MODEF 0 "register_operand" ""))
13774    (use (match_operand:MODEF 1 "register_operand" ""))
13775    (use (match_operand:MODEF 2 "register_operand" ""))]
13776   "TARGET_USE_FANCY_MATH_387
13777    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13778        || TARGET_MIX_SSE_I387)
13779    && flag_unsafe_math_optimizations"
13780 {
13781   rtx op0 = gen_reg_rtx (XFmode);
13782
13783   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13784   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13785   DONE;
13786 })
13787
13788 (define_expand "atanxf2"
13789   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13790                    (unspec:XF [(match_dup 2)
13791                                (match_operand:XF 1 "register_operand" "")]
13792                               UNSPEC_FPATAN))
13793               (clobber (match_scratch:XF 3 ""))])]
13794   "TARGET_USE_FANCY_MATH_387
13795    && flag_unsafe_math_optimizations"
13796 {
13797   operands[2] = gen_reg_rtx (XFmode);
13798   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13799 })
13800
13801 (define_expand "atan<mode>2"
13802   [(use (match_operand:MODEF 0 "register_operand" ""))
13803    (use (match_operand:MODEF 1 "register_operand" ""))]
13804   "TARGET_USE_FANCY_MATH_387
13805    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13806        || TARGET_MIX_SSE_I387)
13807    && flag_unsafe_math_optimizations"
13808 {
13809   rtx op0 = gen_reg_rtx (XFmode);
13810
13811   rtx op2 = gen_reg_rtx (<MODE>mode);
13812   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13813
13814   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13815   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13816   DONE;
13817 })
13818
13819 (define_expand "asinxf2"
13820   [(set (match_dup 2)
13821         (mult:XF (match_operand:XF 1 "register_operand" "")
13822                  (match_dup 1)))
13823    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13824    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13825    (parallel [(set (match_operand:XF 0 "register_operand" "")
13826                    (unspec:XF [(match_dup 5) (match_dup 1)]
13827                               UNSPEC_FPATAN))
13828               (clobber (match_scratch:XF 6 ""))])]
13829   "TARGET_USE_FANCY_MATH_387
13830    && flag_unsafe_math_optimizations"
13831 {
13832   int i;
13833
13834   if (optimize_insn_for_size_p ())
13835     FAIL;
13836
13837   for (i = 2; i < 6; i++)
13838     operands[i] = gen_reg_rtx (XFmode);
13839
13840   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13841 })
13842
13843 (define_expand "asin<mode>2"
13844   [(use (match_operand:MODEF 0 "register_operand" ""))
13845    (use (match_operand:MODEF 1 "general_operand" ""))]
13846  "TARGET_USE_FANCY_MATH_387
13847    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13848        || TARGET_MIX_SSE_I387)
13849    && flag_unsafe_math_optimizations"
13850 {
13851   rtx op0 = gen_reg_rtx (XFmode);
13852   rtx op1 = gen_reg_rtx (XFmode);
13853
13854   if (optimize_insn_for_size_p ())
13855     FAIL;
13856
13857   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13858   emit_insn (gen_asinxf2 (op0, op1));
13859   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13860   DONE;
13861 })
13862
13863 (define_expand "acosxf2"
13864   [(set (match_dup 2)
13865         (mult:XF (match_operand:XF 1 "register_operand" "")
13866                  (match_dup 1)))
13867    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13868    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13869    (parallel [(set (match_operand:XF 0 "register_operand" "")
13870                    (unspec:XF [(match_dup 1) (match_dup 5)]
13871                               UNSPEC_FPATAN))
13872               (clobber (match_scratch:XF 6 ""))])]
13873   "TARGET_USE_FANCY_MATH_387
13874    && flag_unsafe_math_optimizations"
13875 {
13876   int i;
13877
13878   if (optimize_insn_for_size_p ())
13879     FAIL;
13880
13881   for (i = 2; i < 6; i++)
13882     operands[i] = gen_reg_rtx (XFmode);
13883
13884   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13885 })
13886
13887 (define_expand "acos<mode>2"
13888   [(use (match_operand:MODEF 0 "register_operand" ""))
13889    (use (match_operand:MODEF 1 "general_operand" ""))]
13890  "TARGET_USE_FANCY_MATH_387
13891    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892        || TARGET_MIX_SSE_I387)
13893    && flag_unsafe_math_optimizations"
13894 {
13895   rtx op0 = gen_reg_rtx (XFmode);
13896   rtx op1 = gen_reg_rtx (XFmode);
13897
13898   if (optimize_insn_for_size_p ())
13899     FAIL;
13900
13901   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13902   emit_insn (gen_acosxf2 (op0, op1));
13903   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13904   DONE;
13905 })
13906
13907 (define_insn "fyl2xxf3_i387"
13908   [(set (match_operand:XF 0 "register_operand" "=f")
13909         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13910                     (match_operand:XF 2 "register_operand" "u")]
13911                    UNSPEC_FYL2X))
13912    (clobber (match_scratch:XF 3 "=2"))]
13913   "TARGET_USE_FANCY_MATH_387
13914    && flag_unsafe_math_optimizations"
13915   "fyl2x"
13916   [(set_attr "type" "fpspc")
13917    (set_attr "mode" "XF")])
13918
13919 (define_insn "fyl2x_extend<mode>xf3_i387"
13920   [(set (match_operand:XF 0 "register_operand" "=f")
13921         (unspec:XF [(float_extend:XF
13922                       (match_operand:MODEF 1 "register_operand" "0"))
13923                     (match_operand:XF 2 "register_operand" "u")]
13924                    UNSPEC_FYL2X))
13925    (clobber (match_scratch:XF 3 "=2"))]
13926   "TARGET_USE_FANCY_MATH_387
13927    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13928        || TARGET_MIX_SSE_I387)
13929    && flag_unsafe_math_optimizations"
13930   "fyl2x"
13931   [(set_attr "type" "fpspc")
13932    (set_attr "mode" "XF")])
13933
13934 (define_expand "logxf2"
13935   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13936                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13937                                (match_dup 2)] UNSPEC_FYL2X))
13938               (clobber (match_scratch:XF 3 ""))])]
13939   "TARGET_USE_FANCY_MATH_387
13940    && flag_unsafe_math_optimizations"
13941 {
13942   operands[2] = gen_reg_rtx (XFmode);
13943   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13944 })
13945
13946 (define_expand "log<mode>2"
13947   [(use (match_operand:MODEF 0 "register_operand" ""))
13948    (use (match_operand:MODEF 1 "register_operand" ""))]
13949   "TARGET_USE_FANCY_MATH_387
13950    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13951        || TARGET_MIX_SSE_I387)
13952    && flag_unsafe_math_optimizations"
13953 {
13954   rtx op0 = gen_reg_rtx (XFmode);
13955
13956   rtx op2 = gen_reg_rtx (XFmode);
13957   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13958
13959   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13960   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13961   DONE;
13962 })
13963
13964 (define_expand "log10xf2"
13965   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13966                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13967                                (match_dup 2)] UNSPEC_FYL2X))
13968               (clobber (match_scratch:XF 3 ""))])]
13969   "TARGET_USE_FANCY_MATH_387
13970    && flag_unsafe_math_optimizations"
13971 {
13972   operands[2] = gen_reg_rtx (XFmode);
13973   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13974 })
13975
13976 (define_expand "log10<mode>2"
13977   [(use (match_operand:MODEF 0 "register_operand" ""))
13978    (use (match_operand:MODEF 1 "register_operand" ""))]
13979   "TARGET_USE_FANCY_MATH_387
13980    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981        || TARGET_MIX_SSE_I387)
13982    && flag_unsafe_math_optimizations"
13983 {
13984   rtx op0 = gen_reg_rtx (XFmode);
13985
13986   rtx op2 = gen_reg_rtx (XFmode);
13987   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13988
13989   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13990   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13991   DONE;
13992 })
13993
13994 (define_expand "log2xf2"
13995   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13996                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13997                                (match_dup 2)] UNSPEC_FYL2X))
13998               (clobber (match_scratch:XF 3 ""))])]
13999   "TARGET_USE_FANCY_MATH_387
14000    && flag_unsafe_math_optimizations"
14001 {
14002   operands[2] = gen_reg_rtx (XFmode);
14003   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14004 })
14005
14006 (define_expand "log2<mode>2"
14007   [(use (match_operand:MODEF 0 "register_operand" ""))
14008    (use (match_operand:MODEF 1 "register_operand" ""))]
14009   "TARGET_USE_FANCY_MATH_387
14010    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011        || TARGET_MIX_SSE_I387)
14012    && flag_unsafe_math_optimizations"
14013 {
14014   rtx op0 = gen_reg_rtx (XFmode);
14015
14016   rtx op2 = gen_reg_rtx (XFmode);
14017   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14018
14019   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14020   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14021   DONE;
14022 })
14023
14024 (define_insn "fyl2xp1xf3_i387"
14025   [(set (match_operand:XF 0 "register_operand" "=f")
14026         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14027                     (match_operand:XF 2 "register_operand" "u")]
14028                    UNSPEC_FYL2XP1))
14029    (clobber (match_scratch:XF 3 "=2"))]
14030   "TARGET_USE_FANCY_MATH_387
14031    && flag_unsafe_math_optimizations"
14032   "fyl2xp1"
14033   [(set_attr "type" "fpspc")
14034    (set_attr "mode" "XF")])
14035
14036 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14037   [(set (match_operand:XF 0 "register_operand" "=f")
14038         (unspec:XF [(float_extend:XF
14039                       (match_operand:MODEF 1 "register_operand" "0"))
14040                     (match_operand:XF 2 "register_operand" "u")]
14041                    UNSPEC_FYL2XP1))
14042    (clobber (match_scratch:XF 3 "=2"))]
14043   "TARGET_USE_FANCY_MATH_387
14044    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045        || TARGET_MIX_SSE_I387)
14046    && flag_unsafe_math_optimizations"
14047   "fyl2xp1"
14048   [(set_attr "type" "fpspc")
14049    (set_attr "mode" "XF")])
14050
14051 (define_expand "log1pxf2"
14052   [(use (match_operand:XF 0 "register_operand" ""))
14053    (use (match_operand:XF 1 "register_operand" ""))]
14054   "TARGET_USE_FANCY_MATH_387
14055    && flag_unsafe_math_optimizations"
14056 {
14057   if (optimize_insn_for_size_p ())
14058     FAIL;
14059
14060   ix86_emit_i387_log1p (operands[0], operands[1]);
14061   DONE;
14062 })
14063
14064 (define_expand "log1p<mode>2"
14065   [(use (match_operand:MODEF 0 "register_operand" ""))
14066    (use (match_operand:MODEF 1 "register_operand" ""))]
14067   "TARGET_USE_FANCY_MATH_387
14068    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14069        || TARGET_MIX_SSE_I387)
14070    && flag_unsafe_math_optimizations"
14071 {
14072   rtx op0;
14073
14074   if (optimize_insn_for_size_p ())
14075     FAIL;
14076
14077   op0 = gen_reg_rtx (XFmode);
14078
14079   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14080
14081   ix86_emit_i387_log1p (op0, operands[1]);
14082   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14083   DONE;
14084 })
14085
14086 (define_insn "fxtractxf3_i387"
14087   [(set (match_operand:XF 0 "register_operand" "=f")
14088         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14089                    UNSPEC_XTRACT_FRACT))
14090    (set (match_operand:XF 1 "register_operand" "=u")
14091         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14092   "TARGET_USE_FANCY_MATH_387
14093    && flag_unsafe_math_optimizations"
14094   "fxtract"
14095   [(set_attr "type" "fpspc")
14096    (set_attr "mode" "XF")])
14097
14098 (define_insn "fxtract_extend<mode>xf3_i387"
14099   [(set (match_operand:XF 0 "register_operand" "=f")
14100         (unspec:XF [(float_extend:XF
14101                       (match_operand:MODEF 2 "register_operand" "0"))]
14102                    UNSPEC_XTRACT_FRACT))
14103    (set (match_operand:XF 1 "register_operand" "=u")
14104         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14105   "TARGET_USE_FANCY_MATH_387
14106    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107        || TARGET_MIX_SSE_I387)
14108    && flag_unsafe_math_optimizations"
14109   "fxtract"
14110   [(set_attr "type" "fpspc")
14111    (set_attr "mode" "XF")])
14112
14113 (define_expand "logbxf2"
14114   [(parallel [(set (match_dup 2)
14115                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14116                               UNSPEC_XTRACT_FRACT))
14117               (set (match_operand:XF 0 "register_operand" "")
14118                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14119   "TARGET_USE_FANCY_MATH_387
14120    && flag_unsafe_math_optimizations"
14121   "operands[2] = gen_reg_rtx (XFmode);")
14122
14123 (define_expand "logb<mode>2"
14124   [(use (match_operand:MODEF 0 "register_operand" ""))
14125    (use (match_operand:MODEF 1 "register_operand" ""))]
14126   "TARGET_USE_FANCY_MATH_387
14127    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14128        || TARGET_MIX_SSE_I387)
14129    && flag_unsafe_math_optimizations"
14130 {
14131   rtx op0 = gen_reg_rtx (XFmode);
14132   rtx op1 = gen_reg_rtx (XFmode);
14133
14134   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14135   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14136   DONE;
14137 })
14138
14139 (define_expand "ilogbxf2"
14140   [(use (match_operand:SI 0 "register_operand" ""))
14141    (use (match_operand:XF 1 "register_operand" ""))]
14142   "TARGET_USE_FANCY_MATH_387
14143    && flag_unsafe_math_optimizations"
14144 {
14145   rtx op0, op1;
14146
14147   if (optimize_insn_for_size_p ())
14148     FAIL;
14149
14150   op0 = gen_reg_rtx (XFmode);
14151   op1 = gen_reg_rtx (XFmode);
14152
14153   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14154   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14155   DONE;
14156 })
14157
14158 (define_expand "ilogb<mode>2"
14159   [(use (match_operand:SI 0 "register_operand" ""))
14160    (use (match_operand:MODEF 1 "register_operand" ""))]
14161   "TARGET_USE_FANCY_MATH_387
14162    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14163        || TARGET_MIX_SSE_I387)
14164    && flag_unsafe_math_optimizations"
14165 {
14166   rtx op0, op1;
14167
14168   if (optimize_insn_for_size_p ())
14169     FAIL;
14170
14171   op0 = gen_reg_rtx (XFmode);
14172   op1 = gen_reg_rtx (XFmode);
14173
14174   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14175   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14176   DONE;
14177 })
14178
14179 (define_insn "*f2xm1xf2_i387"
14180   [(set (match_operand:XF 0 "register_operand" "=f")
14181         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14182                    UNSPEC_F2XM1))]
14183   "TARGET_USE_FANCY_MATH_387
14184    && flag_unsafe_math_optimizations"
14185   "f2xm1"
14186   [(set_attr "type" "fpspc")
14187    (set_attr "mode" "XF")])
14188
14189 (define_insn "*fscalexf4_i387"
14190   [(set (match_operand:XF 0 "register_operand" "=f")
14191         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14192                     (match_operand:XF 3 "register_operand" "1")]
14193                    UNSPEC_FSCALE_FRACT))
14194    (set (match_operand:XF 1 "register_operand" "=u")
14195         (unspec:XF [(match_dup 2) (match_dup 3)]
14196                    UNSPEC_FSCALE_EXP))]
14197   "TARGET_USE_FANCY_MATH_387
14198    && flag_unsafe_math_optimizations"
14199   "fscale"
14200   [(set_attr "type" "fpspc")
14201    (set_attr "mode" "XF")])
14202
14203 (define_expand "expNcorexf3"
14204   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14205                                (match_operand:XF 2 "register_operand" "")))
14206    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14207    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14208    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14209    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14210    (parallel [(set (match_operand:XF 0 "register_operand" "")
14211                    (unspec:XF [(match_dup 8) (match_dup 4)]
14212                               UNSPEC_FSCALE_FRACT))
14213               (set (match_dup 9)
14214                    (unspec:XF [(match_dup 8) (match_dup 4)]
14215                               UNSPEC_FSCALE_EXP))])]
14216   "TARGET_USE_FANCY_MATH_387
14217    && flag_unsafe_math_optimizations"
14218 {
14219   int i;
14220
14221   if (optimize_insn_for_size_p ())
14222     FAIL;
14223
14224   for (i = 3; i < 10; i++)
14225     operands[i] = gen_reg_rtx (XFmode);
14226
14227   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14228 })
14229
14230 (define_expand "expxf2"
14231   [(use (match_operand:XF 0 "register_operand" ""))
14232    (use (match_operand:XF 1 "register_operand" ""))]
14233   "TARGET_USE_FANCY_MATH_387
14234    && flag_unsafe_math_optimizations"
14235 {
14236   rtx op2;
14237
14238   if (optimize_insn_for_size_p ())
14239     FAIL;
14240
14241   op2 = gen_reg_rtx (XFmode);
14242   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14243
14244   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14245   DONE;
14246 })
14247
14248 (define_expand "exp<mode>2"
14249   [(use (match_operand:MODEF 0 "register_operand" ""))
14250    (use (match_operand:MODEF 1 "general_operand" ""))]
14251  "TARGET_USE_FANCY_MATH_387
14252    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14253        || TARGET_MIX_SSE_I387)
14254    && flag_unsafe_math_optimizations"
14255 {
14256   rtx op0, op1;
14257
14258   if (optimize_insn_for_size_p ())
14259     FAIL;
14260
14261   op0 = gen_reg_rtx (XFmode);
14262   op1 = gen_reg_rtx (XFmode);
14263
14264   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14265   emit_insn (gen_expxf2 (op0, op1));
14266   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14267   DONE;
14268 })
14269
14270 (define_expand "exp10xf2"
14271   [(use (match_operand:XF 0 "register_operand" ""))
14272    (use (match_operand:XF 1 "register_operand" ""))]
14273   "TARGET_USE_FANCY_MATH_387
14274    && flag_unsafe_math_optimizations"
14275 {
14276   rtx op2;
14277
14278   if (optimize_insn_for_size_p ())
14279     FAIL;
14280
14281   op2 = gen_reg_rtx (XFmode);
14282   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14283
14284   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14285   DONE;
14286 })
14287
14288 (define_expand "exp10<mode>2"
14289   [(use (match_operand:MODEF 0 "register_operand" ""))
14290    (use (match_operand:MODEF 1 "general_operand" ""))]
14291  "TARGET_USE_FANCY_MATH_387
14292    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14293        || TARGET_MIX_SSE_I387)
14294    && flag_unsafe_math_optimizations"
14295 {
14296   rtx op0, op1;
14297
14298   if (optimize_insn_for_size_p ())
14299     FAIL;
14300
14301   op0 = gen_reg_rtx (XFmode);
14302   op1 = gen_reg_rtx (XFmode);
14303
14304   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14305   emit_insn (gen_exp10xf2 (op0, op1));
14306   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14307   DONE;
14308 })
14309
14310 (define_expand "exp2xf2"
14311   [(use (match_operand:XF 0 "register_operand" ""))
14312    (use (match_operand:XF 1 "register_operand" ""))]
14313   "TARGET_USE_FANCY_MATH_387
14314    && flag_unsafe_math_optimizations"
14315 {
14316   rtx op2;
14317
14318   if (optimize_insn_for_size_p ())
14319     FAIL;
14320
14321   op2 = gen_reg_rtx (XFmode);
14322   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14323
14324   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14325   DONE;
14326 })
14327
14328 (define_expand "exp2<mode>2"
14329   [(use (match_operand:MODEF 0 "register_operand" ""))
14330    (use (match_operand:MODEF 1 "general_operand" ""))]
14331  "TARGET_USE_FANCY_MATH_387
14332    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14333        || TARGET_MIX_SSE_I387)
14334    && flag_unsafe_math_optimizations"
14335 {
14336   rtx op0, op1;
14337
14338   if (optimize_insn_for_size_p ())
14339     FAIL;
14340
14341   op0 = gen_reg_rtx (XFmode);
14342   op1 = gen_reg_rtx (XFmode);
14343
14344   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14345   emit_insn (gen_exp2xf2 (op0, op1));
14346   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14347   DONE;
14348 })
14349
14350 (define_expand "expm1xf2"
14351   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14352                                (match_dup 2)))
14353    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14354    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14355    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14356    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14357    (parallel [(set (match_dup 7)
14358                    (unspec:XF [(match_dup 6) (match_dup 4)]
14359                               UNSPEC_FSCALE_FRACT))
14360               (set (match_dup 8)
14361                    (unspec:XF [(match_dup 6) (match_dup 4)]
14362                               UNSPEC_FSCALE_EXP))])
14363    (parallel [(set (match_dup 10)
14364                    (unspec:XF [(match_dup 9) (match_dup 8)]
14365                               UNSPEC_FSCALE_FRACT))
14366               (set (match_dup 11)
14367                    (unspec:XF [(match_dup 9) (match_dup 8)]
14368                               UNSPEC_FSCALE_EXP))])
14369    (set (match_dup 12) (minus:XF (match_dup 10)
14370                                  (float_extend:XF (match_dup 13))))
14371    (set (match_operand:XF 0 "register_operand" "")
14372         (plus:XF (match_dup 12) (match_dup 7)))]
14373   "TARGET_USE_FANCY_MATH_387
14374    && flag_unsafe_math_optimizations"
14375 {
14376   int i;
14377
14378   if (optimize_insn_for_size_p ())
14379     FAIL;
14380
14381   for (i = 2; i < 13; i++)
14382     operands[i] = gen_reg_rtx (XFmode);
14383
14384   operands[13]
14385     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14386
14387   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14388 })
14389
14390 (define_expand "expm1<mode>2"
14391   [(use (match_operand:MODEF 0 "register_operand" ""))
14392    (use (match_operand:MODEF 1 "general_operand" ""))]
14393  "TARGET_USE_FANCY_MATH_387
14394    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14395        || TARGET_MIX_SSE_I387)
14396    && flag_unsafe_math_optimizations"
14397 {
14398   rtx op0, op1;
14399
14400   if (optimize_insn_for_size_p ())
14401     FAIL;
14402
14403   op0 = gen_reg_rtx (XFmode);
14404   op1 = gen_reg_rtx (XFmode);
14405
14406   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14407   emit_insn (gen_expm1xf2 (op0, op1));
14408   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14409   DONE;
14410 })
14411
14412 (define_expand "ldexpxf3"
14413   [(set (match_dup 3)
14414         (float:XF (match_operand:SI 2 "register_operand" "")))
14415    (parallel [(set (match_operand:XF 0 " register_operand" "")
14416                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14417                                (match_dup 3)]
14418                               UNSPEC_FSCALE_FRACT))
14419               (set (match_dup 4)
14420                    (unspec:XF [(match_dup 1) (match_dup 3)]
14421                               UNSPEC_FSCALE_EXP))])]
14422   "TARGET_USE_FANCY_MATH_387
14423    && flag_unsafe_math_optimizations"
14424 {
14425   if (optimize_insn_for_size_p ())
14426     FAIL;
14427
14428   operands[3] = gen_reg_rtx (XFmode);
14429   operands[4] = gen_reg_rtx (XFmode);
14430 })
14431
14432 (define_expand "ldexp<mode>3"
14433   [(use (match_operand:MODEF 0 "register_operand" ""))
14434    (use (match_operand:MODEF 1 "general_operand" ""))
14435    (use (match_operand:SI 2 "register_operand" ""))]
14436  "TARGET_USE_FANCY_MATH_387
14437    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14438        || TARGET_MIX_SSE_I387)
14439    && flag_unsafe_math_optimizations"
14440 {
14441   rtx op0, op1;
14442
14443   if (optimize_insn_for_size_p ())
14444     FAIL;
14445
14446   op0 = gen_reg_rtx (XFmode);
14447   op1 = gen_reg_rtx (XFmode);
14448
14449   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14450   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14451   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14452   DONE;
14453 })
14454
14455 (define_expand "scalbxf3"
14456   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14457                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14458                                (match_operand:XF 2 "register_operand" "")]
14459                               UNSPEC_FSCALE_FRACT))
14460               (set (match_dup 3)
14461                    (unspec:XF [(match_dup 1) (match_dup 2)]
14462                               UNSPEC_FSCALE_EXP))])]
14463   "TARGET_USE_FANCY_MATH_387
14464    && flag_unsafe_math_optimizations"
14465 {
14466   if (optimize_insn_for_size_p ())
14467     FAIL;
14468
14469   operands[3] = gen_reg_rtx (XFmode);
14470 })
14471
14472 (define_expand "scalb<mode>3"
14473   [(use (match_operand:MODEF 0 "register_operand" ""))
14474    (use (match_operand:MODEF 1 "general_operand" ""))
14475    (use (match_operand:MODEF 2 "general_operand" ""))]
14476  "TARGET_USE_FANCY_MATH_387
14477    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14478        || TARGET_MIX_SSE_I387)
14479    && flag_unsafe_math_optimizations"
14480 {
14481   rtx op0, op1, op2;
14482
14483   if (optimize_insn_for_size_p ())
14484     FAIL;
14485
14486   op0 = gen_reg_rtx (XFmode);
14487   op1 = gen_reg_rtx (XFmode);
14488   op2 = gen_reg_rtx (XFmode);
14489
14490   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14491   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14492   emit_insn (gen_scalbxf3 (op0, op1, op2));
14493   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14494   DONE;
14495 })
14496
14497 (define_expand "significandxf2"
14498   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14499                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14500                               UNSPEC_XTRACT_FRACT))
14501               (set (match_dup 2)
14502                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14503   "TARGET_USE_FANCY_MATH_387
14504    && flag_unsafe_math_optimizations"
14505   "operands[2] = gen_reg_rtx (XFmode);")
14506
14507 (define_expand "significand<mode>2"
14508   [(use (match_operand:MODEF 0 "register_operand" ""))
14509    (use (match_operand:MODEF 1 "register_operand" ""))]
14510   "TARGET_USE_FANCY_MATH_387
14511    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14512        || TARGET_MIX_SSE_I387)
14513    && flag_unsafe_math_optimizations"
14514 {
14515   rtx op0 = gen_reg_rtx (XFmode);
14516   rtx op1 = gen_reg_rtx (XFmode);
14517
14518   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14519   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14520   DONE;
14521 })
14522 \f
14523
14524 (define_insn "sse4_1_round<mode>2"
14525   [(set (match_operand:MODEF 0 "register_operand" "=x")
14526         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14527                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14528                       UNSPEC_ROUND))]
14529   "TARGET_ROUND"
14530   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14531   [(set_attr "type" "ssecvt")
14532    (set_attr "prefix_extra" "1")
14533    (set_attr "prefix" "maybe_vex")
14534    (set_attr "mode" "<MODE>")])
14535
14536 (define_insn "rintxf2"
14537   [(set (match_operand:XF 0 "register_operand" "=f")
14538         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14539                    UNSPEC_FRNDINT))]
14540   "TARGET_USE_FANCY_MATH_387
14541    && flag_unsafe_math_optimizations"
14542   "frndint"
14543   [(set_attr "type" "fpspc")
14544    (set_attr "mode" "XF")])
14545
14546 (define_expand "rint<mode>2"
14547   [(use (match_operand:MODEF 0 "register_operand" ""))
14548    (use (match_operand:MODEF 1 "register_operand" ""))]
14549   "(TARGET_USE_FANCY_MATH_387
14550     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14551         || TARGET_MIX_SSE_I387)
14552     && flag_unsafe_math_optimizations)
14553    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14554        && !flag_trapping_math)"
14555 {
14556   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14557       && !flag_trapping_math)
14558     {
14559       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14560         FAIL;
14561       if (TARGET_ROUND)
14562         emit_insn (gen_sse4_1_round<mode>2
14563                    (operands[0], operands[1], GEN_INT (0x04)));
14564       else
14565         ix86_expand_rint (operand0, operand1);
14566     }
14567   else
14568     {
14569       rtx op0 = gen_reg_rtx (XFmode);
14570       rtx op1 = gen_reg_rtx (XFmode);
14571
14572       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14573       emit_insn (gen_rintxf2 (op0, op1));
14574
14575       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14576     }
14577   DONE;
14578 })
14579
14580 (define_expand "round<mode>2"
14581   [(match_operand:MODEF 0 "register_operand" "")
14582    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14583   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14584    && !flag_trapping_math && !flag_rounding_math"
14585 {
14586   if (optimize_insn_for_size_p ())
14587     FAIL;
14588   if (TARGET_64BIT || (<MODE>mode != DFmode))
14589     ix86_expand_round (operand0, operand1);
14590   else
14591     ix86_expand_rounddf_32 (operand0, operand1);
14592   DONE;
14593 })
14594
14595 (define_insn_and_split "*fistdi2_1"
14596   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14597         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14598                    UNSPEC_FIST))]
14599   "TARGET_USE_FANCY_MATH_387
14600    && can_create_pseudo_p ()"
14601   "#"
14602   "&& 1"
14603   [(const_int 0)]
14604 {
14605   if (memory_operand (operands[0], VOIDmode))
14606     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14607   else
14608     {
14609       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14610       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14611                                          operands[2]));
14612     }
14613   DONE;
14614 }
14615   [(set_attr "type" "fpspc")
14616    (set_attr "mode" "DI")])
14617
14618 (define_insn "fistdi2"
14619   [(set (match_operand:DI 0 "memory_operand" "=m")
14620         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14621                    UNSPEC_FIST))
14622    (clobber (match_scratch:XF 2 "=&1f"))]
14623   "TARGET_USE_FANCY_MATH_387"
14624   "* return output_fix_trunc (insn, operands, 0);"
14625   [(set_attr "type" "fpspc")
14626    (set_attr "mode" "DI")])
14627
14628 (define_insn "fistdi2_with_temp"
14629   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14630         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14631                    UNSPEC_FIST))
14632    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14633    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14634   "TARGET_USE_FANCY_MATH_387"
14635   "#"
14636   [(set_attr "type" "fpspc")
14637    (set_attr "mode" "DI")])
14638
14639 (define_split
14640   [(set (match_operand:DI 0 "register_operand" "")
14641         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14642                    UNSPEC_FIST))
14643    (clobber (match_operand:DI 2 "memory_operand" ""))
14644    (clobber (match_scratch 3 ""))]
14645   "reload_completed"
14646   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14647               (clobber (match_dup 3))])
14648    (set (match_dup 0) (match_dup 2))])
14649
14650 (define_split
14651   [(set (match_operand:DI 0 "memory_operand" "")
14652         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14653                    UNSPEC_FIST))
14654    (clobber (match_operand:DI 2 "memory_operand" ""))
14655    (clobber (match_scratch 3 ""))]
14656   "reload_completed"
14657   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14658               (clobber (match_dup 3))])])
14659
14660 (define_insn_and_split "*fist<mode>2_1"
14661   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14662         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14663                            UNSPEC_FIST))]
14664   "TARGET_USE_FANCY_MATH_387
14665    && can_create_pseudo_p ()"
14666   "#"
14667   "&& 1"
14668   [(const_int 0)]
14669 {
14670   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14671   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14672                                         operands[2]));
14673   DONE;
14674 }
14675   [(set_attr "type" "fpspc")
14676    (set_attr "mode" "<MODE>")])
14677
14678 (define_insn "fist<mode>2"
14679   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14680         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14681                            UNSPEC_FIST))]
14682   "TARGET_USE_FANCY_MATH_387"
14683   "* return output_fix_trunc (insn, operands, 0);"
14684   [(set_attr "type" "fpspc")
14685    (set_attr "mode" "<MODE>")])
14686
14687 (define_insn "fist<mode>2_with_temp"
14688   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14689         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14690                            UNSPEC_FIST))
14691    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14692   "TARGET_USE_FANCY_MATH_387"
14693   "#"
14694   [(set_attr "type" "fpspc")
14695    (set_attr "mode" "<MODE>")])
14696
14697 (define_split
14698   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14699         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14700                            UNSPEC_FIST))
14701    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14702   "reload_completed"
14703   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14704    (set (match_dup 0) (match_dup 2))])
14705
14706 (define_split
14707   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14708         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14709                            UNSPEC_FIST))
14710    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14711   "reload_completed"
14712   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14713
14714 (define_expand "lrintxf<mode>2"
14715   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14716      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14717                       UNSPEC_FIST))]
14718   "TARGET_USE_FANCY_MATH_387")
14719
14720 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14721   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14722      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14723                         UNSPEC_FIX_NOTRUNC))]
14724   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14725    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14726
14727 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14728   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14729    (match_operand:MODEF 1 "register_operand" "")]
14730   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14731    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14732    && !flag_trapping_math && !flag_rounding_math"
14733 {
14734   if (optimize_insn_for_size_p ())
14735     FAIL;
14736   ix86_expand_lround (operand0, operand1);
14737   DONE;
14738 })
14739
14740 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14741 (define_insn_and_split "frndintxf2_floor"
14742   [(set (match_operand:XF 0 "register_operand" "")
14743         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14744          UNSPEC_FRNDINT_FLOOR))
14745    (clobber (reg:CC FLAGS_REG))]
14746   "TARGET_USE_FANCY_MATH_387
14747    && flag_unsafe_math_optimizations
14748    && can_create_pseudo_p ()"
14749   "#"
14750   "&& 1"
14751   [(const_int 0)]
14752 {
14753   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14754
14755   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14756   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14757
14758   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14759                                         operands[2], operands[3]));
14760   DONE;
14761 }
14762   [(set_attr "type" "frndint")
14763    (set_attr "i387_cw" "floor")
14764    (set_attr "mode" "XF")])
14765
14766 (define_insn "frndintxf2_floor_i387"
14767   [(set (match_operand:XF 0 "register_operand" "=f")
14768         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14769          UNSPEC_FRNDINT_FLOOR))
14770    (use (match_operand:HI 2 "memory_operand" "m"))
14771    (use (match_operand:HI 3 "memory_operand" "m"))]
14772   "TARGET_USE_FANCY_MATH_387
14773    && flag_unsafe_math_optimizations"
14774   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14775   [(set_attr "type" "frndint")
14776    (set_attr "i387_cw" "floor")
14777    (set_attr "mode" "XF")])
14778
14779 (define_expand "floorxf2"
14780   [(use (match_operand:XF 0 "register_operand" ""))
14781    (use (match_operand:XF 1 "register_operand" ""))]
14782   "TARGET_USE_FANCY_MATH_387
14783    && flag_unsafe_math_optimizations"
14784 {
14785   if (optimize_insn_for_size_p ())
14786     FAIL;
14787   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14788   DONE;
14789 })
14790
14791 (define_expand "floor<mode>2"
14792   [(use (match_operand:MODEF 0 "register_operand" ""))
14793    (use (match_operand:MODEF 1 "register_operand" ""))]
14794   "(TARGET_USE_FANCY_MATH_387
14795     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14796         || TARGET_MIX_SSE_I387)
14797     && flag_unsafe_math_optimizations)
14798    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14799        && !flag_trapping_math)"
14800 {
14801   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14802       && !flag_trapping_math
14803       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14804     {
14805       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14806         FAIL;
14807       if (TARGET_ROUND)
14808         emit_insn (gen_sse4_1_round<mode>2
14809                    (operands[0], operands[1], GEN_INT (0x01)));
14810       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14811         ix86_expand_floorceil (operand0, operand1, true);
14812       else
14813         ix86_expand_floorceildf_32 (operand0, operand1, true);
14814     }
14815   else
14816     {
14817       rtx op0, op1;
14818
14819       if (optimize_insn_for_size_p ())
14820         FAIL;
14821
14822       op0 = gen_reg_rtx (XFmode);
14823       op1 = gen_reg_rtx (XFmode);
14824       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14825       emit_insn (gen_frndintxf2_floor (op0, op1));
14826
14827       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14828     }
14829   DONE;
14830 })
14831
14832 (define_insn_and_split "*fist<mode>2_floor_1"
14833   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14834         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14835          UNSPEC_FIST_FLOOR))
14836    (clobber (reg:CC FLAGS_REG))]
14837   "TARGET_USE_FANCY_MATH_387
14838    && flag_unsafe_math_optimizations
14839    && can_create_pseudo_p ()"
14840   "#"
14841   "&& 1"
14842   [(const_int 0)]
14843 {
14844   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14845
14846   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14847   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14848   if (memory_operand (operands[0], VOIDmode))
14849     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14850                                       operands[2], operands[3]));
14851   else
14852     {
14853       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14854       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14855                                                   operands[2], operands[3],
14856                                                   operands[4]));
14857     }
14858   DONE;
14859 }
14860   [(set_attr "type" "fistp")
14861    (set_attr "i387_cw" "floor")
14862    (set_attr "mode" "<MODE>")])
14863
14864 (define_insn "fistdi2_floor"
14865   [(set (match_operand:DI 0 "memory_operand" "=m")
14866         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14867          UNSPEC_FIST_FLOOR))
14868    (use (match_operand:HI 2 "memory_operand" "m"))
14869    (use (match_operand:HI 3 "memory_operand" "m"))
14870    (clobber (match_scratch:XF 4 "=&1f"))]
14871   "TARGET_USE_FANCY_MATH_387
14872    && flag_unsafe_math_optimizations"
14873   "* return output_fix_trunc (insn, operands, 0);"
14874   [(set_attr "type" "fistp")
14875    (set_attr "i387_cw" "floor")
14876    (set_attr "mode" "DI")])
14877
14878 (define_insn "fistdi2_floor_with_temp"
14879   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14880         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14881          UNSPEC_FIST_FLOOR))
14882    (use (match_operand:HI 2 "memory_operand" "m,m"))
14883    (use (match_operand:HI 3 "memory_operand" "m,m"))
14884    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14885    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14886   "TARGET_USE_FANCY_MATH_387
14887    && flag_unsafe_math_optimizations"
14888   "#"
14889   [(set_attr "type" "fistp")
14890    (set_attr "i387_cw" "floor")
14891    (set_attr "mode" "DI")])
14892
14893 (define_split
14894   [(set (match_operand:DI 0 "register_operand" "")
14895         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14896          UNSPEC_FIST_FLOOR))
14897    (use (match_operand:HI 2 "memory_operand" ""))
14898    (use (match_operand:HI 3 "memory_operand" ""))
14899    (clobber (match_operand:DI 4 "memory_operand" ""))
14900    (clobber (match_scratch 5 ""))]
14901   "reload_completed"
14902   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14903               (use (match_dup 2))
14904               (use (match_dup 3))
14905               (clobber (match_dup 5))])
14906    (set (match_dup 0) (match_dup 4))])
14907
14908 (define_split
14909   [(set (match_operand:DI 0 "memory_operand" "")
14910         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14911          UNSPEC_FIST_FLOOR))
14912    (use (match_operand:HI 2 "memory_operand" ""))
14913    (use (match_operand:HI 3 "memory_operand" ""))
14914    (clobber (match_operand:DI 4 "memory_operand" ""))
14915    (clobber (match_scratch 5 ""))]
14916   "reload_completed"
14917   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14918               (use (match_dup 2))
14919               (use (match_dup 3))
14920               (clobber (match_dup 5))])])
14921
14922 (define_insn "fist<mode>2_floor"
14923   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14924         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14925          UNSPEC_FIST_FLOOR))
14926    (use (match_operand:HI 2 "memory_operand" "m"))
14927    (use (match_operand:HI 3 "memory_operand" "m"))]
14928   "TARGET_USE_FANCY_MATH_387
14929    && flag_unsafe_math_optimizations"
14930   "* return output_fix_trunc (insn, operands, 0);"
14931   [(set_attr "type" "fistp")
14932    (set_attr "i387_cw" "floor")
14933    (set_attr "mode" "<MODE>")])
14934
14935 (define_insn "fist<mode>2_floor_with_temp"
14936   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14937         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14938          UNSPEC_FIST_FLOOR))
14939    (use (match_operand:HI 2 "memory_operand" "m,m"))
14940    (use (match_operand:HI 3 "memory_operand" "m,m"))
14941    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14942   "TARGET_USE_FANCY_MATH_387
14943    && flag_unsafe_math_optimizations"
14944   "#"
14945   [(set_attr "type" "fistp")
14946    (set_attr "i387_cw" "floor")
14947    (set_attr "mode" "<MODE>")])
14948
14949 (define_split
14950   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14951         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14952          UNSPEC_FIST_FLOOR))
14953    (use (match_operand:HI 2 "memory_operand" ""))
14954    (use (match_operand:HI 3 "memory_operand" ""))
14955    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14956   "reload_completed"
14957   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14958                                   UNSPEC_FIST_FLOOR))
14959               (use (match_dup 2))
14960               (use (match_dup 3))])
14961    (set (match_dup 0) (match_dup 4))])
14962
14963 (define_split
14964   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14965         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14966          UNSPEC_FIST_FLOOR))
14967    (use (match_operand:HI 2 "memory_operand" ""))
14968    (use (match_operand:HI 3 "memory_operand" ""))
14969    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14970   "reload_completed"
14971   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14972                                   UNSPEC_FIST_FLOOR))
14973               (use (match_dup 2))
14974               (use (match_dup 3))])])
14975
14976 (define_expand "lfloorxf<mode>2"
14977   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14978                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14979                     UNSPEC_FIST_FLOOR))
14980               (clobber (reg:CC FLAGS_REG))])]
14981   "TARGET_USE_FANCY_MATH_387
14982    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14983    && flag_unsafe_math_optimizations")
14984
14985 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14986   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14987    (match_operand:MODEF 1 "register_operand" "")]
14988   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14989    && !flag_trapping_math"
14990 {
14991   if (TARGET_64BIT && optimize_insn_for_size_p ())
14992     FAIL;
14993   ix86_expand_lfloorceil (operand0, operand1, true);
14994   DONE;
14995 })
14996
14997 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14998 (define_insn_and_split "frndintxf2_ceil"
14999   [(set (match_operand:XF 0 "register_operand" "")
15000         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15001          UNSPEC_FRNDINT_CEIL))
15002    (clobber (reg:CC FLAGS_REG))]
15003   "TARGET_USE_FANCY_MATH_387
15004    && flag_unsafe_math_optimizations
15005    && can_create_pseudo_p ()"
15006   "#"
15007   "&& 1"
15008   [(const_int 0)]
15009 {
15010   ix86_optimize_mode_switching[I387_CEIL] = 1;
15011
15012   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15013   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15014
15015   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15016                                        operands[2], operands[3]));
15017   DONE;
15018 }
15019   [(set_attr "type" "frndint")
15020    (set_attr "i387_cw" "ceil")
15021    (set_attr "mode" "XF")])
15022
15023 (define_insn "frndintxf2_ceil_i387"
15024   [(set (match_operand:XF 0 "register_operand" "=f")
15025         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15026          UNSPEC_FRNDINT_CEIL))
15027    (use (match_operand:HI 2 "memory_operand" "m"))
15028    (use (match_operand:HI 3 "memory_operand" "m"))]
15029   "TARGET_USE_FANCY_MATH_387
15030    && flag_unsafe_math_optimizations"
15031   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15032   [(set_attr "type" "frndint")
15033    (set_attr "i387_cw" "ceil")
15034    (set_attr "mode" "XF")])
15035
15036 (define_expand "ceilxf2"
15037   [(use (match_operand:XF 0 "register_operand" ""))
15038    (use (match_operand:XF 1 "register_operand" ""))]
15039   "TARGET_USE_FANCY_MATH_387
15040    && flag_unsafe_math_optimizations"
15041 {
15042   if (optimize_insn_for_size_p ())
15043     FAIL;
15044   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15045   DONE;
15046 })
15047
15048 (define_expand "ceil<mode>2"
15049   [(use (match_operand:MODEF 0 "register_operand" ""))
15050    (use (match_operand:MODEF 1 "register_operand" ""))]
15051   "(TARGET_USE_FANCY_MATH_387
15052     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15053         || TARGET_MIX_SSE_I387)
15054     && flag_unsafe_math_optimizations)
15055    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15056        && !flag_trapping_math)"
15057 {
15058   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15059       && !flag_trapping_math
15060       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15061     {
15062       if (TARGET_ROUND)
15063         emit_insn (gen_sse4_1_round<mode>2
15064                    (operands[0], operands[1], GEN_INT (0x02)));
15065       else if (optimize_insn_for_size_p ())
15066         FAIL;
15067       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15068         ix86_expand_floorceil (operand0, operand1, false);
15069       else
15070         ix86_expand_floorceildf_32 (operand0, operand1, false);
15071     }
15072   else
15073     {
15074       rtx op0, op1;
15075
15076       if (optimize_insn_for_size_p ())
15077         FAIL;
15078
15079       op0 = gen_reg_rtx (XFmode);
15080       op1 = gen_reg_rtx (XFmode);
15081       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15082       emit_insn (gen_frndintxf2_ceil (op0, op1));
15083
15084       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15085     }
15086   DONE;
15087 })
15088
15089 (define_insn_and_split "*fist<mode>2_ceil_1"
15090   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15091         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15092          UNSPEC_FIST_CEIL))
15093    (clobber (reg:CC FLAGS_REG))]
15094   "TARGET_USE_FANCY_MATH_387
15095    && flag_unsafe_math_optimizations
15096    && can_create_pseudo_p ()"
15097   "#"
15098   "&& 1"
15099   [(const_int 0)]
15100 {
15101   ix86_optimize_mode_switching[I387_CEIL] = 1;
15102
15103   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15104   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15105   if (memory_operand (operands[0], VOIDmode))
15106     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15107                                      operands[2], operands[3]));
15108   else
15109     {
15110       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15111       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15112                                                  operands[2], operands[3],
15113                                                  operands[4]));
15114     }
15115   DONE;
15116 }
15117   [(set_attr "type" "fistp")
15118    (set_attr "i387_cw" "ceil")
15119    (set_attr "mode" "<MODE>")])
15120
15121 (define_insn "fistdi2_ceil"
15122   [(set (match_operand:DI 0 "memory_operand" "=m")
15123         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15124          UNSPEC_FIST_CEIL))
15125    (use (match_operand:HI 2 "memory_operand" "m"))
15126    (use (match_operand:HI 3 "memory_operand" "m"))
15127    (clobber (match_scratch:XF 4 "=&1f"))]
15128   "TARGET_USE_FANCY_MATH_387
15129    && flag_unsafe_math_optimizations"
15130   "* return output_fix_trunc (insn, operands, 0);"
15131   [(set_attr "type" "fistp")
15132    (set_attr "i387_cw" "ceil")
15133    (set_attr "mode" "DI")])
15134
15135 (define_insn "fistdi2_ceil_with_temp"
15136   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15137         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15138          UNSPEC_FIST_CEIL))
15139    (use (match_operand:HI 2 "memory_operand" "m,m"))
15140    (use (match_operand:HI 3 "memory_operand" "m,m"))
15141    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15142    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15143   "TARGET_USE_FANCY_MATH_387
15144    && flag_unsafe_math_optimizations"
15145   "#"
15146   [(set_attr "type" "fistp")
15147    (set_attr "i387_cw" "ceil")
15148    (set_attr "mode" "DI")])
15149
15150 (define_split
15151   [(set (match_operand:DI 0 "register_operand" "")
15152         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15153          UNSPEC_FIST_CEIL))
15154    (use (match_operand:HI 2 "memory_operand" ""))
15155    (use (match_operand:HI 3 "memory_operand" ""))
15156    (clobber (match_operand:DI 4 "memory_operand" ""))
15157    (clobber (match_scratch 5 ""))]
15158   "reload_completed"
15159   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15160               (use (match_dup 2))
15161               (use (match_dup 3))
15162               (clobber (match_dup 5))])
15163    (set (match_dup 0) (match_dup 4))])
15164
15165 (define_split
15166   [(set (match_operand:DI 0 "memory_operand" "")
15167         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15168          UNSPEC_FIST_CEIL))
15169    (use (match_operand:HI 2 "memory_operand" ""))
15170    (use (match_operand:HI 3 "memory_operand" ""))
15171    (clobber (match_operand:DI 4 "memory_operand" ""))
15172    (clobber (match_scratch 5 ""))]
15173   "reload_completed"
15174   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15175               (use (match_dup 2))
15176               (use (match_dup 3))
15177               (clobber (match_dup 5))])])
15178
15179 (define_insn "fist<mode>2_ceil"
15180   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15181         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15182          UNSPEC_FIST_CEIL))
15183    (use (match_operand:HI 2 "memory_operand" "m"))
15184    (use (match_operand:HI 3 "memory_operand" "m"))]
15185   "TARGET_USE_FANCY_MATH_387
15186    && flag_unsafe_math_optimizations"
15187   "* return output_fix_trunc (insn, operands, 0);"
15188   [(set_attr "type" "fistp")
15189    (set_attr "i387_cw" "ceil")
15190    (set_attr "mode" "<MODE>")])
15191
15192 (define_insn "fist<mode>2_ceil_with_temp"
15193   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15194         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15195          UNSPEC_FIST_CEIL))
15196    (use (match_operand:HI 2 "memory_operand" "m,m"))
15197    (use (match_operand:HI 3 "memory_operand" "m,m"))
15198    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15199   "TARGET_USE_FANCY_MATH_387
15200    && flag_unsafe_math_optimizations"
15201   "#"
15202   [(set_attr "type" "fistp")
15203    (set_attr "i387_cw" "ceil")
15204    (set_attr "mode" "<MODE>")])
15205
15206 (define_split
15207   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15208         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15209          UNSPEC_FIST_CEIL))
15210    (use (match_operand:HI 2 "memory_operand" ""))
15211    (use (match_operand:HI 3 "memory_operand" ""))
15212    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15213   "reload_completed"
15214   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15215                                   UNSPEC_FIST_CEIL))
15216               (use (match_dup 2))
15217               (use (match_dup 3))])
15218    (set (match_dup 0) (match_dup 4))])
15219
15220 (define_split
15221   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15222         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15223          UNSPEC_FIST_CEIL))
15224    (use (match_operand:HI 2 "memory_operand" ""))
15225    (use (match_operand:HI 3 "memory_operand" ""))
15226    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15227   "reload_completed"
15228   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15229                                   UNSPEC_FIST_CEIL))
15230               (use (match_dup 2))
15231               (use (match_dup 3))])])
15232
15233 (define_expand "lceilxf<mode>2"
15234   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15235                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15236                     UNSPEC_FIST_CEIL))
15237               (clobber (reg:CC FLAGS_REG))])]
15238   "TARGET_USE_FANCY_MATH_387
15239    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15240    && flag_unsafe_math_optimizations")
15241
15242 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15243   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15244    (match_operand:MODEF 1 "register_operand" "")]
15245   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15246    && !flag_trapping_math"
15247 {
15248   ix86_expand_lfloorceil (operand0, operand1, false);
15249   DONE;
15250 })
15251
15252 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15253 (define_insn_and_split "frndintxf2_trunc"
15254   [(set (match_operand:XF 0 "register_operand" "")
15255         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15256          UNSPEC_FRNDINT_TRUNC))
15257    (clobber (reg:CC FLAGS_REG))]
15258   "TARGET_USE_FANCY_MATH_387
15259    && flag_unsafe_math_optimizations
15260    && can_create_pseudo_p ()"
15261   "#"
15262   "&& 1"
15263   [(const_int 0)]
15264 {
15265   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15266
15267   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15268   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15269
15270   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15271                                         operands[2], operands[3]));
15272   DONE;
15273 }
15274   [(set_attr "type" "frndint")
15275    (set_attr "i387_cw" "trunc")
15276    (set_attr "mode" "XF")])
15277
15278 (define_insn "frndintxf2_trunc_i387"
15279   [(set (match_operand:XF 0 "register_operand" "=f")
15280         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15281          UNSPEC_FRNDINT_TRUNC))
15282    (use (match_operand:HI 2 "memory_operand" "m"))
15283    (use (match_operand:HI 3 "memory_operand" "m"))]
15284   "TARGET_USE_FANCY_MATH_387
15285    && flag_unsafe_math_optimizations"
15286   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15287   [(set_attr "type" "frndint")
15288    (set_attr "i387_cw" "trunc")
15289    (set_attr "mode" "XF")])
15290
15291 (define_expand "btruncxf2"
15292   [(use (match_operand:XF 0 "register_operand" ""))
15293    (use (match_operand:XF 1 "register_operand" ""))]
15294   "TARGET_USE_FANCY_MATH_387
15295    && flag_unsafe_math_optimizations"
15296 {
15297   if (optimize_insn_for_size_p ())
15298     FAIL;
15299   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15300   DONE;
15301 })
15302
15303 (define_expand "btrunc<mode>2"
15304   [(use (match_operand:MODEF 0 "register_operand" ""))
15305    (use (match_operand:MODEF 1 "register_operand" ""))]
15306   "(TARGET_USE_FANCY_MATH_387
15307     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15308         || TARGET_MIX_SSE_I387)
15309     && flag_unsafe_math_optimizations)
15310    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15311        && !flag_trapping_math)"
15312 {
15313   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15314       && !flag_trapping_math
15315       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15316     {
15317       if (TARGET_ROUND)
15318         emit_insn (gen_sse4_1_round<mode>2
15319                    (operands[0], operands[1], GEN_INT (0x03)));
15320       else if (optimize_insn_for_size_p ())
15321         FAIL;
15322       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15323         ix86_expand_trunc (operand0, operand1);
15324       else
15325         ix86_expand_truncdf_32 (operand0, operand1);
15326     }
15327   else
15328     {
15329       rtx op0, op1;
15330
15331       if (optimize_insn_for_size_p ())
15332         FAIL;
15333
15334       op0 = gen_reg_rtx (XFmode);
15335       op1 = gen_reg_rtx (XFmode);
15336       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15337       emit_insn (gen_frndintxf2_trunc (op0, op1));
15338
15339       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15340     }
15341   DONE;
15342 })
15343
15344 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15345 (define_insn_and_split "frndintxf2_mask_pm"
15346   [(set (match_operand:XF 0 "register_operand" "")
15347         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15348          UNSPEC_FRNDINT_MASK_PM))
15349    (clobber (reg:CC FLAGS_REG))]
15350   "TARGET_USE_FANCY_MATH_387
15351    && flag_unsafe_math_optimizations
15352    && can_create_pseudo_p ()"
15353   "#"
15354   "&& 1"
15355   [(const_int 0)]
15356 {
15357   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15358
15359   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15360   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15361
15362   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15363                                           operands[2], operands[3]));
15364   DONE;
15365 }
15366   [(set_attr "type" "frndint")
15367    (set_attr "i387_cw" "mask_pm")
15368    (set_attr "mode" "XF")])
15369
15370 (define_insn "frndintxf2_mask_pm_i387"
15371   [(set (match_operand:XF 0 "register_operand" "=f")
15372         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15373          UNSPEC_FRNDINT_MASK_PM))
15374    (use (match_operand:HI 2 "memory_operand" "m"))
15375    (use (match_operand:HI 3 "memory_operand" "m"))]
15376   "TARGET_USE_FANCY_MATH_387
15377    && flag_unsafe_math_optimizations"
15378   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15379   [(set_attr "type" "frndint")
15380    (set_attr "i387_cw" "mask_pm")
15381    (set_attr "mode" "XF")])
15382
15383 (define_expand "nearbyintxf2"
15384   [(use (match_operand:XF 0 "register_operand" ""))
15385    (use (match_operand:XF 1 "register_operand" ""))]
15386   "TARGET_USE_FANCY_MATH_387
15387    && flag_unsafe_math_optimizations"
15388 {
15389   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15390   DONE;
15391 })
15392
15393 (define_expand "nearbyint<mode>2"
15394   [(use (match_operand:MODEF 0 "register_operand" ""))
15395    (use (match_operand:MODEF 1 "register_operand" ""))]
15396   "TARGET_USE_FANCY_MATH_387
15397    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15398        || TARGET_MIX_SSE_I387)
15399    && flag_unsafe_math_optimizations"
15400 {
15401   rtx op0 = gen_reg_rtx (XFmode);
15402   rtx op1 = gen_reg_rtx (XFmode);
15403
15404   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15405   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15406
15407   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15408   DONE;
15409 })
15410
15411 (define_insn "fxam<mode>2_i387"
15412   [(set (match_operand:HI 0 "register_operand" "=a")
15413         (unspec:HI
15414           [(match_operand:X87MODEF 1 "register_operand" "f")]
15415           UNSPEC_FXAM))]
15416   "TARGET_USE_FANCY_MATH_387"
15417   "fxam\n\tfnstsw\t%0"
15418   [(set_attr "type" "multi")
15419    (set_attr "length" "4")
15420    (set_attr "unit" "i387")
15421    (set_attr "mode" "<MODE>")])
15422
15423 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15424   [(set (match_operand:HI 0 "register_operand" "")
15425         (unspec:HI
15426           [(match_operand:MODEF 1 "memory_operand" "")]
15427           UNSPEC_FXAM_MEM))]
15428   "TARGET_USE_FANCY_MATH_387
15429    && can_create_pseudo_p ()"
15430   "#"
15431   "&& 1"
15432   [(set (match_dup 2)(match_dup 1))
15433    (set (match_dup 0)
15434         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15435 {
15436   operands[2] = gen_reg_rtx (<MODE>mode);
15437
15438   MEM_VOLATILE_P (operands[1]) = 1;
15439 }
15440   [(set_attr "type" "multi")
15441    (set_attr "unit" "i387")
15442    (set_attr "mode" "<MODE>")])
15443
15444 (define_expand "isinfxf2"
15445   [(use (match_operand:SI 0 "register_operand" ""))
15446    (use (match_operand:XF 1 "register_operand" ""))]
15447   "TARGET_USE_FANCY_MATH_387
15448    && TARGET_C99_FUNCTIONS"
15449 {
15450   rtx mask = GEN_INT (0x45);
15451   rtx val = GEN_INT (0x05);
15452
15453   rtx cond;
15454
15455   rtx scratch = gen_reg_rtx (HImode);
15456   rtx res = gen_reg_rtx (QImode);
15457
15458   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15459
15460   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15461   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15462   cond = gen_rtx_fmt_ee (EQ, QImode,
15463                          gen_rtx_REG (CCmode, FLAGS_REG),
15464                          const0_rtx);
15465   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15466   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15467   DONE;
15468 })
15469
15470 (define_expand "isinf<mode>2"
15471   [(use (match_operand:SI 0 "register_operand" ""))
15472    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15473   "TARGET_USE_FANCY_MATH_387
15474    && TARGET_C99_FUNCTIONS
15475    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15476 {
15477   rtx mask = GEN_INT (0x45);
15478   rtx val = GEN_INT (0x05);
15479
15480   rtx cond;
15481
15482   rtx scratch = gen_reg_rtx (HImode);
15483   rtx res = gen_reg_rtx (QImode);
15484
15485   /* Remove excess precision by forcing value through memory. */
15486   if (memory_operand (operands[1], VOIDmode))
15487     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15488   else
15489     {
15490       enum ix86_stack_slot slot = (virtuals_instantiated
15491                                    ? SLOT_TEMP
15492                                    : SLOT_VIRTUAL);
15493       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15494
15495       emit_move_insn (temp, operands[1]);
15496       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15497     }
15498
15499   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15500   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15501   cond = gen_rtx_fmt_ee (EQ, QImode,
15502                          gen_rtx_REG (CCmode, FLAGS_REG),
15503                          const0_rtx);
15504   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15505   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15506   DONE;
15507 })
15508
15509 (define_expand "signbitxf2"
15510   [(use (match_operand:SI 0 "register_operand" ""))
15511    (use (match_operand:XF 1 "register_operand" ""))]
15512   "TARGET_USE_FANCY_MATH_387"
15513 {
15514   rtx scratch = gen_reg_rtx (HImode);
15515
15516   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15517   emit_insn (gen_andsi3 (operands[0],
15518              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15519   DONE;
15520 })
15521
15522 (define_insn "movmsk_df"
15523   [(set (match_operand:SI 0 "register_operand" "=r")
15524         (unspec:SI
15525           [(match_operand:DF 1 "register_operand" "x")]
15526           UNSPEC_MOVMSK))]
15527   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15528   "%vmovmskpd\t{%1, %0|%0, %1}"
15529   [(set_attr "type" "ssemov")
15530    (set_attr "prefix" "maybe_vex")
15531    (set_attr "mode" "DF")])
15532
15533 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15534 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15535 (define_expand "signbitdf2"
15536   [(use (match_operand:SI 0 "register_operand" ""))
15537    (use (match_operand:DF 1 "register_operand" ""))]
15538   "TARGET_USE_FANCY_MATH_387
15539    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15540 {
15541   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15542     {
15543       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15544       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15545     }
15546   else
15547     {
15548       rtx scratch = gen_reg_rtx (HImode);
15549
15550       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15551       emit_insn (gen_andsi3 (operands[0],
15552                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15553     }
15554   DONE;
15555 })
15556
15557 (define_expand "signbitsf2"
15558   [(use (match_operand:SI 0 "register_operand" ""))
15559    (use (match_operand:SF 1 "register_operand" ""))]
15560   "TARGET_USE_FANCY_MATH_387
15561    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15562 {
15563   rtx scratch = gen_reg_rtx (HImode);
15564
15565   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15566   emit_insn (gen_andsi3 (operands[0],
15567              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15568   DONE;
15569 })
15570 \f
15571 ;; Block operation instructions
15572
15573 (define_insn "cld"
15574   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15575   ""
15576   "cld"
15577   [(set_attr "length" "1")
15578    (set_attr "length_immediate" "0")
15579    (set_attr "modrm" "0")])
15580
15581 (define_expand "movmem<mode>"
15582   [(use (match_operand:BLK 0 "memory_operand" ""))
15583    (use (match_operand:BLK 1 "memory_operand" ""))
15584    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15585    (use (match_operand:SWI48 3 "const_int_operand" ""))
15586    (use (match_operand:SI 4 "const_int_operand" ""))
15587    (use (match_operand:SI 5 "const_int_operand" ""))]
15588   ""
15589 {
15590  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15591                          operands[4], operands[5]))
15592    DONE;
15593  else
15594    FAIL;
15595 })
15596
15597 ;; Most CPUs don't like single string operations
15598 ;; Handle this case here to simplify previous expander.
15599
15600 (define_expand "strmov"
15601   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15602    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15603    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15604               (clobber (reg:CC FLAGS_REG))])
15605    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15606               (clobber (reg:CC FLAGS_REG))])]
15607   ""
15608 {
15609   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15610
15611   /* If .md ever supports :P for Pmode, these can be directly
15612      in the pattern above.  */
15613   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15614   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15615
15616   /* Can't use this if the user has appropriated esi or edi.  */
15617   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15618       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15619     {
15620       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15621                                       operands[2], operands[3],
15622                                       operands[5], operands[6]));
15623       DONE;
15624     }
15625
15626   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15627 })
15628
15629 (define_expand "strmov_singleop"
15630   [(parallel [(set (match_operand 1 "memory_operand" "")
15631                    (match_operand 3 "memory_operand" ""))
15632               (set (match_operand 0 "register_operand" "")
15633                    (match_operand 4 "" ""))
15634               (set (match_operand 2 "register_operand" "")
15635                    (match_operand 5 "" ""))])]
15636   ""
15637   "ix86_current_function_needs_cld = 1;")
15638
15639 (define_insn "*strmovdi_rex_1"
15640   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15641         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15642    (set (match_operand:DI 0 "register_operand" "=D")
15643         (plus:DI (match_dup 2)
15644                  (const_int 8)))
15645    (set (match_operand:DI 1 "register_operand" "=S")
15646         (plus:DI (match_dup 3)
15647                  (const_int 8)))]
15648   "TARGET_64BIT"
15649   "movsq"
15650   [(set_attr "type" "str")
15651    (set_attr "memory" "both")
15652    (set_attr "mode" "DI")])
15653
15654 (define_insn "*strmovsi_1"
15655   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15656         (mem:SI (match_operand:P 3 "register_operand" "1")))
15657    (set (match_operand:P 0 "register_operand" "=D")
15658         (plus:P (match_dup 2)
15659                 (const_int 4)))
15660    (set (match_operand:P 1 "register_operand" "=S")
15661         (plus:P (match_dup 3)
15662                 (const_int 4)))]
15663   ""
15664   "movs{l|d}"
15665   [(set_attr "type" "str")
15666    (set_attr "memory" "both")
15667    (set_attr "mode" "SI")])
15668
15669 (define_insn "*strmovhi_1"
15670   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15671         (mem:HI (match_operand:P 3 "register_operand" "1")))
15672    (set (match_operand:P 0 "register_operand" "=D")
15673         (plus:P (match_dup 2)
15674                 (const_int 2)))
15675    (set (match_operand:P 1 "register_operand" "=S")
15676         (plus:P (match_dup 3)
15677                 (const_int 2)))]
15678   ""
15679   "movsw"
15680   [(set_attr "type" "str")
15681    (set_attr "memory" "both")
15682    (set_attr "mode" "HI")])
15683
15684 (define_insn "*strmovqi_1"
15685   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15686         (mem:QI (match_operand:P 3 "register_operand" "1")))
15687    (set (match_operand:P 0 "register_operand" "=D")
15688         (plus:P (match_dup 2)
15689                 (const_int 1)))
15690    (set (match_operand:P 1 "register_operand" "=S")
15691         (plus:P (match_dup 3)
15692                 (const_int 1)))]
15693   ""
15694   "movsb"
15695   [(set_attr "type" "str")
15696    (set_attr "memory" "both")
15697    (set (attr "prefix_rex")
15698         (if_then_else
15699           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15700           (const_string "0")
15701           (const_string "*")))
15702    (set_attr "mode" "QI")])
15703
15704 (define_expand "rep_mov"
15705   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15706               (set (match_operand 0 "register_operand" "")
15707                    (match_operand 5 "" ""))
15708               (set (match_operand 2 "register_operand" "")
15709                    (match_operand 6 "" ""))
15710               (set (match_operand 1 "memory_operand" "")
15711                    (match_operand 3 "memory_operand" ""))
15712               (use (match_dup 4))])]
15713   ""
15714   "ix86_current_function_needs_cld = 1;")
15715
15716 (define_insn "*rep_movdi_rex64"
15717   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15718    (set (match_operand:DI 0 "register_operand" "=D")
15719         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15720                             (const_int 3))
15721                  (match_operand:DI 3 "register_operand" "0")))
15722    (set (match_operand:DI 1 "register_operand" "=S")
15723         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15724                  (match_operand:DI 4 "register_operand" "1")))
15725    (set (mem:BLK (match_dup 3))
15726         (mem:BLK (match_dup 4)))
15727    (use (match_dup 5))]
15728   "TARGET_64BIT"
15729   "rep{%;} movsq"
15730   [(set_attr "type" "str")
15731    (set_attr "prefix_rep" "1")
15732    (set_attr "memory" "both")
15733    (set_attr "mode" "DI")])
15734
15735 (define_insn "*rep_movsi"
15736   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15737    (set (match_operand:P 0 "register_operand" "=D")
15738         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15739                           (const_int 2))
15740                  (match_operand:P 3 "register_operand" "0")))
15741    (set (match_operand:P 1 "register_operand" "=S")
15742         (plus:P (ashift:P (match_dup 5) (const_int 2))
15743                 (match_operand:P 4 "register_operand" "1")))
15744    (set (mem:BLK (match_dup 3))
15745         (mem:BLK (match_dup 4)))
15746    (use (match_dup 5))]
15747   ""
15748   "rep{%;} movs{l|d}"
15749   [(set_attr "type" "str")
15750    (set_attr "prefix_rep" "1")
15751    (set_attr "memory" "both")
15752    (set_attr "mode" "SI")])
15753
15754 (define_insn "*rep_movqi"
15755   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15756    (set (match_operand:P 0 "register_operand" "=D")
15757         (plus:P (match_operand:P 3 "register_operand" "0")
15758                 (match_operand:P 5 "register_operand" "2")))
15759    (set (match_operand:P 1 "register_operand" "=S")
15760         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15761    (set (mem:BLK (match_dup 3))
15762         (mem:BLK (match_dup 4)))
15763    (use (match_dup 5))]
15764   ""
15765   "rep{%;} movsb"
15766   [(set_attr "type" "str")
15767    (set_attr "prefix_rep" "1")
15768    (set_attr "memory" "both")
15769    (set_attr "mode" "QI")])
15770
15771 (define_expand "setmem<mode>"
15772    [(use (match_operand:BLK 0 "memory_operand" ""))
15773     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15774     (use (match_operand 2 "const_int_operand" ""))
15775     (use (match_operand 3 "const_int_operand" ""))
15776     (use (match_operand:SI 4 "const_int_operand" ""))
15777     (use (match_operand:SI 5 "const_int_operand" ""))]
15778   ""
15779 {
15780  if (ix86_expand_setmem (operands[0], operands[1],
15781                          operands[2], operands[3],
15782                          operands[4], operands[5]))
15783    DONE;
15784  else
15785    FAIL;
15786 })
15787
15788 ;; Most CPUs don't like single string operations
15789 ;; Handle this case here to simplify previous expander.
15790
15791 (define_expand "strset"
15792   [(set (match_operand 1 "memory_operand" "")
15793         (match_operand 2 "register_operand" ""))
15794    (parallel [(set (match_operand 0 "register_operand" "")
15795                    (match_dup 3))
15796               (clobber (reg:CC FLAGS_REG))])]
15797   ""
15798 {
15799   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15800     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15801
15802   /* If .md ever supports :P for Pmode, this can be directly
15803      in the pattern above.  */
15804   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15805                               GEN_INT (GET_MODE_SIZE (GET_MODE
15806                                                       (operands[2]))));
15807   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15808     {
15809       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15810                                       operands[3]));
15811       DONE;
15812     }
15813 })
15814
15815 (define_expand "strset_singleop"
15816   [(parallel [(set (match_operand 1 "memory_operand" "")
15817                    (match_operand 2 "register_operand" ""))
15818               (set (match_operand 0 "register_operand" "")
15819                    (match_operand 3 "" ""))])]
15820   ""
15821   "ix86_current_function_needs_cld = 1;")
15822
15823 (define_insn "*strsetdi_rex_1"
15824   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15825         (match_operand:DI 2 "register_operand" "a"))
15826    (set (match_operand:DI 0 "register_operand" "=D")
15827         (plus:DI (match_dup 1)
15828                  (const_int 8)))]
15829   "TARGET_64BIT"
15830   "stosq"
15831   [(set_attr "type" "str")
15832    (set_attr "memory" "store")
15833    (set_attr "mode" "DI")])
15834
15835 (define_insn "*strsetsi_1"
15836   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15837         (match_operand:SI 2 "register_operand" "a"))
15838    (set (match_operand:P 0 "register_operand" "=D")
15839         (plus:P (match_dup 1)
15840                 (const_int 4)))]
15841   ""
15842   "stos{l|d}"
15843   [(set_attr "type" "str")
15844    (set_attr "memory" "store")
15845    (set_attr "mode" "SI")])
15846
15847 (define_insn "*strsethi_1"
15848   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15849         (match_operand:HI 2 "register_operand" "a"))
15850    (set (match_operand:P 0 "register_operand" "=D")
15851         (plus:P (match_dup 1)
15852                 (const_int 2)))]
15853   ""
15854   "stosw"
15855   [(set_attr "type" "str")
15856    (set_attr "memory" "store")
15857    (set_attr "mode" "HI")])
15858
15859 (define_insn "*strsetqi_1"
15860   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15861         (match_operand:QI 2 "register_operand" "a"))
15862    (set (match_operand:P 0 "register_operand" "=D")
15863         (plus:P (match_dup 1)
15864                 (const_int 1)))]
15865   ""
15866   "stosb"
15867   [(set_attr "type" "str")
15868    (set_attr "memory" "store")
15869    (set (attr "prefix_rex")
15870         (if_then_else
15871           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15872           (const_string "0")
15873           (const_string "*")))
15874    (set_attr "mode" "QI")])
15875
15876 (define_expand "rep_stos"
15877   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15878               (set (match_operand 0 "register_operand" "")
15879                    (match_operand 4 "" ""))
15880               (set (match_operand 2 "memory_operand" "") (const_int 0))
15881               (use (match_operand 3 "register_operand" ""))
15882               (use (match_dup 1))])]
15883   ""
15884   "ix86_current_function_needs_cld = 1;")
15885
15886 (define_insn "*rep_stosdi_rex64"
15887   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15888    (set (match_operand:DI 0 "register_operand" "=D")
15889         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15890                             (const_int 3))
15891                  (match_operand:DI 3 "register_operand" "0")))
15892    (set (mem:BLK (match_dup 3))
15893         (const_int 0))
15894    (use (match_operand:DI 2 "register_operand" "a"))
15895    (use (match_dup 4))]
15896   "TARGET_64BIT"
15897   "rep{%;} stosq"
15898   [(set_attr "type" "str")
15899    (set_attr "prefix_rep" "1")
15900    (set_attr "memory" "store")
15901    (set_attr "mode" "DI")])
15902
15903 (define_insn "*rep_stossi"
15904   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15905    (set (match_operand:P 0 "register_operand" "=D")
15906         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15907                           (const_int 2))
15908                  (match_operand:P 3 "register_operand" "0")))
15909    (set (mem:BLK (match_dup 3))
15910         (const_int 0))
15911    (use (match_operand:SI 2 "register_operand" "a"))
15912    (use (match_dup 4))]
15913   ""
15914   "rep{%;} stos{l|d}"
15915   [(set_attr "type" "str")
15916    (set_attr "prefix_rep" "1")
15917    (set_attr "memory" "store")
15918    (set_attr "mode" "SI")])
15919
15920 (define_insn "*rep_stosqi"
15921   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15922    (set (match_operand:P 0 "register_operand" "=D")
15923         (plus:P (match_operand:P 3 "register_operand" "0")
15924                 (match_operand:P 4 "register_operand" "1")))
15925    (set (mem:BLK (match_dup 3))
15926         (const_int 0))
15927    (use (match_operand:QI 2 "register_operand" "a"))
15928    (use (match_dup 4))]
15929   ""
15930   "rep{%;} stosb"
15931   [(set_attr "type" "str")
15932    (set_attr "prefix_rep" "1")
15933    (set_attr "memory" "store")
15934    (set (attr "prefix_rex")
15935         (if_then_else
15936           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15937           (const_string "0")
15938           (const_string "*")))
15939    (set_attr "mode" "QI")])
15940
15941 (define_expand "cmpstrnsi"
15942   [(set (match_operand:SI 0 "register_operand" "")
15943         (compare:SI (match_operand:BLK 1 "general_operand" "")
15944                     (match_operand:BLK 2 "general_operand" "")))
15945    (use (match_operand 3 "general_operand" ""))
15946    (use (match_operand 4 "immediate_operand" ""))]
15947   ""
15948 {
15949   rtx addr1, addr2, out, outlow, count, countreg, align;
15950
15951   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15952     FAIL;
15953
15954   /* Can't use this if the user has appropriated esi or edi.  */
15955   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15956     FAIL;
15957
15958   out = operands[0];
15959   if (!REG_P (out))
15960     out = gen_reg_rtx (SImode);
15961
15962   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15963   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15964   if (addr1 != XEXP (operands[1], 0))
15965     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15966   if (addr2 != XEXP (operands[2], 0))
15967     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15968
15969   count = operands[3];
15970   countreg = ix86_zero_extend_to_Pmode (count);
15971
15972   /* %%% Iff we are testing strict equality, we can use known alignment
15973      to good advantage.  This may be possible with combine, particularly
15974      once cc0 is dead.  */
15975   align = operands[4];
15976
15977   if (CONST_INT_P (count))
15978     {
15979       if (INTVAL (count) == 0)
15980         {
15981           emit_move_insn (operands[0], const0_rtx);
15982           DONE;
15983         }
15984       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15985                                      operands[1], operands[2]));
15986     }
15987   else
15988     {
15989       rtx (*gen_cmp) (rtx, rtx);
15990
15991       gen_cmp = (TARGET_64BIT
15992                  ? gen_cmpdi_1 : gen_cmpsi_1);
15993
15994       emit_insn (gen_cmp (countreg, countreg));
15995       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15996                                   operands[1], operands[2]));
15997     }
15998
15999   outlow = gen_lowpart (QImode, out);
16000   emit_insn (gen_cmpintqi (outlow));
16001   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16002
16003   if (operands[0] != out)
16004     emit_move_insn (operands[0], out);
16005
16006   DONE;
16007 })
16008
16009 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16010
16011 (define_expand "cmpintqi"
16012   [(set (match_dup 1)
16013         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16014    (set (match_dup 2)
16015         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16016    (parallel [(set (match_operand:QI 0 "register_operand" "")
16017                    (minus:QI (match_dup 1)
16018                              (match_dup 2)))
16019               (clobber (reg:CC FLAGS_REG))])]
16020   ""
16021 {
16022   operands[1] = gen_reg_rtx (QImode);
16023   operands[2] = gen_reg_rtx (QImode);
16024 })
16025
16026 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16027 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16028
16029 (define_expand "cmpstrnqi_nz_1"
16030   [(parallel [(set (reg:CC FLAGS_REG)
16031                    (compare:CC (match_operand 4 "memory_operand" "")
16032                                (match_operand 5 "memory_operand" "")))
16033               (use (match_operand 2 "register_operand" ""))
16034               (use (match_operand:SI 3 "immediate_operand" ""))
16035               (clobber (match_operand 0 "register_operand" ""))
16036               (clobber (match_operand 1 "register_operand" ""))
16037               (clobber (match_dup 2))])]
16038   ""
16039   "ix86_current_function_needs_cld = 1;")
16040
16041 (define_insn "*cmpstrnqi_nz_1"
16042   [(set (reg:CC FLAGS_REG)
16043         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16044                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16045    (use (match_operand:P 6 "register_operand" "2"))
16046    (use (match_operand:SI 3 "immediate_operand" "i"))
16047    (clobber (match_operand:P 0 "register_operand" "=S"))
16048    (clobber (match_operand:P 1 "register_operand" "=D"))
16049    (clobber (match_operand:P 2 "register_operand" "=c"))]
16050   ""
16051   "repz{%;} cmpsb"
16052   [(set_attr "type" "str")
16053    (set_attr "mode" "QI")
16054    (set (attr "prefix_rex")
16055         (if_then_else
16056           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16057           (const_string "0")
16058           (const_string "*")))
16059    (set_attr "prefix_rep" "1")])
16060
16061 ;; The same, but the count is not known to not be zero.
16062
16063 (define_expand "cmpstrnqi_1"
16064   [(parallel [(set (reg:CC FLAGS_REG)
16065                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16066                                      (const_int 0))
16067                   (compare:CC (match_operand 4 "memory_operand" "")
16068                               (match_operand 5 "memory_operand" ""))
16069                   (const_int 0)))
16070               (use (match_operand:SI 3 "immediate_operand" ""))
16071               (use (reg:CC FLAGS_REG))
16072               (clobber (match_operand 0 "register_operand" ""))
16073               (clobber (match_operand 1 "register_operand" ""))
16074               (clobber (match_dup 2))])]
16075   ""
16076   "ix86_current_function_needs_cld = 1;")
16077
16078 (define_insn "*cmpstrnqi_1"
16079   [(set (reg:CC FLAGS_REG)
16080         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16081                              (const_int 0))
16082           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16083                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16084           (const_int 0)))
16085    (use (match_operand:SI 3 "immediate_operand" "i"))
16086    (use (reg:CC FLAGS_REG))
16087    (clobber (match_operand:P 0 "register_operand" "=S"))
16088    (clobber (match_operand:P 1 "register_operand" "=D"))
16089    (clobber (match_operand:P 2 "register_operand" "=c"))]
16090   ""
16091   "repz{%;} cmpsb"
16092   [(set_attr "type" "str")
16093    (set_attr "mode" "QI")
16094    (set (attr "prefix_rex")
16095         (if_then_else
16096           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16097           (const_string "0")
16098           (const_string "*")))
16099    (set_attr "prefix_rep" "1")])
16100
16101 (define_expand "strlen<mode>"
16102   [(set (match_operand:SWI48x 0 "register_operand" "")
16103         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16104                         (match_operand:QI 2 "immediate_operand" "")
16105                         (match_operand 3 "immediate_operand" "")]
16106                        UNSPEC_SCAS))]
16107   ""
16108 {
16109  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16110    DONE;
16111  else
16112    FAIL;
16113 })
16114
16115 (define_expand "strlenqi_1"
16116   [(parallel [(set (match_operand 0 "register_operand" "")
16117                    (match_operand 2 "" ""))
16118               (clobber (match_operand 1 "register_operand" ""))
16119               (clobber (reg:CC FLAGS_REG))])]
16120   ""
16121   "ix86_current_function_needs_cld = 1;")
16122
16123 (define_insn "*strlenqi_1"
16124   [(set (match_operand:P 0 "register_operand" "=&c")
16125         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16126                    (match_operand:QI 2 "register_operand" "a")
16127                    (match_operand:P 3 "immediate_operand" "i")
16128                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16129    (clobber (match_operand:P 1 "register_operand" "=D"))
16130    (clobber (reg:CC FLAGS_REG))]
16131   ""
16132   "repnz{%;} scasb"
16133   [(set_attr "type" "str")
16134    (set_attr "mode" "QI")
16135    (set (attr "prefix_rex")
16136         (if_then_else
16137           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16138           (const_string "0")
16139           (const_string "*")))
16140    (set_attr "prefix_rep" "1")])
16141
16142 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16143 ;; handled in combine, but it is not currently up to the task.
16144 ;; When used for their truth value, the cmpstrn* expanders generate
16145 ;; code like this:
16146 ;;
16147 ;;   repz cmpsb
16148 ;;   seta       %al
16149 ;;   setb       %dl
16150 ;;   cmpb       %al, %dl
16151 ;;   jcc        label
16152 ;;
16153 ;; The intermediate three instructions are unnecessary.
16154
16155 ;; This one handles cmpstrn*_nz_1...
16156 (define_peephole2
16157   [(parallel[
16158      (set (reg:CC FLAGS_REG)
16159           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16160                       (mem:BLK (match_operand 5 "register_operand" ""))))
16161      (use (match_operand 6 "register_operand" ""))
16162      (use (match_operand:SI 3 "immediate_operand" ""))
16163      (clobber (match_operand 0 "register_operand" ""))
16164      (clobber (match_operand 1 "register_operand" ""))
16165      (clobber (match_operand 2 "register_operand" ""))])
16166    (set (match_operand:QI 7 "register_operand" "")
16167         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16168    (set (match_operand:QI 8 "register_operand" "")
16169         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16170    (set (reg FLAGS_REG)
16171         (compare (match_dup 7) (match_dup 8)))
16172   ]
16173   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16174   [(parallel[
16175      (set (reg:CC FLAGS_REG)
16176           (compare:CC (mem:BLK (match_dup 4))
16177                       (mem:BLK (match_dup 5))))
16178      (use (match_dup 6))
16179      (use (match_dup 3))
16180      (clobber (match_dup 0))
16181      (clobber (match_dup 1))
16182      (clobber (match_dup 2))])])
16183
16184 ;; ...and this one handles cmpstrn*_1.
16185 (define_peephole2
16186   [(parallel[
16187      (set (reg:CC FLAGS_REG)
16188           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16189                                (const_int 0))
16190             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16191                         (mem:BLK (match_operand 5 "register_operand" "")))
16192             (const_int 0)))
16193      (use (match_operand:SI 3 "immediate_operand" ""))
16194      (use (reg:CC FLAGS_REG))
16195      (clobber (match_operand 0 "register_operand" ""))
16196      (clobber (match_operand 1 "register_operand" ""))
16197      (clobber (match_operand 2 "register_operand" ""))])
16198    (set (match_operand:QI 7 "register_operand" "")
16199         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16200    (set (match_operand:QI 8 "register_operand" "")
16201         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16202    (set (reg FLAGS_REG)
16203         (compare (match_dup 7) (match_dup 8)))
16204   ]
16205   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16206   [(parallel[
16207      (set (reg:CC FLAGS_REG)
16208           (if_then_else:CC (ne (match_dup 6)
16209                                (const_int 0))
16210             (compare:CC (mem:BLK (match_dup 4))
16211                         (mem:BLK (match_dup 5)))
16212             (const_int 0)))
16213      (use (match_dup 3))
16214      (use (reg:CC FLAGS_REG))
16215      (clobber (match_dup 0))
16216      (clobber (match_dup 1))
16217      (clobber (match_dup 2))])])
16218 \f
16219 ;; Conditional move instructions.
16220
16221 (define_expand "mov<mode>cc"
16222   [(set (match_operand:SWIM 0 "register_operand" "")
16223         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16224                            (match_operand:SWIM 2 "general_operand" "")
16225                            (match_operand:SWIM 3 "general_operand" "")))]
16226   ""
16227   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16228
16229 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16230 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16231 ;; So just document what we're doing explicitly.
16232
16233 (define_expand "x86_mov<mode>cc_0_m1"
16234   [(parallel
16235     [(set (match_operand:SWI48 0 "register_operand" "")
16236           (if_then_else:SWI48
16237             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16238              [(match_operand 1 "flags_reg_operand" "")
16239               (const_int 0)])
16240             (const_int -1)
16241             (const_int 0)))
16242      (clobber (reg:CC FLAGS_REG))])])
16243
16244 (define_insn "*x86_mov<mode>cc_0_m1"
16245   [(set (match_operand:SWI48 0 "register_operand" "=r")
16246         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16247                              [(reg FLAGS_REG) (const_int 0)])
16248           (const_int -1)
16249           (const_int 0)))
16250    (clobber (reg:CC FLAGS_REG))]
16251   ""
16252   "sbb{<imodesuffix>}\t%0, %0"
16253   ; Since we don't have the proper number of operands for an alu insn,
16254   ; fill in all the blanks.
16255   [(set_attr "type" "alu")
16256    (set_attr "use_carry" "1")
16257    (set_attr "pent_pair" "pu")
16258    (set_attr "memory" "none")
16259    (set_attr "imm_disp" "false")
16260    (set_attr "mode" "<MODE>")
16261    (set_attr "length_immediate" "0")])
16262
16263 (define_insn "*x86_mov<mode>cc_0_m1_se"
16264   [(set (match_operand:SWI48 0 "register_operand" "=r")
16265         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16266                              [(reg FLAGS_REG) (const_int 0)])
16267                             (const_int 1)
16268                             (const_int 0)))
16269    (clobber (reg:CC FLAGS_REG))]
16270   ""
16271   "sbb{<imodesuffix>}\t%0, %0"
16272   [(set_attr "type" "alu")
16273    (set_attr "use_carry" "1")
16274    (set_attr "pent_pair" "pu")
16275    (set_attr "memory" "none")
16276    (set_attr "imm_disp" "false")
16277    (set_attr "mode" "<MODE>")
16278    (set_attr "length_immediate" "0")])
16279
16280 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16281   [(set (match_operand:SWI48 0 "register_operand" "=r")
16282         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16283                     [(reg FLAGS_REG) (const_int 0)])))]
16284   ""
16285   "sbb{<imodesuffix>}\t%0, %0"
16286   [(set_attr "type" "alu")
16287    (set_attr "use_carry" "1")
16288    (set_attr "pent_pair" "pu")
16289    (set_attr "memory" "none")
16290    (set_attr "imm_disp" "false")
16291    (set_attr "mode" "<MODE>")
16292    (set_attr "length_immediate" "0")])
16293
16294 (define_insn "*mov<mode>cc_noc"
16295   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16296         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16297                                [(reg FLAGS_REG) (const_int 0)])
16298           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16299           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16300   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16301   "@
16302    cmov%O2%C1\t{%2, %0|%0, %2}
16303    cmov%O2%c1\t{%3, %0|%0, %3}"
16304   [(set_attr "type" "icmov")
16305    (set_attr "mode" "<MODE>")])
16306
16307 (define_insn_and_split "*movqicc_noc"
16308   [(set (match_operand:QI 0 "register_operand" "=r,r")
16309         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16310                            [(match_operand 4 "flags_reg_operand" "")
16311                             (const_int 0)])
16312                       (match_operand:QI 2 "register_operand" "r,0")
16313                       (match_operand:QI 3 "register_operand" "0,r")))]
16314   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16315   "#"
16316   "&& reload_completed"
16317   [(set (match_dup 0)
16318         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16319                       (match_dup 2)
16320                       (match_dup 3)))]
16321   "operands[0] = gen_lowpart (SImode, operands[0]);
16322    operands[2] = gen_lowpart (SImode, operands[2]);
16323    operands[3] = gen_lowpart (SImode, operands[3]);"
16324   [(set_attr "type" "icmov")
16325    (set_attr "mode" "SI")])
16326
16327 (define_expand "mov<mode>cc"
16328   [(set (match_operand:X87MODEF 0 "register_operand" "")
16329         (if_then_else:X87MODEF
16330           (match_operand 1 "ix86_fp_comparison_operator" "")
16331           (match_operand:X87MODEF 2 "register_operand" "")
16332           (match_operand:X87MODEF 3 "register_operand" "")))]
16333   "(TARGET_80387 && TARGET_CMOVE)
16334    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16335   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16336
16337 (define_insn "*movxfcc_1"
16338   [(set (match_operand:XF 0 "register_operand" "=f,f")
16339         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16340                                 [(reg FLAGS_REG) (const_int 0)])
16341                       (match_operand:XF 2 "register_operand" "f,0")
16342                       (match_operand:XF 3 "register_operand" "0,f")))]
16343   "TARGET_80387 && TARGET_CMOVE"
16344   "@
16345    fcmov%F1\t{%2, %0|%0, %2}
16346    fcmov%f1\t{%3, %0|%0, %3}"
16347   [(set_attr "type" "fcmov")
16348    (set_attr "mode" "XF")])
16349
16350 (define_insn "*movdfcc_1_rex64"
16351   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16352         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16353                                 [(reg FLAGS_REG) (const_int 0)])
16354                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16355                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16356   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16357    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16358   "@
16359    fcmov%F1\t{%2, %0|%0, %2}
16360    fcmov%f1\t{%3, %0|%0, %3}
16361    cmov%O2%C1\t{%2, %0|%0, %2}
16362    cmov%O2%c1\t{%3, %0|%0, %3}"
16363   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16364    (set_attr "mode" "DF,DF,DI,DI")])
16365
16366 (define_insn "*movdfcc_1"
16367   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16368         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16369                                 [(reg FLAGS_REG) (const_int 0)])
16370                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16371                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16372   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16373    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16374   "@
16375    fcmov%F1\t{%2, %0|%0, %2}
16376    fcmov%f1\t{%3, %0|%0, %3}
16377    #
16378    #"
16379   [(set_attr "type" "fcmov,fcmov,multi,multi")
16380    (set_attr "mode" "DF,DF,DI,DI")])
16381
16382 (define_split
16383   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16384         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16385                                 [(match_operand 4 "flags_reg_operand" "")
16386                                  (const_int 0)])
16387                       (match_operand:DF 2 "nonimmediate_operand" "")
16388                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16389   "!TARGET_64BIT && reload_completed"
16390   [(set (match_dup 2)
16391         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16392                       (match_dup 5)
16393                       (match_dup 6)))
16394    (set (match_dup 3)
16395         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16396                       (match_dup 7)
16397                       (match_dup 8)))]
16398 {
16399   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16400   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16401 })
16402
16403 (define_insn "*movsfcc_1_387"
16404   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16405         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16406                                 [(reg FLAGS_REG) (const_int 0)])
16407                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16408                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16409   "TARGET_80387 && TARGET_CMOVE
16410    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16411   "@
16412    fcmov%F1\t{%2, %0|%0, %2}
16413    fcmov%f1\t{%3, %0|%0, %3}
16414    cmov%O2%C1\t{%2, %0|%0, %2}
16415    cmov%O2%c1\t{%3, %0|%0, %3}"
16416   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16417    (set_attr "mode" "SF,SF,SI,SI")])
16418
16419 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16420 ;; the scalar versions to have only XMM registers as operands.
16421
16422 ;; XOP conditional move
16423 (define_insn "*xop_pcmov_<mode>"
16424   [(set (match_operand:MODEF 0 "register_operand" "=x")
16425         (if_then_else:MODEF
16426           (match_operand:MODEF 1 "register_operand" "x")
16427           (match_operand:MODEF 2 "register_operand" "x")
16428           (match_operand:MODEF 3 "register_operand" "x")))]
16429   "TARGET_XOP"
16430   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16431   [(set_attr "type" "sse4arg")])
16432
16433 ;; These versions of the min/max patterns are intentionally ignorant of
16434 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16435 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16436 ;; are undefined in this condition, we're certain this is correct.
16437
16438 (define_insn "*avx_<code><mode>3"
16439   [(set (match_operand:MODEF 0 "register_operand" "=x")
16440         (smaxmin:MODEF
16441           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16442           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16443   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16444   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16445   [(set_attr "type" "sseadd")
16446    (set_attr "prefix" "vex")
16447    (set_attr "mode" "<MODE>")])
16448
16449 (define_insn "<code><mode>3"
16450   [(set (match_operand:MODEF 0 "register_operand" "=x")
16451         (smaxmin:MODEF
16452           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16453           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16454   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16455   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16456   [(set_attr "type" "sseadd")
16457    (set_attr "mode" "<MODE>")])
16458
16459 ;; These versions of the min/max patterns implement exactly the operations
16460 ;;   min = (op1 < op2 ? op1 : op2)
16461 ;;   max = (!(op1 < op2) ? op1 : op2)
16462 ;; Their operands are not commutative, and thus they may be used in the
16463 ;; presence of -0.0 and NaN.
16464
16465 (define_insn "*avx_ieee_smin<mode>3"
16466   [(set (match_operand:MODEF 0 "register_operand" "=x")
16467         (unspec:MODEF
16468           [(match_operand:MODEF 1 "register_operand" "x")
16469            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16470          UNSPEC_IEEE_MIN))]
16471   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16472   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16473   [(set_attr "type" "sseadd")
16474    (set_attr "prefix" "vex")
16475    (set_attr "mode" "<MODE>")])
16476
16477 (define_insn "*ieee_smin<mode>3"
16478   [(set (match_operand:MODEF 0 "register_operand" "=x")
16479         (unspec:MODEF
16480           [(match_operand:MODEF 1 "register_operand" "0")
16481            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16482          UNSPEC_IEEE_MIN))]
16483   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16484   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16485   [(set_attr "type" "sseadd")
16486    (set_attr "mode" "<MODE>")])
16487
16488 (define_insn "*avx_ieee_smax<mode>3"
16489   [(set (match_operand:MODEF 0 "register_operand" "=x")
16490         (unspec:MODEF
16491           [(match_operand:MODEF 1 "register_operand" "0")
16492            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16493          UNSPEC_IEEE_MAX))]
16494   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16495   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16496   [(set_attr "type" "sseadd")
16497    (set_attr "prefix" "vex")
16498    (set_attr "mode" "<MODE>")])
16499
16500 (define_insn "*ieee_smax<mode>3"
16501   [(set (match_operand:MODEF 0 "register_operand" "=x")
16502         (unspec:MODEF
16503           [(match_operand:MODEF 1 "register_operand" "0")
16504            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16505          UNSPEC_IEEE_MAX))]
16506   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16507   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16508   [(set_attr "type" "sseadd")
16509    (set_attr "mode" "<MODE>")])
16510
16511 ;; Make two stack loads independent:
16512 ;;   fld aa              fld aa
16513 ;;   fld %st(0)     ->   fld bb
16514 ;;   fmul bb             fmul %st(1), %st
16515 ;;
16516 ;; Actually we only match the last two instructions for simplicity.
16517 (define_peephole2
16518   [(set (match_operand 0 "fp_register_operand" "")
16519         (match_operand 1 "fp_register_operand" ""))
16520    (set (match_dup 0)
16521         (match_operator 2 "binary_fp_operator"
16522            [(match_dup 0)
16523             (match_operand 3 "memory_operand" "")]))]
16524   "REGNO (operands[0]) != REGNO (operands[1])"
16525   [(set (match_dup 0) (match_dup 3))
16526    (set (match_dup 0) (match_dup 4))]
16527
16528   ;; The % modifier is not operational anymore in peephole2's, so we have to
16529   ;; swap the operands manually in the case of addition and multiplication.
16530   "if (COMMUTATIVE_ARITH_P (operands[2]))
16531      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16532                                    GET_MODE (operands[2]),
16533                                    operands[0], operands[1]);
16534    else
16535      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16536                                    GET_MODE (operands[2]),
16537                                    operands[1], operands[0]);")
16538
16539 ;; Conditional addition patterns
16540 (define_expand "add<mode>cc"
16541   [(match_operand:SWI 0 "register_operand" "")
16542    (match_operand 1 "ordered_comparison_operator" "")
16543    (match_operand:SWI 2 "register_operand" "")
16544    (match_operand:SWI 3 "const_int_operand" "")]
16545   ""
16546   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16547 \f
16548 ;; Misc patterns (?)
16549
16550 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16551 ;; Otherwise there will be nothing to keep
16552 ;;
16553 ;; [(set (reg ebp) (reg esp))]
16554 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16555 ;;  (clobber (eflags)]
16556 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16557 ;;
16558 ;; in proper program order.
16559
16560 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16561   [(set (match_operand:P 0 "register_operand" "=r,r")
16562         (plus:P (match_operand:P 1 "register_operand" "0,r")
16563                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16564    (clobber (reg:CC FLAGS_REG))
16565    (clobber (mem:BLK (scratch)))]
16566   ""
16567 {
16568   switch (get_attr_type (insn))
16569     {
16570     case TYPE_IMOV:
16571       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16572
16573     case TYPE_ALU:
16574       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16575       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16576         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16577
16578       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16579
16580     default:
16581       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16582       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16583     }
16584 }
16585   [(set (attr "type")
16586         (cond [(and (eq_attr "alternative" "0")
16587                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16588                  (const_string "alu")
16589                (match_operand:<MODE> 2 "const0_operand" "")
16590                  (const_string "imov")
16591               ]
16592               (const_string "lea")))
16593    (set (attr "length_immediate")
16594         (cond [(eq_attr "type" "imov")
16595                  (const_string "0")
16596                (and (eq_attr "type" "alu")
16597                     (match_operand 2 "const128_operand" ""))
16598                  (const_string "1")
16599               ]
16600               (const_string "*")))
16601    (set_attr "mode" "<MODE>")])
16602
16603 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16604   [(set (match_operand:P 0 "register_operand" "=r")
16605         (minus:P (match_operand:P 1 "register_operand" "0")
16606                  (match_operand:P 2 "register_operand" "r")))
16607    (clobber (reg:CC FLAGS_REG))
16608    (clobber (mem:BLK (scratch)))]
16609   ""
16610   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16611   [(set_attr "type" "alu")
16612    (set_attr "mode" "<MODE>")])
16613
16614 (define_insn "allocate_stack_worker_probe_<mode>"
16615   [(set (match_operand:P 0 "register_operand" "=a")
16616         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16617                             UNSPECV_STACK_PROBE))
16618    (clobber (reg:CC FLAGS_REG))]
16619   "ix86_target_stack_probe ()"
16620   "call\t___chkstk_ms"
16621   [(set_attr "type" "multi")
16622    (set_attr "length" "5")])
16623
16624 (define_expand "allocate_stack"
16625   [(match_operand 0 "register_operand" "")
16626    (match_operand 1 "general_operand" "")]
16627   "ix86_target_stack_probe ()"
16628 {
16629   rtx x;
16630
16631 #ifndef CHECK_STACK_LIMIT
16632 #define CHECK_STACK_LIMIT 0
16633 #endif
16634
16635   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16636       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16637     {
16638       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16639                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16640       if (x != stack_pointer_rtx)
16641         emit_move_insn (stack_pointer_rtx, x);
16642     }
16643   else
16644     {
16645       x = copy_to_mode_reg (Pmode, operands[1]);
16646       if (TARGET_64BIT)
16647         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16648       else
16649         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16650       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16651                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16652       if (x != stack_pointer_rtx)
16653         emit_move_insn (stack_pointer_rtx, x);
16654     }
16655
16656   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16657   DONE;
16658 })
16659
16660 ;; Use IOR for stack probes, this is shorter.
16661 (define_expand "probe_stack"
16662   [(match_operand 0 "memory_operand" "")]
16663   ""
16664 {
16665   rtx (*gen_ior3) (rtx, rtx, rtx);
16666
16667   gen_ior3 = (GET_MODE (operands[0]) == DImode
16668               ? gen_iordi3 : gen_iorsi3);
16669
16670   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16671   DONE;
16672 })
16673
16674 (define_insn "adjust_stack_and_probe<mode>"
16675   [(set (match_operand:P 0 "register_operand" "=r")
16676         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16677                             UNSPECV_PROBE_STACK_RANGE))
16678    (set (reg:P SP_REG)
16679         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16680    (clobber (reg:CC FLAGS_REG))
16681    (clobber (mem:BLK (scratch)))]
16682   ""
16683   "* return output_adjust_stack_and_probe (operands[0]);"
16684   [(set_attr "type" "multi")])
16685
16686 (define_insn "probe_stack_range<mode>"
16687   [(set (match_operand:P 0 "register_operand" "=r")
16688         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16689                             (match_operand:P 2 "const_int_operand" "n")]
16690                             UNSPECV_PROBE_STACK_RANGE))
16691    (clobber (reg:CC FLAGS_REG))]
16692   ""
16693   "* return output_probe_stack_range (operands[0], operands[2]);"
16694   [(set_attr "type" "multi")])
16695
16696 (define_expand "builtin_setjmp_receiver"
16697   [(label_ref (match_operand 0 "" ""))]
16698   "!TARGET_64BIT && flag_pic"
16699 {
16700 #if TARGET_MACHO
16701   if (TARGET_MACHO)
16702     {
16703       rtx xops[3];
16704       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16705       rtx label_rtx = gen_label_rtx ();
16706       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16707       xops[0] = xops[1] = picreg;
16708       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16709       ix86_expand_binary_operator (MINUS, SImode, xops);
16710     }
16711   else
16712 #endif
16713     emit_insn (gen_set_got (pic_offset_table_rtx));
16714   DONE;
16715 })
16716 \f
16717 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16718
16719 (define_split
16720   [(set (match_operand 0 "register_operand" "")
16721         (match_operator 3 "promotable_binary_operator"
16722            [(match_operand 1 "register_operand" "")
16723             (match_operand 2 "aligned_operand" "")]))
16724    (clobber (reg:CC FLAGS_REG))]
16725   "! TARGET_PARTIAL_REG_STALL && reload_completed
16726    && ((GET_MODE (operands[0]) == HImode
16727         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16728             /* ??? next two lines just !satisfies_constraint_K (...) */
16729             || !CONST_INT_P (operands[2])
16730             || satisfies_constraint_K (operands[2])))
16731        || (GET_MODE (operands[0]) == QImode
16732            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16733   [(parallel [(set (match_dup 0)
16734                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16735               (clobber (reg:CC FLAGS_REG))])]
16736   "operands[0] = gen_lowpart (SImode, operands[0]);
16737    operands[1] = gen_lowpart (SImode, operands[1]);
16738    if (GET_CODE (operands[3]) != ASHIFT)
16739      operands[2] = gen_lowpart (SImode, operands[2]);
16740    PUT_MODE (operands[3], SImode);")
16741
16742 ; Promote the QImode tests, as i386 has encoding of the AND
16743 ; instruction with 32-bit sign-extended immediate and thus the
16744 ; instruction size is unchanged, except in the %eax case for
16745 ; which it is increased by one byte, hence the ! optimize_size.
16746 (define_split
16747   [(set (match_operand 0 "flags_reg_operand" "")
16748         (match_operator 2 "compare_operator"
16749           [(and (match_operand 3 "aligned_operand" "")
16750                 (match_operand 4 "const_int_operand" ""))
16751            (const_int 0)]))
16752    (set (match_operand 1 "register_operand" "")
16753         (and (match_dup 3) (match_dup 4)))]
16754   "! TARGET_PARTIAL_REG_STALL && reload_completed
16755    && optimize_insn_for_speed_p ()
16756    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16757        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16758    /* Ensure that the operand will remain sign-extended immediate.  */
16759    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16760   [(parallel [(set (match_dup 0)
16761                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16762                                     (const_int 0)]))
16763               (set (match_dup 1)
16764                    (and:SI (match_dup 3) (match_dup 4)))])]
16765 {
16766   operands[4]
16767     = gen_int_mode (INTVAL (operands[4])
16768                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16769   operands[1] = gen_lowpart (SImode, operands[1]);
16770   operands[3] = gen_lowpart (SImode, operands[3]);
16771 })
16772
16773 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16774 ; the TEST instruction with 32-bit sign-extended immediate and thus
16775 ; the instruction size would at least double, which is not what we
16776 ; want even with ! optimize_size.
16777 (define_split
16778   [(set (match_operand 0 "flags_reg_operand" "")
16779         (match_operator 1 "compare_operator"
16780           [(and (match_operand:HI 2 "aligned_operand" "")
16781                 (match_operand:HI 3 "const_int_operand" ""))
16782            (const_int 0)]))]
16783   "! TARGET_PARTIAL_REG_STALL && reload_completed
16784    && ! TARGET_FAST_PREFIX
16785    && optimize_insn_for_speed_p ()
16786    /* Ensure that the operand will remain sign-extended immediate.  */
16787    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16788   [(set (match_dup 0)
16789         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16790                          (const_int 0)]))]
16791 {
16792   operands[3]
16793     = gen_int_mode (INTVAL (operands[3])
16794                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16795   operands[2] = gen_lowpart (SImode, operands[2]);
16796 })
16797
16798 (define_split
16799   [(set (match_operand 0 "register_operand" "")
16800         (neg (match_operand 1 "register_operand" "")))
16801    (clobber (reg:CC FLAGS_REG))]
16802   "! TARGET_PARTIAL_REG_STALL && reload_completed
16803    && (GET_MODE (operands[0]) == HImode
16804        || (GET_MODE (operands[0]) == QImode
16805            && (TARGET_PROMOTE_QImode
16806                || optimize_insn_for_size_p ())))"
16807   [(parallel [(set (match_dup 0)
16808                    (neg:SI (match_dup 1)))
16809               (clobber (reg:CC FLAGS_REG))])]
16810   "operands[0] = gen_lowpart (SImode, operands[0]);
16811    operands[1] = gen_lowpart (SImode, operands[1]);")
16812
16813 (define_split
16814   [(set (match_operand 0 "register_operand" "")
16815         (not (match_operand 1 "register_operand" "")))]
16816   "! TARGET_PARTIAL_REG_STALL && reload_completed
16817    && (GET_MODE (operands[0]) == HImode
16818        || (GET_MODE (operands[0]) == QImode
16819            && (TARGET_PROMOTE_QImode
16820                || optimize_insn_for_size_p ())))"
16821   [(set (match_dup 0)
16822         (not:SI (match_dup 1)))]
16823   "operands[0] = gen_lowpart (SImode, operands[0]);
16824    operands[1] = gen_lowpart (SImode, operands[1]);")
16825
16826 (define_split
16827   [(set (match_operand 0 "register_operand" "")
16828         (if_then_else (match_operator 1 "ordered_comparison_operator"
16829                                 [(reg FLAGS_REG) (const_int 0)])
16830                       (match_operand 2 "register_operand" "")
16831                       (match_operand 3 "register_operand" "")))]
16832   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16833    && (GET_MODE (operands[0]) == HImode
16834        || (GET_MODE (operands[0]) == QImode
16835            && (TARGET_PROMOTE_QImode
16836                || optimize_insn_for_size_p ())))"
16837   [(set (match_dup 0)
16838         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16839   "operands[0] = gen_lowpart (SImode, operands[0]);
16840    operands[2] = gen_lowpart (SImode, operands[2]);
16841    operands[3] = gen_lowpart (SImode, operands[3]);")
16842 \f
16843 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16844 ;; transform a complex memory operation into two memory to register operations.
16845
16846 ;; Don't push memory operands
16847 (define_peephole2
16848   [(set (match_operand:SWI 0 "push_operand" "")
16849         (match_operand:SWI 1 "memory_operand" ""))
16850    (match_scratch:SWI 2 "<r>")]
16851   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16852    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16853   [(set (match_dup 2) (match_dup 1))
16854    (set (match_dup 0) (match_dup 2))])
16855
16856 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16857 ;; SImode pushes.
16858 (define_peephole2
16859   [(set (match_operand:SF 0 "push_operand" "")
16860         (match_operand:SF 1 "memory_operand" ""))
16861    (match_scratch:SF 2 "r")]
16862   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16863    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16864   [(set (match_dup 2) (match_dup 1))
16865    (set (match_dup 0) (match_dup 2))])
16866
16867 ;; Don't move an immediate directly to memory when the instruction
16868 ;; gets too big.
16869 (define_peephole2
16870   [(match_scratch:SWI124 1 "<r>")
16871    (set (match_operand:SWI124 0 "memory_operand" "")
16872         (const_int 0))]
16873   "optimize_insn_for_speed_p ()
16874    && !TARGET_USE_MOV0
16875    && TARGET_SPLIT_LONG_MOVES
16876    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16877    && peep2_regno_dead_p (0, FLAGS_REG)"
16878   [(parallel [(set (match_dup 2) (const_int 0))
16879               (clobber (reg:CC FLAGS_REG))])
16880    (set (match_dup 0) (match_dup 1))]
16881   "operands[2] = gen_lowpart (SImode, operands[1]);")
16882
16883 (define_peephole2
16884   [(match_scratch:SWI124 2 "<r>")
16885    (set (match_operand:SWI124 0 "memory_operand" "")
16886         (match_operand:SWI124 1 "immediate_operand" ""))]
16887   "optimize_insn_for_speed_p ()
16888    && TARGET_SPLIT_LONG_MOVES
16889    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16890   [(set (match_dup 2) (match_dup 1))
16891    (set (match_dup 0) (match_dup 2))])
16892
16893 ;; Don't compare memory with zero, load and use a test instead.
16894 (define_peephole2
16895   [(set (match_operand 0 "flags_reg_operand" "")
16896         (match_operator 1 "compare_operator"
16897           [(match_operand:SI 2 "memory_operand" "")
16898            (const_int 0)]))
16899    (match_scratch:SI 3 "r")]
16900   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16901   [(set (match_dup 3) (match_dup 2))
16902    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16903
16904 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16905 ;; Don't split NOTs with a displacement operand, because resulting XOR
16906 ;; will not be pairable anyway.
16907 ;;
16908 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16909 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16910 ;; so this split helps here as well.
16911 ;;
16912 ;; Note: Can't do this as a regular split because we can't get proper
16913 ;; lifetime information then.
16914
16915 (define_peephole2
16916   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16917         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16918   "optimize_insn_for_speed_p ()
16919    && ((TARGET_NOT_UNPAIRABLE
16920         && (!MEM_P (operands[0])
16921             || !memory_displacement_operand (operands[0], <MODE>mode)))
16922        || (TARGET_NOT_VECTORMODE
16923            && long_memory_operand (operands[0], <MODE>mode)))
16924    && peep2_regno_dead_p (0, FLAGS_REG)"
16925   [(parallel [(set (match_dup 0)
16926                    (xor:SWI124 (match_dup 1) (const_int -1)))
16927               (clobber (reg:CC FLAGS_REG))])])
16928
16929 ;; Non pairable "test imm, reg" instructions can be translated to
16930 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16931 ;; byte opcode instead of two, have a short form for byte operands),
16932 ;; so do it for other CPUs as well.  Given that the value was dead,
16933 ;; this should not create any new dependencies.  Pass on the sub-word
16934 ;; versions if we're concerned about partial register stalls.
16935
16936 (define_peephole2
16937   [(set (match_operand 0 "flags_reg_operand" "")
16938         (match_operator 1 "compare_operator"
16939           [(and:SI (match_operand:SI 2 "register_operand" "")
16940                    (match_operand:SI 3 "immediate_operand" ""))
16941            (const_int 0)]))]
16942   "ix86_match_ccmode (insn, CCNOmode)
16943    && (true_regnum (operands[2]) != AX_REG
16944        || satisfies_constraint_K (operands[3]))
16945    && peep2_reg_dead_p (1, operands[2])"
16946   [(parallel
16947      [(set (match_dup 0)
16948            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16949                             (const_int 0)]))
16950       (set (match_dup 2)
16951            (and:SI (match_dup 2) (match_dup 3)))])])
16952
16953 ;; We don't need to handle HImode case, because it will be promoted to SImode
16954 ;; on ! TARGET_PARTIAL_REG_STALL
16955
16956 (define_peephole2
16957   [(set (match_operand 0 "flags_reg_operand" "")
16958         (match_operator 1 "compare_operator"
16959           [(and:QI (match_operand:QI 2 "register_operand" "")
16960                    (match_operand:QI 3 "immediate_operand" ""))
16961            (const_int 0)]))]
16962   "! TARGET_PARTIAL_REG_STALL
16963    && ix86_match_ccmode (insn, CCNOmode)
16964    && true_regnum (operands[2]) != AX_REG
16965    && peep2_reg_dead_p (1, operands[2])"
16966   [(parallel
16967      [(set (match_dup 0)
16968            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16969                             (const_int 0)]))
16970       (set (match_dup 2)
16971            (and:QI (match_dup 2) (match_dup 3)))])])
16972
16973 (define_peephole2
16974   [(set (match_operand 0 "flags_reg_operand" "")
16975         (match_operator 1 "compare_operator"
16976           [(and:SI
16977              (zero_extract:SI
16978                (match_operand 2 "ext_register_operand" "")
16979                (const_int 8)
16980                (const_int 8))
16981              (match_operand 3 "const_int_operand" ""))
16982            (const_int 0)]))]
16983   "! TARGET_PARTIAL_REG_STALL
16984    && ix86_match_ccmode (insn, CCNOmode)
16985    && true_regnum (operands[2]) != AX_REG
16986    && peep2_reg_dead_p (1, operands[2])"
16987   [(parallel [(set (match_dup 0)
16988                    (match_op_dup 1
16989                      [(and:SI
16990                         (zero_extract:SI
16991                           (match_dup 2)
16992                           (const_int 8)
16993                           (const_int 8))
16994                         (match_dup 3))
16995                       (const_int 0)]))
16996               (set (zero_extract:SI (match_dup 2)
16997                                     (const_int 8)
16998                                     (const_int 8))
16999                    (and:SI
17000                      (zero_extract:SI
17001                        (match_dup 2)
17002                        (const_int 8)
17003                        (const_int 8))
17004                      (match_dup 3)))])])
17005
17006 ;; Don't do logical operations with memory inputs.
17007 (define_peephole2
17008   [(match_scratch:SI 2 "r")
17009    (parallel [(set (match_operand:SI 0 "register_operand" "")
17010                    (match_operator:SI 3 "arith_or_logical_operator"
17011                      [(match_dup 0)
17012                       (match_operand:SI 1 "memory_operand" "")]))
17013               (clobber (reg:CC FLAGS_REG))])]
17014   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17015   [(set (match_dup 2) (match_dup 1))
17016    (parallel [(set (match_dup 0)
17017                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17018               (clobber (reg:CC FLAGS_REG))])])
17019
17020 (define_peephole2
17021   [(match_scratch:SI 2 "r")
17022    (parallel [(set (match_operand:SI 0 "register_operand" "")
17023                    (match_operator:SI 3 "arith_or_logical_operator"
17024                      [(match_operand:SI 1 "memory_operand" "")
17025                       (match_dup 0)]))
17026               (clobber (reg:CC FLAGS_REG))])]
17027   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17028   [(set (match_dup 2) (match_dup 1))
17029    (parallel [(set (match_dup 0)
17030                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17031               (clobber (reg:CC FLAGS_REG))])])
17032
17033 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17034 ;; refers to the destination of the load!
17035
17036 (define_peephole2
17037   [(set (match_operand:SI 0 "register_operand" "")
17038         (match_operand:SI 1 "register_operand" ""))
17039    (parallel [(set (match_dup 0)
17040                    (match_operator:SI 3 "commutative_operator"
17041                      [(match_dup 0)
17042                       (match_operand:SI 2 "memory_operand" "")]))
17043               (clobber (reg:CC FLAGS_REG))])]
17044   "REGNO (operands[0]) != REGNO (operands[1])
17045    && GENERAL_REGNO_P (REGNO (operands[0]))
17046    && GENERAL_REGNO_P (REGNO (operands[1]))"
17047   [(set (match_dup 0) (match_dup 4))
17048    (parallel [(set (match_dup 0)
17049                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17050               (clobber (reg:CC FLAGS_REG))])]
17051   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17052
17053 (define_peephole2
17054   [(set (match_operand 0 "register_operand" "")
17055         (match_operand 1 "register_operand" ""))
17056    (set (match_dup 0)
17057                    (match_operator 3 "commutative_operator"
17058                      [(match_dup 0)
17059                       (match_operand 2 "memory_operand" "")]))]
17060   "REGNO (operands[0]) != REGNO (operands[1])
17061    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17062        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17063   [(set (match_dup 0) (match_dup 2))
17064    (set (match_dup 0)
17065         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17066
17067 ; Don't do logical operations with memory outputs
17068 ;
17069 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17070 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17071 ; the same decoder scheduling characteristics as the original.
17072
17073 (define_peephole2
17074   [(match_scratch:SI 2 "r")
17075    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17076                    (match_operator:SI 3 "arith_or_logical_operator"
17077                      [(match_dup 0)
17078                       (match_operand:SI 1 "nonmemory_operand" "")]))
17079               (clobber (reg:CC FLAGS_REG))])]
17080   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17081    /* Do not split stack checking probes.  */
17082    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17083   [(set (match_dup 2) (match_dup 0))
17084    (parallel [(set (match_dup 2)
17085                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17086               (clobber (reg:CC FLAGS_REG))])
17087    (set (match_dup 0) (match_dup 2))])
17088
17089 (define_peephole2
17090   [(match_scratch:SI 2 "r")
17091    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17092                    (match_operator:SI 3 "arith_or_logical_operator"
17093                      [(match_operand:SI 1 "nonmemory_operand" "")
17094                       (match_dup 0)]))
17095               (clobber (reg:CC FLAGS_REG))])]
17096   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17097    /* Do not split stack checking probes.  */
17098    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17099   [(set (match_dup 2) (match_dup 0))
17100    (parallel [(set (match_dup 2)
17101                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17102               (clobber (reg:CC FLAGS_REG))])
17103    (set (match_dup 0) (match_dup 2))])
17104
17105 ;; Attempt to always use XOR for zeroing registers.
17106 (define_peephole2
17107   [(set (match_operand 0 "register_operand" "")
17108         (match_operand 1 "const0_operand" ""))]
17109   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17110    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17111    && GENERAL_REG_P (operands[0])
17112    && peep2_regno_dead_p (0, FLAGS_REG)"
17113   [(parallel [(set (match_dup 0) (const_int 0))
17114               (clobber (reg:CC FLAGS_REG))])]
17115   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17116
17117 (define_peephole2
17118   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17119         (const_int 0))]
17120   "(GET_MODE (operands[0]) == QImode
17121     || GET_MODE (operands[0]) == HImode)
17122    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17123    && peep2_regno_dead_p (0, FLAGS_REG)"
17124   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17125               (clobber (reg:CC FLAGS_REG))])])
17126
17127 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17128 (define_peephole2
17129   [(set (match_operand:SWI248 0 "register_operand" "")
17130         (const_int -1))]
17131   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17132    && peep2_regno_dead_p (0, FLAGS_REG)"
17133   [(parallel [(set (match_dup 0) (const_int -1))
17134               (clobber (reg:CC FLAGS_REG))])]
17135 {
17136   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17137     operands[0] = gen_lowpart (SImode, operands[0]);
17138 })
17139
17140 ;; Attempt to convert simple lea to add/shift.
17141 ;; These can be created by move expanders.
17142
17143 (define_peephole2
17144   [(set (match_operand:SWI48 0 "register_operand" "")
17145         (plus:SWI48 (match_dup 0)
17146                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17147   "peep2_regno_dead_p (0, FLAGS_REG)"
17148   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17149               (clobber (reg:CC FLAGS_REG))])])
17150
17151 (define_peephole2
17152   [(set (match_operand:SI 0 "register_operand" "")
17153         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17154                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17155   "TARGET_64BIT
17156    && peep2_regno_dead_p (0, FLAGS_REG)
17157    && REGNO (operands[0]) == REGNO (operands[1])"
17158   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17159               (clobber (reg:CC FLAGS_REG))])]
17160   "operands[2] = gen_lowpart (SImode, operands[2]);")
17161
17162 (define_peephole2
17163   [(set (match_operand:SWI48 0 "register_operand" "")
17164         (mult:SWI48 (match_dup 0)
17165                     (match_operand:SWI48 1 "const_int_operand" "")))]
17166   "exact_log2 (INTVAL (operands[1])) >= 0
17167    && peep2_regno_dead_p (0, FLAGS_REG)"
17168   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17169               (clobber (reg:CC FLAGS_REG))])]
17170   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17171
17172 (define_peephole2
17173   [(set (match_operand:SI 0 "register_operand" "")
17174         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17175                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17176   "TARGET_64BIT
17177    && exact_log2 (INTVAL (operands[2])) >= 0
17178    && REGNO (operands[0]) == REGNO (operands[1])
17179    && peep2_regno_dead_p (0, FLAGS_REG)"
17180   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17181               (clobber (reg:CC FLAGS_REG))])]
17182   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17183
17184 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17185 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17186 ;; On many CPUs it is also faster, since special hardware to avoid esp
17187 ;; dependencies is present.
17188
17189 ;; While some of these conversions may be done using splitters, we use
17190 ;; peepholes in order to allow combine_stack_adjustments pass to see
17191 ;; nonobfuscated RTL.
17192
17193 ;; Convert prologue esp subtractions to push.
17194 ;; We need register to push.  In order to keep verify_flow_info happy we have
17195 ;; two choices
17196 ;; - use scratch and clobber it in order to avoid dependencies
17197 ;; - use already live register
17198 ;; We can't use the second way right now, since there is no reliable way how to
17199 ;; verify that given register is live.  First choice will also most likely in
17200 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17201 ;; call clobbered registers are dead.  We may want to use base pointer as an
17202 ;; alternative when no register is available later.
17203
17204 (define_peephole2
17205   [(match_scratch:P 1 "r")
17206    (parallel [(set (reg:P SP_REG)
17207                    (plus:P (reg:P SP_REG)
17208                            (match_operand:P 0 "const_int_operand" "")))
17209               (clobber (reg:CC FLAGS_REG))
17210               (clobber (mem:BLK (scratch)))])]
17211   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17212    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17213   [(clobber (match_dup 1))
17214    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17215               (clobber (mem:BLK (scratch)))])])
17216
17217 (define_peephole2
17218   [(match_scratch:P 1 "r")
17219    (parallel [(set (reg:P SP_REG)
17220                    (plus:P (reg:P SP_REG)
17221                            (match_operand:P 0 "const_int_operand" "")))
17222               (clobber (reg:CC FLAGS_REG))
17223               (clobber (mem:BLK (scratch)))])]
17224   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17225    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17226   [(clobber (match_dup 1))
17227    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17228    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17229               (clobber (mem:BLK (scratch)))])])
17230
17231 ;; Convert esp subtractions to push.
17232 (define_peephole2
17233   [(match_scratch:P 1 "r")
17234    (parallel [(set (reg:P SP_REG)
17235                    (plus:P (reg:P SP_REG)
17236                            (match_operand:P 0 "const_int_operand" "")))
17237               (clobber (reg:CC FLAGS_REG))])]
17238   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17239    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17240   [(clobber (match_dup 1))
17241    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17242
17243 (define_peephole2
17244   [(match_scratch:P 1 "r")
17245    (parallel [(set (reg:P SP_REG)
17246                    (plus:P (reg:P SP_REG)
17247                            (match_operand:P 0 "const_int_operand" "")))
17248               (clobber (reg:CC FLAGS_REG))])]
17249   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17250    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17251   [(clobber (match_dup 1))
17252    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17253    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17254
17255 ;; Convert epilogue deallocator to pop.
17256 (define_peephole2
17257   [(match_scratch:P 1 "r")
17258    (parallel [(set (reg:P SP_REG)
17259                    (plus:P (reg:P SP_REG)
17260                            (match_operand:P 0 "const_int_operand" "")))
17261               (clobber (reg:CC FLAGS_REG))
17262               (clobber (mem:BLK (scratch)))])]
17263   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17264    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17265   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17266               (clobber (mem:BLK (scratch)))])])
17267
17268 ;; Two pops case is tricky, since pop causes dependency
17269 ;; on destination register.  We use two registers if available.
17270 (define_peephole2
17271   [(match_scratch:P 1 "r")
17272    (match_scratch:P 2 "r")
17273    (parallel [(set (reg:P SP_REG)
17274                    (plus:P (reg:P SP_REG)
17275                            (match_operand:P 0 "const_int_operand" "")))
17276               (clobber (reg:CC FLAGS_REG))
17277               (clobber (mem:BLK (scratch)))])]
17278   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17279    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17280   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17281               (clobber (mem:BLK (scratch)))])
17282    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17283
17284 (define_peephole2
17285   [(match_scratch:P 1 "r")
17286    (parallel [(set (reg:P SP_REG)
17287                    (plus:P (reg:P SP_REG)
17288                            (match_operand:P 0 "const_int_operand" "")))
17289               (clobber (reg:CC FLAGS_REG))
17290               (clobber (mem:BLK (scratch)))])]
17291   "optimize_insn_for_size_p ()
17292    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17293   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17294               (clobber (mem:BLK (scratch)))])
17295    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17296
17297 ;; Convert esp additions to pop.
17298 (define_peephole2
17299   [(match_scratch:P 1 "r")
17300    (parallel [(set (reg:P SP_REG)
17301                    (plus:P (reg:P SP_REG)
17302                            (match_operand:P 0 "const_int_operand" "")))
17303               (clobber (reg:CC FLAGS_REG))])]
17304   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17305   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17306
17307 ;; Two pops case is tricky, since pop causes dependency
17308 ;; on destination register.  We use two registers if available.
17309 (define_peephole2
17310   [(match_scratch:P 1 "r")
17311    (match_scratch:P 2 "r")
17312    (parallel [(set (reg:P SP_REG)
17313                    (plus:P (reg:P SP_REG)
17314                            (match_operand:P 0 "const_int_operand" "")))
17315               (clobber (reg:CC FLAGS_REG))])]
17316   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17317   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17318    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17319
17320 (define_peephole2
17321   [(match_scratch:P 1 "r")
17322    (parallel [(set (reg:P SP_REG)
17323                    (plus:P (reg:P SP_REG)
17324                            (match_operand:P 0 "const_int_operand" "")))
17325               (clobber (reg:CC FLAGS_REG))])]
17326   "optimize_insn_for_size_p ()
17327    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17328   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17329    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17330 \f
17331 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17332 ;; required and register dies.  Similarly for 128 to -128.
17333 (define_peephole2
17334   [(set (match_operand 0 "flags_reg_operand" "")
17335         (match_operator 1 "compare_operator"
17336           [(match_operand 2 "register_operand" "")
17337            (match_operand 3 "const_int_operand" "")]))]
17338   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17339      && incdec_operand (operands[3], GET_MODE (operands[3])))
17340     || (!TARGET_FUSE_CMP_AND_BRANCH
17341         && INTVAL (operands[3]) == 128))
17342    && ix86_match_ccmode (insn, CCGCmode)
17343    && peep2_reg_dead_p (1, operands[2])"
17344   [(parallel [(set (match_dup 0)
17345                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17346               (clobber (match_dup 2))])])
17347 \f
17348 ;; Convert imul by three, five and nine into lea
17349 (define_peephole2
17350   [(parallel
17351     [(set (match_operand:SWI48 0 "register_operand" "")
17352           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17353                       (match_operand:SWI48 2 "const_int_operand" "")))
17354      (clobber (reg:CC FLAGS_REG))])]
17355   "INTVAL (operands[2]) == 3
17356    || INTVAL (operands[2]) == 5
17357    || INTVAL (operands[2]) == 9"
17358   [(set (match_dup 0)
17359         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17360                     (match_dup 1)))]
17361   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17362
17363 (define_peephole2
17364   [(parallel
17365     [(set (match_operand:SWI48 0 "register_operand" "")
17366           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17367                       (match_operand:SWI48 2 "const_int_operand" "")))
17368      (clobber (reg:CC FLAGS_REG))])]
17369   "optimize_insn_for_speed_p ()
17370    && (INTVAL (operands[2]) == 3
17371        || INTVAL (operands[2]) == 5
17372        || INTVAL (operands[2]) == 9)"
17373   [(set (match_dup 0) (match_dup 1))
17374    (set (match_dup 0)
17375         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17376                     (match_dup 0)))]
17377   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17378
17379 ;; imul $32bit_imm, mem, reg is vector decoded, while
17380 ;; imul $32bit_imm, reg, reg is direct decoded.
17381 (define_peephole2
17382   [(match_scratch:SWI48 3 "r")
17383    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17384                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17385                                (match_operand:SWI48 2 "immediate_operand" "")))
17386               (clobber (reg:CC FLAGS_REG))])]
17387   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17388    && !satisfies_constraint_K (operands[2])"
17389   [(set (match_dup 3) (match_dup 1))
17390    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17391               (clobber (reg:CC FLAGS_REG))])])
17392
17393 (define_peephole2
17394   [(match_scratch:SI 3 "r")
17395    (parallel [(set (match_operand:DI 0 "register_operand" "")
17396                    (zero_extend:DI
17397                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17398                               (match_operand:SI 2 "immediate_operand" ""))))
17399               (clobber (reg:CC FLAGS_REG))])]
17400   "TARGET_64BIT
17401    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17402    && !satisfies_constraint_K (operands[2])"
17403   [(set (match_dup 3) (match_dup 1))
17404    (parallel [(set (match_dup 0)
17405                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17406               (clobber (reg:CC FLAGS_REG))])])
17407
17408 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17409 ;; Convert it into imul reg, reg
17410 ;; It would be better to force assembler to encode instruction using long
17411 ;; immediate, but there is apparently no way to do so.
17412 (define_peephole2
17413   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17414                    (mult:SWI248
17415                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17416                     (match_operand:SWI248 2 "const_int_operand" "")))
17417               (clobber (reg:CC FLAGS_REG))])
17418    (match_scratch:SWI248 3 "r")]
17419   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17420    && satisfies_constraint_K (operands[2])"
17421   [(set (match_dup 3) (match_dup 2))
17422    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17423               (clobber (reg:CC FLAGS_REG))])]
17424 {
17425   if (!rtx_equal_p (operands[0], operands[1]))
17426     emit_move_insn (operands[0], operands[1]);
17427 })
17428
17429 ;; After splitting up read-modify operations, array accesses with memory
17430 ;; operands might end up in form:
17431 ;;  sall    $2, %eax
17432 ;;  movl    4(%esp), %edx
17433 ;;  addl    %edx, %eax
17434 ;; instead of pre-splitting:
17435 ;;  sall    $2, %eax
17436 ;;  addl    4(%esp), %eax
17437 ;; Turn it into:
17438 ;;  movl    4(%esp), %edx
17439 ;;  leal    (%edx,%eax,4), %eax
17440
17441 (define_peephole2
17442   [(match_scratch:P 5 "r")
17443    (parallel [(set (match_operand 0 "register_operand" "")
17444                    (ashift (match_operand 1 "register_operand" "")
17445                            (match_operand 2 "const_int_operand" "")))
17446                (clobber (reg:CC FLAGS_REG))])
17447    (parallel [(set (match_operand 3 "register_operand" "")
17448                    (plus (match_dup 0)
17449                          (match_operand 4 "x86_64_general_operand" "")))
17450                    (clobber (reg:CC FLAGS_REG))])]
17451   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17452    /* Validate MODE for lea.  */
17453    && ((!TARGET_PARTIAL_REG_STALL
17454         && (GET_MODE (operands[0]) == QImode
17455             || GET_MODE (operands[0]) == HImode))
17456        || GET_MODE (operands[0]) == SImode
17457        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17458    && (rtx_equal_p (operands[0], operands[3])
17459        || peep2_reg_dead_p (2, operands[0]))
17460    /* We reorder load and the shift.  */
17461    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17462   [(set (match_dup 5) (match_dup 4))
17463    (set (match_dup 0) (match_dup 1))]
17464 {
17465   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17466   int scale = 1 << INTVAL (operands[2]);
17467   rtx index = gen_lowpart (Pmode, operands[1]);
17468   rtx base = gen_lowpart (Pmode, operands[5]);
17469   rtx dest = gen_lowpart (mode, operands[3]);
17470
17471   operands[1] = gen_rtx_PLUS (Pmode, base,
17472                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17473   operands[5] = base;
17474   if (mode != Pmode)
17475     {
17476       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17477       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17478     }
17479   operands[0] = dest;
17480 })
17481 \f
17482 ;; Call-value patterns last so that the wildcard operand does not
17483 ;; disrupt insn-recog's switch tables.
17484
17485 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17486   [(parallel
17487     [(set (match_operand 0 "" "")
17488           (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17489                 (match_operand:SI 2 "" "")))
17490      (set (reg:SI SP_REG)
17491           (plus:SI (reg:SI SP_REG)
17492                    (match_operand:SI 3 "immediate_operand" "")))])
17493    (unspec [(match_operand 4 "const_int_operand" "")]
17494            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17495   "TARGET_VZEROUPPER && !TARGET_64BIT"
17496   "#"
17497   "&& reload_completed"
17498   [(const_int 0)]
17499   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17500   [(set_attr "type" "callv")])
17501
17502 (define_insn "*call_value_pop_0"
17503   [(set (match_operand 0 "" "")
17504         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17505               (match_operand:SI 2 "" "")))
17506    (set (reg:SI SP_REG)
17507         (plus:SI (reg:SI SP_REG)
17508                  (match_operand:SI 3 "immediate_operand" "")))]
17509   "!TARGET_64BIT"
17510   { return ix86_output_call_insn (insn, operands[1], 1); }
17511   [(set_attr "type" "callv")])
17512
17513 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17514   [(parallel
17515     [(set (match_operand 0 "" "")
17516           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17517                 (match_operand:SI 2 "" "")))
17518      (set (reg:SI SP_REG)
17519           (plus:SI (reg:SI SP_REG)
17520                    (match_operand:SI 3 "immediate_operand" "i")))])
17521    (unspec [(match_operand 4 "const_int_operand" "")]
17522            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17523   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17524   "#"
17525   "&& reload_completed"
17526   [(const_int 0)]
17527   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17528   [(set_attr "type" "callv")])
17529
17530 (define_insn "*call_value_pop_1"
17531   [(set (match_operand 0 "" "")
17532         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17533               (match_operand:SI 2 "" "")))
17534    (set (reg:SI SP_REG)
17535         (plus:SI (reg:SI SP_REG)
17536                  (match_operand:SI 3 "immediate_operand" "i")))]
17537   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17538   { return ix86_output_call_insn (insn, operands[1], 1); }
17539   [(set_attr "type" "callv")])
17540
17541 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17542  [(parallel
17543    [(set (match_operand 0 "" "")
17544           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17545                 (match_operand:SI 2 "" "")))
17546      (set (reg:SI SP_REG)
17547           (plus:SI (reg:SI SP_REG)
17548                    (match_operand:SI 3 "immediate_operand" "i,i")))])
17549    (unspec [(match_operand 4 "const_int_operand" "")]
17550            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17551   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17552   "#"
17553   "&& reload_completed"
17554   [(const_int 0)]
17555   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17556   [(set_attr "type" "callv")])
17557
17558 (define_insn "*sibcall_value_pop_1"
17559   [(set (match_operand 0 "" "")
17560         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17561               (match_operand:SI 2 "" "")))
17562    (set (reg:SI SP_REG)
17563         (plus:SI (reg:SI SP_REG)
17564                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17565   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17566   { return ix86_output_call_insn (insn, operands[1], 1); }
17567   [(set_attr "type" "callv")])
17568
17569 (define_insn_and_split "*call_value_0_vzeroupper"
17570   [(set (match_operand 0 "" "")
17571         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17572               (match_operand:SI 2 "" "")))
17573    (unspec [(match_operand 3 "const_int_operand" "")]
17574            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17575   "TARGET_VZEROUPPER && !TARGET_64BIT"
17576   "#"
17577   "&& reload_completed"
17578   [(const_int 0)]
17579   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17580   [(set_attr "type" "callv")])
17581
17582 (define_insn "*call_value_0"
17583   [(set (match_operand 0 "" "")
17584         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17585               (match_operand:SI 2 "" "")))]
17586   "!TARGET_64BIT"
17587   { return ix86_output_call_insn (insn, operands[1], 1); }
17588   [(set_attr "type" "callv")])
17589
17590 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17591   [(set (match_operand 0 "" "")
17592         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17593               (match_operand:DI 2 "const_int_operand" "")))
17594    (unspec [(match_operand 3 "const_int_operand" "")]
17595            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17596   "TARGET_VZEROUPPER && TARGET_64BIT"
17597   "#"
17598   "&& reload_completed"
17599   [(const_int 0)]
17600   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17601   [(set_attr "type" "callv")])
17602
17603 (define_insn "*call_value_0_rex64"
17604   [(set (match_operand 0 "" "")
17605         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17606               (match_operand:DI 2 "const_int_operand" "")))]
17607   "TARGET_64BIT"
17608   { return ix86_output_call_insn (insn, operands[1], 1); }
17609   [(set_attr "type" "callv")])
17610
17611 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17612   [(parallel
17613     [(set (match_operand 0 "" "")
17614           (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17615                 (match_operand:DI 2 "const_int_operand" "")))
17616      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17617      (clobber (reg:TI XMM6_REG))
17618      (clobber (reg:TI XMM7_REG))
17619      (clobber (reg:TI XMM8_REG))
17620      (clobber (reg:TI XMM9_REG))
17621      (clobber (reg:TI XMM10_REG))
17622      (clobber (reg:TI XMM11_REG))
17623      (clobber (reg:TI XMM12_REG))
17624      (clobber (reg:TI XMM13_REG))
17625      (clobber (reg:TI XMM14_REG))
17626      (clobber (reg:TI XMM15_REG))
17627      (clobber (reg:DI SI_REG))
17628      (clobber (reg:DI DI_REG))])
17629    (unspec [(match_operand 3 "const_int_operand" "")]
17630            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17631   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17632   "#"
17633   "&& reload_completed"
17634   [(const_int 0)]
17635   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17636   [(set_attr "type" "callv")])
17637
17638 (define_insn "*call_value_0_rex64_ms_sysv"
17639   [(set (match_operand 0 "" "")
17640         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17641               (match_operand:DI 2 "const_int_operand" "")))
17642    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17643    (clobber (reg:TI XMM6_REG))
17644    (clobber (reg:TI XMM7_REG))
17645    (clobber (reg:TI XMM8_REG))
17646    (clobber (reg:TI XMM9_REG))
17647    (clobber (reg:TI XMM10_REG))
17648    (clobber (reg:TI XMM11_REG))
17649    (clobber (reg:TI XMM12_REG))
17650    (clobber (reg:TI XMM13_REG))
17651    (clobber (reg:TI XMM14_REG))
17652    (clobber (reg:TI XMM15_REG))
17653    (clobber (reg:DI SI_REG))
17654    (clobber (reg:DI DI_REG))]
17655   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17656   { return ix86_output_call_insn (insn, operands[1], 1); }
17657   [(set_attr "type" "callv")])
17658
17659 (define_insn_and_split "*call_value_1_vzeroupper"
17660   [(set (match_operand 0 "" "")
17661         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17662               (match_operand:SI 2 "" "")))
17663    (unspec [(match_operand 3 "const_int_operand" "")]
17664            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17665   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17666   "#"
17667   "&& reload_completed"
17668   [(const_int 0)]
17669   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17670   [(set_attr "type" "callv")])
17671
17672 (define_insn "*call_value_1"
17673   [(set (match_operand 0 "" "")
17674         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17675               (match_operand:SI 2 "" "")))]
17676   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17677   { return ix86_output_call_insn (insn, operands[1], 1); }
17678   [(set_attr "type" "callv")])
17679
17680 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17681   [(set (match_operand 0 "" "")
17682         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17683               (match_operand:SI 2 "" "")))
17684    (unspec [(match_operand 3 "const_int_operand" "")]
17685            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17686   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17687   "#"
17688   "&& reload_completed"
17689   [(const_int 0)]
17690   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17691   [(set_attr "type" "callv")])
17692
17693 (define_insn "*sibcall_value_1"
17694   [(set (match_operand 0 "" "")
17695         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17696               (match_operand:SI 2 "" "")))]
17697   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17698   { return ix86_output_call_insn (insn, operands[1], 1); }
17699   [(set_attr "type" "callv")])
17700
17701 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17702   [(set (match_operand 0 "" "")
17703         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17704               (match_operand:DI 2 "" "")))
17705    (unspec [(match_operand 3 "const_int_operand" "")]
17706            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17707   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17708    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17709   "#"
17710   "&& reload_completed"
17711   [(const_int 0)]
17712   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17713   [(set_attr "type" "callv")])
17714
17715 (define_insn "*call_value_1_rex64"
17716   [(set (match_operand 0 "" "")
17717         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17718               (match_operand:DI 2 "" "")))]
17719   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17720    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17721   { return ix86_output_call_insn (insn, operands[1], 1); }
17722   [(set_attr "type" "callv")])
17723
17724 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17725   [(parallel
17726     [(set (match_operand 0 "" "")
17727           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17728                 (match_operand:DI 2 "" "")))
17729      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17730      (clobber (reg:TI XMM6_REG))
17731      (clobber (reg:TI XMM7_REG))
17732      (clobber (reg:TI XMM8_REG))
17733      (clobber (reg:TI XMM9_REG))
17734      (clobber (reg:TI XMM10_REG))
17735      (clobber (reg:TI XMM11_REG))
17736      (clobber (reg:TI XMM12_REG))
17737      (clobber (reg:TI XMM13_REG))
17738      (clobber (reg:TI XMM14_REG))
17739      (clobber (reg:TI XMM15_REG))
17740      (clobber (reg:DI SI_REG))
17741      (clobber (reg:DI DI_REG))])
17742    (unspec [(match_operand 3 "const_int_operand" "")]
17743            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17744   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17745   "#"
17746   "&& reload_completed"
17747   [(const_int 0)]
17748   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17749   [(set_attr "type" "callv")])
17750
17751 (define_insn "*call_value_1_rex64_ms_sysv"
17752   [(set (match_operand 0 "" "")
17753         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17754               (match_operand:DI 2 "" "")))
17755    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17756    (clobber (reg:TI XMM6_REG))
17757    (clobber (reg:TI XMM7_REG))
17758    (clobber (reg:TI XMM8_REG))
17759    (clobber (reg:TI XMM9_REG))
17760    (clobber (reg:TI XMM10_REG))
17761    (clobber (reg:TI XMM11_REG))
17762    (clobber (reg:TI XMM12_REG))
17763    (clobber (reg:TI XMM13_REG))
17764    (clobber (reg:TI XMM14_REG))
17765    (clobber (reg:TI XMM15_REG))
17766    (clobber (reg:DI SI_REG))
17767    (clobber (reg:DI DI_REG))]
17768   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17769   { return ix86_output_call_insn (insn, operands[1], 1); }
17770   [(set_attr "type" "callv")])
17771
17772 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17773   [(set (match_operand 0 "" "")
17774         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17775               (match_operand:DI 2 "" "")))
17776    (unspec [(match_operand 3 "const_int_operand" "")]
17777            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17778   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17779   "#"
17780   "&& reload_completed"
17781   [(const_int 0)]
17782   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17783   [(set_attr "type" "callv")])
17784
17785 (define_insn "*call_value_1_rex64_large"
17786   [(set (match_operand 0 "" "")
17787         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17788               (match_operand:DI 2 "" "")))]
17789   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17790   { return ix86_output_call_insn (insn, operands[1], 1); }
17791   [(set_attr "type" "callv")])
17792
17793 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17794   [(set (match_operand 0 "" "")
17795         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17796               (match_operand:DI 2 "" "")))
17797    (unspec [(match_operand 3 "const_int_operand" "")]
17798            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17799   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17800   "#"
17801   "&& reload_completed"
17802   [(const_int 0)]
17803   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17804   [(set_attr "type" "callv")])
17805
17806 (define_insn "*sibcall_value_1_rex64"
17807   [(set (match_operand 0 "" "")
17808         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17809               (match_operand:DI 2 "" "")))]
17810   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17811   { return ix86_output_call_insn (insn, operands[1], 1); }
17812   [(set_attr "type" "callv")])
17813 \f
17814 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17815 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17816 ;; caught for use by garbage collectors and the like.  Using an insn that
17817 ;; maps to SIGILL makes it more likely the program will rightfully die.
17818 ;; Keeping with tradition, "6" is in honor of #UD.
17819 (define_insn "trap"
17820   [(trap_if (const_int 1) (const_int 6))]
17821   ""
17822   { return ASM_SHORT "0x0b0f"; }
17823   [(set_attr "length" "2")])
17824
17825 (define_expand "prefetch"
17826   [(prefetch (match_operand 0 "address_operand" "")
17827              (match_operand:SI 1 "const_int_operand" "")
17828              (match_operand:SI 2 "const_int_operand" ""))]
17829   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17830 {
17831   int rw = INTVAL (operands[1]);
17832   int locality = INTVAL (operands[2]);
17833
17834   gcc_assert (rw == 0 || rw == 1);
17835   gcc_assert (locality >= 0 && locality <= 3);
17836   gcc_assert (GET_MODE (operands[0]) == Pmode
17837               || GET_MODE (operands[0]) == VOIDmode);
17838
17839   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17840      supported by SSE counterpart or the SSE prefetch is not available
17841      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17842      of locality.  */
17843   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17844     operands[2] = GEN_INT (3);
17845   else
17846     operands[1] = const0_rtx;
17847 })
17848
17849 (define_insn "*prefetch_sse_<mode>"
17850   [(prefetch (match_operand:P 0 "address_operand" "p")
17851              (const_int 0)
17852              (match_operand:SI 1 "const_int_operand" ""))]
17853   "TARGET_PREFETCH_SSE"
17854 {
17855   static const char * const patterns[4] = {
17856    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17857   };
17858
17859   int locality = INTVAL (operands[1]);
17860   gcc_assert (locality >= 0 && locality <= 3);
17861
17862   return patterns[locality];
17863 }
17864   [(set_attr "type" "sse")
17865    (set_attr "atom_sse_attr" "prefetch")
17866    (set (attr "length_address")
17867         (symbol_ref "memory_address_length (operands[0])"))
17868    (set_attr "memory" "none")])
17869
17870 (define_insn "*prefetch_3dnow_<mode>"
17871   [(prefetch (match_operand:P 0 "address_operand" "p")
17872              (match_operand:SI 1 "const_int_operand" "n")
17873              (const_int 3))]
17874   "TARGET_3DNOW"
17875 {
17876   if (INTVAL (operands[1]) == 0)
17877     return "prefetch\t%a0";
17878   else
17879     return "prefetchw\t%a0";
17880 }
17881   [(set_attr "type" "mmx")
17882    (set (attr "length_address")
17883         (symbol_ref "memory_address_length (operands[0])"))
17884    (set_attr "memory" "none")])
17885
17886 (define_expand "stack_protect_set"
17887   [(match_operand 0 "memory_operand" "")
17888    (match_operand 1 "memory_operand" "")]
17889   ""
17890 {
17891   rtx (*insn)(rtx, rtx);
17892
17893 #ifdef TARGET_THREAD_SSP_OFFSET
17894   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17895   insn = (TARGET_64BIT
17896           ? gen_stack_tls_protect_set_di
17897           : gen_stack_tls_protect_set_si);
17898 #else
17899   insn = (TARGET_64BIT
17900           ? gen_stack_protect_set_di
17901           : gen_stack_protect_set_si);
17902 #endif
17903
17904   emit_insn (insn (operands[0], operands[1]));
17905   DONE;
17906 })
17907
17908 (define_insn "stack_protect_set_<mode>"
17909   [(set (match_operand:P 0 "memory_operand" "=m")
17910         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17911    (set (match_scratch:P 2 "=&r") (const_int 0))
17912    (clobber (reg:CC FLAGS_REG))]
17913   ""
17914   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17915   [(set_attr "type" "multi")])
17916
17917 (define_insn "stack_tls_protect_set_<mode>"
17918   [(set (match_operand:P 0 "memory_operand" "=m")
17919         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17920                   UNSPEC_SP_TLS_SET))
17921    (set (match_scratch:P 2 "=&r") (const_int 0))
17922    (clobber (reg:CC FLAGS_REG))]
17923   ""
17924   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17925   [(set_attr "type" "multi")])
17926
17927 (define_expand "stack_protect_test"
17928   [(match_operand 0 "memory_operand" "")
17929    (match_operand 1 "memory_operand" "")
17930    (match_operand 2 "" "")]
17931   ""
17932 {
17933   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17934
17935   rtx (*insn)(rtx, rtx, rtx);
17936
17937 #ifdef TARGET_THREAD_SSP_OFFSET
17938   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17939   insn = (TARGET_64BIT
17940           ? gen_stack_tls_protect_test_di
17941           : gen_stack_tls_protect_test_si);
17942 #else
17943   insn = (TARGET_64BIT
17944           ? gen_stack_protect_test_di
17945           : gen_stack_protect_test_si);
17946 #endif
17947
17948   emit_insn (insn (flags, operands[0], operands[1]));
17949
17950   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17951                                   flags, const0_rtx, operands[2]));
17952   DONE;
17953 })
17954
17955 (define_insn "stack_protect_test_<mode>"
17956   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17957         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17958                      (match_operand:P 2 "memory_operand" "m")]
17959                     UNSPEC_SP_TEST))
17960    (clobber (match_scratch:P 3 "=&r"))]
17961   ""
17962   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17963   [(set_attr "type" "multi")])
17964
17965 (define_insn "stack_tls_protect_test_<mode>"
17966   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17967         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17968                      (match_operand:P 2 "const_int_operand" "i")]
17969                     UNSPEC_SP_TLS_TEST))
17970    (clobber (match_scratch:P 3 "=r"))]
17971   ""
17972   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17973   [(set_attr "type" "multi")])
17974
17975 (define_insn "sse4_2_crc32<mode>"
17976   [(set (match_operand:SI 0 "register_operand" "=r")
17977         (unspec:SI
17978           [(match_operand:SI 1 "register_operand" "0")
17979            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17980           UNSPEC_CRC32))]
17981   "TARGET_SSE4_2 || TARGET_CRC32"
17982   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17983   [(set_attr "type" "sselog1")
17984    (set_attr "prefix_rep" "1")
17985    (set_attr "prefix_extra" "1")
17986    (set (attr "prefix_data16")
17987      (if_then_else (match_operand:HI 2 "" "")
17988        (const_string "1")
17989        (const_string "*")))
17990    (set (attr "prefix_rex")
17991      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17992        (const_string "1")
17993        (const_string "*")))
17994    (set_attr "mode" "SI")])
17995
17996 (define_insn "sse4_2_crc32di"
17997   [(set (match_operand:DI 0 "register_operand" "=r")
17998         (unspec:DI
17999           [(match_operand:DI 1 "register_operand" "0")
18000            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18001           UNSPEC_CRC32))]
18002   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18003   "crc32{q}\t{%2, %0|%0, %2}"
18004   [(set_attr "type" "sselog1")
18005    (set_attr "prefix_rep" "1")
18006    (set_attr "prefix_extra" "1")
18007    (set_attr "mode" "DI")])
18008
18009 (define_expand "rdpmc"
18010   [(match_operand:DI 0 "register_operand" "")
18011    (match_operand:SI 1 "register_operand" "")]
18012   ""
18013 {
18014   rtx reg = gen_reg_rtx (DImode);
18015   rtx si;
18016
18017   /* Force operand 1 into ECX.  */
18018   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18019   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18020   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18021                                 UNSPECV_RDPMC);
18022
18023   if (TARGET_64BIT)
18024     {
18025       rtvec vec = rtvec_alloc (2);
18026       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18027       rtx upper = gen_reg_rtx (DImode);
18028       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18029                                         gen_rtvec (1, const0_rtx),
18030                                         UNSPECV_RDPMC);
18031       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18032       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18033       emit_insn (load);
18034       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18035                                    NULL, 1, OPTAB_DIRECT);
18036       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18037                                  OPTAB_DIRECT);
18038     }
18039   else
18040     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18041   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18042   DONE;
18043 })
18044
18045 (define_insn "*rdpmc"
18046   [(set (match_operand:DI 0 "register_operand" "=A")
18047         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18048                             UNSPECV_RDPMC))]
18049   "!TARGET_64BIT"
18050   "rdpmc"
18051   [(set_attr "type" "other")
18052    (set_attr "length" "2")])
18053
18054 (define_insn "*rdpmc_rex64"
18055   [(set (match_operand:DI 0 "register_operand" "=a")
18056         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18057                             UNSPECV_RDPMC))
18058   (set (match_operand:DI 1 "register_operand" "=d")
18059        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18060   "TARGET_64BIT"
18061   "rdpmc"
18062   [(set_attr "type" "other")
18063    (set_attr "length" "2")])
18064
18065 (define_expand "rdtsc"
18066   [(set (match_operand:DI 0 "register_operand" "")
18067         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18068   ""
18069 {
18070   if (TARGET_64BIT)
18071     {
18072       rtvec vec = rtvec_alloc (2);
18073       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18074       rtx upper = gen_reg_rtx (DImode);
18075       rtx lower = gen_reg_rtx (DImode);
18076       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18077                                          gen_rtvec (1, const0_rtx),
18078                                          UNSPECV_RDTSC);
18079       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18080       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18081       emit_insn (load);
18082       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18083                                    NULL, 1, OPTAB_DIRECT);
18084       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18085                                    OPTAB_DIRECT);
18086       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18087       DONE;
18088     }
18089 })
18090
18091 (define_insn "*rdtsc"
18092   [(set (match_operand:DI 0 "register_operand" "=A")
18093         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18094   "!TARGET_64BIT"
18095   "rdtsc"
18096   [(set_attr "type" "other")
18097    (set_attr "length" "2")])
18098
18099 (define_insn "*rdtsc_rex64"
18100   [(set (match_operand:DI 0 "register_operand" "=a")
18101         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18102    (set (match_operand:DI 1 "register_operand" "=d")
18103         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18104   "TARGET_64BIT"
18105   "rdtsc"
18106   [(set_attr "type" "other")
18107    (set_attr "length" "2")])
18108
18109 (define_expand "rdtscp"
18110   [(match_operand:DI 0 "register_operand" "")
18111    (match_operand:SI 1 "memory_operand" "")]
18112   ""
18113 {
18114   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18115                                     gen_rtvec (1, const0_rtx),
18116                                     UNSPECV_RDTSCP);
18117   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18118                                     gen_rtvec (1, const0_rtx),
18119                                     UNSPECV_RDTSCP);
18120   rtx reg = gen_reg_rtx (DImode);
18121   rtx tmp = gen_reg_rtx (SImode);
18122
18123   if (TARGET_64BIT)
18124     {
18125       rtvec vec = rtvec_alloc (3);
18126       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18127       rtx upper = gen_reg_rtx (DImode);
18128       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18129       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18130       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18131       emit_insn (load);
18132       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18133                                    NULL, 1, OPTAB_DIRECT);
18134       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18135                                  OPTAB_DIRECT);
18136     }
18137   else
18138     {
18139       rtvec vec = rtvec_alloc (2);
18140       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18141       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18142       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18143       emit_insn (load);
18144     }
18145   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18146   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18147   DONE;
18148 })
18149
18150 (define_insn "*rdtscp"
18151   [(set (match_operand:DI 0 "register_operand" "=A")
18152         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18153    (set (match_operand:SI 1 "register_operand" "=c")
18154         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18155   "!TARGET_64BIT"
18156   "rdtscp"
18157   [(set_attr "type" "other")
18158    (set_attr "length" "3")])
18159
18160 (define_insn "*rdtscp_rex64"
18161   [(set (match_operand:DI 0 "register_operand" "=a")
18162         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18163    (set (match_operand:DI 1 "register_operand" "=d")
18164         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18165    (set (match_operand:SI 2 "register_operand" "=c")
18166         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18167   "TARGET_64BIT"
18168   "rdtscp"
18169   [(set_attr "type" "other")
18170    (set_attr "length" "3")])
18171
18172 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18173 ;;
18174 ;; LWP instructions
18175 ;;
18176 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18177
18178 (define_expand "lwp_llwpcb"
18179   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18180                     UNSPECV_LLWP_INTRINSIC)]
18181   "TARGET_LWP")
18182
18183 (define_insn "*lwp_llwpcb<mode>1"
18184   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18185                     UNSPECV_LLWP_INTRINSIC)]
18186   "TARGET_LWP"
18187   "llwpcb\t%0"
18188   [(set_attr "type" "lwp")
18189    (set_attr "mode" "<MODE>")
18190    (set_attr "length" "5")])
18191
18192 (define_expand "lwp_slwpcb"
18193   [(set (match_operand 0 "register_operand" "=r")
18194         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18195   "TARGET_LWP"
18196 {
18197   if (TARGET_64BIT)
18198     emit_insn (gen_lwp_slwpcbdi (operands[0]));
18199   else
18200     emit_insn (gen_lwp_slwpcbsi (operands[0]));
18201   DONE;
18202 })
18203
18204 (define_insn "lwp_slwpcb<mode>"
18205   [(set (match_operand:P 0 "register_operand" "=r")
18206         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18207   "TARGET_LWP"
18208   "slwpcb\t%0"
18209   [(set_attr "type" "lwp")
18210    (set_attr "mode" "<MODE>")
18211    (set_attr "length" "5")])
18212
18213 (define_expand "lwp_lwpval<mode>3"
18214   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18215                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18216                      (match_operand:SI 3 "const_int_operand" "i")]
18217                     UNSPECV_LWPVAL_INTRINSIC)]
18218   "TARGET_LWP"
18219   "/* Avoid unused variable warning.  */
18220    (void) operand0;")
18221
18222 (define_insn "*lwp_lwpval<mode>3_1"
18223   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18224                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18225                      (match_operand:SI 2 "const_int_operand" "i")]
18226                     UNSPECV_LWPVAL_INTRINSIC)]
18227   "TARGET_LWP"
18228   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18229   [(set_attr "type" "lwp")
18230    (set_attr "mode" "<MODE>")
18231    (set (attr "length")
18232         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18233
18234 (define_expand "lwp_lwpins<mode>3"
18235   [(set (reg:CCC FLAGS_REG)
18236         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18237                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18238                               (match_operand:SI 3 "const_int_operand" "i")]
18239                              UNSPECV_LWPINS_INTRINSIC))
18240    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18241         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18242   "TARGET_LWP")
18243
18244 (define_insn "*lwp_lwpins<mode>3_1"
18245   [(set (reg:CCC FLAGS_REG)
18246         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18247                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18248                               (match_operand:SI 2 "const_int_operand" "i")]
18249                              UNSPECV_LWPINS_INTRINSIC))]
18250   "TARGET_LWP"
18251   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18252   [(set_attr "type" "lwp")
18253    (set_attr "mode" "<MODE>")
18254    (set (attr "length")
18255         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18256
18257 (define_insn "rdfsbase<mode>"
18258   [(set (match_operand:SWI48 0 "register_operand" "=r")
18259         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18260   "TARGET_64BIT && TARGET_FSGSBASE"
18261   "rdfsbase %0"
18262   [(set_attr "type" "other")
18263    (set_attr "prefix_extra" "2")])
18264
18265 (define_insn "rdgsbase<mode>"
18266   [(set (match_operand:SWI48 0 "register_operand" "=r")
18267         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18268   "TARGET_64BIT && TARGET_FSGSBASE"
18269   "rdgsbase %0"
18270   [(set_attr "type" "other")
18271    (set_attr "prefix_extra" "2")])
18272
18273 (define_insn "wrfsbase<mode>"
18274   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18275                     UNSPECV_WRFSBASE)]
18276   "TARGET_64BIT && TARGET_FSGSBASE"
18277   "wrfsbase %0"
18278   [(set_attr "type" "other")
18279    (set_attr "prefix_extra" "2")])
18280
18281 (define_insn "wrgsbase<mode>"
18282   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18283                     UNSPECV_WRGSBASE)]
18284   "TARGET_64BIT && TARGET_FSGSBASE"
18285   "wrgsbase %0"
18286   [(set_attr "type" "other")
18287    (set_attr "prefix_extra" "2")])
18288
18289 (define_insn "rdrand<mode>_1"
18290   [(set (match_operand:SWI248 0 "register_operand" "=r")
18291         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18292    (set (reg:CCC FLAGS_REG)
18293         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18294   "TARGET_RDRND"
18295   "rdrand\t%0"
18296   [(set_attr "type" "other")
18297    (set_attr "prefix_extra" "1")])
18298
18299 (include "mmx.md")
18300 (include "sse.md")
18301 (include "sync.md")