OSDN Git Service

c3e74e5bfb1cd073a5b6f859d8c0561230fa3c48
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 ;; UNSPEC usage:
66
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
81
82   ;; Prologue support
83   UNSPEC_STACK_ALLOC
84   UNSPEC_SET_GOT
85   UNSPEC_REG_SAVE
86   UNSPEC_DEF_CFA
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
91
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
98
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_ADD_CARRY
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_CALL_NEEDS_VZEROUPPER
112   UNSPEC_PAUSE
113
114   ;; For SSE/MMX support:
115   UNSPEC_FIX_NOTRUNC
116   UNSPEC_MASKMOV
117   UNSPEC_MOVMSK
118   UNSPEC_MOVNT
119   UNSPEC_MOVU
120   UNSPEC_RCP
121   UNSPEC_RSQRT
122   UNSPEC_SFENCE
123   UNSPEC_PFRCP
124   UNSPEC_PFRCPIT1
125   UNSPEC_PFRCPIT2
126   UNSPEC_PFRSQRT
127   UNSPEC_PFRSQIT1
128   UNSPEC_MFENCE
129   UNSPEC_LFENCE
130   UNSPEC_PSADBW
131   UNSPEC_LDDQU
132   UNSPEC_MS_TO_SYSV_CALL
133
134   ;; Generic math support
135   UNSPEC_COPYSIGN
136   UNSPEC_IEEE_MIN       ; not commutative
137   UNSPEC_IEEE_MAX       ; not commutative
138
139   ;; x87 Floating point
140   UNSPEC_SIN
141   UNSPEC_COS
142   UNSPEC_FPATAN
143   UNSPEC_FYL2X
144   UNSPEC_FYL2XP1
145   UNSPEC_FRNDINT
146   UNSPEC_FIST
147   UNSPEC_F2XM1
148   UNSPEC_TAN
149   UNSPEC_FXAM
150
151   ;; x87 Rounding
152   UNSPEC_FRNDINT_FLOOR
153   UNSPEC_FRNDINT_CEIL
154   UNSPEC_FRNDINT_TRUNC
155   UNSPEC_FRNDINT_MASK_PM
156   UNSPEC_FIST_FLOOR
157   UNSPEC_FIST_CEIL
158
159   ;; x87 Double output FP
160   UNSPEC_SINCOS_COS
161   UNSPEC_SINCOS_SIN
162   UNSPEC_XTRACT_FRACT
163   UNSPEC_XTRACT_EXP
164   UNSPEC_FSCALE_FRACT
165   UNSPEC_FSCALE_EXP
166   UNSPEC_FPREM_F
167   UNSPEC_FPREM_U
168   UNSPEC_FPREM1_F
169   UNSPEC_FPREM1_U
170
171   UNSPEC_C2_FLAG
172   UNSPEC_FXAM_MEM
173
174   ;; SSP patterns
175   UNSPEC_SP_SET
176   UNSPEC_SP_TEST
177   UNSPEC_SP_TLS_SET
178   UNSPEC_SP_TLS_TEST
179
180   ;; SSSE3
181   UNSPEC_PSHUFB
182   UNSPEC_PSIGN
183   UNSPEC_PALIGNR
184
185   ;; For SSE4A support
186   UNSPEC_EXTRQI
187   UNSPEC_EXTRQ
188   UNSPEC_INSERTQI
189   UNSPEC_INSERTQ
190
191   ;; For SSE4.1 support
192   UNSPEC_BLENDV
193   UNSPEC_INSERTPS
194   UNSPEC_DP
195   UNSPEC_MOVNTDQA
196   UNSPEC_MPSADBW
197   UNSPEC_PHMINPOSUW
198   UNSPEC_PTEST
199   UNSPEC_ROUND
200
201   ;; For SSE4.2 support
202   UNSPEC_CRC32
203   UNSPEC_PCMPESTR
204   UNSPEC_PCMPISTR
205
206   ;; For FMA4 support
207   UNSPEC_FMADDSUB
208   UNSPEC_XOP_UNSIGNED_CMP
209   UNSPEC_XOP_TRUEFALSE
210   UNSPEC_XOP_PERMUTE
211   UNSPEC_FRCZ
212
213   ;; For AES support
214   UNSPEC_AESENC
215   UNSPEC_AESENCLAST
216   UNSPEC_AESDEC
217   UNSPEC_AESDECLAST
218   UNSPEC_AESIMC
219   UNSPEC_AESKEYGENASSIST
220
221   ;; For PCLMUL support
222   UNSPEC_PCLMUL
223
224   ;; For AVX support
225   UNSPEC_PCMP
226   UNSPEC_VPERMIL
227   UNSPEC_VPERMIL2
228   UNSPEC_VPERMIL2F128
229   UNSPEC_CAST
230   UNSPEC_VTESTP
231   UNSPEC_VCVTPH2PS
232   UNSPEC_VCVTPS2PH
233
234   ;; For BMI support
235   UNSPEC_BEXTR
236
237   ;; For RDRAND support
238   UNSPEC_RDRAND
239 ])
240
241 (define_c_enum "unspecv" [
242   UNSPECV_BLOCKAGE
243   UNSPECV_STACK_PROBE
244   UNSPECV_PROBE_STACK_RANGE
245   UNSPECV_EMMS
246   UNSPECV_LDMXCSR
247   UNSPECV_STMXCSR
248   UNSPECV_FEMMS
249   UNSPECV_CLFLUSH
250   UNSPECV_ALIGN
251   UNSPECV_MONITOR
252   UNSPECV_MWAIT
253   UNSPECV_CMPXCHG
254   UNSPECV_XCHG
255   UNSPECV_LOCK
256   UNSPECV_PROLOGUE_USE
257   UNSPECV_CLD
258   UNSPECV_NOPS
259   UNSPECV_VZEROALL
260   UNSPECV_VZEROUPPER
261   UNSPECV_RDTSC
262   UNSPECV_RDTSCP
263   UNSPECV_RDPMC
264   UNSPECV_LLWP_INTRINSIC
265   UNSPECV_SLWP_INTRINSIC
266   UNSPECV_LWPVAL_INTRINSIC
267   UNSPECV_LWPINS_INTRINSIC
268   UNSPECV_RDFSBASE
269   UNSPECV_RDGSBASE
270   UNSPECV_WRFSBASE
271   UNSPECV_WRGSBASE
272   UNSPECV_SPLIT_STACK_RETURN
273 ])
274
275 ;; Constants to represent rounding modes in the ROUND instruction
276 (define_constants
277   [(ROUND_FLOOR                 0x1)
278    (ROUND_CEIL                  0x2)
279    (ROUND_TRUNC                 0x3)
280    (ROUND_MXCSR                 0x4)
281    (ROUND_NO_EXC                0x8)
282   ])
283
284 ;; Constants to represent pcomtrue/pcomfalse variants
285 (define_constants
286   [(PCOM_FALSE                  0)
287    (PCOM_TRUE                   1)
288    (COM_FALSE_S                 2)
289    (COM_FALSE_P                 3)
290    (COM_TRUE_S                  4)
291    (COM_TRUE_P                  5)
292   ])
293
294 ;; Constants used in the XOP pperm instruction
295 (define_constants
296   [(PPERM_SRC                   0x00)   /* copy source */
297    (PPERM_INVERT                0x20)   /* invert source */
298    (PPERM_REVERSE               0x40)   /* bit reverse source */
299    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
300    (PPERM_ZERO                  0x80)   /* all 0's */
301    (PPERM_ONES                  0xa0)   /* all 1's */
302    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
303    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
304    (PPERM_SRC1                  0x00)   /* use first source byte */
305    (PPERM_SRC2                  0x10)   /* use second source byte */
306    ])
307
308 ;; Registers by name.
309 (define_constants
310   [(AX_REG                       0)
311    (DX_REG                       1)
312    (CX_REG                       2)
313    (BX_REG                       3)
314    (SI_REG                       4)
315    (DI_REG                       5)
316    (BP_REG                       6)
317    (SP_REG                       7)
318    (ST0_REG                      8)
319    (ST1_REG                      9)
320    (ST2_REG                     10)
321    (ST3_REG                     11)
322    (ST4_REG                     12)
323    (ST5_REG                     13)
324    (ST6_REG                     14)
325    (ST7_REG                     15)
326    (FLAGS_REG                   17)
327    (FPSR_REG                    18)
328    (FPCR_REG                    19)
329    (XMM0_REG                    21)
330    (XMM1_REG                    22)
331    (XMM2_REG                    23)
332    (XMM3_REG                    24)
333    (XMM4_REG                    25)
334    (XMM5_REG                    26)
335    (XMM6_REG                    27)
336    (XMM7_REG                    28)
337    (MM0_REG                     29)
338    (MM1_REG                     30)
339    (MM2_REG                     31)
340    (MM3_REG                     32)
341    (MM4_REG                     33)
342    (MM5_REG                     34)
343    (MM6_REG                     35)
344    (MM7_REG                     36)
345    (R8_REG                      37)
346    (R9_REG                      38)
347    (R10_REG                     39)
348    (R11_REG                     40)
349    (R12_REG                     41)
350    (R13_REG                     42)
351    (XMM8_REG                    45)
352    (XMM9_REG                    46)
353    (XMM10_REG                   47)
354    (XMM11_REG                   48)
355    (XMM12_REG                   49)
356    (XMM13_REG                   50)
357    (XMM14_REG                   51)
358    (XMM15_REG                   52)
359   ])
360
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; from i386.c.
363
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first.  This allows for better optimization.  For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
368
369 \f
370 ;; Processor type.
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
373   (const (symbol_ref "ix86_schedule")))
374
375 ;; A basic instruction type.  Refinements due to arguments to be
376 ;; provided in other attributes.
377 (define_attr "type"
378   "other,multi,
379    alu,alu1,negnot,imov,imovx,lea,
380    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381    icmp,test,ibr,setcc,icmov,
382    push,pop,call,callv,leave,
383    str,bitmanip,
384    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387    ssemuladd,sse4arg,lwp,
388    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389   (const_string "other"))
390
391 ;; Main data type used by the insn
392 (define_attr "mode"
393   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394   (const_string "unknown"))
395
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399            (const_string "i387")
400          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
403            (const_string "sse")
404          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
405            (const_string "mmx")
406          (eq_attr "type" "other")
407            (const_string "unknown")]
408          (const_string "integer")))
409
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413                           bitmanip")
414            (const_int 0)
415          (eq_attr "unit" "i387,sse,mmx")
416            (const_int 0)
417          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
418                           imul,icmp,push,pop")
419            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420          (eq_attr "type" "imov,test")
421            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422          (eq_attr "type" "call")
423            (if_then_else (match_operand 0 "constant_call_address_operand" "")
424              (const_int 4)
425              (const_int 0))
426          (eq_attr "type" "callv")
427            (if_then_else (match_operand 1 "constant_call_address_operand" "")
428              (const_int 4)
429              (const_int 0))
430          ;; We don't know the size before shorten_branches.  Expect
431          ;; the instruction to fit for better scheduling.
432          (eq_attr "type" "ibr")
433            (const_int 1)
434          ]
435          (symbol_ref "/* Update immediate_length and other attributes! */
436                       gcc_unreachable (),1")))
437
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440   (cond [(eq_attr "type" "str,other,multi,fxch")
441            (const_int 0)
442          (and (eq_attr "type" "call")
443               (match_operand 0 "constant_call_address_operand" ""))
444              (const_int 0)
445          (and (eq_attr "type" "callv")
446               (match_operand 1 "constant_call_address_operand" ""))
447              (const_int 0)
448          ]
449          (symbol_ref "ix86_attr_length_address_default (insn)")))
450
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
454            (const_int 0)
455          (eq_attr "mode" "HI")
456            (const_int 1)
457          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
458            (const_int 1)
459         ]
460         (const_int 0)))
461
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
465            (const_int 0)
466          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
467            (const_int 1)
468         ]
469         (const_int 0)))
470
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
473   (if_then_else
474     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475          (eq_attr "unit" "sse,mmx"))
476     (const_int 1)
477     (const_int 0)))
478
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
482            (const_int 0)
483          (and (eq_attr "mode" "DI")
484               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485                    (eq_attr "unit" "!mmx")))
486            (const_int 1)
487          (and (eq_attr "mode" "QI")
488               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489                   (const_int 0)))
490            (const_int 1)
491          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492              (const_int 0))
493            (const_int 1)
494          (and (eq_attr "type" "imovx")
495               (match_operand:QI 1 "ext_QIreg_operand" ""))
496            (const_int 1)
497         ]
498         (const_int 0)))
499
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505   (cond [(eq_attr "type" "ssemuladd,sse4arg")
506            (const_int 2)
507          (eq_attr "type" "sseiadd1,ssecvt1")
508            (const_int 1)
509         ]
510         (const_int 0)))
511
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
515     (const_string "vex")
516     (const_string "orig")))
517
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
520
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526   (if_then_else (and (eq_attr "prefix_0f" "1")
527                      (eq_attr "prefix_extra" "0"))
528     (if_then_else (eq_attr "prefix_vex_w" "1")
529       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531     (if_then_else (eq_attr "prefix_vex_w" "1")
532       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
534
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537   (cond [(eq_attr "type" "str,leave")
538            (const_int 0)
539          (eq_attr "unit" "i387")
540            (const_int 0)
541          (and (eq_attr "type" "incdec")
542               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543                    (ior (match_operand:SI 1 "register_operand" "")
544                         (match_operand:HI 1 "register_operand" ""))))
545            (const_int 0)
546          (and (eq_attr "type" "push")
547               (not (match_operand 1 "memory_operand" "")))
548            (const_int 0)
549          (and (eq_attr "type" "pop")
550               (not (match_operand 0 "memory_operand" "")))
551            (const_int 0)
552          (and (eq_attr "type" "imov")
553               (and (not (eq_attr "mode" "DI"))
554                    (ior (and (match_operand 0 "register_operand" "")
555                              (match_operand 1 "immediate_operand" ""))
556                         (ior (and (match_operand 0 "ax_reg_operand" "")
557                                   (match_operand 1 "memory_displacement_only_operand" ""))
558                              (and (match_operand 0 "memory_displacement_only_operand" "")
559                                   (match_operand 1 "ax_reg_operand" ""))))))
560            (const_int 0)
561          (and (eq_attr "type" "call")
562               (match_operand 0 "constant_call_address_operand" ""))
563              (const_int 0)
564          (and (eq_attr "type" "callv")
565               (match_operand 1 "constant_call_address_operand" ""))
566              (const_int 0)
567          (and (eq_attr "type" "alu,alu1,icmp,test")
568               (match_operand 0 "ax_reg_operand" ""))
569              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
570          ]
571          (const_int 1)))
572
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
576 ;; other insns.
577 (define_attr "length" ""
578   (cond [(eq_attr "type" "other,multi,fistp,frndint")
579            (const_int 16)
580          (eq_attr "type" "fcmp")
581            (const_int 4)
582          (eq_attr "unit" "i387")
583            (plus (const_int 2)
584                  (plus (attr "prefix_data16")
585                        (attr "length_address")))
586          (ior (eq_attr "prefix" "vex")
587               (and (eq_attr "prefix" "maybe_vex")
588                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589            (plus (attr "length_vex")
590                  (plus (attr "length_immediate")
591                        (plus (attr "modrm")
592                              (attr "length_address"))))]
593          (plus (plus (attr "modrm")
594                      (plus (attr "prefix_0f")
595                            (plus (attr "prefix_rex")
596                                  (plus (attr "prefix_extra")
597                                        (const_int 1)))))
598                (plus (attr "prefix_rep")
599                      (plus (attr "prefix_data16")
600                            (plus (attr "length_immediate")
601                                  (attr "length_address")))))))
602
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
606
607 (define_attr "memory" "none,load,store,both,unknown"
608   (cond [(eq_attr "type" "other,multi,str,lwp")
609            (const_string "unknown")
610          (eq_attr "type" "lea,fcmov,fpspc")
611            (const_string "none")
612          (eq_attr "type" "fistp,leave")
613            (const_string "both")
614          (eq_attr "type" "frndint")
615            (const_string "load")
616          (eq_attr "type" "push")
617            (if_then_else (match_operand 1 "memory_operand" "")
618              (const_string "both")
619              (const_string "store"))
620          (eq_attr "type" "pop")
621            (if_then_else (match_operand 0 "memory_operand" "")
622              (const_string "both")
623              (const_string "load"))
624          (eq_attr "type" "setcc")
625            (if_then_else (match_operand 0 "memory_operand" "")
626              (const_string "store")
627              (const_string "none"))
628          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629            (if_then_else (ior (match_operand 0 "memory_operand" "")
630                               (match_operand 1 "memory_operand" ""))
631              (const_string "load")
632              (const_string "none"))
633          (eq_attr "type" "ibr")
634            (if_then_else (match_operand 0 "memory_operand" "")
635              (const_string "load")
636              (const_string "none"))
637          (eq_attr "type" "call")
638            (if_then_else (match_operand 0 "constant_call_address_operand" "")
639              (const_string "none")
640              (const_string "load"))
641          (eq_attr "type" "callv")
642            (if_then_else (match_operand 1 "constant_call_address_operand" "")
643              (const_string "none")
644              (const_string "load"))
645          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646               (match_operand 1 "memory_operand" ""))
647            (const_string "both")
648          (and (match_operand 0 "memory_operand" "")
649               (match_operand 1 "memory_operand" ""))
650            (const_string "both")
651          (match_operand 0 "memory_operand" "")
652            (const_string "store")
653          (match_operand 1 "memory_operand" "")
654            (const_string "load")
655          (and (eq_attr "type"
656                  "!alu1,negnot,ishift1,
657                    imov,imovx,icmp,test,bitmanip,
658                    fmov,fcmp,fsgn,
659                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661               (match_operand 2 "memory_operand" ""))
662            (const_string "load")
663          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664               (match_operand 3 "memory_operand" ""))
665            (const_string "load")
666         ]
667         (const_string "none")))
668
669 ;; Indicates if an instruction has both an immediate and a displacement.
670
671 (define_attr "imm_disp" "false,true,unknown"
672   (cond [(eq_attr "type" "other,multi")
673            (const_string "unknown")
674          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675               (and (match_operand 0 "memory_displacement_operand" "")
676                    (match_operand 1 "immediate_operand" "")))
677            (const_string "true")
678          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679               (and (match_operand 0 "memory_displacement_operand" "")
680                    (match_operand 2 "immediate_operand" "")))
681            (const_string "true")
682         ]
683         (const_string "false")))
684
685 ;; Indicates if an FP operation has an integer source.
686
687 (define_attr "fp_int_src" "false,true"
688   (const_string "false"))
689
690 ;; Defines rounding mode of an FP operation.
691
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693   (const_string "any"))
694
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
697
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
700
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703   (const_string "base"))
704
705 (define_attr "enabled" ""
706   (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
708         ]
709         (const_int 1)))
710
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713   [(set_attr "length" "128")
714    (set_attr "type" "multi")])
715
716 (define_code_iterator plusminus [plus minus])
717
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
719
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727   [(plus "add") (ss_plus "adds") (us_plus "addus")
728    (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730   [(plus "adc") (minus "sbb")])
731
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734                         (minus "") (ss_minus "") (us_minus "")])
735
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
738
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
741
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744                               (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
746
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
750
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
753
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
756
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
759
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
762
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
765
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
768
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
771
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
774
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
777
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
780
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783                      (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
785
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
788
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791                              (div "i") (udiv "")])
792
793 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
795
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
798
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
801
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
804
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
807
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
810
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
813
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
816
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
819
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822                              (HI "TARGET_HIMODE_MATH")
823                              SI DI (TI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827                             (HI "TARGET_HIMODE_MATH")
828                             SI (DI "TARGET_64BIT")])
829
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832                                (HI "TARGET_HIMODE_MATH")
833                                SI])
834
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837                                SI (DI "TARGET_64BIT")])
838
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841                            (TI "TARGET_64BIT")])
842
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
846
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849                             (DI "TARGET_64BIT")])
850
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
853
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
856                             (HI "WORD")
857                             (SI "DWORD")
858                             (DI "QWORD")])
859
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
862
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
865
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
868
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "nF") (DI "e")])
871
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
874
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877         [(QI "general_operand")
878          (HI "general_operand")
879          (SI "x86_64_general_operand")
880          (DI "x86_64_general_operand")
881          (TI "x86_64_general_operand")])
882
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885         [(QI "general_operand")
886          (HI "general_operand")
887          (SI "x86_64_szext_general_operand")
888          (DI "x86_64_szext_general_operand")])
889
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892         [(QI "immediate_operand")
893          (HI "immediate_operand")
894          (SI "x86_64_immediate_operand")
895          (DI "x86_64_immediate_operand")])
896
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899         [(QI "nonmemory_operand")
900          (HI "nonmemory_operand")
901          (SI "x86_64_nonmemory_operand")
902          (DI "x86_64_nonmemory_operand")])
903
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906         [(QI "nonimmediate_operand")
907          (HI "nonimmediate_operand")
908          (SI "nonimmediate_operand")
909          (DI "shiftdi_operand")
910          (TI "register_operand")])
911
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914         [(QI "const_1_to_31_operand")
915          (HI "const_1_to_31_operand")
916          (SI "const_1_to_31_operand")
917          (DI "const_1_to_63_operand")])
918
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921         [(QI "nonimmediate_operand")
922          (HI "nonimmediate_operand")
923          (SI "nonimmediate_operand")
924          (DI "ashldi_input_operand")
925          (TI "reg_or_pm1_operand")])
926
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
929
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
932
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
935   [(SF "ss") (DF "sd")
936    (V8SF "ps") (V4DF "pd")
937    (V4SF "ps") (V2DF "pd")
938    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
939    (V8SI "si")])
940
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
943
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
947
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
950
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
954
955 ;; This mode iterator allows :PTR to be used for patterns that operate on
956 ;; ptr_mode sized quantities.
957 (define_mode_iterator PTR
958   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
959 \f
960 ;; Scheduling descriptions
961
962 (include "pentium.md")
963 (include "ppro.md")
964 (include "k6.md")
965 (include "athlon.md")
966 (include "bdver1.md")
967 (include "geode.md")
968 (include "atom.md")
969 (include "core2.md")
970
971 \f
972 ;; Operand and operator predicates and constraints
973
974 (include "predicates.md")
975 (include "constraints.md")
976
977 \f
978 ;; Compare and branch/compare and store instructions.
979
980 (define_expand "cbranch<mode>4"
981   [(set (reg:CC FLAGS_REG)
982         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
983                     (match_operand:SDWIM 2 "<general_operand>" "")))
984    (set (pc) (if_then_else
985                (match_operator 0 "ordered_comparison_operator"
986                 [(reg:CC FLAGS_REG) (const_int 0)])
987                (label_ref (match_operand 3 "" ""))
988                (pc)))]
989   ""
990 {
991   if (MEM_P (operands[1]) && MEM_P (operands[2]))
992     operands[1] = force_reg (<MODE>mode, operands[1]);
993   ix86_expand_branch (GET_CODE (operands[0]),
994                       operands[1], operands[2], operands[3]);
995   DONE;
996 })
997
998 (define_expand "cstore<mode>4"
999   [(set (reg:CC FLAGS_REG)
1000         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1001                     (match_operand:SWIM 3 "<general_operand>" "")))
1002    (set (match_operand:QI 0 "register_operand" "")
1003         (match_operator 1 "ordered_comparison_operator"
1004           [(reg:CC FLAGS_REG) (const_int 0)]))]
1005   ""
1006 {
1007   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1008     operands[2] = force_reg (<MODE>mode, operands[2]);
1009   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1010                      operands[2], operands[3]);
1011   DONE;
1012 })
1013
1014 (define_expand "cmp<mode>_1"
1015   [(set (reg:CC FLAGS_REG)
1016         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1017                     (match_operand:SWI48 1 "<general_operand>" "")))])
1018
1019 (define_insn "*cmp<mode>_ccno_1"
1020   [(set (reg FLAGS_REG)
1021         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1022                  (match_operand:SWI 1 "const0_operand" "")))]
1023   "ix86_match_ccmode (insn, CCNOmode)"
1024   "@
1025    test{<imodesuffix>}\t%0, %0
1026    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1027   [(set_attr "type" "test,icmp")
1028    (set_attr "length_immediate" "0,1")
1029    (set_attr "mode" "<MODE>")])
1030
1031 (define_insn "*cmp<mode>_1"
1032   [(set (reg FLAGS_REG)
1033         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1034                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1035   "ix86_match_ccmode (insn, CCmode)"
1036   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1037   [(set_attr "type" "icmp")
1038    (set_attr "mode" "<MODE>")])
1039
1040 (define_insn "*cmp<mode>_minus_1"
1041   [(set (reg FLAGS_REG)
1042         (compare
1043           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1044                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1045           (const_int 0)))]
1046   "ix86_match_ccmode (insn, CCGOCmode)"
1047   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1048   [(set_attr "type" "icmp")
1049    (set_attr "mode" "<MODE>")])
1050
1051 (define_insn "*cmpqi_ext_1"
1052   [(set (reg FLAGS_REG)
1053         (compare
1054           (match_operand:QI 0 "general_operand" "Qm")
1055           (subreg:QI
1056             (zero_extract:SI
1057               (match_operand 1 "ext_register_operand" "Q")
1058               (const_int 8)
1059               (const_int 8)) 0)))]
1060   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1061   "cmp{b}\t{%h1, %0|%0, %h1}"
1062   [(set_attr "type" "icmp")
1063    (set_attr "mode" "QI")])
1064
1065 (define_insn "*cmpqi_ext_1_rex64"
1066   [(set (reg FLAGS_REG)
1067         (compare
1068           (match_operand:QI 0 "register_operand" "Q")
1069           (subreg:QI
1070             (zero_extract:SI
1071               (match_operand 1 "ext_register_operand" "Q")
1072               (const_int 8)
1073               (const_int 8)) 0)))]
1074   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1075   "cmp{b}\t{%h1, %0|%0, %h1}"
1076   [(set_attr "type" "icmp")
1077    (set_attr "mode" "QI")])
1078
1079 (define_insn "*cmpqi_ext_2"
1080   [(set (reg FLAGS_REG)
1081         (compare
1082           (subreg:QI
1083             (zero_extract:SI
1084               (match_operand 0 "ext_register_operand" "Q")
1085               (const_int 8)
1086               (const_int 8)) 0)
1087           (match_operand:QI 1 "const0_operand" "")))]
1088   "ix86_match_ccmode (insn, CCNOmode)"
1089   "test{b}\t%h0, %h0"
1090   [(set_attr "type" "test")
1091    (set_attr "length_immediate" "0")
1092    (set_attr "mode" "QI")])
1093
1094 (define_expand "cmpqi_ext_3"
1095   [(set (reg:CC FLAGS_REG)
1096         (compare:CC
1097           (subreg:QI
1098             (zero_extract:SI
1099               (match_operand 0 "ext_register_operand" "")
1100               (const_int 8)
1101               (const_int 8)) 0)
1102           (match_operand:QI 1 "immediate_operand" "")))])
1103
1104 (define_insn "*cmpqi_ext_3_insn"
1105   [(set (reg FLAGS_REG)
1106         (compare
1107           (subreg:QI
1108             (zero_extract:SI
1109               (match_operand 0 "ext_register_operand" "Q")
1110               (const_int 8)
1111               (const_int 8)) 0)
1112           (match_operand:QI 1 "general_operand" "Qmn")))]
1113   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1114   "cmp{b}\t{%1, %h0|%h0, %1}"
1115   [(set_attr "type" "icmp")
1116    (set_attr "modrm" "1")
1117    (set_attr "mode" "QI")])
1118
1119 (define_insn "*cmpqi_ext_3_insn_rex64"
1120   [(set (reg FLAGS_REG)
1121         (compare
1122           (subreg:QI
1123             (zero_extract:SI
1124               (match_operand 0 "ext_register_operand" "Q")
1125               (const_int 8)
1126               (const_int 8)) 0)
1127           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1128   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1129   "cmp{b}\t{%1, %h0|%h0, %1}"
1130   [(set_attr "type" "icmp")
1131    (set_attr "modrm" "1")
1132    (set_attr "mode" "QI")])
1133
1134 (define_insn "*cmpqi_ext_4"
1135   [(set (reg FLAGS_REG)
1136         (compare
1137           (subreg:QI
1138             (zero_extract:SI
1139               (match_operand 0 "ext_register_operand" "Q")
1140               (const_int 8)
1141               (const_int 8)) 0)
1142           (subreg:QI
1143             (zero_extract:SI
1144               (match_operand 1 "ext_register_operand" "Q")
1145               (const_int 8)
1146               (const_int 8)) 0)))]
1147   "ix86_match_ccmode (insn, CCmode)"
1148   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1149   [(set_attr "type" "icmp")
1150    (set_attr "mode" "QI")])
1151
1152 ;; These implement float point compares.
1153 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1154 ;; which would allow mix and match FP modes on the compares.  Which is what
1155 ;; the old patterns did, but with many more of them.
1156
1157 (define_expand "cbranchxf4"
1158   [(set (reg:CC FLAGS_REG)
1159         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1160                     (match_operand:XF 2 "nonmemory_operand" "")))
1161    (set (pc) (if_then_else
1162               (match_operator 0 "ix86_fp_comparison_operator"
1163                [(reg:CC FLAGS_REG)
1164                 (const_int 0)])
1165               (label_ref (match_operand 3 "" ""))
1166               (pc)))]
1167   "TARGET_80387"
1168 {
1169   ix86_expand_branch (GET_CODE (operands[0]),
1170                       operands[1], operands[2], operands[3]);
1171   DONE;
1172 })
1173
1174 (define_expand "cstorexf4"
1175   [(set (reg:CC FLAGS_REG)
1176         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1177                     (match_operand:XF 3 "nonmemory_operand" "")))
1178    (set (match_operand:QI 0 "register_operand" "")
1179               (match_operator 1 "ix86_fp_comparison_operator"
1180                [(reg:CC FLAGS_REG)
1181                 (const_int 0)]))]
1182   "TARGET_80387"
1183 {
1184   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1185                      operands[2], operands[3]);
1186   DONE;
1187 })
1188
1189 (define_expand "cbranch<mode>4"
1190   [(set (reg:CC FLAGS_REG)
1191         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1192                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1193    (set (pc) (if_then_else
1194               (match_operator 0 "ix86_fp_comparison_operator"
1195                [(reg:CC FLAGS_REG)
1196                 (const_int 0)])
1197               (label_ref (match_operand 3 "" ""))
1198               (pc)))]
1199   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1200 {
1201   ix86_expand_branch (GET_CODE (operands[0]),
1202                       operands[1], operands[2], operands[3]);
1203   DONE;
1204 })
1205
1206 (define_expand "cstore<mode>4"
1207   [(set (reg:CC FLAGS_REG)
1208         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1209                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1210    (set (match_operand:QI 0 "register_operand" "")
1211               (match_operator 1 "ix86_fp_comparison_operator"
1212                [(reg:CC FLAGS_REG)
1213                 (const_int 0)]))]
1214   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1215 {
1216   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1217                      operands[2], operands[3]);
1218   DONE;
1219 })
1220
1221 (define_expand "cbranchcc4"
1222   [(set (pc) (if_then_else
1223               (match_operator 0 "comparison_operator"
1224                [(match_operand 1 "flags_reg_operand" "")
1225                 (match_operand 2 "const0_operand" "")])
1226               (label_ref (match_operand 3 "" ""))
1227               (pc)))]
1228   ""
1229 {
1230   ix86_expand_branch (GET_CODE (operands[0]),
1231                       operands[1], operands[2], operands[3]);
1232   DONE;
1233 })
1234
1235 (define_expand "cstorecc4"
1236   [(set (match_operand:QI 0 "register_operand" "")
1237               (match_operator 1 "comparison_operator"
1238                [(match_operand 2 "flags_reg_operand" "")
1239                 (match_operand 3 "const0_operand" "")]))]
1240   ""
1241 {
1242   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1243                      operands[2], operands[3]);
1244   DONE;
1245 })
1246
1247
1248 ;; FP compares, step 1:
1249 ;; Set the FP condition codes.
1250 ;;
1251 ;; CCFPmode     compare with exceptions
1252 ;; CCFPUmode    compare with no exceptions
1253
1254 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1255 ;; used to manage the reg stack popping would not be preserved.
1256
1257 (define_insn "*cmpfp_0"
1258   [(set (match_operand:HI 0 "register_operand" "=a")
1259         (unspec:HI
1260           [(compare:CCFP
1261              (match_operand 1 "register_operand" "f")
1262              (match_operand 2 "const0_operand" ""))]
1263         UNSPEC_FNSTSW))]
1264   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1265    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1266   "* return output_fp_compare (insn, operands, false, false);"
1267   [(set_attr "type" "multi")
1268    (set_attr "unit" "i387")
1269    (set (attr "mode")
1270      (cond [(match_operand:SF 1 "" "")
1271               (const_string "SF")
1272             (match_operand:DF 1 "" "")
1273               (const_string "DF")
1274            ]
1275            (const_string "XF")))])
1276
1277 (define_insn_and_split "*cmpfp_0_cc"
1278   [(set (reg:CCFP FLAGS_REG)
1279         (compare:CCFP
1280           (match_operand 1 "register_operand" "f")
1281           (match_operand 2 "const0_operand" "")))
1282    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1283   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1284    && TARGET_SAHF && !TARGET_CMOVE
1285    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1286   "#"
1287   "&& reload_completed"
1288   [(set (match_dup 0)
1289         (unspec:HI
1290           [(compare:CCFP (match_dup 1)(match_dup 2))]
1291         UNSPEC_FNSTSW))
1292    (set (reg:CC FLAGS_REG)
1293         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294   ""
1295   [(set_attr "type" "multi")
1296    (set_attr "unit" "i387")
1297    (set (attr "mode")
1298      (cond [(match_operand:SF 1 "" "")
1299               (const_string "SF")
1300             (match_operand:DF 1 "" "")
1301               (const_string "DF")
1302            ]
1303            (const_string "XF")))])
1304
1305 (define_insn "*cmpfp_xf"
1306   [(set (match_operand:HI 0 "register_operand" "=a")
1307         (unspec:HI
1308           [(compare:CCFP
1309              (match_operand:XF 1 "register_operand" "f")
1310              (match_operand:XF 2 "register_operand" "f"))]
1311           UNSPEC_FNSTSW))]
1312   "TARGET_80387"
1313   "* return output_fp_compare (insn, operands, false, false);"
1314   [(set_attr "type" "multi")
1315    (set_attr "unit" "i387")
1316    (set_attr "mode" "XF")])
1317
1318 (define_insn_and_split "*cmpfp_xf_cc"
1319   [(set (reg:CCFP FLAGS_REG)
1320         (compare:CCFP
1321           (match_operand:XF 1 "register_operand" "f")
1322           (match_operand:XF 2 "register_operand" "f")))
1323    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1324   "TARGET_80387
1325    && TARGET_SAHF && !TARGET_CMOVE"
1326   "#"
1327   "&& reload_completed"
1328   [(set (match_dup 0)
1329         (unspec:HI
1330           [(compare:CCFP (match_dup 1)(match_dup 2))]
1331         UNSPEC_FNSTSW))
1332    (set (reg:CC FLAGS_REG)
1333         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334   ""
1335   [(set_attr "type" "multi")
1336    (set_attr "unit" "i387")
1337    (set_attr "mode" "XF")])
1338
1339 (define_insn "*cmpfp_<mode>"
1340   [(set (match_operand:HI 0 "register_operand" "=a")
1341         (unspec:HI
1342           [(compare:CCFP
1343              (match_operand:MODEF 1 "register_operand" "f")
1344              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1345           UNSPEC_FNSTSW))]
1346   "TARGET_80387"
1347   "* return output_fp_compare (insn, operands, false, false);"
1348   [(set_attr "type" "multi")
1349    (set_attr "unit" "i387")
1350    (set_attr "mode" "<MODE>")])
1351
1352 (define_insn_and_split "*cmpfp_<mode>_cc"
1353   [(set (reg:CCFP FLAGS_REG)
1354         (compare:CCFP
1355           (match_operand:MODEF 1 "register_operand" "f")
1356           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1357    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1358   "TARGET_80387
1359    && TARGET_SAHF && !TARGET_CMOVE"
1360   "#"
1361   "&& reload_completed"
1362   [(set (match_dup 0)
1363         (unspec:HI
1364           [(compare:CCFP (match_dup 1)(match_dup 2))]
1365         UNSPEC_FNSTSW))
1366    (set (reg:CC FLAGS_REG)
1367         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1368   ""
1369   [(set_attr "type" "multi")
1370    (set_attr "unit" "i387")
1371    (set_attr "mode" "<MODE>")])
1372
1373 (define_insn "*cmpfp_u"
1374   [(set (match_operand:HI 0 "register_operand" "=a")
1375         (unspec:HI
1376           [(compare:CCFPU
1377              (match_operand 1 "register_operand" "f")
1378              (match_operand 2 "register_operand" "f"))]
1379           UNSPEC_FNSTSW))]
1380   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1381    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1382   "* return output_fp_compare (insn, operands, false, true);"
1383   [(set_attr "type" "multi")
1384    (set_attr "unit" "i387")
1385    (set (attr "mode")
1386      (cond [(match_operand:SF 1 "" "")
1387               (const_string "SF")
1388             (match_operand:DF 1 "" "")
1389               (const_string "DF")
1390            ]
1391            (const_string "XF")))])
1392
1393 (define_insn_and_split "*cmpfp_u_cc"
1394   [(set (reg:CCFPU FLAGS_REG)
1395         (compare:CCFPU
1396           (match_operand 1 "register_operand" "f")
1397           (match_operand 2 "register_operand" "f")))
1398    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1399   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1400    && TARGET_SAHF && !TARGET_CMOVE
1401    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1402   "#"
1403   "&& reload_completed"
1404   [(set (match_dup 0)
1405         (unspec:HI
1406           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1407         UNSPEC_FNSTSW))
1408    (set (reg:CC FLAGS_REG)
1409         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1410   ""
1411   [(set_attr "type" "multi")
1412    (set_attr "unit" "i387")
1413    (set (attr "mode")
1414      (cond [(match_operand:SF 1 "" "")
1415               (const_string "SF")
1416             (match_operand:DF 1 "" "")
1417               (const_string "DF")
1418            ]
1419            (const_string "XF")))])
1420
1421 (define_insn "*cmpfp_<mode>"
1422   [(set (match_operand:HI 0 "register_operand" "=a")
1423         (unspec:HI
1424           [(compare:CCFP
1425              (match_operand 1 "register_operand" "f")
1426              (match_operator 3 "float_operator"
1427                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1428           UNSPEC_FNSTSW))]
1429   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1430    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1431    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1432   "* return output_fp_compare (insn, operands, false, false);"
1433   [(set_attr "type" "multi")
1434    (set_attr "unit" "i387")
1435    (set_attr "fp_int_src" "true")
1436    (set_attr "mode" "<MODE>")])
1437
1438 (define_insn_and_split "*cmpfp_<mode>_cc"
1439   [(set (reg:CCFP FLAGS_REG)
1440         (compare:CCFP
1441           (match_operand 1 "register_operand" "f")
1442           (match_operator 3 "float_operator"
1443             [(match_operand:SWI24 2 "memory_operand" "m")])))
1444    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1445   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1446    && TARGET_SAHF && !TARGET_CMOVE
1447    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1448    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1449   "#"
1450   "&& reload_completed"
1451   [(set (match_dup 0)
1452         (unspec:HI
1453           [(compare:CCFP
1454              (match_dup 1)
1455              (match_op_dup 3 [(match_dup 2)]))]
1456         UNSPEC_FNSTSW))
1457    (set (reg:CC FLAGS_REG)
1458         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1459   ""
1460   [(set_attr "type" "multi")
1461    (set_attr "unit" "i387")
1462    (set_attr "fp_int_src" "true")
1463    (set_attr "mode" "<MODE>")])
1464
1465 ;; FP compares, step 2
1466 ;; Move the fpsw to ax.
1467
1468 (define_insn "x86_fnstsw_1"
1469   [(set (match_operand:HI 0 "register_operand" "=a")
1470         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1471   "TARGET_80387"
1472   "fnstsw\t%0"
1473   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1474    (set_attr "mode" "SI")
1475    (set_attr "unit" "i387")])
1476
1477 ;; FP compares, step 3
1478 ;; Get ax into flags, general case.
1479
1480 (define_insn "x86_sahf_1"
1481   [(set (reg:CC FLAGS_REG)
1482         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1483                    UNSPEC_SAHF))]
1484   "TARGET_SAHF"
1485 {
1486 #ifndef HAVE_AS_IX86_SAHF
1487   if (TARGET_64BIT)
1488     return ASM_BYTE "0x9e";
1489   else
1490 #endif
1491   return "sahf";
1492 }
1493   [(set_attr "length" "1")
1494    (set_attr "athlon_decode" "vector")
1495    (set_attr "amdfam10_decode" "direct")
1496    (set_attr "bdver1_decode" "direct")
1497    (set_attr "mode" "SI")])
1498
1499 ;; Pentium Pro can do steps 1 through 3 in one go.
1500 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1501 (define_insn "*cmpfp_i_mixed"
1502   [(set (reg:CCFP FLAGS_REG)
1503         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1504                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1505   "TARGET_MIX_SSE_I387
1506    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1507    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1508   "* return output_fp_compare (insn, operands, true, false);"
1509   [(set_attr "type" "fcmp,ssecomi")
1510    (set_attr "prefix" "orig,maybe_vex")
1511    (set (attr "mode")
1512      (if_then_else (match_operand:SF 1 "" "")
1513         (const_string "SF")
1514         (const_string "DF")))
1515    (set (attr "prefix_rep")
1516         (if_then_else (eq_attr "type" "ssecomi")
1517                       (const_string "0")
1518                       (const_string "*")))
1519    (set (attr "prefix_data16")
1520         (cond [(eq_attr "type" "fcmp")
1521                  (const_string "*")
1522                (eq_attr "mode" "DF")
1523                  (const_string "1")
1524               ]
1525               (const_string "0")))
1526    (set_attr "athlon_decode" "vector")
1527    (set_attr "amdfam10_decode" "direct")
1528    (set_attr "bdver1_decode" "double")])
1529
1530 (define_insn "*cmpfp_i_sse"
1531   [(set (reg:CCFP FLAGS_REG)
1532         (compare:CCFP (match_operand 0 "register_operand" "x")
1533                       (match_operand 1 "nonimmediate_operand" "xm")))]
1534   "TARGET_SSE_MATH
1535    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1536    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1537   "* return output_fp_compare (insn, operands, true, false);"
1538   [(set_attr "type" "ssecomi")
1539    (set_attr "prefix" "maybe_vex")
1540    (set (attr "mode")
1541      (if_then_else (match_operand:SF 1 "" "")
1542         (const_string "SF")
1543         (const_string "DF")))
1544    (set_attr "prefix_rep" "0")
1545    (set (attr "prefix_data16")
1546         (if_then_else (eq_attr "mode" "DF")
1547                       (const_string "1")
1548                       (const_string "0")))
1549    (set_attr "athlon_decode" "vector")
1550    (set_attr "amdfam10_decode" "direct")
1551    (set_attr "bdver1_decode" "double")])
1552
1553 (define_insn "*cmpfp_i_i387"
1554   [(set (reg:CCFP FLAGS_REG)
1555         (compare:CCFP (match_operand 0 "register_operand" "f")
1556                       (match_operand 1 "register_operand" "f")))]
1557   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1558    && TARGET_CMOVE
1559    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1560    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1561   "* return output_fp_compare (insn, operands, true, false);"
1562   [(set_attr "type" "fcmp")
1563    (set (attr "mode")
1564      (cond [(match_operand:SF 1 "" "")
1565               (const_string "SF")
1566             (match_operand:DF 1 "" "")
1567               (const_string "DF")
1568            ]
1569            (const_string "XF")))
1570    (set_attr "athlon_decode" "vector")
1571    (set_attr "amdfam10_decode" "direct")
1572    (set_attr "bdver1_decode" "double")])
1573
1574 (define_insn "*cmpfp_iu_mixed"
1575   [(set (reg:CCFPU FLAGS_REG)
1576         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1577                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1578   "TARGET_MIX_SSE_I387
1579    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1580    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1581   "* return output_fp_compare (insn, operands, true, true);"
1582   [(set_attr "type" "fcmp,ssecomi")
1583    (set_attr "prefix" "orig,maybe_vex")
1584    (set (attr "mode")
1585      (if_then_else (match_operand:SF 1 "" "")
1586         (const_string "SF")
1587         (const_string "DF")))
1588    (set (attr "prefix_rep")
1589         (if_then_else (eq_attr "type" "ssecomi")
1590                       (const_string "0")
1591                       (const_string "*")))
1592    (set (attr "prefix_data16")
1593         (cond [(eq_attr "type" "fcmp")
1594                  (const_string "*")
1595                (eq_attr "mode" "DF")
1596                  (const_string "1")
1597               ]
1598               (const_string "0")))
1599    (set_attr "athlon_decode" "vector")
1600    (set_attr "amdfam10_decode" "direct")
1601    (set_attr "bdver1_decode" "double")])
1602
1603 (define_insn "*cmpfp_iu_sse"
1604   [(set (reg:CCFPU FLAGS_REG)
1605         (compare:CCFPU (match_operand 0 "register_operand" "x")
1606                        (match_operand 1 "nonimmediate_operand" "xm")))]
1607   "TARGET_SSE_MATH
1608    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1609    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1610   "* return output_fp_compare (insn, operands, true, true);"
1611   [(set_attr "type" "ssecomi")
1612    (set_attr "prefix" "maybe_vex")
1613    (set (attr "mode")
1614      (if_then_else (match_operand:SF 1 "" "")
1615         (const_string "SF")
1616         (const_string "DF")))
1617    (set_attr "prefix_rep" "0")
1618    (set (attr "prefix_data16")
1619         (if_then_else (eq_attr "mode" "DF")
1620                       (const_string "1")
1621                       (const_string "0")))
1622    (set_attr "athlon_decode" "vector")
1623    (set_attr "amdfam10_decode" "direct")
1624    (set_attr "bdver1_decode" "double")])
1625
1626 (define_insn "*cmpfp_iu_387"
1627   [(set (reg:CCFPU FLAGS_REG)
1628         (compare:CCFPU (match_operand 0 "register_operand" "f")
1629                        (match_operand 1 "register_operand" "f")))]
1630   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1631    && TARGET_CMOVE
1632    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1633    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1634   "* return output_fp_compare (insn, operands, true, true);"
1635   [(set_attr "type" "fcmp")
1636    (set (attr "mode")
1637      (cond [(match_operand:SF 1 "" "")
1638               (const_string "SF")
1639             (match_operand:DF 1 "" "")
1640               (const_string "DF")
1641            ]
1642            (const_string "XF")))
1643    (set_attr "athlon_decode" "vector")
1644    (set_attr "amdfam10_decode" "direct")
1645    (set_attr "bdver1_decode" "direct")])
1646 \f
1647 ;; Push/pop instructions.
1648
1649 (define_insn "*push<mode>2"
1650   [(set (match_operand:DWI 0 "push_operand" "=<")
1651         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1652   ""
1653   "#"
1654   [(set_attr "type" "multi")
1655    (set_attr "mode" "<MODE>")])
1656
1657 (define_split
1658   [(set (match_operand:TI 0 "push_operand" "")
1659         (match_operand:TI 1 "general_operand" ""))]
1660   "TARGET_64BIT && reload_completed
1661    && !SSE_REG_P (operands[1])"
1662   [(const_int 0)]
1663   "ix86_split_long_move (operands); DONE;")
1664
1665 (define_insn "*pushdi2_rex64"
1666   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1667         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1668   "TARGET_64BIT"
1669   "@
1670    push{q}\t%1
1671    #"
1672   [(set_attr "type" "push,multi")
1673    (set_attr "mode" "DI")])
1674
1675 ;; Convert impossible pushes of immediate to existing instructions.
1676 ;; First try to get scratch register and go through it.  In case this
1677 ;; fails, push sign extended lower part first and then overwrite
1678 ;; upper part by 32bit move.
1679 (define_peephole2
1680   [(match_scratch:DI 2 "r")
1681    (set (match_operand:DI 0 "push_operand" "")
1682         (match_operand:DI 1 "immediate_operand" ""))]
1683   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1684    && !x86_64_immediate_operand (operands[1], DImode)"
1685   [(set (match_dup 2) (match_dup 1))
1686    (set (match_dup 0) (match_dup 2))])
1687
1688 ;; We need to define this as both peepholer and splitter for case
1689 ;; peephole2 pass is not run.
1690 ;; "&& 1" is needed to keep it from matching the previous pattern.
1691 (define_peephole2
1692   [(set (match_operand:DI 0 "push_operand" "")
1693         (match_operand:DI 1 "immediate_operand" ""))]
1694   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1695    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1696   [(set (match_dup 0) (match_dup 1))
1697    (set (match_dup 2) (match_dup 3))]
1698 {
1699   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1700
1701   operands[1] = gen_lowpart (DImode, operands[2]);
1702   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1703                                                    GEN_INT (4)));
1704 })
1705
1706 (define_split
1707   [(set (match_operand:DI 0 "push_operand" "")
1708         (match_operand:DI 1 "immediate_operand" ""))]
1709   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1710                     ? epilogue_completed : reload_completed)
1711    && !symbolic_operand (operands[1], DImode)
1712    && !x86_64_immediate_operand (operands[1], DImode)"
1713   [(set (match_dup 0) (match_dup 1))
1714    (set (match_dup 2) (match_dup 3))]
1715 {
1716   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1717
1718   operands[1] = gen_lowpart (DImode, operands[2]);
1719   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1720                                                    GEN_INT (4)));
1721 })
1722
1723 (define_split
1724   [(set (match_operand:DI 0 "push_operand" "")
1725         (match_operand:DI 1 "general_operand" ""))]
1726   "!TARGET_64BIT && reload_completed
1727    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1728   [(const_int 0)]
1729   "ix86_split_long_move (operands); DONE;")
1730
1731 (define_insn "*pushsi2"
1732   [(set (match_operand:SI 0 "push_operand" "=<")
1733         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1734   "!TARGET_64BIT"
1735   "push{l}\t%1"
1736   [(set_attr "type" "push")
1737    (set_attr "mode" "SI")])
1738
1739 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1740 ;; "push a byte/word".  But actually we use pushl, which has the effect
1741 ;; of rounding the amount pushed up to a word.
1742
1743 ;; For TARGET_64BIT we always round up to 8 bytes.
1744 (define_insn "*push<mode>2_rex64"
1745   [(set (match_operand:SWI124 0 "push_operand" "=X")
1746         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1747   "TARGET_64BIT"
1748   "push{q}\t%q1"
1749   [(set_attr "type" "push")
1750    (set_attr "mode" "DI")])
1751
1752 (define_insn "*push<mode>2"
1753   [(set (match_operand:SWI12 0 "push_operand" "=X")
1754         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1755   "!TARGET_64BIT"
1756   "push{l}\t%k1"
1757   [(set_attr "type" "push")
1758    (set_attr "mode" "SI")])
1759
1760 (define_insn "*push<mode>2_prologue"
1761   [(set (match_operand:P 0 "push_operand" "=<")
1762         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1763    (clobber (mem:BLK (scratch)))]
1764   ""
1765   "push{<imodesuffix>}\t%1"
1766   [(set_attr "type" "push")
1767    (set_attr "mode" "<MODE>")])
1768
1769 (define_insn "*pop<mode>1"
1770   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1771         (match_operand:P 1 "pop_operand" ">"))]
1772   ""
1773   "pop{<imodesuffix>}\t%0"
1774   [(set_attr "type" "pop")
1775    (set_attr "mode" "<MODE>")])
1776
1777 (define_insn "*pop<mode>1_epilogue"
1778   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1779         (match_operand:P 1 "pop_operand" ">"))
1780    (clobber (mem:BLK (scratch)))]
1781   ""
1782   "pop{<imodesuffix>}\t%0"
1783   [(set_attr "type" "pop")
1784    (set_attr "mode" "<MODE>")])
1785 \f
1786 ;; Move instructions.
1787
1788 (define_expand "movoi"
1789   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1790         (match_operand:OI 1 "general_operand" ""))]
1791   "TARGET_AVX"
1792   "ix86_expand_move (OImode, operands); DONE;")
1793
1794 (define_expand "movti"
1795   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1796         (match_operand:TI 1 "nonimmediate_operand" ""))]
1797   "TARGET_64BIT || TARGET_SSE"
1798 {
1799   if (TARGET_64BIT)
1800     ix86_expand_move (TImode, operands);
1801   else if (push_operand (operands[0], TImode))
1802     ix86_expand_push (TImode, operands[1]);
1803   else
1804     ix86_expand_vector_move (TImode, operands);
1805   DONE;
1806 })
1807
1808 ;; This expands to what emit_move_complex would generate if we didn't
1809 ;; have a movti pattern.  Having this avoids problems with reload on
1810 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1811 ;; to have around all the time.
1812 (define_expand "movcdi"
1813   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1814         (match_operand:CDI 1 "general_operand" ""))]
1815   ""
1816 {
1817   if (push_operand (operands[0], CDImode))
1818     emit_move_complex_push (CDImode, operands[0], operands[1]);
1819   else
1820     emit_move_complex_parts (operands[0], operands[1]);
1821   DONE;
1822 })
1823
1824 (define_expand "mov<mode>"
1825   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1826         (match_operand:SWI1248x 1 "general_operand" ""))]
1827   ""
1828   "ix86_expand_move (<MODE>mode, operands); DONE;")
1829
1830 (define_insn "*mov<mode>_xor"
1831   [(set (match_operand:SWI48 0 "register_operand" "=r")
1832         (match_operand:SWI48 1 "const0_operand" ""))
1833    (clobber (reg:CC FLAGS_REG))]
1834   "reload_completed"
1835   "xor{l}\t%k0, %k0"
1836   [(set_attr "type" "alu1")
1837    (set_attr "mode" "SI")
1838    (set_attr "length_immediate" "0")])
1839
1840 (define_insn "*mov<mode>_or"
1841   [(set (match_operand:SWI48 0 "register_operand" "=r")
1842         (match_operand:SWI48 1 "const_int_operand" ""))
1843    (clobber (reg:CC FLAGS_REG))]
1844   "reload_completed
1845    && operands[1] == constm1_rtx"
1846   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1847   [(set_attr "type" "alu1")
1848    (set_attr "mode" "<MODE>")
1849    (set_attr "length_immediate" "1")])
1850
1851 (define_insn "*movoi_internal_avx"
1852   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1853         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1854   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1855 {
1856   switch (which_alternative)
1857     {
1858     case 0:
1859       return standard_sse_constant_opcode (insn, operands[1]);
1860     case 1:
1861     case 2:
1862       if (misaligned_operand (operands[0], OImode)
1863           || misaligned_operand (operands[1], OImode))
1864         return "vmovdqu\t{%1, %0|%0, %1}";
1865       else
1866         return "vmovdqa\t{%1, %0|%0, %1}";
1867     default:
1868       gcc_unreachable ();
1869     }
1870 }
1871   [(set_attr "type" "sselog1,ssemov,ssemov")
1872    (set_attr "prefix" "vex")
1873    (set_attr "mode" "OI")])
1874
1875 (define_insn "*movti_internal_rex64"
1876   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1877         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1878   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1879 {
1880   switch (which_alternative)
1881     {
1882     case 0:
1883     case 1:
1884       return "#";
1885     case 2:
1886       return standard_sse_constant_opcode (insn, operands[1]);
1887     case 3:
1888     case 4:
1889       /* TDmode values are passed as TImode on the stack.  Moving them
1890          to stack may result in unaligned memory access.  */
1891       if (misaligned_operand (operands[0], TImode)
1892           || misaligned_operand (operands[1], TImode))
1893         {
1894           if (get_attr_mode (insn) == MODE_V4SF)
1895             return "%vmovups\t{%1, %0|%0, %1}";
1896           else
1897             return "%vmovdqu\t{%1, %0|%0, %1}";
1898         }
1899       else
1900         {
1901           if (get_attr_mode (insn) == MODE_V4SF)
1902             return "%vmovaps\t{%1, %0|%0, %1}";
1903           else
1904             return "%vmovdqa\t{%1, %0|%0, %1}";
1905         }
1906     default:
1907       gcc_unreachable ();
1908     }
1909 }
1910   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1912    (set (attr "mode")
1913         (cond [(eq_attr "alternative" "2,3")
1914                  (if_then_else
1915                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1916                        (const_int 0))
1917                    (const_string "V4SF")
1918                    (const_string "TI"))
1919                (eq_attr "alternative" "4")
1920                  (if_then_else
1921                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1922                             (const_int 0))
1923                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1924                             (const_int 0)))
1925                    (const_string "V4SF")
1926                    (const_string "TI"))]
1927                (const_string "DI")))])
1928
1929 (define_split
1930   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931         (match_operand:TI 1 "general_operand" ""))]
1932   "reload_completed
1933    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1934   [(const_int 0)]
1935   "ix86_split_long_move (operands); DONE;")
1936
1937 (define_insn "*movti_internal_sse"
1938   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940   "TARGET_SSE && !TARGET_64BIT
1941    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 {
1943   switch (which_alternative)
1944     {
1945     case 0:
1946       return standard_sse_constant_opcode (insn, operands[1]);
1947     case 1:
1948     case 2:
1949       /* TDmode values are passed as TImode on the stack.  Moving them
1950          to stack may result in unaligned memory access.  */
1951       if (misaligned_operand (operands[0], TImode)
1952           || misaligned_operand (operands[1], TImode))
1953         {
1954           if (get_attr_mode (insn) == MODE_V4SF)
1955             return "%vmovups\t{%1, %0|%0, %1}";
1956           else
1957             return "%vmovdqu\t{%1, %0|%0, %1}";
1958         }
1959       else
1960         {
1961           if (get_attr_mode (insn) == MODE_V4SF)
1962             return "%vmovaps\t{%1, %0|%0, %1}";
1963           else
1964             return "%vmovdqa\t{%1, %0|%0, %1}";
1965         }
1966     default:
1967       gcc_unreachable ();
1968     }
1969 }
1970   [(set_attr "type" "sselog1,ssemov,ssemov")
1971    (set_attr "prefix" "maybe_vex")
1972    (set (attr "mode")
1973         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1974                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1975                         (const_int 0)))
1976                  (const_string "V4SF")
1977                (and (eq_attr "alternative" "2")
1978                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1979                         (const_int 0)))
1980                  (const_string "V4SF")]
1981               (const_string "TI")))])
1982
1983 (define_insn "*movdi_internal_rex64"
1984   [(set (match_operand:DI 0 "nonimmediate_operand"
1985           "=r,r  ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1986         (match_operand:DI 1 "general_operand"
1987           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1988   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1989 {
1990   switch (get_attr_type (insn))
1991     {
1992     case TYPE_SSECVT:
1993       if (SSE_REG_P (operands[0]))
1994         return "movq2dq\t{%1, %0|%0, %1}";
1995       else
1996         return "movdq2q\t{%1, %0|%0, %1}";
1997
1998     case TYPE_SSEMOV:
1999       if (get_attr_mode (insn) == MODE_TI)
2000         return "%vmovdqa\t{%1, %0|%0, %1}";
2001       /* Handle broken assemblers that require movd instead of movq.  */
2002       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003         return "%vmovd\t{%1, %0|%0, %1}";
2004       else
2005         return "%vmovq\t{%1, %0|%0, %1}";
2006
2007     case TYPE_MMXMOV:
2008       /* Handle broken assemblers that require movd instead of movq.  */
2009       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2010         return "movd\t{%1, %0|%0, %1}";
2011       else
2012         return "movq\t{%1, %0|%0, %1}";
2013
2014     case TYPE_SSELOG1:
2015       return standard_sse_constant_opcode (insn, operands[1]);
2016
2017     case TYPE_MMX:
2018       return "pxor\t%0, %0";
2019
2020     case TYPE_MULTI:
2021       return "#";
2022
2023     case TYPE_LEA:
2024       return "lea{q}\t{%a1, %0|%0, %a1}";
2025
2026     default:
2027       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2028       if (get_attr_mode (insn) == MODE_SI)
2029         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2030       else if (which_alternative == 2)
2031         return "movabs{q}\t{%1, %0|%0, %1}";
2032       else
2033         return "mov{q}\t{%1, %0|%0, %1}";
2034     }
2035 }
2036   [(set (attr "type")
2037      (cond [(eq_attr "alternative" "4")
2038               (const_string "multi")
2039             (eq_attr "alternative" "5")
2040               (const_string "mmx")
2041             (eq_attr "alternative" "6,7,8,9")
2042               (const_string "mmxmov")
2043             (eq_attr "alternative" "10")
2044               (const_string "sselog1")
2045             (eq_attr "alternative" "11,12,13,14,15")
2046               (const_string "ssemov")
2047             (eq_attr "alternative" "16,17")
2048               (const_string "ssecvt")
2049             (match_operand 1 "pic_32bit_operand" "")
2050               (const_string "lea")
2051            ]
2052            (const_string "imov")))
2053    (set (attr "modrm")
2054      (if_then_else
2055        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2056          (const_string "0")
2057          (const_string "*")))
2058    (set (attr "length_immediate")
2059      (if_then_else
2060        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2061          (const_string "8")
2062          (const_string "*")))
2063    (set (attr "prefix_rex")
2064      (if_then_else (eq_attr "alternative" "8,9")
2065        (const_string "1")
2066        (const_string "*")))
2067    (set (attr "prefix_data16")
2068      (if_then_else (eq_attr "alternative" "11")
2069        (const_string "1")
2070        (const_string "*")))
2071    (set (attr "prefix")
2072      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2073        (const_string "maybe_vex")
2074        (const_string "orig")))
2075    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2076
2077 ;; Convert impossible stores of immediate to existing instructions.
2078 ;; First try to get scratch register and go through it.  In case this
2079 ;; fails, move by 32bit parts.
2080 (define_peephole2
2081   [(match_scratch:DI 2 "r")
2082    (set (match_operand:DI 0 "memory_operand" "")
2083         (match_operand:DI 1 "immediate_operand" ""))]
2084   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085    && !x86_64_immediate_operand (operands[1], DImode)"
2086   [(set (match_dup 2) (match_dup 1))
2087    (set (match_dup 0) (match_dup 2))])
2088
2089 ;; We need to define this as both peepholer and splitter for case
2090 ;; peephole2 pass is not run.
2091 ;; "&& 1" is needed to keep it from matching the previous pattern.
2092 (define_peephole2
2093   [(set (match_operand:DI 0 "memory_operand" "")
2094         (match_operand:DI 1 "immediate_operand" ""))]
2095   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2096    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2097   [(set (match_dup 2) (match_dup 3))
2098    (set (match_dup 4) (match_dup 5))]
2099   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2100
2101 (define_split
2102   [(set (match_operand:DI 0 "memory_operand" "")
2103         (match_operand:DI 1 "immediate_operand" ""))]
2104   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2105                     ? epilogue_completed : reload_completed)
2106    && !symbolic_operand (operands[1], DImode)
2107    && !x86_64_immediate_operand (operands[1], DImode)"
2108   [(set (match_dup 2) (match_dup 3))
2109    (set (match_dup 4) (match_dup 5))]
2110   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2111
2112 (define_insn "*movdi_internal"
2113   [(set (match_operand:DI 0 "nonimmediate_operand"
2114           "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2115         (match_operand:DI 1 "general_operand"
2116           "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m ,*Ym ,*Y2"))]
2117   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2118 {
2119   switch (get_attr_type (insn))
2120     {
2121     case TYPE_SSECVT:
2122       if (SSE_REG_P (operands[0]))
2123         return "movq2dq\t{%1, %0|%0, %1}";
2124       else
2125         return "movdq2q\t{%1, %0|%0, %1}";
2126
2127     case TYPE_SSEMOV:
2128       switch (get_attr_mode (insn))
2129         {
2130         case MODE_TI:
2131           return "%vmovdqa\t{%1, %0|%0, %1}";
2132         case MODE_DI:
2133            return "%vmovq\t{%1, %0|%0, %1}";
2134         case MODE_V4SF:
2135           return "movaps\t{%1, %0|%0, %1}";
2136         case MODE_V2SF:
2137           return "movlps\t{%1, %0|%0, %1}";
2138         default:
2139           gcc_unreachable ();
2140         }
2141
2142     case TYPE_MMXMOV:
2143       return "movq\t{%1, %0|%0, %1}";
2144
2145     case TYPE_SSELOG1:
2146       return standard_sse_constant_opcode (insn, operands[1]);
2147
2148     case TYPE_MMX:
2149       return "pxor\t%0, %0";
2150
2151     case TYPE_MULTI:
2152       return "#";
2153
2154     default:
2155       gcc_unreachable ();
2156     }
2157 }
2158   [(set (attr "isa")
2159      (if_then_else (eq_attr "alternative" "9,10,11,12")
2160        (const_string "noavx")
2161        (const_string "*")))
2162    (set (attr "type")
2163      (cond [(eq_attr "alternative" "0,1")
2164               (const_string "multi")
2165             (eq_attr "alternative" "2")
2166               (const_string "mmx")
2167             (eq_attr "alternative" "3,4")
2168               (const_string "mmxmov")
2169             (eq_attr "alternative" "5,9")
2170               (const_string "sselog1")
2171             (eq_attr "alternative" "13,14")
2172               (const_string "ssecvt")
2173            ]
2174            (const_string "ssemov")))
2175    (set (attr "prefix")
2176      (if_then_else (eq_attr "alternative" "5,6,7,8")
2177        (const_string "maybe_vex")
2178        (const_string "orig")))
2179    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2180
2181 (define_split
2182   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2183         (match_operand:DI 1 "general_operand" ""))]
2184   "!TARGET_64BIT && reload_completed
2185    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2186    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2187   [(const_int 0)]
2188   "ix86_split_long_move (operands); DONE;")
2189
2190 (define_insn "*movsi_internal"
2191   [(set (match_operand:SI 0 "nonimmediate_operand"
2192                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2193         (match_operand:SI 1 "general_operand"
2194                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2195   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196 {
2197   switch (get_attr_type (insn))
2198     {
2199     case TYPE_SSELOG1:
2200       return standard_sse_constant_opcode (insn, operands[1]);
2201
2202     case TYPE_SSEMOV:
2203       switch (get_attr_mode (insn))
2204         {
2205         case MODE_TI:
2206           return "%vmovdqa\t{%1, %0|%0, %1}";
2207         case MODE_V4SF:
2208           return "%vmovaps\t{%1, %0|%0, %1}";
2209         case MODE_SI:
2210           return "%vmovd\t{%1, %0|%0, %1}";
2211         case MODE_SF:
2212           return "%vmovss\t{%1, %0|%0, %1}";
2213         default:
2214           gcc_unreachable ();
2215         }
2216
2217     case TYPE_MMX:
2218       return "pxor\t%0, %0";
2219
2220     case TYPE_MMXMOV:
2221       if (get_attr_mode (insn) == MODE_DI)
2222         return "movq\t{%1, %0|%0, %1}";
2223       return "movd\t{%1, %0|%0, %1}";
2224
2225     case TYPE_LEA:
2226       return "lea{l}\t{%a1, %0|%0, %a1}";
2227
2228     default:
2229       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2230       return "mov{l}\t{%1, %0|%0, %1}";
2231     }
2232 }
2233   [(set (attr "type")
2234      (cond [(eq_attr "alternative" "2")
2235               (const_string "mmx")
2236             (eq_attr "alternative" "3,4,5")
2237               (const_string "mmxmov")
2238             (eq_attr "alternative" "6")
2239               (const_string "sselog1")
2240             (eq_attr "alternative" "7,8,9,10,11")
2241               (const_string "ssemov")
2242             (match_operand 1 "pic_32bit_operand" "")
2243               (const_string "lea")
2244            ]
2245            (const_string "imov")))
2246    (set (attr "prefix")
2247      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2248        (const_string "orig")
2249        (const_string "maybe_vex")))
2250    (set (attr "prefix_data16")
2251      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2252        (const_string "1")
2253        (const_string "*")))
2254    (set (attr "mode")
2255      (cond [(eq_attr "alternative" "2,3")
2256               (const_string "DI")
2257             (eq_attr "alternative" "6,7")
2258               (if_then_else
2259                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2260                 (const_string "V4SF")
2261                 (const_string "TI"))
2262             (and (eq_attr "alternative" "8,9,10,11")
2263                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2264               (const_string "SF")
2265            ]
2266            (const_string "SI")))])
2267
2268 (define_insn "*movhi_internal"
2269   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2270         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2271   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2272 {
2273   switch (get_attr_type (insn))
2274     {
2275     case TYPE_IMOVX:
2276       /* movzwl is faster than movw on p2 due to partial word stalls,
2277          though not as fast as an aligned movl.  */
2278       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2279     default:
2280       if (get_attr_mode (insn) == MODE_SI)
2281         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2282       else
2283         return "mov{w}\t{%1, %0|%0, %1}";
2284     }
2285 }
2286   [(set (attr "type")
2287      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2288                 (const_int 0))
2289               (const_string "imov")
2290             (and (eq_attr "alternative" "0")
2291                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2292                           (const_int 0))
2293                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2294                           (const_int 0))))
2295               (const_string "imov")
2296             (and (eq_attr "alternative" "1,2")
2297                  (match_operand:HI 1 "aligned_operand" ""))
2298               (const_string "imov")
2299             (and (ne (symbol_ref "TARGET_MOVX")
2300                      (const_int 0))
2301                  (eq_attr "alternative" "0,2"))
2302               (const_string "imovx")
2303            ]
2304            (const_string "imov")))
2305     (set (attr "mode")
2306       (cond [(eq_attr "type" "imovx")
2307                (const_string "SI")
2308              (and (eq_attr "alternative" "1,2")
2309                   (match_operand:HI 1 "aligned_operand" ""))
2310                (const_string "SI")
2311              (and (eq_attr "alternative" "0")
2312                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2313                            (const_int 0))
2314                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2315                            (const_int 0))))
2316                (const_string "SI")
2317             ]
2318             (const_string "HI")))])
2319
2320 ;; Situation is quite tricky about when to choose full sized (SImode) move
2321 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2322 ;; partial register dependency machines (such as AMD Athlon), where QImode
2323 ;; moves issue extra dependency and for partial register stalls machines
2324 ;; that don't use QImode patterns (and QImode move cause stall on the next
2325 ;; instruction).
2326 ;;
2327 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2328 ;; register stall machines with, where we use QImode instructions, since
2329 ;; partial register stall can be caused there.  Then we use movzx.
2330 (define_insn "*movqi_internal"
2331   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2332         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2333   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2334 {
2335   switch (get_attr_type (insn))
2336     {
2337     case TYPE_IMOVX:
2338       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2339       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2340     default:
2341       if (get_attr_mode (insn) == MODE_SI)
2342         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2343       else
2344         return "mov{b}\t{%1, %0|%0, %1}";
2345     }
2346 }
2347   [(set (attr "type")
2348      (cond [(and (eq_attr "alternative" "5")
2349                  (not (match_operand:QI 1 "aligned_operand" "")))
2350               (const_string "imovx")
2351             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2352                 (const_int 0))
2353               (const_string "imov")
2354             (and (eq_attr "alternative" "3")
2355                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2356                           (const_int 0))
2357                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2358                           (const_int 0))))
2359               (const_string "imov")
2360             (eq_attr "alternative" "3,5")
2361               (const_string "imovx")
2362             (and (ne (symbol_ref "TARGET_MOVX")
2363                      (const_int 0))
2364                  (eq_attr "alternative" "2"))
2365               (const_string "imovx")
2366            ]
2367            (const_string "imov")))
2368    (set (attr "mode")
2369       (cond [(eq_attr "alternative" "3,4,5")
2370                (const_string "SI")
2371              (eq_attr "alternative" "6")
2372                (const_string "QI")
2373              (eq_attr "type" "imovx")
2374                (const_string "SI")
2375              (and (eq_attr "type" "imov")
2376                   (and (eq_attr "alternative" "0,1")
2377                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2378                                 (const_int 0))
2379                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2380                                      (const_int 0))
2381                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2382                                      (const_int 0))))))
2383                (const_string "SI")
2384              ;; Avoid partial register stalls when not using QImode arithmetic
2385              (and (eq_attr "type" "imov")
2386                   (and (eq_attr "alternative" "0,1")
2387                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2388                                 (const_int 0))
2389                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2390                                 (const_int 0)))))
2391                (const_string "SI")
2392            ]
2393            (const_string "QI")))])
2394
2395 ;; Stores and loads of ax to arbitrary constant address.
2396 ;; We fake an second form of instruction to force reload to load address
2397 ;; into register when rax is not available
2398 (define_insn "*movabs<mode>_1"
2399   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2400         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2401   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2402   "@
2403    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2404    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2405   [(set_attr "type" "imov")
2406    (set_attr "modrm" "0,*")
2407    (set_attr "length_address" "8,0")
2408    (set_attr "length_immediate" "0,*")
2409    (set_attr "memory" "store")
2410    (set_attr "mode" "<MODE>")])
2411
2412 (define_insn "*movabs<mode>_2"
2413   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2414         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2415   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2416   "@
2417    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2418    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2419   [(set_attr "type" "imov")
2420    (set_attr "modrm" "0,*")
2421    (set_attr "length_address" "8,0")
2422    (set_attr "length_immediate" "0")
2423    (set_attr "memory" "load")
2424    (set_attr "mode" "<MODE>")])
2425
2426 (define_insn "*swap<mode>"
2427   [(set (match_operand:SWI48 0 "register_operand" "+r")
2428         (match_operand:SWI48 1 "register_operand" "+r"))
2429    (set (match_dup 1)
2430         (match_dup 0))]
2431   ""
2432   "xchg{<imodesuffix>}\t%1, %0"
2433   [(set_attr "type" "imov")
2434    (set_attr "mode" "<MODE>")
2435    (set_attr "pent_pair" "np")
2436    (set_attr "athlon_decode" "vector")
2437    (set_attr "amdfam10_decode" "double")
2438    (set_attr "bdver1_decode" "double")])
2439
2440 (define_insn "*swap<mode>_1"
2441   [(set (match_operand:SWI12 0 "register_operand" "+r")
2442         (match_operand:SWI12 1 "register_operand" "+r"))
2443    (set (match_dup 1)
2444         (match_dup 0))]
2445   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2446   "xchg{l}\t%k1, %k0"
2447   [(set_attr "type" "imov")
2448    (set_attr "mode" "SI")
2449    (set_attr "pent_pair" "np")
2450    (set_attr "athlon_decode" "vector")
2451    (set_attr "amdfam10_decode" "double")
2452    (set_attr "bdver1_decode" "double")])
2453
2454 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2455 ;; is disabled for AMDFAM10
2456 (define_insn "*swap<mode>_2"
2457   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2458         (match_operand:SWI12 1 "register_operand" "+<r>"))
2459    (set (match_dup 1)
2460         (match_dup 0))]
2461   "TARGET_PARTIAL_REG_STALL"
2462   "xchg{<imodesuffix>}\t%1, %0"
2463   [(set_attr "type" "imov")
2464    (set_attr "mode" "<MODE>")
2465    (set_attr "pent_pair" "np")
2466    (set_attr "athlon_decode" "vector")])
2467
2468 (define_expand "movstrict<mode>"
2469   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2470         (match_operand:SWI12 1 "general_operand" ""))]
2471   ""
2472 {
2473   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2474     FAIL;
2475   if (GET_CODE (operands[0]) == SUBREG
2476       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2477     FAIL;
2478   /* Don't generate memory->memory moves, go through a register */
2479   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2480     operands[1] = force_reg (<MODE>mode, operands[1]);
2481 })
2482
2483 (define_insn "*movstrict<mode>_1"
2484   [(set (strict_low_part
2485           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2486         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2487   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2488    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2489   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2490   [(set_attr "type" "imov")
2491    (set_attr "mode" "<MODE>")])
2492
2493 (define_insn "*movstrict<mode>_xor"
2494   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2495         (match_operand:SWI12 1 "const0_operand" ""))
2496    (clobber (reg:CC FLAGS_REG))]
2497   "reload_completed"
2498   "xor{<imodesuffix>}\t%0, %0"
2499   [(set_attr "type" "alu1")
2500    (set_attr "mode" "<MODE>")
2501    (set_attr "length_immediate" "0")])
2502
2503 (define_insn "*mov<mode>_extv_1"
2504   [(set (match_operand:SWI24 0 "register_operand" "=R")
2505         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2506                             (const_int 8)
2507                             (const_int 8)))]
2508   ""
2509   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2510   [(set_attr "type" "imovx")
2511    (set_attr "mode" "SI")])
2512
2513 (define_insn "*movqi_extv_1_rex64"
2514   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2515         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2516                          (const_int 8)
2517                          (const_int 8)))]
2518   "TARGET_64BIT"
2519 {
2520   switch (get_attr_type (insn))
2521     {
2522     case TYPE_IMOVX:
2523       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2524     default:
2525       return "mov{b}\t{%h1, %0|%0, %h1}";
2526     }
2527 }
2528   [(set (attr "type")
2529      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2530                         (ne (symbol_ref "TARGET_MOVX")
2531                             (const_int 0)))
2532         (const_string "imovx")
2533         (const_string "imov")))
2534    (set (attr "mode")
2535      (if_then_else (eq_attr "type" "imovx")
2536         (const_string "SI")
2537         (const_string "QI")))])
2538
2539 (define_insn "*movqi_extv_1"
2540   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2541         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2542                          (const_int 8)
2543                          (const_int 8)))]
2544   "!TARGET_64BIT"
2545 {
2546   switch (get_attr_type (insn))
2547     {
2548     case TYPE_IMOVX:
2549       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2550     default:
2551       return "mov{b}\t{%h1, %0|%0, %h1}";
2552     }
2553 }
2554   [(set (attr "type")
2555      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2556                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2557                              (ne (symbol_ref "TARGET_MOVX")
2558                                  (const_int 0))))
2559         (const_string "imovx")
2560         (const_string "imov")))
2561    (set (attr "mode")
2562      (if_then_else (eq_attr "type" "imovx")
2563         (const_string "SI")
2564         (const_string "QI")))])
2565
2566 (define_insn "*mov<mode>_extzv_1"
2567   [(set (match_operand:SWI48 0 "register_operand" "=R")
2568         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2569                             (const_int 8)
2570                             (const_int 8)))]
2571   ""
2572   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2573   [(set_attr "type" "imovx")
2574    (set_attr "mode" "SI")])
2575
2576 (define_insn "*movqi_extzv_2_rex64"
2577   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2578         (subreg:QI
2579           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2580                            (const_int 8)
2581                            (const_int 8)) 0))]
2582   "TARGET_64BIT"
2583 {
2584   switch (get_attr_type (insn))
2585     {
2586     case TYPE_IMOVX:
2587       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2588     default:
2589       return "mov{b}\t{%h1, %0|%0, %h1}";
2590     }
2591 }
2592   [(set (attr "type")
2593      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2594                         (ne (symbol_ref "TARGET_MOVX")
2595                             (const_int 0)))
2596         (const_string "imovx")
2597         (const_string "imov")))
2598    (set (attr "mode")
2599      (if_then_else (eq_attr "type" "imovx")
2600         (const_string "SI")
2601         (const_string "QI")))])
2602
2603 (define_insn "*movqi_extzv_2"
2604   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2605         (subreg:QI
2606           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2607                            (const_int 8)
2608                            (const_int 8)) 0))]
2609   "!TARGET_64BIT"
2610 {
2611   switch (get_attr_type (insn))
2612     {
2613     case TYPE_IMOVX:
2614       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2615     default:
2616       return "mov{b}\t{%h1, %0|%0, %h1}";
2617     }
2618 }
2619   [(set (attr "type")
2620      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2621                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2622                              (ne (symbol_ref "TARGET_MOVX")
2623                                  (const_int 0))))
2624         (const_string "imovx")
2625         (const_string "imov")))
2626    (set (attr "mode")
2627      (if_then_else (eq_attr "type" "imovx")
2628         (const_string "SI")
2629         (const_string "QI")))])
2630
2631 (define_expand "mov<mode>_insv_1"
2632   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2633                             (const_int 8)
2634                             (const_int 8))
2635         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2636
2637 (define_insn "*mov<mode>_insv_1_rex64"
2638   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2639                              (const_int 8)
2640                              (const_int 8))
2641         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2642   "TARGET_64BIT"
2643   "mov{b}\t{%b1, %h0|%h0, %b1}"
2644   [(set_attr "type" "imov")
2645    (set_attr "mode" "QI")])
2646
2647 (define_insn "*movsi_insv_1"
2648   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2649                          (const_int 8)
2650                          (const_int 8))
2651         (match_operand:SI 1 "general_operand" "Qmn"))]
2652   "!TARGET_64BIT"
2653   "mov{b}\t{%b1, %h0|%h0, %b1}"
2654   [(set_attr "type" "imov")
2655    (set_attr "mode" "QI")])
2656
2657 (define_insn "*movqi_insv_2"
2658   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2659                          (const_int 8)
2660                          (const_int 8))
2661         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2662                      (const_int 8)))]
2663   ""
2664   "mov{b}\t{%h1, %h0|%h0, %h1}"
2665   [(set_attr "type" "imov")
2666    (set_attr "mode" "QI")])
2667 \f
2668 ;; Floating point push instructions.
2669
2670 (define_insn "*pushtf"
2671   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2672         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2673   "TARGET_SSE2"
2674 {
2675   /* This insn should be already split before reg-stack.  */
2676   gcc_unreachable ();
2677 }
2678   [(set_attr "type" "multi")
2679    (set_attr "unit" "sse,*,*")
2680    (set_attr "mode" "TF,SI,SI")])
2681
2682 ;; %%% Kill this when call knows how to work this out.
2683 (define_split
2684   [(set (match_operand:TF 0 "push_operand" "")
2685         (match_operand:TF 1 "sse_reg_operand" ""))]
2686   "TARGET_SSE2 && reload_completed"
2687   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2688    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2689
2690 (define_insn "*pushxf"
2691   [(set (match_operand:XF 0 "push_operand" "=<,<")
2692         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2693   "optimize_function_for_speed_p (cfun)"
2694 {
2695   /* This insn should be already split before reg-stack.  */
2696   gcc_unreachable ();
2697 }
2698   [(set_attr "type" "multi")
2699    (set_attr "unit" "i387,*")
2700    (set_attr "mode" "XF,SI")])
2701
2702 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2703 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2704 ;; Pushing using integer instructions is longer except for constants
2705 ;; and direct memory references (assuming that any given constant is pushed
2706 ;; only once, but this ought to be handled elsewhere).
2707
2708 (define_insn "*pushxf_nointeger"
2709   [(set (match_operand:XF 0 "push_operand" "=<,<")
2710         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2711   "optimize_function_for_size_p (cfun)"
2712 {
2713   /* This insn should be already split before reg-stack.  */
2714   gcc_unreachable ();
2715 }
2716   [(set_attr "type" "multi")
2717    (set_attr "unit" "i387,*")
2718    (set_attr "mode" "XF,SI")])
2719
2720 ;; %%% Kill this when call knows how to work this out.
2721 (define_split
2722   [(set (match_operand:XF 0 "push_operand" "")
2723         (match_operand:XF 1 "fp_register_operand" ""))]
2724   "reload_completed"
2725   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2726    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2727   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2728
2729 (define_insn "*pushdf_rex64"
2730   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2731         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,Y2"))]
2732   "TARGET_64BIT"
2733 {
2734   /* This insn should be already split before reg-stack.  */
2735   gcc_unreachable ();
2736 }
2737   [(set_attr "type" "multi")
2738    (set_attr "unit" "i387,*,*")
2739    (set_attr "mode" "DF,DI,DF")])
2740
2741 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2742 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2743 ;; On the average, pushdf using integers can be still shorter.
2744
2745 (define_insn "*pushdf"
2746   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2747         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2748   "!TARGET_64BIT"
2749 {
2750   /* This insn should be already split before reg-stack.  */
2751   gcc_unreachable ();
2752 }
2753   [(set_attr "type" "multi")
2754    (set_attr "unit" "i387,*,*")
2755    (set_attr "mode" "DF,DI,DF")])
2756
2757 ;; %%% Kill this when call knows how to work this out.
2758 (define_split
2759   [(set (match_operand:DF 0 "push_operand" "")
2760         (match_operand:DF 1 "any_fp_register_operand" ""))]
2761   "reload_completed"
2762   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2763    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2764
2765 (define_insn "*pushsf_rex64"
2766   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2767         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2768   "TARGET_64BIT"
2769 {
2770   /* Anything else should be already split before reg-stack.  */
2771   gcc_assert (which_alternative == 1);
2772   return "push{q}\t%q1";
2773 }
2774   [(set_attr "type" "multi,push,multi")
2775    (set_attr "unit" "i387,*,*")
2776    (set_attr "mode" "SF,DI,SF")])
2777
2778 (define_insn "*pushsf"
2779   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2780         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2781   "!TARGET_64BIT"
2782 {
2783   /* Anything else should be already split before reg-stack.  */
2784   gcc_assert (which_alternative == 1);
2785   return "push{l}\t%1";
2786 }
2787   [(set_attr "type" "multi,push,multi")
2788    (set_attr "unit" "i387,*,*")
2789    (set_attr "mode" "SF,SI,SF")])
2790
2791 ;; %%% Kill this when call knows how to work this out.
2792 (define_split
2793   [(set (match_operand:SF 0 "push_operand" "")
2794         (match_operand:SF 1 "any_fp_register_operand" ""))]
2795   "reload_completed"
2796   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2797    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2798   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2799
2800 (define_split
2801   [(set (match_operand:SF 0 "push_operand" "")
2802         (match_operand:SF 1 "memory_operand" ""))]
2803   "reload_completed
2804    && (operands[2] = find_constant_src (insn))"
2805   [(set (match_dup 0) (match_dup 2))])
2806
2807 (define_split
2808   [(set (match_operand 0 "push_operand" "")
2809         (match_operand 1 "general_operand" ""))]
2810   "reload_completed
2811    && (GET_MODE (operands[0]) == TFmode
2812        || GET_MODE (operands[0]) == XFmode
2813        || GET_MODE (operands[0]) == DFmode)
2814    && !ANY_FP_REG_P (operands[1])"
2815   [(const_int 0)]
2816   "ix86_split_long_move (operands); DONE;")
2817 \f
2818 ;; Floating point move instructions.
2819
2820 (define_expand "movtf"
2821   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2822         (match_operand:TF 1 "nonimmediate_operand" ""))]
2823   "TARGET_SSE2"
2824 {
2825   ix86_expand_move (TFmode, operands);
2826   DONE;
2827 })
2828
2829 (define_expand "mov<mode>"
2830   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2831         (match_operand:X87MODEF 1 "general_operand" ""))]
2832   ""
2833   "ix86_expand_move (<MODE>mode, operands); DONE;")
2834
2835 (define_insn "*movtf_internal"
2836   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2837         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2838   "TARGET_SSE2
2839    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2840    && (!can_create_pseudo_p ()
2841        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2842        || GET_CODE (operands[1]) != CONST_DOUBLE
2843        || (optimize_function_for_size_p (cfun)
2844            && standard_sse_constant_p (operands[1])
2845            && !memory_operand (operands[0], TFmode))
2846        || (!TARGET_MEMORY_MISMATCH_STALL
2847            && memory_operand (operands[0], TFmode)))"
2848 {
2849   switch (which_alternative)
2850     {
2851     case 0:
2852     case 1:
2853       /* Handle misaligned load/store since we
2854          don't have movmisaligntf pattern. */
2855       if (misaligned_operand (operands[0], TFmode)
2856           || misaligned_operand (operands[1], TFmode))
2857         {
2858           if (get_attr_mode (insn) == MODE_V4SF)
2859             return "%vmovups\t{%1, %0|%0, %1}";
2860           else
2861             return "%vmovdqu\t{%1, %0|%0, %1}";
2862         }
2863       else
2864         {
2865           if (get_attr_mode (insn) == MODE_V4SF)
2866             return "%vmovaps\t{%1, %0|%0, %1}";
2867           else
2868             return "%vmovdqa\t{%1, %0|%0, %1}";
2869         }
2870
2871     case 2:
2872       return standard_sse_constant_opcode (insn, operands[1]);
2873
2874     case 3:
2875     case 4:
2876         return "#";
2877
2878     default:
2879       gcc_unreachable ();
2880     }
2881 }
2882   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2883    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2884    (set (attr "mode")
2885         (cond [(eq_attr "alternative" "0,2")
2886                  (if_then_else
2887                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2888                        (const_int 0))
2889                    (const_string "V4SF")
2890                    (const_string "TI"))
2891                (eq_attr "alternative" "1")
2892                  (if_then_else
2893                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2894                             (const_int 0))
2895                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2896                             (const_int 0)))
2897                    (const_string "V4SF")
2898                    (const_string "TI"))]
2899                (const_string "DI")))])
2900
2901 ;; Possible store forwarding (partial memory) stall in alternative 4.
2902 (define_insn "*movxf_internal"
2903   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2904         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2905   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2906    && (!can_create_pseudo_p ()
2907        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2908        || GET_CODE (operands[1]) != CONST_DOUBLE
2909        || (optimize_function_for_size_p (cfun)
2910            && standard_80387_constant_p (operands[1]) > 0
2911            && !memory_operand (operands[0], XFmode))
2912        || (!TARGET_MEMORY_MISMATCH_STALL
2913            && memory_operand (operands[0], XFmode)))"
2914 {
2915   switch (which_alternative)
2916     {
2917     case 0:
2918     case 1:
2919       return output_387_reg_move (insn, operands);
2920
2921     case 2:
2922       return standard_80387_constant_opcode (operands[1]);
2923
2924     case 3:
2925     case 4:
2926       return "#";
2927
2928     default:
2929       gcc_unreachable ();
2930     }
2931 }
2932   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2933    (set_attr "mode" "XF,XF,XF,SI,SI")])
2934
2935 (define_insn "*movdf_internal_rex64"
2936   [(set (match_operand:DF 0 "nonimmediate_operand"
2937                 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2938         (match_operand:DF 1 "general_operand"
2939                 "fm,f,G,rm,r ,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2940   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2941    && (!can_create_pseudo_p ()
2942        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2943        || GET_CODE (operands[1]) != CONST_DOUBLE
2944        || (optimize_function_for_size_p (cfun)
2945            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2946                 && standard_80387_constant_p (operands[1]) > 0)
2947                || (TARGET_SSE2 && TARGET_SSE_MATH
2948                    && standard_sse_constant_p (operands[1]))))
2949        || memory_operand (operands[0], DFmode))"
2950 {
2951   switch (which_alternative)
2952     {
2953     case 0:
2954     case 1:
2955       return output_387_reg_move (insn, operands);
2956
2957     case 2:
2958       return standard_80387_constant_opcode (operands[1]);
2959
2960     case 3:
2961     case 4:
2962       return "mov{q}\t{%1, %0|%0, %1}";
2963
2964     case 5:
2965       return "movabs{q}\t{%1, %0|%0, %1}";
2966
2967     case 6:
2968       return "#";
2969
2970     case 7:
2971       return standard_sse_constant_opcode (insn, operands[1]);
2972
2973     case 8:
2974     case 9:
2975     case 10:
2976       switch (get_attr_mode (insn))
2977         {
2978         case MODE_V2DF:
2979           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2980             return "%vmovapd\t{%1, %0|%0, %1}";
2981         case MODE_V4SF:
2982           return "%vmovaps\t{%1, %0|%0, %1}";
2983
2984         case MODE_DI:
2985           return "%vmovq\t{%1, %0|%0, %1}";
2986         case MODE_DF:
2987           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2988             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2989           return "%vmovsd\t{%1, %0|%0, %1}";
2990         case MODE_V1DF:
2991           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2992         case MODE_V2SF:
2993           return "%vmovlps\t{%1, %d0|%d0, %1}";
2994         default:
2995           gcc_unreachable ();
2996         }
2997
2998     case 11:
2999     case 12:
3000       /* Handle broken assemblers that require movd instead of movq.  */
3001       return "%vmovd\t{%1, %0|%0, %1}";
3002
3003     default:
3004       gcc_unreachable();
3005     }
3006 }
3007   [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3008    (set (attr "modrm")
3009      (if_then_else
3010        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3011          (const_string "0")
3012          (const_string "*")))
3013    (set (attr "length_immediate")
3014      (if_then_else
3015        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3016          (const_string "8")
3017          (const_string "*")))
3018    (set (attr "prefix")
3019      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3020        (const_string "orig")
3021        (const_string "maybe_vex")))
3022    (set (attr "prefix_data16")
3023      (if_then_else (eq_attr "mode" "V1DF")
3024        (const_string "1")
3025        (const_string "*")))
3026    (set (attr "mode")
3027         (cond [(eq_attr "alternative" "0,1,2")
3028                  (const_string "DF")
3029                (eq_attr "alternative" "3,4,5,6,11,12")
3030                  (const_string "DI")
3031
3032                /* xorps is one byte shorter.  */
3033                (eq_attr "alternative" "7")
3034                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3035                             (const_int 0))
3036                           (const_string "V4SF")
3037                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3038                             (const_int 0))
3039                           (const_string "TI")
3040                        ]
3041                        (const_string "V2DF"))
3042
3043                /* For architectures resolving dependencies on
3044                   whole SSE registers use APD move to break dependency
3045                   chains, otherwise use short move to avoid extra work.
3046
3047                   movaps encodes one byte shorter.  */
3048                (eq_attr "alternative" "8")
3049                  (cond
3050                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3051                         (const_int 0))
3052                       (const_string "V4SF")
3053                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3054                         (const_int 0))
3055                       (const_string "V2DF")
3056                    ]
3057                    (const_string "DF"))
3058                /* For architectures resolving dependencies on register
3059                   parts we may avoid extra work to zero out upper part
3060                   of register.  */
3061                (eq_attr "alternative" "9")
3062                  (if_then_else
3063                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3064                        (const_int 0))
3065                    (const_string "V1DF")
3066                    (const_string "DF"))
3067               ]
3068               (const_string "DF")))])
3069
3070 ;; Possible store forwarding (partial memory) stall in alternative 4.
3071 (define_insn "*movdf_internal"
3072   [(set (match_operand:DF 0 "nonimmediate_operand"
3073                 "=f,m,f,?Yd*r ,!o   ,Y2*x,Y2*x,Y2*x,m  ")
3074         (match_operand:DF 1 "general_operand"
3075                 "fm,f,G,Yd*roF,FYd*r,C   ,Y2*x,m   ,Y2*x"))]
3076   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3077    && (!can_create_pseudo_p ()
3078        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3079        || GET_CODE (operands[1]) != CONST_DOUBLE
3080        || (optimize_function_for_size_p (cfun)
3081            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3082                 && standard_80387_constant_p (operands[1]) > 0)
3083                || (TARGET_SSE2 && TARGET_SSE_MATH
3084                    && standard_sse_constant_p (operands[1])))
3085            && !memory_operand (operands[0], DFmode))
3086        || (!TARGET_MEMORY_MISMATCH_STALL
3087            && memory_operand (operands[0], DFmode)))"
3088 {
3089   switch (which_alternative)
3090     {
3091     case 0:
3092     case 1:
3093       return output_387_reg_move (insn, operands);
3094
3095     case 2:
3096       return standard_80387_constant_opcode (operands[1]);
3097
3098     case 3:
3099     case 4:
3100       return "#";
3101
3102     case 5:
3103       return standard_sse_constant_opcode (insn, operands[1]);
3104
3105     case 6:
3106     case 7:
3107     case 8:
3108       switch (get_attr_mode (insn))
3109         {
3110         case MODE_V2DF:
3111           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3112             return "%vmovapd\t{%1, %0|%0, %1}";
3113         case MODE_V4SF:
3114           return "%vmovaps\t{%1, %0|%0, %1}";
3115
3116         case MODE_DI:
3117           return "%vmovq\t{%1, %0|%0, %1}";
3118         case MODE_DF:
3119           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3120             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3121           return "%vmovsd\t{%1, %0|%0, %1}";
3122         case MODE_V1DF:
3123           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3124         case MODE_V2SF:
3125           return "%vmovlps\t{%1, %d0|%d0, %1}";
3126         default:
3127           gcc_unreachable ();
3128         }
3129
3130     default:
3131       gcc_unreachable ();
3132     }
3133 }
3134   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3135    (set (attr "prefix")
3136      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3137        (const_string "orig")
3138        (const_string "maybe_vex")))
3139    (set (attr "prefix_data16")
3140      (if_then_else (eq_attr "mode" "V1DF")
3141        (const_string "1")
3142        (const_string "*")))
3143    (set (attr "mode")
3144         (cond [(eq_attr "alternative" "0,1,2")
3145                  (const_string "DF")
3146                (eq_attr "alternative" "3,4")
3147                  (const_string "SI")
3148
3149                /* For SSE1, we have many fewer alternatives.  */
3150                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3151                  (if_then_else
3152                    (eq_attr "alternative" "5,6")
3153                    (const_string "V4SF")
3154                    (const_string "V2SF"))
3155
3156                /* xorps is one byte shorter.  */
3157                (eq_attr "alternative" "5")
3158                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3159                             (const_int 0))
3160                           (const_string "V4SF")
3161                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3162                             (const_int 0))
3163                           (const_string "TI")
3164                        ]
3165                        (const_string "V2DF"))
3166
3167                /* For architectures resolving dependencies on
3168                   whole SSE registers use APD move to break dependency
3169                   chains, otherwise use short move to avoid extra work.
3170
3171                   movaps encodes one byte shorter.  */
3172                (eq_attr "alternative" "6")
3173                  (cond
3174                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3175                         (const_int 0))
3176                       (const_string "V4SF")
3177                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3178                         (const_int 0))
3179                       (const_string "V2DF")
3180                    ]
3181                    (const_string "DF"))
3182                /* For architectures resolving dependencies on register
3183                   parts we may avoid extra work to zero out upper part
3184                   of register.  */
3185                (eq_attr "alternative" "7")
3186                  (if_then_else
3187                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3188                        (const_int 0))
3189                    (const_string "V1DF")
3190                    (const_string "DF"))
3191               ]
3192               (const_string "DF")))])
3193
3194 (define_insn "*movsf_internal"
3195   [(set (match_operand:SF 0 "nonimmediate_operand"
3196           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3197         (match_operand:SF 1 "general_operand"
3198           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3199   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3200    && (!can_create_pseudo_p ()
3201        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3202        || GET_CODE (operands[1]) != CONST_DOUBLE
3203        || (optimize_function_for_size_p (cfun)
3204            && ((!TARGET_SSE_MATH
3205                 && standard_80387_constant_p (operands[1]) > 0)
3206                || (TARGET_SSE_MATH
3207                    && standard_sse_constant_p (operands[1]))))
3208        || memory_operand (operands[0], SFmode))"
3209 {
3210   switch (which_alternative)
3211     {
3212     case 0:
3213     case 1:
3214       return output_387_reg_move (insn, operands);
3215
3216     case 2:
3217       return standard_80387_constant_opcode (operands[1]);
3218
3219     case 3:
3220     case 4:
3221       return "mov{l}\t{%1, %0|%0, %1}";
3222
3223     case 5:
3224       return standard_sse_constant_opcode (insn, operands[1]);
3225
3226     case 6:
3227       if (get_attr_mode (insn) == MODE_V4SF)
3228         return "%vmovaps\t{%1, %0|%0, %1}";
3229       if (TARGET_AVX)
3230         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3231
3232     case 7:
3233     case 8:
3234       return "%vmovss\t{%1, %0|%0, %1}";
3235
3236     case 9:
3237     case 10:
3238     case 14:
3239     case 15:
3240       return "movd\t{%1, %0|%0, %1}";
3241
3242     case 11:
3243       return "movq\t{%1, %0|%0, %1}";
3244
3245     case 12:
3246     case 13:
3247       return "%vmovd\t{%1, %0|%0, %1}";
3248
3249     default:
3250       gcc_unreachable ();
3251     }
3252 }
3253   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3254    (set (attr "prefix")
3255      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256        (const_string "maybe_vex")
3257        (const_string "orig")))
3258    (set (attr "mode")
3259         (cond [(eq_attr "alternative" "3,4,9,10")
3260                  (const_string "SI")
3261                (eq_attr "alternative" "5")
3262                  (if_then_else
3263                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3264                                  (const_int 0))
3265                              (ne (symbol_ref "TARGET_SSE2")
3266                                  (const_int 0)))
3267                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3268                             (const_int 0)))
3269                    (const_string "TI")
3270                    (const_string "V4SF"))
3271                /* For architectures resolving dependencies on
3272                   whole SSE registers use APS move to break dependency
3273                   chains, otherwise use short move to avoid extra work.
3274
3275                   Do the same for architectures resolving dependencies on
3276                   the parts.  While in DF mode it is better to always handle
3277                   just register parts, the SF mode is different due to lack
3278                   of instructions to load just part of the register.  It is
3279                   better to maintain the whole registers in single format
3280                   to avoid problems on using packed logical operations.  */
3281                (eq_attr "alternative" "6")
3282                  (if_then_else
3283                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3284                             (const_int 0))
3285                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3286                             (const_int 0)))
3287                    (const_string "V4SF")
3288                    (const_string "SF"))
3289                (eq_attr "alternative" "11")
3290                  (const_string "DI")]
3291                (const_string "SF")))])
3292
3293 (define_split
3294   [(set (match_operand 0 "any_fp_register_operand" "")
3295         (match_operand 1 "memory_operand" ""))]
3296   "reload_completed
3297    && (GET_MODE (operands[0]) == TFmode
3298        || GET_MODE (operands[0]) == XFmode
3299        || GET_MODE (operands[0]) == DFmode
3300        || GET_MODE (operands[0]) == SFmode)
3301    && (operands[2] = find_constant_src (insn))"
3302   [(set (match_dup 0) (match_dup 2))]
3303 {
3304   rtx c = operands[2];
3305   int r = REGNO (operands[0]);
3306
3307   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3308       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3309     FAIL;
3310 })
3311
3312 (define_split
3313   [(set (match_operand 0 "any_fp_register_operand" "")
3314         (float_extend (match_operand 1 "memory_operand" "")))]
3315   "reload_completed
3316    && (GET_MODE (operands[0]) == TFmode
3317        || GET_MODE (operands[0]) == XFmode
3318        || GET_MODE (operands[0]) == DFmode)
3319    && (operands[2] = find_constant_src (insn))"
3320   [(set (match_dup 0) (match_dup 2))]
3321 {
3322   rtx c = operands[2];
3323   int r = REGNO (operands[0]);
3324
3325   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3326       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3327     FAIL;
3328 })
3329
3330 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3331 (define_split
3332   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3333         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3334   "reload_completed
3335    && (standard_80387_constant_p (operands[1]) == 8
3336        || standard_80387_constant_p (operands[1]) == 9)"
3337   [(set (match_dup 0)(match_dup 1))
3338    (set (match_dup 0)
3339         (neg:X87MODEF (match_dup 0)))]
3340 {
3341   REAL_VALUE_TYPE r;
3342
3343   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3344   if (real_isnegzero (&r))
3345     operands[1] = CONST0_RTX (<MODE>mode);
3346   else
3347     operands[1] = CONST1_RTX (<MODE>mode);
3348 })
3349
3350 (define_split
3351   [(set (match_operand 0 "nonimmediate_operand" "")
3352         (match_operand 1 "general_operand" ""))]
3353   "reload_completed
3354    && (GET_MODE (operands[0]) == TFmode
3355        || GET_MODE (operands[0]) == XFmode
3356        || GET_MODE (operands[0]) == DFmode)
3357    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3358   [(const_int 0)]
3359   "ix86_split_long_move (operands); DONE;")
3360
3361 (define_insn "swapxf"
3362   [(set (match_operand:XF 0 "register_operand" "+f")
3363         (match_operand:XF 1 "register_operand" "+f"))
3364    (set (match_dup 1)
3365         (match_dup 0))]
3366   "TARGET_80387"
3367 {
3368   if (STACK_TOP_P (operands[0]))
3369     return "fxch\t%1";
3370   else
3371     return "fxch\t%0";
3372 }
3373   [(set_attr "type" "fxch")
3374    (set_attr "mode" "XF")])
3375
3376 (define_insn "*swap<mode>"
3377   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3378         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3379    (set (match_dup 1)
3380         (match_dup 0))]
3381   "TARGET_80387 || reload_completed"
3382 {
3383   if (STACK_TOP_P (operands[0]))
3384     return "fxch\t%1";
3385   else
3386     return "fxch\t%0";
3387 }
3388   [(set_attr "type" "fxch")
3389    (set_attr "mode" "<MODE>")])
3390 \f
3391 ;; Zero extension instructions
3392
3393 (define_expand "zero_extendsidi2"
3394   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3395         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3396   ""
3397 {
3398   if (!TARGET_64BIT)
3399     {
3400       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3401       DONE;
3402     }
3403 })
3404
3405 (define_insn "*zero_extendsidi2_rex64"
3406   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3407         (zero_extend:DI
3408          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3409   "TARGET_64BIT"
3410   "@
3411    mov\t{%k1, %k0|%k0, %k1}
3412    #
3413    movd\t{%1, %0|%0, %1}
3414    movd\t{%1, %0|%0, %1}
3415    %vmovd\t{%1, %0|%0, %1}
3416    %vmovd\t{%1, %0|%0, %1}"
3417   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3418    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3419    (set_attr "prefix_0f" "0,*,*,*,*,*")
3420    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3421
3422 (define_split
3423   [(set (match_operand:DI 0 "memory_operand" "")
3424         (zero_extend:DI (match_dup 0)))]
3425   "TARGET_64BIT"
3426   [(set (match_dup 4) (const_int 0))]
3427   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3428
3429 ;; %%% Kill me once multi-word ops are sane.
3430 (define_insn "zero_extendsidi2_1"
3431   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3432         (zero_extend:DI
3433          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3434    (clobber (reg:CC FLAGS_REG))]
3435   "!TARGET_64BIT"
3436   "@
3437    #
3438    #
3439    #
3440    movd\t{%1, %0|%0, %1}
3441    movd\t{%1, %0|%0, %1}
3442    %vmovd\t{%1, %0|%0, %1}
3443    %vmovd\t{%1, %0|%0, %1}"
3444   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3445    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3446    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3447
3448 (define_split
3449   [(set (match_operand:DI 0 "register_operand" "")
3450         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3451    (clobber (reg:CC FLAGS_REG))]
3452   "!TARGET_64BIT && reload_completed
3453    && true_regnum (operands[0]) == true_regnum (operands[1])"
3454   [(set (match_dup 4) (const_int 0))]
3455   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3456
3457 (define_split
3458   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3459         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3460    (clobber (reg:CC FLAGS_REG))]
3461   "!TARGET_64BIT && reload_completed
3462    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3463   [(set (match_dup 3) (match_dup 1))
3464    (set (match_dup 4) (const_int 0))]
3465   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3466
3467 (define_insn "zero_extend<mode>di2"
3468   [(set (match_operand:DI 0 "register_operand" "=r")
3469         (zero_extend:DI
3470          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3471   "TARGET_64BIT"
3472   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3473   [(set_attr "type" "imovx")
3474    (set_attr "mode" "SI")])
3475
3476 (define_expand "zero_extendhisi2"
3477   [(set (match_operand:SI 0 "register_operand" "")
3478         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3479   ""
3480 {
3481   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3482     {
3483       operands[1] = force_reg (HImode, operands[1]);
3484       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3485       DONE;
3486     }
3487 })
3488
3489 (define_insn_and_split "zero_extendhisi2_and"
3490   [(set (match_operand:SI 0 "register_operand" "=r")
3491         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3492    (clobber (reg:CC FLAGS_REG))]
3493   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3494   "#"
3495   "&& reload_completed"
3496   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3497               (clobber (reg:CC FLAGS_REG))])]
3498   ""
3499   [(set_attr "type" "alu1")
3500    (set_attr "mode" "SI")])
3501
3502 (define_insn "*zero_extendhisi2_movzwl"
3503   [(set (match_operand:SI 0 "register_operand" "=r")
3504         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3505   "!TARGET_ZERO_EXTEND_WITH_AND
3506    || optimize_function_for_size_p (cfun)"
3507   "movz{wl|x}\t{%1, %0|%0, %1}"
3508   [(set_attr "type" "imovx")
3509    (set_attr "mode" "SI")])
3510
3511 (define_expand "zero_extendqi<mode>2"
3512   [(parallel
3513     [(set (match_operand:SWI24 0 "register_operand" "")
3514           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3515      (clobber (reg:CC FLAGS_REG))])])
3516
3517 (define_insn "*zero_extendqi<mode>2_and"
3518   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3519         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3520    (clobber (reg:CC FLAGS_REG))]
3521   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3522   "#"
3523   [(set_attr "type" "alu1")
3524    (set_attr "mode" "<MODE>")])
3525
3526 ;; When source and destination does not overlap, clear destination
3527 ;; first and then do the movb
3528 (define_split
3529   [(set (match_operand:SWI24 0 "register_operand" "")
3530         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3531    (clobber (reg:CC FLAGS_REG))]
3532   "reload_completed
3533    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3534    && ANY_QI_REG_P (operands[0])
3535    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3536    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3537   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3538 {
3539   operands[2] = gen_lowpart (QImode, operands[0]);
3540   ix86_expand_clear (operands[0]);
3541 })
3542
3543 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3544   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3545         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3546    (clobber (reg:CC FLAGS_REG))]
3547   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3548   "#"
3549   [(set_attr "type" "imovx,alu1")
3550    (set_attr "mode" "<MODE>")])
3551
3552 ;; For the movzbl case strip only the clobber
3553 (define_split
3554   [(set (match_operand:SWI24 0 "register_operand" "")
3555         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3556    (clobber (reg:CC FLAGS_REG))]
3557   "reload_completed
3558    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3559    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3560   [(set (match_dup 0)
3561         (zero_extend:SWI24 (match_dup 1)))])
3562
3563 ; zero extend to SImode to avoid partial register stalls
3564 (define_insn "*zero_extendqi<mode>2_movzbl"
3565   [(set (match_operand:SWI24 0 "register_operand" "=r")
3566         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3567   "reload_completed
3568    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3569   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3570   [(set_attr "type" "imovx")
3571    (set_attr "mode" "SI")])
3572
3573 ;; Rest is handled by single and.
3574 (define_split
3575   [(set (match_operand:SWI24 0 "register_operand" "")
3576         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3577    (clobber (reg:CC FLAGS_REG))]
3578   "reload_completed
3579    && true_regnum (operands[0]) == true_regnum (operands[1])"
3580   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3581               (clobber (reg:CC FLAGS_REG))])])
3582 \f
3583 ;; Sign extension instructions
3584
3585 (define_expand "extendsidi2"
3586   [(set (match_operand:DI 0 "register_operand" "")
3587         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3588   ""
3589 {
3590   if (!TARGET_64BIT)
3591     {
3592       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3593       DONE;
3594     }
3595 })
3596
3597 (define_insn "*extendsidi2_rex64"
3598   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3599         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3600   "TARGET_64BIT"
3601   "@
3602    {cltq|cdqe}
3603    movs{lq|x}\t{%1, %0|%0, %1}"
3604   [(set_attr "type" "imovx")
3605    (set_attr "mode" "DI")
3606    (set_attr "prefix_0f" "0")
3607    (set_attr "modrm" "0,1")])
3608
3609 (define_insn "extendsidi2_1"
3610   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3611         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3612    (clobber (reg:CC FLAGS_REG))
3613    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3614   "!TARGET_64BIT"
3615   "#")
3616
3617 ;; Extend to memory case when source register does die.
3618 (define_split
3619   [(set (match_operand:DI 0 "memory_operand" "")
3620         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3621    (clobber (reg:CC FLAGS_REG))
3622    (clobber (match_operand:SI 2 "register_operand" ""))]
3623   "(reload_completed
3624     && dead_or_set_p (insn, operands[1])
3625     && !reg_mentioned_p (operands[1], operands[0]))"
3626   [(set (match_dup 3) (match_dup 1))
3627    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3628               (clobber (reg:CC FLAGS_REG))])
3629    (set (match_dup 4) (match_dup 1))]
3630   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3631
3632 ;; Extend to memory case when source register does not die.
3633 (define_split
3634   [(set (match_operand:DI 0 "memory_operand" "")
3635         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3636    (clobber (reg:CC FLAGS_REG))
3637    (clobber (match_operand:SI 2 "register_operand" ""))]
3638   "reload_completed"
3639   [(const_int 0)]
3640 {
3641   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3642
3643   emit_move_insn (operands[3], operands[1]);
3644
3645   /* Generate a cltd if possible and doing so it profitable.  */
3646   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3647       && true_regnum (operands[1]) == AX_REG
3648       && true_regnum (operands[2]) == DX_REG)
3649     {
3650       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3651     }
3652   else
3653     {
3654       emit_move_insn (operands[2], operands[1]);
3655       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3656     }
3657   emit_move_insn (operands[4], operands[2]);
3658   DONE;
3659 })
3660
3661 ;; Extend to register case.  Optimize case where source and destination
3662 ;; registers match and cases where we can use cltd.
3663 (define_split
3664   [(set (match_operand:DI 0 "register_operand" "")
3665         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3666    (clobber (reg:CC FLAGS_REG))
3667    (clobber (match_scratch:SI 2 ""))]
3668   "reload_completed"
3669   [(const_int 0)]
3670 {
3671   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3672
3673   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3674     emit_move_insn (operands[3], operands[1]);
3675
3676   /* Generate a cltd if possible and doing so it profitable.  */
3677   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3678       && true_regnum (operands[3]) == AX_REG
3679       && true_regnum (operands[4]) == DX_REG)
3680     {
3681       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3682       DONE;
3683     }
3684
3685   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3686     emit_move_insn (operands[4], operands[1]);
3687
3688   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3689   DONE;
3690 })
3691
3692 (define_insn "extend<mode>di2"
3693   [(set (match_operand:DI 0 "register_operand" "=r")
3694         (sign_extend:DI
3695          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3696   "TARGET_64BIT"
3697   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3698   [(set_attr "type" "imovx")
3699    (set_attr "mode" "DI")])
3700
3701 (define_insn "extendhisi2"
3702   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3703         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3704   ""
3705 {
3706   switch (get_attr_prefix_0f (insn))
3707     {
3708     case 0:
3709       return "{cwtl|cwde}";
3710     default:
3711       return "movs{wl|x}\t{%1, %0|%0, %1}";
3712     }
3713 }
3714   [(set_attr "type" "imovx")
3715    (set_attr "mode" "SI")
3716    (set (attr "prefix_0f")
3717      ;; movsx is short decodable while cwtl is vector decoded.
3718      (if_then_else (and (eq_attr "cpu" "!k6")
3719                         (eq_attr "alternative" "0"))
3720         (const_string "0")
3721         (const_string "1")))
3722    (set (attr "modrm")
3723      (if_then_else (eq_attr "prefix_0f" "0")
3724         (const_string "0")
3725         (const_string "1")))])
3726
3727 (define_insn "*extendhisi2_zext"
3728   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3729         (zero_extend:DI
3730          (sign_extend:SI
3731           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3732   "TARGET_64BIT"
3733 {
3734   switch (get_attr_prefix_0f (insn))
3735     {
3736     case 0:
3737       return "{cwtl|cwde}";
3738     default:
3739       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3740     }
3741 }
3742   [(set_attr "type" "imovx")
3743    (set_attr "mode" "SI")
3744    (set (attr "prefix_0f")
3745      ;; movsx is short decodable while cwtl is vector decoded.
3746      (if_then_else (and (eq_attr "cpu" "!k6")
3747                         (eq_attr "alternative" "0"))
3748         (const_string "0")
3749         (const_string "1")))
3750    (set (attr "modrm")
3751      (if_then_else (eq_attr "prefix_0f" "0")
3752         (const_string "0")
3753         (const_string "1")))])
3754
3755 (define_insn "extendqisi2"
3756   [(set (match_operand:SI 0 "register_operand" "=r")
3757         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3758   ""
3759   "movs{bl|x}\t{%1, %0|%0, %1}"
3760    [(set_attr "type" "imovx")
3761     (set_attr "mode" "SI")])
3762
3763 (define_insn "*extendqisi2_zext"
3764   [(set (match_operand:DI 0 "register_operand" "=r")
3765         (zero_extend:DI
3766           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3767   "TARGET_64BIT"
3768   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3769    [(set_attr "type" "imovx")
3770     (set_attr "mode" "SI")])
3771
3772 (define_insn "extendqihi2"
3773   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3774         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3775   ""
3776 {
3777   switch (get_attr_prefix_0f (insn))
3778     {
3779     case 0:
3780       return "{cbtw|cbw}";
3781     default:
3782       return "movs{bw|x}\t{%1, %0|%0, %1}";
3783     }
3784 }
3785   [(set_attr "type" "imovx")
3786    (set_attr "mode" "HI")
3787    (set (attr "prefix_0f")
3788      ;; movsx is short decodable while cwtl is vector decoded.
3789      (if_then_else (and (eq_attr "cpu" "!k6")
3790                         (eq_attr "alternative" "0"))
3791         (const_string "0")
3792         (const_string "1")))
3793    (set (attr "modrm")
3794      (if_then_else (eq_attr "prefix_0f" "0")
3795         (const_string "0")
3796         (const_string "1")))])
3797 \f
3798 ;; Conversions between float and double.
3799
3800 ;; These are all no-ops in the model used for the 80387.
3801 ;; So just emit moves.
3802
3803 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3804 (define_split
3805   [(set (match_operand:DF 0 "push_operand" "")
3806         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3807   "reload_completed"
3808   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3809    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3810
3811 (define_split
3812   [(set (match_operand:XF 0 "push_operand" "")
3813         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3814   "reload_completed"
3815   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3816    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3817   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3818
3819 (define_expand "extendsfdf2"
3820   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3821         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3822   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3823 {
3824   /* ??? Needed for compress_float_constant since all fp constants
3825      are TARGET_LEGITIMATE_CONSTANT_P.  */
3826   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3827     {
3828       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3829           && standard_80387_constant_p (operands[1]) > 0)
3830         {
3831           operands[1] = simplify_const_unary_operation
3832             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3833           emit_move_insn_1 (operands[0], operands[1]);
3834           DONE;
3835         }
3836       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3837     }
3838 })
3839
3840 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3841    cvtss2sd:
3842       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3843       cvtps2pd xmm2,xmm1
3844    We do the conversion post reload to avoid producing of 128bit spills
3845    that might lead to ICE on 32bit target.  The sequence unlikely combine
3846    anyway.  */
3847 (define_split
3848   [(set (match_operand:DF 0 "register_operand" "")
3849         (float_extend:DF
3850           (match_operand:SF 1 "nonimmediate_operand" "")))]
3851   "TARGET_USE_VECTOR_FP_CONVERTS
3852    && optimize_insn_for_speed_p ()
3853    && reload_completed && SSE_REG_P (operands[0])"
3854    [(set (match_dup 2)
3855          (float_extend:V2DF
3856            (vec_select:V2SF
3857              (match_dup 3)
3858              (parallel [(const_int 0) (const_int 1)]))))]
3859 {
3860   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3861   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3862   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3863      Try to avoid move when unpacking can be done in source.  */
3864   if (REG_P (operands[1]))
3865     {
3866       /* If it is unsafe to overwrite upper half of source, we need
3867          to move to destination and unpack there.  */
3868       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3869            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3870           && true_regnum (operands[0]) != true_regnum (operands[1]))
3871         {
3872           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3873           emit_move_insn (tmp, operands[1]);
3874         }
3875       else
3876         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3877       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3878                                              operands[3]));
3879     }
3880   else
3881     emit_insn (gen_vec_setv4sf_0 (operands[3],
3882                                   CONST0_RTX (V4SFmode), operands[1]));
3883 })
3884
3885 (define_insn "*extendsfdf2_mixed"
3886   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3887         (float_extend:DF
3888           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3889   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3890 {
3891   switch (which_alternative)
3892     {
3893     case 0:
3894     case 1:
3895       return output_387_reg_move (insn, operands);
3896
3897     case 2:
3898       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3899
3900     default:
3901       gcc_unreachable ();
3902     }
3903 }
3904   [(set_attr "type" "fmov,fmov,ssecvt")
3905    (set_attr "prefix" "orig,orig,maybe_vex")
3906    (set_attr "mode" "SF,XF,DF")])
3907
3908 (define_insn "*extendsfdf2_sse"
3909   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3910         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3911   "TARGET_SSE2 && TARGET_SSE_MATH"
3912   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3913   [(set_attr "type" "ssecvt")
3914    (set_attr "prefix" "maybe_vex")
3915    (set_attr "mode" "DF")])
3916
3917 (define_insn "*extendsfdf2_i387"
3918   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3919         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3920   "TARGET_80387"
3921   "* return output_387_reg_move (insn, operands);"
3922   [(set_attr "type" "fmov")
3923    (set_attr "mode" "SF,XF")])
3924
3925 (define_expand "extend<mode>xf2"
3926   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3927         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3928   "TARGET_80387"
3929 {
3930   /* ??? Needed for compress_float_constant since all fp constants
3931      are TARGET_LEGITIMATE_CONSTANT_P.  */
3932   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3933     {
3934       if (standard_80387_constant_p (operands[1]) > 0)
3935         {
3936           operands[1] = simplify_const_unary_operation
3937             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3938           emit_move_insn_1 (operands[0], operands[1]);
3939           DONE;
3940         }
3941       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3942     }
3943 })
3944
3945 (define_insn "*extend<mode>xf2_i387"
3946   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3947         (float_extend:XF
3948           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3949   "TARGET_80387"
3950   "* return output_387_reg_move (insn, operands);"
3951   [(set_attr "type" "fmov")
3952    (set_attr "mode" "<MODE>,XF")])
3953
3954 ;; %%% This seems bad bad news.
3955 ;; This cannot output into an f-reg because there is no way to be sure
3956 ;; of truncating in that case.  Otherwise this is just like a simple move
3957 ;; insn.  So we pretend we can output to a reg in order to get better
3958 ;; register preferencing, but we really use a stack slot.
3959
3960 ;; Conversion from DFmode to SFmode.
3961
3962 (define_expand "truncdfsf2"
3963   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3964         (float_truncate:SF
3965           (match_operand:DF 1 "nonimmediate_operand" "")))]
3966   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3967 {
3968   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3969     ;
3970   else if (flag_unsafe_math_optimizations)
3971     ;
3972   else
3973     {
3974       enum ix86_stack_slot slot = (virtuals_instantiated
3975                                    ? SLOT_TEMP
3976                                    : SLOT_VIRTUAL);
3977       rtx temp = assign_386_stack_local (SFmode, slot);
3978       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3979       DONE;
3980     }
3981 })
3982
3983 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3984    cvtsd2ss:
3985       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3986       cvtpd2ps xmm2,xmm1
3987    We do the conversion post reload to avoid producing of 128bit spills
3988    that might lead to ICE on 32bit target.  The sequence unlikely combine
3989    anyway.  */
3990 (define_split
3991   [(set (match_operand:SF 0 "register_operand" "")
3992         (float_truncate:SF
3993           (match_operand:DF 1 "nonimmediate_operand" "")))]
3994   "TARGET_USE_VECTOR_FP_CONVERTS
3995    && optimize_insn_for_speed_p ()
3996    && reload_completed && SSE_REG_P (operands[0])"
3997    [(set (match_dup 2)
3998          (vec_concat:V4SF
3999            (float_truncate:V2SF
4000              (match_dup 4))
4001            (match_dup 3)))]
4002 {
4003   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4004   operands[3] = CONST0_RTX (V2SFmode);
4005   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4006   /* Use movsd for loading from memory, unpcklpd for registers.
4007      Try to avoid move when unpacking can be done in source, or SSE3
4008      movddup is available.  */
4009   if (REG_P (operands[1]))
4010     {
4011       if (!TARGET_SSE3
4012           && true_regnum (operands[0]) != true_regnum (operands[1])
4013           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4014               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4015         {
4016           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4017           emit_move_insn (tmp, operands[1]);
4018           operands[1] = tmp;
4019         }
4020       else if (!TARGET_SSE3)
4021         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4022       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4023     }
4024   else
4025     emit_insn (gen_sse2_loadlpd (operands[4],
4026                                  CONST0_RTX (V2DFmode), operands[1]));
4027 })
4028
4029 (define_expand "truncdfsf2_with_temp"
4030   [(parallel [(set (match_operand:SF 0 "" "")
4031                    (float_truncate:SF (match_operand:DF 1 "" "")))
4032               (clobber (match_operand:SF 2 "" ""))])])
4033
4034 (define_insn "*truncdfsf_fast_mixed"
4035   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4036         (float_truncate:SF
4037           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4038   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4039 {
4040   switch (which_alternative)
4041     {
4042     case 0:
4043       return output_387_reg_move (insn, operands);
4044     case 1:
4045       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4046     default:
4047       gcc_unreachable ();
4048     }
4049 }
4050   [(set_attr "type" "fmov,ssecvt")
4051    (set_attr "prefix" "orig,maybe_vex")
4052    (set_attr "mode" "SF")])
4053
4054 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4055 ;; because nothing we do here is unsafe.
4056 (define_insn "*truncdfsf_fast_sse"
4057   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4058         (float_truncate:SF
4059           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4060   "TARGET_SSE2 && TARGET_SSE_MATH"
4061   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4062   [(set_attr "type" "ssecvt")
4063    (set_attr "prefix" "maybe_vex")
4064    (set_attr "mode" "SF")])
4065
4066 (define_insn "*truncdfsf_fast_i387"
4067   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4068         (float_truncate:SF
4069           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4070   "TARGET_80387 && flag_unsafe_math_optimizations"
4071   "* return output_387_reg_move (insn, operands);"
4072   [(set_attr "type" "fmov")
4073    (set_attr "mode" "SF")])
4074
4075 (define_insn "*truncdfsf_mixed"
4076   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4077         (float_truncate:SF
4078           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4079    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4080   "TARGET_MIX_SSE_I387"
4081 {
4082   switch (which_alternative)
4083     {
4084     case 0:
4085       return output_387_reg_move (insn, operands);
4086     case 1:
4087       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4088
4089     default:
4090       return "#";
4091     }
4092 }
4093   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4094    (set_attr "unit" "*,*,i387,i387,i387")
4095    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4096    (set_attr "mode" "SF")])
4097
4098 (define_insn "*truncdfsf_i387"
4099   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4100         (float_truncate:SF
4101           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4102    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4103   "TARGET_80387"
4104 {
4105   switch (which_alternative)
4106     {
4107     case 0:
4108       return output_387_reg_move (insn, operands);
4109
4110     default:
4111       return "#";
4112     }
4113 }
4114   [(set_attr "type" "fmov,multi,multi,multi")
4115    (set_attr "unit" "*,i387,i387,i387")
4116    (set_attr "mode" "SF")])
4117
4118 (define_insn "*truncdfsf2_i387_1"
4119   [(set (match_operand:SF 0 "memory_operand" "=m")
4120         (float_truncate:SF
4121           (match_operand:DF 1 "register_operand" "f")))]
4122   "TARGET_80387
4123    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4124    && !TARGET_MIX_SSE_I387"
4125   "* return output_387_reg_move (insn, operands);"
4126   [(set_attr "type" "fmov")
4127    (set_attr "mode" "SF")])
4128
4129 (define_split
4130   [(set (match_operand:SF 0 "register_operand" "")
4131         (float_truncate:SF
4132          (match_operand:DF 1 "fp_register_operand" "")))
4133    (clobber (match_operand 2 "" ""))]
4134   "reload_completed"
4135   [(set (match_dup 2) (match_dup 1))
4136    (set (match_dup 0) (match_dup 2))]
4137   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4138
4139 ;; Conversion from XFmode to {SF,DF}mode
4140
4141 (define_expand "truncxf<mode>2"
4142   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4143                    (float_truncate:MODEF
4144                      (match_operand:XF 1 "register_operand" "")))
4145               (clobber (match_dup 2))])]
4146   "TARGET_80387"
4147 {
4148   if (flag_unsafe_math_optimizations)
4149     {
4150       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4151       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4152       if (reg != operands[0])
4153         emit_move_insn (operands[0], reg);
4154       DONE;
4155     }
4156   else
4157     {
4158       enum ix86_stack_slot slot = (virtuals_instantiated
4159                                    ? SLOT_TEMP
4160                                    : SLOT_VIRTUAL);
4161       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4162     }
4163 })
4164
4165 (define_insn "*truncxfsf2_mixed"
4166   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4167         (float_truncate:SF
4168           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4169    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4170   "TARGET_80387"
4171 {
4172   gcc_assert (!which_alternative);
4173   return output_387_reg_move (insn, operands);
4174 }
4175   [(set_attr "type" "fmov,multi,multi,multi")
4176    (set_attr "unit" "*,i387,i387,i387")
4177    (set_attr "mode" "SF")])
4178
4179 (define_insn "*truncxfdf2_mixed"
4180   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4181         (float_truncate:DF
4182           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4183    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4184   "TARGET_80387"
4185 {
4186   gcc_assert (!which_alternative);
4187   return output_387_reg_move (insn, operands);
4188 }
4189   [(set_attr "type" "fmov,multi,multi,multi")
4190    (set_attr "unit" "*,i387,i387,i387")
4191    (set_attr "mode" "DF")])
4192
4193 (define_insn "truncxf<mode>2_i387_noop"
4194   [(set (match_operand:MODEF 0 "register_operand" "=f")
4195         (float_truncate:MODEF
4196           (match_operand:XF 1 "register_operand" "f")))]
4197   "TARGET_80387 && flag_unsafe_math_optimizations"
4198   "* return output_387_reg_move (insn, operands);"
4199   [(set_attr "type" "fmov")
4200    (set_attr "mode" "<MODE>")])
4201
4202 (define_insn "*truncxf<mode>2_i387"
4203   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4204         (float_truncate:MODEF
4205           (match_operand:XF 1 "register_operand" "f")))]
4206   "TARGET_80387"
4207   "* return output_387_reg_move (insn, operands);"
4208   [(set_attr "type" "fmov")
4209    (set_attr "mode" "<MODE>")])
4210
4211 (define_split
4212   [(set (match_operand:MODEF 0 "register_operand" "")
4213         (float_truncate:MODEF
4214           (match_operand:XF 1 "register_operand" "")))
4215    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4216   "TARGET_80387 && reload_completed"
4217   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4218    (set (match_dup 0) (match_dup 2))])
4219
4220 (define_split
4221   [(set (match_operand:MODEF 0 "memory_operand" "")
4222         (float_truncate:MODEF
4223           (match_operand:XF 1 "register_operand" "")))
4224    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4225   "TARGET_80387"
4226   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4227 \f
4228 ;; Signed conversion to DImode.
4229
4230 (define_expand "fix_truncxfdi2"
4231   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4232                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4233               (clobber (reg:CC FLAGS_REG))])]
4234   "TARGET_80387"
4235 {
4236   if (TARGET_FISTTP)
4237    {
4238      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4239      DONE;
4240    }
4241 })
4242
4243 (define_expand "fix_trunc<mode>di2"
4244   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4245                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4246               (clobber (reg:CC FLAGS_REG))])]
4247   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4248 {
4249   if (TARGET_FISTTP
4250       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4251    {
4252      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4253      DONE;
4254    }
4255   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4256    {
4257      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4258      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4259      if (out != operands[0])
4260         emit_move_insn (operands[0], out);
4261      DONE;
4262    }
4263 })
4264
4265 ;; Signed conversion to SImode.
4266
4267 (define_expand "fix_truncxfsi2"
4268   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4269                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4270               (clobber (reg:CC FLAGS_REG))])]
4271   "TARGET_80387"
4272 {
4273   if (TARGET_FISTTP)
4274    {
4275      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4276      DONE;
4277    }
4278 })
4279
4280 (define_expand "fix_trunc<mode>si2"
4281   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4282                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4283               (clobber (reg:CC FLAGS_REG))])]
4284   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4285 {
4286   if (TARGET_FISTTP
4287       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4288    {
4289      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4290      DONE;
4291    }
4292   if (SSE_FLOAT_MODE_P (<MODE>mode))
4293    {
4294      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4295      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4296      if (out != operands[0])
4297         emit_move_insn (operands[0], out);
4298      DONE;
4299    }
4300 })
4301
4302 ;; Signed conversion to HImode.
4303
4304 (define_expand "fix_trunc<mode>hi2"
4305   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4306                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4307               (clobber (reg:CC FLAGS_REG))])]
4308   "TARGET_80387
4309    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4310 {
4311   if (TARGET_FISTTP)
4312    {
4313      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4314      DONE;
4315    }
4316 })
4317
4318 ;; Unsigned conversion to SImode.
4319
4320 (define_expand "fixuns_trunc<mode>si2"
4321   [(parallel
4322     [(set (match_operand:SI 0 "register_operand" "")
4323           (unsigned_fix:SI
4324             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4325      (use (match_dup 2))
4326      (clobber (match_scratch:<ssevecmode> 3 ""))
4327      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4328   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4329 {
4330   enum machine_mode mode = <MODE>mode;
4331   enum machine_mode vecmode = <ssevecmode>mode;
4332   REAL_VALUE_TYPE TWO31r;
4333   rtx two31;
4334
4335   if (optimize_insn_for_size_p ())
4336     FAIL;
4337
4338   real_ldexp (&TWO31r, &dconst1, 31);
4339   two31 = const_double_from_real_value (TWO31r, mode);
4340   two31 = ix86_build_const_vector (vecmode, true, two31);
4341   operands[2] = force_reg (vecmode, two31);
4342 })
4343
4344 (define_insn_and_split "*fixuns_trunc<mode>_1"
4345   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4346         (unsigned_fix:SI
4347           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4348    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4349    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4350    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4351   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4352    && optimize_function_for_speed_p (cfun)"
4353   "#"
4354   "&& reload_completed"
4355   [(const_int 0)]
4356 {
4357   ix86_split_convert_uns_si_sse (operands);
4358   DONE;
4359 })
4360
4361 ;; Unsigned conversion to HImode.
4362 ;; Without these patterns, we'll try the unsigned SI conversion which
4363 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4364
4365 (define_expand "fixuns_trunc<mode>hi2"
4366   [(set (match_dup 2)
4367         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4368    (set (match_operand:HI 0 "nonimmediate_operand" "")
4369         (subreg:HI (match_dup 2) 0))]
4370   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4371   "operands[2] = gen_reg_rtx (SImode);")
4372
4373 ;; When SSE is available, it is always faster to use it!
4374 (define_insn "fix_trunc<mode>di_sse"
4375   [(set (match_operand:DI 0 "register_operand" "=r,r")
4376         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4377   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4378    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4379   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4380   [(set_attr "type" "sseicvt")
4381    (set_attr "prefix" "maybe_vex")
4382    (set_attr "prefix_rex" "1")
4383    (set_attr "mode" "<MODE>")
4384    (set_attr "athlon_decode" "double,vector")
4385    (set_attr "amdfam10_decode" "double,double")
4386    (set_attr "bdver1_decode" "double,double")])
4387
4388 (define_insn "fix_trunc<mode>si_sse"
4389   [(set (match_operand:SI 0 "register_operand" "=r,r")
4390         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4391   "SSE_FLOAT_MODE_P (<MODE>mode)
4392    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4393   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4394   [(set_attr "type" "sseicvt")
4395    (set_attr "prefix" "maybe_vex")
4396    (set_attr "mode" "<MODE>")
4397    (set_attr "athlon_decode" "double,vector")
4398    (set_attr "amdfam10_decode" "double,double")
4399    (set_attr "bdver1_decode" "double,double")])
4400
4401 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4402 (define_peephole2
4403   [(set (match_operand:MODEF 0 "register_operand" "")
4404         (match_operand:MODEF 1 "memory_operand" ""))
4405    (set (match_operand:SWI48x 2 "register_operand" "")
4406         (fix:SWI48x (match_dup 0)))]
4407   "TARGET_SHORTEN_X87_SSE
4408    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4409    && peep2_reg_dead_p (2, operands[0])"
4410   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4411
4412 ;; Avoid vector decoded forms of the instruction.
4413 (define_peephole2
4414   [(match_scratch:DF 2 "Y2")
4415    (set (match_operand:SWI48x 0 "register_operand" "")
4416         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4417   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4418   [(set (match_dup 2) (match_dup 1))
4419    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4420
4421 (define_peephole2
4422   [(match_scratch:SF 2 "x")
4423    (set (match_operand:SWI48x 0 "register_operand" "")
4424         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4425   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4426   [(set (match_dup 2) (match_dup 1))
4427    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4428
4429 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4430   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4431         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4432   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4433    && TARGET_FISTTP
4434    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4435          && (TARGET_64BIT || <MODE>mode != DImode))
4436         && TARGET_SSE_MATH)
4437    && can_create_pseudo_p ()"
4438   "#"
4439   "&& 1"
4440   [(const_int 0)]
4441 {
4442   if (memory_operand (operands[0], VOIDmode))
4443     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4444   else
4445     {
4446       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4447       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4448                                                             operands[1],
4449                                                             operands[2]));
4450     }
4451   DONE;
4452 }
4453   [(set_attr "type" "fisttp")
4454    (set_attr "mode" "<MODE>")])
4455
4456 (define_insn "fix_trunc<mode>_i387_fisttp"
4457   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4458         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4459    (clobber (match_scratch:XF 2 "=&1f"))]
4460   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4461    && TARGET_FISTTP
4462    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4463          && (TARGET_64BIT || <MODE>mode != DImode))
4464         && TARGET_SSE_MATH)"
4465   "* return output_fix_trunc (insn, operands, true);"
4466   [(set_attr "type" "fisttp")
4467    (set_attr "mode" "<MODE>")])
4468
4469 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4470   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4471         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4472    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4473    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4474   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4475    && TARGET_FISTTP
4476    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4477         && (TARGET_64BIT || <MODE>mode != DImode))
4478         && TARGET_SSE_MATH)"
4479   "#"
4480   [(set_attr "type" "fisttp")
4481    (set_attr "mode" "<MODE>")])
4482
4483 (define_split
4484   [(set (match_operand:SWI248x 0 "register_operand" "")
4485         (fix:SWI248x (match_operand 1 "register_operand" "")))
4486    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4487    (clobber (match_scratch 3 ""))]
4488   "reload_completed"
4489   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4490               (clobber (match_dup 3))])
4491    (set (match_dup 0) (match_dup 2))])
4492
4493 (define_split
4494   [(set (match_operand:SWI248x 0 "memory_operand" "")
4495         (fix:SWI248x (match_operand 1 "register_operand" "")))
4496    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4497    (clobber (match_scratch 3 ""))]
4498   "reload_completed"
4499   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4500               (clobber (match_dup 3))])])
4501
4502 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4503 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4504 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4505 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4506 ;; function in i386.c.
4507 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4508   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4509         (fix:SWI248x (match_operand 1 "register_operand" "")))
4510    (clobber (reg:CC FLAGS_REG))]
4511   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4512    && !TARGET_FISTTP
4513    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4514          && (TARGET_64BIT || <MODE>mode != DImode))
4515    && can_create_pseudo_p ()"
4516   "#"
4517   "&& 1"
4518   [(const_int 0)]
4519 {
4520   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4521
4522   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4523   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4524   if (memory_operand (operands[0], VOIDmode))
4525     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4526                                          operands[2], operands[3]));
4527   else
4528     {
4529       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4530       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4531                                                      operands[2], operands[3],
4532                                                      operands[4]));
4533     }
4534   DONE;
4535 }
4536   [(set_attr "type" "fistp")
4537    (set_attr "i387_cw" "trunc")
4538    (set_attr "mode" "<MODE>")])
4539
4540 (define_insn "fix_truncdi_i387"
4541   [(set (match_operand:DI 0 "memory_operand" "=m")
4542         (fix:DI (match_operand 1 "register_operand" "f")))
4543    (use (match_operand:HI 2 "memory_operand" "m"))
4544    (use (match_operand:HI 3 "memory_operand" "m"))
4545    (clobber (match_scratch:XF 4 "=&1f"))]
4546   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4547    && !TARGET_FISTTP
4548    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4549   "* return output_fix_trunc (insn, operands, false);"
4550   [(set_attr "type" "fistp")
4551    (set_attr "i387_cw" "trunc")
4552    (set_attr "mode" "DI")])
4553
4554 (define_insn "fix_truncdi_i387_with_temp"
4555   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4556         (fix:DI (match_operand 1 "register_operand" "f,f")))
4557    (use (match_operand:HI 2 "memory_operand" "m,m"))
4558    (use (match_operand:HI 3 "memory_operand" "m,m"))
4559    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4560    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4561   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4562    && !TARGET_FISTTP
4563    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4564   "#"
4565   [(set_attr "type" "fistp")
4566    (set_attr "i387_cw" "trunc")
4567    (set_attr "mode" "DI")])
4568
4569 (define_split
4570   [(set (match_operand:DI 0 "register_operand" "")
4571         (fix:DI (match_operand 1 "register_operand" "")))
4572    (use (match_operand:HI 2 "memory_operand" ""))
4573    (use (match_operand:HI 3 "memory_operand" ""))
4574    (clobber (match_operand:DI 4 "memory_operand" ""))
4575    (clobber (match_scratch 5 ""))]
4576   "reload_completed"
4577   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4578               (use (match_dup 2))
4579               (use (match_dup 3))
4580               (clobber (match_dup 5))])
4581    (set (match_dup 0) (match_dup 4))])
4582
4583 (define_split
4584   [(set (match_operand:DI 0 "memory_operand" "")
4585         (fix:DI (match_operand 1 "register_operand" "")))
4586    (use (match_operand:HI 2 "memory_operand" ""))
4587    (use (match_operand:HI 3 "memory_operand" ""))
4588    (clobber (match_operand:DI 4 "memory_operand" ""))
4589    (clobber (match_scratch 5 ""))]
4590   "reload_completed"
4591   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4592               (use (match_dup 2))
4593               (use (match_dup 3))
4594               (clobber (match_dup 5))])])
4595
4596 (define_insn "fix_trunc<mode>_i387"
4597   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4598         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4599    (use (match_operand:HI 2 "memory_operand" "m"))
4600    (use (match_operand:HI 3 "memory_operand" "m"))]
4601   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4602    && !TARGET_FISTTP
4603    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4604   "* return output_fix_trunc (insn, operands, false);"
4605   [(set_attr "type" "fistp")
4606    (set_attr "i387_cw" "trunc")
4607    (set_attr "mode" "<MODE>")])
4608
4609 (define_insn "fix_trunc<mode>_i387_with_temp"
4610   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4611         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4612    (use (match_operand:HI 2 "memory_operand" "m,m"))
4613    (use (match_operand:HI 3 "memory_operand" "m,m"))
4614    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4615   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616    && !TARGET_FISTTP
4617    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4618   "#"
4619   [(set_attr "type" "fistp")
4620    (set_attr "i387_cw" "trunc")
4621    (set_attr "mode" "<MODE>")])
4622
4623 (define_split
4624   [(set (match_operand:SWI24 0 "register_operand" "")
4625         (fix:SWI24 (match_operand 1 "register_operand" "")))
4626    (use (match_operand:HI 2 "memory_operand" ""))
4627    (use (match_operand:HI 3 "memory_operand" ""))
4628    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4629   "reload_completed"
4630   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4631               (use (match_dup 2))
4632               (use (match_dup 3))])
4633    (set (match_dup 0) (match_dup 4))])
4634
4635 (define_split
4636   [(set (match_operand:SWI24 0 "memory_operand" "")
4637         (fix:SWI24 (match_operand 1 "register_operand" "")))
4638    (use (match_operand:HI 2 "memory_operand" ""))
4639    (use (match_operand:HI 3 "memory_operand" ""))
4640    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4641   "reload_completed"
4642   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4643               (use (match_dup 2))
4644               (use (match_dup 3))])])
4645
4646 (define_insn "x86_fnstcw_1"
4647   [(set (match_operand:HI 0 "memory_operand" "=m")
4648         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4649   "TARGET_80387"
4650   "fnstcw\t%0"
4651   [(set (attr "length")
4652         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4653    (set_attr "mode" "HI")
4654    (set_attr "unit" "i387")
4655    (set_attr "bdver1_decode" "vector")])
4656
4657 (define_insn "x86_fldcw_1"
4658   [(set (reg:HI FPCR_REG)
4659         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4660   "TARGET_80387"
4661   "fldcw\t%0"
4662   [(set (attr "length")
4663         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4664    (set_attr "mode" "HI")
4665    (set_attr "unit" "i387")
4666    (set_attr "athlon_decode" "vector")
4667    (set_attr "amdfam10_decode" "vector")
4668    (set_attr "bdver1_decode" "vector")])
4669 \f
4670 ;; Conversion between fixed point and floating point.
4671
4672 ;; Even though we only accept memory inputs, the backend _really_
4673 ;; wants to be able to do this between registers.
4674
4675 (define_expand "floathi<mode>2"
4676   [(set (match_operand:X87MODEF 0 "register_operand" "")
4677         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4678   "TARGET_80387
4679    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4680        || TARGET_MIX_SSE_I387)")
4681
4682 ;; Pre-reload splitter to add memory clobber to the pattern.
4683 (define_insn_and_split "*floathi<mode>2_1"
4684   [(set (match_operand:X87MODEF 0 "register_operand" "")
4685         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4686   "TARGET_80387
4687    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4688        || TARGET_MIX_SSE_I387)
4689    && can_create_pseudo_p ()"
4690   "#"
4691   "&& 1"
4692   [(parallel [(set (match_dup 0)
4693               (float:X87MODEF (match_dup 1)))
4694    (clobber (match_dup 2))])]
4695   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4696
4697 (define_insn "*floathi<mode>2_i387_with_temp"
4698   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4699         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4700   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4701   "TARGET_80387
4702    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4703        || TARGET_MIX_SSE_I387)"
4704   "#"
4705   [(set_attr "type" "fmov,multi")
4706    (set_attr "mode" "<MODE>")
4707    (set_attr "unit" "*,i387")
4708    (set_attr "fp_int_src" "true")])
4709
4710 (define_insn "*floathi<mode>2_i387"
4711   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4712         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4713   "TARGET_80387
4714    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4715        || TARGET_MIX_SSE_I387)"
4716   "fild%Z1\t%1"
4717   [(set_attr "type" "fmov")
4718    (set_attr "mode" "<MODE>")
4719    (set_attr "fp_int_src" "true")])
4720
4721 (define_split
4722   [(set (match_operand:X87MODEF 0 "register_operand" "")
4723         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4724    (clobber (match_operand:HI 2 "memory_operand" ""))]
4725   "TARGET_80387
4726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4727        || TARGET_MIX_SSE_I387)
4728    && reload_completed"
4729   [(set (match_dup 2) (match_dup 1))
4730    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4731
4732 (define_split
4733   [(set (match_operand:X87MODEF 0 "register_operand" "")
4734         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4735    (clobber (match_operand:HI 2 "memory_operand" ""))]
4736    "TARGET_80387
4737     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738         || TARGET_MIX_SSE_I387)
4739     && reload_completed"
4740   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4741
4742 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4743   [(set (match_operand:X87MODEF 0 "register_operand" "")
4744         (float:X87MODEF
4745           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4746   "TARGET_80387
4747    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4748        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4749 {
4750   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4751         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4752       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4753     {
4754       rtx reg = gen_reg_rtx (XFmode);
4755       rtx (*insn)(rtx, rtx);
4756
4757       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4758
4759       if (<X87MODEF:MODE>mode == SFmode)
4760         insn = gen_truncxfsf2;
4761       else if (<X87MODEF:MODE>mode == DFmode)
4762         insn = gen_truncxfdf2;
4763       else
4764         gcc_unreachable ();
4765
4766       emit_insn (insn (operands[0], reg));
4767       DONE;
4768     }
4769 })
4770
4771 ;; Pre-reload splitter to add memory clobber to the pattern.
4772 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4773   [(set (match_operand:X87MODEF 0 "register_operand" "")
4774         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4775   "((TARGET_80387
4776      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4777      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4778            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4779          || TARGET_MIX_SSE_I387))
4780     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4781         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4782         && ((<SWI48x:MODE>mode == SImode
4783              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4784              && optimize_function_for_speed_p (cfun)
4785              && flag_trapping_math)
4786             || !(TARGET_INTER_UNIT_CONVERSIONS
4787                  || optimize_function_for_size_p (cfun)))))
4788    && can_create_pseudo_p ()"
4789   "#"
4790   "&& 1"
4791   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4792               (clobber (match_dup 2))])]
4793 {
4794   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4795
4796   /* Avoid store forwarding (partial memory) stall penalty
4797      by passing DImode value through XMM registers.  */
4798   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4799       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4800       && optimize_function_for_speed_p (cfun))
4801     {
4802       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4803                                                             operands[1],
4804                                                             operands[2]));
4805       DONE;
4806     }
4807 })
4808
4809 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4810   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4811         (float:MODEF
4812           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4813    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4814   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4815    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4816   "#"
4817   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4818    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4819    (set_attr "unit" "*,i387,*,*,*")
4820    (set_attr "athlon_decode" "*,*,double,direct,double")
4821    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4822    (set_attr "bdver1_decode" "*,*,double,direct,double")
4823    (set_attr "fp_int_src" "true")])
4824
4825 (define_insn "*floatsi<mode>2_vector_mixed"
4826   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4827         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4828   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4829    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4830   "@
4831    fild%Z1\t%1
4832    #"
4833   [(set_attr "type" "fmov,sseicvt")
4834    (set_attr "mode" "<MODE>,<ssevecmode>")
4835    (set_attr "unit" "i387,*")
4836    (set_attr "athlon_decode" "*,direct")
4837    (set_attr "amdfam10_decode" "*,double")
4838    (set_attr "bdver1_decode" "*,direct")
4839    (set_attr "fp_int_src" "true")])
4840
4841 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4842   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4843         (float:MODEF
4844           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4845    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4846   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4847    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4848   "#"
4849   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4850    (set_attr "mode" "<MODEF:MODE>")
4851    (set_attr "unit" "*,i387,*,*")
4852    (set_attr "athlon_decode" "*,*,double,direct")
4853    (set_attr "amdfam10_decode" "*,*,vector,double")
4854    (set_attr "bdver1_decode" "*,*,double,direct")
4855    (set_attr "fp_int_src" "true")])
4856
4857 (define_split
4858   [(set (match_operand:MODEF 0 "register_operand" "")
4859         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4860    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4861   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4862    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4863    && TARGET_INTER_UNIT_CONVERSIONS
4864    && reload_completed
4865    && (SSE_REG_P (operands[0])
4866        || (GET_CODE (operands[0]) == SUBREG
4867            && SSE_REG_P (operands[0])))"
4868   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4869
4870 (define_split
4871   [(set (match_operand:MODEF 0 "register_operand" "")
4872         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4873    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4874   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4875    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4876    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4877    && reload_completed
4878    && (SSE_REG_P (operands[0])
4879        || (GET_CODE (operands[0]) == SUBREG
4880            && SSE_REG_P (operands[0])))"
4881   [(set (match_dup 2) (match_dup 1))
4882    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4883
4884 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4885   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4886         (float:MODEF
4887           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4888   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4889    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4890    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4891   "@
4892    fild%Z1\t%1
4893    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4894    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4895   [(set_attr "type" "fmov,sseicvt,sseicvt")
4896    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4897    (set_attr "mode" "<MODEF:MODE>")
4898    (set (attr "prefix_rex")
4899      (if_then_else
4900        (and (eq_attr "prefix" "maybe_vex")
4901             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4902        (const_string "1")
4903        (const_string "*")))
4904    (set_attr "unit" "i387,*,*")
4905    (set_attr "athlon_decode" "*,double,direct")
4906    (set_attr "amdfam10_decode" "*,vector,double")
4907    (set_attr "bdver1_decode" "*,double,direct")
4908    (set_attr "fp_int_src" "true")])
4909
4910 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4911   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4912         (float:MODEF
4913           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4914   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4915    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4916    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4917   "@
4918    fild%Z1\t%1
4919    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4920   [(set_attr "type" "fmov,sseicvt")
4921    (set_attr "prefix" "orig,maybe_vex")
4922    (set_attr "mode" "<MODEF:MODE>")
4923    (set (attr "prefix_rex")
4924      (if_then_else
4925        (and (eq_attr "prefix" "maybe_vex")
4926             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4927        (const_string "1")
4928        (const_string "*")))
4929    (set_attr "athlon_decode" "*,direct")
4930    (set_attr "amdfam10_decode" "*,double")
4931    (set_attr "bdver1_decode" "*,direct")
4932    (set_attr "fp_int_src" "true")])
4933
4934 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4935   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4936         (float:MODEF
4937           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4938    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4939   "TARGET_SSE2 && TARGET_SSE_MATH
4940    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4941   "#"
4942   [(set_attr "type" "sseicvt")
4943    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4944    (set_attr "athlon_decode" "double,direct,double")
4945    (set_attr "amdfam10_decode" "vector,double,double")
4946    (set_attr "bdver1_decode" "double,direct,double")
4947    (set_attr "fp_int_src" "true")])
4948
4949 (define_insn "*floatsi<mode>2_vector_sse"
4950   [(set (match_operand:MODEF 0 "register_operand" "=x")
4951         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4952   "TARGET_SSE2 && TARGET_SSE_MATH
4953    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4954   "#"
4955   [(set_attr "type" "sseicvt")
4956    (set_attr "mode" "<MODE>")
4957    (set_attr "athlon_decode" "direct")
4958    (set_attr "amdfam10_decode" "double")
4959    (set_attr "bdver1_decode" "direct")
4960    (set_attr "fp_int_src" "true")])
4961
4962 (define_split
4963   [(set (match_operand:MODEF 0 "register_operand" "")
4964         (float:MODEF (match_operand:SI 1 "register_operand" "")))
4965    (clobber (match_operand:SI 2 "memory_operand" ""))]
4966   "TARGET_SSE2 && TARGET_SSE_MATH
4967    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4968    && reload_completed
4969    && (SSE_REG_P (operands[0])
4970        || (GET_CODE (operands[0]) == SUBREG
4971            && SSE_REG_P (operands[0])))"
4972   [(const_int 0)]
4973 {
4974   rtx op1 = operands[1];
4975
4976   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4977                                      <MODE>mode, 0);
4978   if (GET_CODE (op1) == SUBREG)
4979     op1 = SUBREG_REG (op1);
4980
4981   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4982     {
4983       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4984       emit_insn (gen_sse2_loadld (operands[4],
4985                                   CONST0_RTX (V4SImode), operands[1]));
4986     }
4987   /* We can ignore possible trapping value in the
4988      high part of SSE register for non-trapping math. */
4989   else if (SSE_REG_P (op1) && !flag_trapping_math)
4990     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4991   else
4992     {
4993       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4994       emit_move_insn (operands[2], operands[1]);
4995       emit_insn (gen_sse2_loadld (operands[4],
4996                                   CONST0_RTX (V4SImode), operands[2]));
4997     }
4998   emit_insn
4999     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5000   DONE;
5001 })
5002
5003 (define_split
5004   [(set (match_operand:MODEF 0 "register_operand" "")
5005         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5006    (clobber (match_operand:SI 2 "memory_operand" ""))]
5007   "TARGET_SSE2 && TARGET_SSE_MATH
5008    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5009    && reload_completed
5010    && (SSE_REG_P (operands[0])
5011        || (GET_CODE (operands[0]) == SUBREG
5012            && SSE_REG_P (operands[0])))"
5013   [(const_int 0)]
5014 {
5015   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5016                                      <MODE>mode, 0);
5017   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5018
5019   emit_insn (gen_sse2_loadld (operands[4],
5020                               CONST0_RTX (V4SImode), operands[1]));
5021   emit_insn
5022     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5023   DONE;
5024 })
5025
5026 (define_split
5027   [(set (match_operand:MODEF 0 "register_operand" "")
5028         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5029   "TARGET_SSE2 && TARGET_SSE_MATH
5030    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5031    && reload_completed
5032    && (SSE_REG_P (operands[0])
5033        || (GET_CODE (operands[0]) == SUBREG
5034            && SSE_REG_P (operands[0])))"
5035   [(const_int 0)]
5036 {
5037   rtx op1 = operands[1];
5038
5039   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5040                                      <MODE>mode, 0);
5041   if (GET_CODE (op1) == SUBREG)
5042     op1 = SUBREG_REG (op1);
5043
5044   if (GENERAL_REG_P (op1))
5045     {
5046       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5047       if (TARGET_INTER_UNIT_MOVES)
5048         emit_insn (gen_sse2_loadld (operands[4],
5049                                     CONST0_RTX (V4SImode), operands[1]));
5050       else
5051         {
5052           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5053                                               operands[1]);
5054           emit_insn (gen_sse2_loadld (operands[4],
5055                                       CONST0_RTX (V4SImode), operands[5]));
5056           ix86_free_from_memory (GET_MODE (operands[1]));
5057         }
5058     }
5059   /* We can ignore possible trapping value in the
5060      high part of SSE register for non-trapping math. */
5061   else if (SSE_REG_P (op1) && !flag_trapping_math)
5062     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5063   else
5064     gcc_unreachable ();
5065   emit_insn
5066     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5067   DONE;
5068 })
5069
5070 (define_split
5071   [(set (match_operand:MODEF 0 "register_operand" "")
5072         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5073   "TARGET_SSE2 && TARGET_SSE_MATH
5074    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5075    && reload_completed
5076    && (SSE_REG_P (operands[0])
5077        || (GET_CODE (operands[0]) == SUBREG
5078            && SSE_REG_P (operands[0])))"
5079   [(const_int 0)]
5080 {
5081   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5082                                      <MODE>mode, 0);
5083   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5084
5085   emit_insn (gen_sse2_loadld (operands[4],
5086                               CONST0_RTX (V4SImode), operands[1]));
5087   emit_insn
5088     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5089   DONE;
5090 })
5091
5092 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5093   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5094         (float:MODEF
5095           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5096   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5097   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5098    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5099   "#"
5100   [(set_attr "type" "sseicvt")
5101    (set_attr "mode" "<MODEF:MODE>")
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<SWI48x:mode><MODEF:mode>2_sse_interunit"
5108   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5109         (float:MODEF
5110           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5111   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5112    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5113    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5114   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5115   [(set_attr "type" "sseicvt")
5116    (set_attr "prefix" "maybe_vex")
5117    (set_attr "mode" "<MODEF:MODE>")
5118    (set (attr "prefix_rex")
5119      (if_then_else
5120        (and (eq_attr "prefix" "maybe_vex")
5121             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5122        (const_string "1")
5123        (const_string "*")))
5124    (set_attr "athlon_decode" "double,direct")
5125    (set_attr "amdfam10_decode" "vector,double")
5126    (set_attr "bdver1_decode" "double,direct")
5127    (set_attr "fp_int_src" "true")])
5128
5129 (define_split
5130   [(set (match_operand:MODEF 0 "register_operand" "")
5131         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5132    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5133   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5134    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5135    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5136    && reload_completed
5137    && (SSE_REG_P (operands[0])
5138        || (GET_CODE (operands[0]) == SUBREG
5139            && SSE_REG_P (operands[0])))"
5140   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5141
5142 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5143   [(set (match_operand:MODEF 0 "register_operand" "=x")
5144         (float:MODEF
5145           (match_operand:SWI48x 1 "memory_operand" "m")))]
5146   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5147    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5148    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5149   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5150   [(set_attr "type" "sseicvt")
5151    (set_attr "prefix" "maybe_vex")
5152    (set_attr "mode" "<MODEF:MODE>")
5153    (set (attr "prefix_rex")
5154      (if_then_else
5155        (and (eq_attr "prefix" "maybe_vex")
5156             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5157        (const_string "1")
5158        (const_string "*")))
5159    (set_attr "athlon_decode" "direct")
5160    (set_attr "amdfam10_decode" "double")
5161    (set_attr "bdver1_decode" "direct")
5162    (set_attr "fp_int_src" "true")])
5163
5164 (define_split
5165   [(set (match_operand:MODEF 0 "register_operand" "")
5166         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5167    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5168   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5169    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5170    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5171    && reload_completed
5172    && (SSE_REG_P (operands[0])
5173        || (GET_CODE (operands[0]) == SUBREG
5174            && SSE_REG_P (operands[0])))"
5175   [(set (match_dup 2) (match_dup 1))
5176    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5177
5178 (define_split
5179   [(set (match_operand:MODEF 0 "register_operand" "")
5180         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5181    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5182   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5183    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5184    && reload_completed
5185    && (SSE_REG_P (operands[0])
5186        || (GET_CODE (operands[0]) == SUBREG
5187            && SSE_REG_P (operands[0])))"
5188   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5189
5190 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5191   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5192         (float:X87MODEF
5193           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5194   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5195   "TARGET_80387
5196    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5197   "@
5198    fild%Z1\t%1
5199    #"
5200   [(set_attr "type" "fmov,multi")
5201    (set_attr "mode" "<X87MODEF:MODE>")
5202    (set_attr "unit" "*,i387")
5203    (set_attr "fp_int_src" "true")])
5204
5205 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5206   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5207         (float:X87MODEF
5208           (match_operand:SWI48x 1 "memory_operand" "m")))]
5209   "TARGET_80387
5210    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5211   "fild%Z1\t%1"
5212   [(set_attr "type" "fmov")
5213    (set_attr "mode" "<X87MODEF:MODE>")
5214    (set_attr "fp_int_src" "true")])
5215
5216 (define_split
5217   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5218         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5219    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5220   "TARGET_80387
5221    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5222    && reload_completed"
5223   [(set (match_dup 2) (match_dup 1))
5224    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5225
5226 (define_split
5227   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5228         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5229    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5230   "TARGET_80387
5231    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5232    && reload_completed"
5233   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5234
5235 ;; Avoid store forwarding (partial memory) stall penalty
5236 ;; by passing DImode value through XMM registers.  */
5237
5238 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5239   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5240         (float:X87MODEF
5241           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5242    (clobber (match_scratch:V4SI 3 "=X,x"))
5243    (clobber (match_scratch:V4SI 4 "=X,x"))
5244    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5245   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5246    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5247    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5248   "#"
5249   [(set_attr "type" "multi")
5250    (set_attr "mode" "<X87MODEF:MODE>")
5251    (set_attr "unit" "i387")
5252    (set_attr "fp_int_src" "true")])
5253
5254 (define_split
5255   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5256         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5257    (clobber (match_scratch:V4SI 3 ""))
5258    (clobber (match_scratch:V4SI 4 ""))
5259    (clobber (match_operand:DI 2 "memory_operand" ""))]
5260   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5261    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5262    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5263    && reload_completed"
5264   [(set (match_dup 2) (match_dup 3))
5265    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5266 {
5267   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5268      Assemble the 64-bit DImode value in an xmm register.  */
5269   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5270                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5271   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5272                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5273   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5274                                          operands[4]));
5275
5276   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5277 })
5278
5279 (define_split
5280   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5281         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5282    (clobber (match_scratch:V4SI 3 ""))
5283    (clobber (match_scratch:V4SI 4 ""))
5284    (clobber (match_operand:DI 2 "memory_operand" ""))]
5285   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5287    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5288    && reload_completed"
5289   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5290
5291 ;; Avoid store forwarding (partial memory) stall penalty by extending
5292 ;; SImode value to DImode through XMM register instead of pushing two
5293 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5294 ;; targets benefit from this optimization. Also note that fild
5295 ;; loads from memory only.
5296
5297 (define_insn "*floatunssi<mode>2_1"
5298   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5299         (unsigned_float:X87MODEF
5300           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5301    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5302    (clobber (match_scratch:SI 3 "=X,x"))]
5303   "!TARGET_64BIT
5304    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305    && TARGET_SSE"
5306   "#"
5307   [(set_attr "type" "multi")
5308    (set_attr "mode" "<MODE>")])
5309
5310 (define_split
5311   [(set (match_operand:X87MODEF 0 "register_operand" "")
5312         (unsigned_float:X87MODEF
5313           (match_operand:SI 1 "register_operand" "")))
5314    (clobber (match_operand:DI 2 "memory_operand" ""))
5315    (clobber (match_scratch:SI 3 ""))]
5316   "!TARGET_64BIT
5317    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5318    && TARGET_SSE
5319    && reload_completed"
5320   [(set (match_dup 2) (match_dup 1))
5321    (set (match_dup 0)
5322         (float:X87MODEF (match_dup 2)))]
5323   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5324
5325 (define_split
5326   [(set (match_operand:X87MODEF 0 "register_operand" "")
5327         (unsigned_float:X87MODEF
5328           (match_operand:SI 1 "memory_operand" "")))
5329    (clobber (match_operand:DI 2 "memory_operand" ""))
5330    (clobber (match_scratch:SI 3 ""))]
5331   "!TARGET_64BIT
5332    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5333    && TARGET_SSE
5334    && reload_completed"
5335   [(set (match_dup 2) (match_dup 3))
5336    (set (match_dup 0)
5337         (float:X87MODEF (match_dup 2)))]
5338 {
5339   emit_move_insn (operands[3], operands[1]);
5340   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5341 })
5342
5343 (define_expand "floatunssi<mode>2"
5344   [(parallel
5345      [(set (match_operand:X87MODEF 0 "register_operand" "")
5346            (unsigned_float:X87MODEF
5347              (match_operand:SI 1 "nonimmediate_operand" "")))
5348       (clobber (match_dup 2))
5349       (clobber (match_scratch:SI 3 ""))])]
5350   "!TARGET_64BIT
5351    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5352         && TARGET_SSE)
5353        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5354 {
5355   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5356     {
5357       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5358       DONE;
5359     }
5360   else
5361     {
5362       enum ix86_stack_slot slot = (virtuals_instantiated
5363                                    ? SLOT_TEMP
5364                                    : SLOT_VIRTUAL);
5365       operands[2] = assign_386_stack_local (DImode, slot);
5366     }
5367 })
5368
5369 (define_expand "floatunsdisf2"
5370   [(use (match_operand:SF 0 "register_operand" ""))
5371    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5372   "TARGET_64BIT && TARGET_SSE_MATH"
5373   "x86_emit_floatuns (operands); DONE;")
5374
5375 (define_expand "floatunsdidf2"
5376   [(use (match_operand:DF 0 "register_operand" ""))
5377    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5378   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5379    && TARGET_SSE2 && TARGET_SSE_MATH"
5380 {
5381   if (TARGET_64BIT)
5382     x86_emit_floatuns (operands);
5383   else
5384     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5385   DONE;
5386 })
5387 \f
5388 ;; Add instructions
5389
5390 (define_expand "add<mode>3"
5391   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5392         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5393                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5394   ""
5395   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5396
5397 (define_insn_and_split "*add<dwi>3_doubleword"
5398   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5399         (plus:<DWI>
5400           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5401           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5402    (clobber (reg:CC FLAGS_REG))]
5403   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5404   "#"
5405   "reload_completed"
5406   [(parallel [(set (reg:CC FLAGS_REG)
5407                    (unspec:CC [(match_dup 1) (match_dup 2)]
5408                               UNSPEC_ADD_CARRY))
5409               (set (match_dup 0)
5410                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5411    (parallel [(set (match_dup 3)
5412                    (plus:DWIH
5413                      (match_dup 4)
5414                      (plus:DWIH
5415                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5416                        (match_dup 5))))
5417               (clobber (reg:CC FLAGS_REG))])]
5418   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5419
5420 (define_insn "*add<mode>3_cc"
5421   [(set (reg:CC FLAGS_REG)
5422         (unspec:CC
5423           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5424            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5425           UNSPEC_ADD_CARRY))
5426    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5427         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5428   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5429   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5430   [(set_attr "type" "alu")
5431    (set_attr "mode" "<MODE>")])
5432
5433 (define_insn "addqi3_cc"
5434   [(set (reg:CC FLAGS_REG)
5435         (unspec:CC
5436           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5437            (match_operand:QI 2 "general_operand" "qn,qm")]
5438           UNSPEC_ADD_CARRY))
5439    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5440         (plus:QI (match_dup 1) (match_dup 2)))]
5441   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5442   "add{b}\t{%2, %0|%0, %2}"
5443   [(set_attr "type" "alu")
5444    (set_attr "mode" "QI")])
5445
5446 (define_insn "*lea_1"
5447   [(set (match_operand:SWI48 0 "register_operand" "=r")
5448         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5449   ""
5450   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5451   [(set_attr "type" "lea")
5452    (set_attr "mode" "<MODE>")])
5453
5454 (define_insn "*lea_1_zext"
5455   [(set (match_operand:DI 0 "register_operand" "=r")
5456         (zero_extend:DI
5457           (match_operand:SI 1 "lea_address_operand" "p")))]
5458   "TARGET_64BIT"
5459   "lea{l}\t{%a1, %k0|%k0, %a1}"
5460   [(set_attr "type" "lea")
5461    (set_attr "mode" "SI")])
5462
5463 (define_insn "*lea_2"
5464   [(set (match_operand:SI 0 "register_operand" "=r")
5465         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5466   "TARGET_64BIT"
5467   "lea{l}\t{%a1, %0|%0, %a1}"
5468   [(set_attr "type" "lea")
5469    (set_attr "mode" "SI")])
5470
5471 (define_insn "*lea_2_zext"
5472   [(set (match_operand:DI 0 "register_operand" "=r")
5473         (zero_extend:DI
5474           (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5475   "TARGET_64BIT"
5476   "lea{l}\t{%a1, %k0|%k0, %a1}"
5477   [(set_attr "type" "lea")
5478    (set_attr "mode" "SI")])
5479
5480 (define_insn "*add<mode>_1"
5481   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5482         (plus:SWI48
5483           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5484           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5485    (clobber (reg:CC FLAGS_REG))]
5486   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5487 {
5488   switch (get_attr_type (insn))
5489     {
5490     case TYPE_LEA:
5491       return "#";
5492
5493     case TYPE_INCDEC:
5494       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5495       if (operands[2] == const1_rtx)
5496         return "inc{<imodesuffix>}\t%0";
5497       else
5498         {
5499           gcc_assert (operands[2] == constm1_rtx);
5500           return "dec{<imodesuffix>}\t%0";
5501         }
5502
5503     default:
5504       /* For most processors, ADD is faster than LEA.  This alternative
5505          was added to use ADD as much as possible.  */
5506       if (which_alternative == 2)
5507         {
5508           rtx tmp;
5509           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5510         }
5511         
5512       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5513       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5514         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5515
5516       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5517     }
5518 }
5519   [(set (attr "type")
5520      (cond [(eq_attr "alternative" "3")
5521               (const_string "lea")
5522             (match_operand:SWI48 2 "incdec_operand" "")
5523               (const_string "incdec")
5524            ]
5525            (const_string "alu")))
5526    (set (attr "length_immediate")
5527       (if_then_else
5528         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5529         (const_string "1")
5530         (const_string "*")))
5531    (set_attr "mode" "<MODE>")])
5532
5533 ;; It may seem that nonimmediate operand is proper one for operand 1.
5534 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5535 ;; we take care in ix86_binary_operator_ok to not allow two memory
5536 ;; operands so proper swapping will be done in reload.  This allow
5537 ;; patterns constructed from addsi_1 to match.
5538
5539 (define_insn "addsi_1_zext"
5540   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5541         (zero_extend:DI
5542           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5543                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5544    (clobber (reg:CC FLAGS_REG))]
5545   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5546 {
5547   switch (get_attr_type (insn))
5548     {
5549     case TYPE_LEA:
5550       return "#";
5551
5552     case TYPE_INCDEC:
5553       if (operands[2] == const1_rtx)
5554         return "inc{l}\t%k0";
5555       else
5556         {
5557           gcc_assert (operands[2] == constm1_rtx);
5558           return "dec{l}\t%k0";
5559         }
5560
5561     default:
5562       /* For most processors, ADD is faster than LEA.  This alternative
5563          was added to use ADD as much as possible.  */
5564       if (which_alternative == 1)
5565         {
5566           rtx tmp;
5567           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5568         }
5569
5570       if (x86_maybe_negate_const_int (&operands[2], SImode))
5571         return "sub{l}\t{%2, %k0|%k0, %2}";
5572
5573       return "add{l}\t{%2, %k0|%k0, %2}";
5574     }
5575 }
5576   [(set (attr "type")
5577      (cond [(eq_attr "alternative" "2")
5578               (const_string "lea")
5579             (match_operand:SI 2 "incdec_operand" "")
5580               (const_string "incdec")
5581            ]
5582            (const_string "alu")))
5583    (set (attr "length_immediate")
5584       (if_then_else
5585         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5586         (const_string "1")
5587         (const_string "*")))
5588    (set_attr "mode" "SI")])
5589
5590 (define_insn "*addhi_1"
5591   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5592         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5593                  (match_operand:HI 2 "general_operand" "rn,rm")))
5594    (clobber (reg:CC FLAGS_REG))]
5595   "TARGET_PARTIAL_REG_STALL
5596    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5597 {
5598   switch (get_attr_type (insn))
5599     {
5600     case TYPE_INCDEC:
5601       if (operands[2] == const1_rtx)
5602         return "inc{w}\t%0";
5603       else
5604         {
5605           gcc_assert (operands[2] == constm1_rtx);
5606           return "dec{w}\t%0";
5607         }
5608
5609     default:
5610       if (x86_maybe_negate_const_int (&operands[2], HImode))
5611         return "sub{w}\t{%2, %0|%0, %2}";
5612
5613       return "add{w}\t{%2, %0|%0, %2}";
5614     }
5615 }
5616   [(set (attr "type")
5617      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5618         (const_string "incdec")
5619         (const_string "alu")))
5620    (set (attr "length_immediate")
5621       (if_then_else
5622         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5623         (const_string "1")
5624         (const_string "*")))
5625    (set_attr "mode" "HI")])
5626
5627 (define_insn "*addhi_1_lea"
5628   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5629         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5630                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5631    (clobber (reg:CC FLAGS_REG))]
5632   "!TARGET_PARTIAL_REG_STALL
5633    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5634 {
5635   switch (get_attr_type (insn))
5636     {
5637     case TYPE_LEA:
5638       return "#";
5639
5640     case TYPE_INCDEC:
5641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642       if (operands[2] == const1_rtx)
5643         return "inc{w}\t%0";
5644       else
5645         {
5646           gcc_assert (operands[2] == constm1_rtx);
5647           return "dec{w}\t%0";
5648         }
5649
5650     default:
5651       /* For most processors, ADD is faster than LEA.  This alternative
5652          was added to use ADD as much as possible.  */
5653       if (which_alternative == 2)
5654         {
5655           rtx tmp;
5656           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5657         }
5658
5659       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660       if (x86_maybe_negate_const_int (&operands[2], HImode))
5661         return "sub{w}\t{%2, %0|%0, %2}";
5662
5663       return "add{w}\t{%2, %0|%0, %2}";
5664     }
5665 }
5666   [(set (attr "type")
5667      (cond [(eq_attr "alternative" "3")
5668               (const_string "lea")
5669             (match_operand:HI 2 "incdec_operand" "")
5670               (const_string "incdec")
5671            ]
5672            (const_string "alu")))
5673    (set (attr "length_immediate")
5674       (if_then_else
5675         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5676         (const_string "1")
5677         (const_string "*")))
5678    (set_attr "mode" "HI,HI,HI,SI")])
5679
5680 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5681 (define_insn "*addqi_1"
5682   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5683         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5684                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5685    (clobber (reg:CC FLAGS_REG))]
5686   "TARGET_PARTIAL_REG_STALL
5687    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5688 {
5689   int widen = (which_alternative == 2);
5690   switch (get_attr_type (insn))
5691     {
5692     case TYPE_INCDEC:
5693       if (operands[2] == const1_rtx)
5694         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5695       else
5696         {
5697           gcc_assert (operands[2] == constm1_rtx);
5698           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5699         }
5700
5701     default:
5702       if (x86_maybe_negate_const_int (&operands[2], QImode))
5703         {
5704           if (widen)
5705             return "sub{l}\t{%2, %k0|%k0, %2}";
5706           else
5707             return "sub{b}\t{%2, %0|%0, %2}";
5708         }
5709       if (widen)
5710         return "add{l}\t{%k2, %k0|%k0, %k2}";
5711       else
5712         return "add{b}\t{%2, %0|%0, %2}";
5713     }
5714 }
5715   [(set (attr "type")
5716      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5717         (const_string "incdec")
5718         (const_string "alu")))
5719    (set (attr "length_immediate")
5720       (if_then_else
5721         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5722         (const_string "1")
5723         (const_string "*")))
5724    (set_attr "mode" "QI,QI,SI")])
5725
5726 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5727 (define_insn "*addqi_1_lea"
5728   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5729         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5730                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5731    (clobber (reg:CC FLAGS_REG))]
5732   "!TARGET_PARTIAL_REG_STALL
5733    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5734 {
5735   int widen = (which_alternative == 3 || which_alternative == 4);
5736
5737   switch (get_attr_type (insn))
5738     {
5739     case TYPE_LEA:
5740       return "#";
5741
5742     case TYPE_INCDEC:
5743       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744       if (operands[2] == const1_rtx)
5745         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5746       else
5747         {
5748           gcc_assert (operands[2] == constm1_rtx);
5749           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5750         }
5751
5752     default:
5753       /* For most processors, ADD is faster than LEA.  These alternatives
5754          were added to use ADD as much as possible.  */
5755       if (which_alternative == 2 || which_alternative == 4)
5756         {
5757           rtx tmp;
5758           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5759         }
5760
5761       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5762       if (x86_maybe_negate_const_int (&operands[2], QImode))
5763         {
5764           if (widen)
5765             return "sub{l}\t{%2, %k0|%k0, %2}";
5766           else
5767             return "sub{b}\t{%2, %0|%0, %2}";
5768         }
5769       if (widen)
5770         return "add{l}\t{%k2, %k0|%k0, %k2}";
5771       else
5772         return "add{b}\t{%2, %0|%0, %2}";
5773     }
5774 }
5775   [(set (attr "type")
5776      (cond [(eq_attr "alternative" "5")
5777               (const_string "lea")
5778             (match_operand:QI 2 "incdec_operand" "")
5779               (const_string "incdec")
5780            ]
5781            (const_string "alu")))
5782    (set (attr "length_immediate")
5783       (if_then_else
5784         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5785         (const_string "1")
5786         (const_string "*")))
5787    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5788
5789 (define_insn "*addqi_1_slp"
5790   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5791         (plus:QI (match_dup 0)
5792                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5793    (clobber (reg:CC FLAGS_REG))]
5794   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5796 {
5797   switch (get_attr_type (insn))
5798     {
5799     case TYPE_INCDEC:
5800       if (operands[1] == const1_rtx)
5801         return "inc{b}\t%0";
5802       else
5803         {
5804           gcc_assert (operands[1] == constm1_rtx);
5805           return "dec{b}\t%0";
5806         }
5807
5808     default:
5809       if (x86_maybe_negate_const_int (&operands[1], QImode))
5810         return "sub{b}\t{%1, %0|%0, %1}";
5811
5812       return "add{b}\t{%1, %0|%0, %1}";
5813     }
5814 }
5815   [(set (attr "type")
5816      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5817         (const_string "incdec")
5818         (const_string "alu1")))
5819    (set (attr "memory")
5820      (if_then_else (match_operand 1 "memory_operand" "")
5821         (const_string "load")
5822         (const_string "none")))
5823    (set_attr "mode" "QI")])
5824
5825 ;; Convert add to the lea pattern to avoid flags dependency.
5826 (define_split
5827   [(set (match_operand:SWI 0 "register_operand" "")
5828         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5829                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5830    (clobber (reg:CC FLAGS_REG))]
5831   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5832   [(const_int 0)]
5833 {
5834   enum machine_mode mode = <MODE>mode;
5835   rtx pat;
5836
5837   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5838     { 
5839       mode = SImode; 
5840       operands[0] = gen_lowpart (mode, operands[0]);
5841       operands[1] = gen_lowpart (mode, operands[1]);
5842       operands[2] = gen_lowpart (mode, operands[2]);
5843     }
5844
5845   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5846
5847   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5848   DONE;
5849 })
5850
5851 ;; Convert add to the lea pattern to avoid flags dependency.
5852 (define_split
5853   [(set (match_operand:DI 0 "register_operand" "")
5854         (zero_extend:DI
5855           (plus:SI (match_operand:SI 1 "register_operand" "")
5856                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5857    (clobber (reg:CC FLAGS_REG))]
5858   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5859   [(set (match_dup 0)
5860         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5861
5862 (define_insn "*add<mode>_2"
5863   [(set (reg FLAGS_REG)
5864         (compare
5865           (plus:SWI
5866             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5867             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5868           (const_int 0)))
5869    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5870         (plus:SWI (match_dup 1) (match_dup 2)))]
5871   "ix86_match_ccmode (insn, CCGOCmode)
5872    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5873 {
5874   switch (get_attr_type (insn))
5875     {
5876     case TYPE_INCDEC:
5877       if (operands[2] == const1_rtx)
5878         return "inc{<imodesuffix>}\t%0";
5879       else
5880         {
5881           gcc_assert (operands[2] == constm1_rtx);
5882           return "dec{<imodesuffix>}\t%0";
5883         }
5884
5885     default:
5886       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5887         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5888
5889       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5890     }
5891 }
5892   [(set (attr "type")
5893      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5894         (const_string "incdec")
5895         (const_string "alu")))
5896    (set (attr "length_immediate")
5897       (if_then_else
5898         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5899         (const_string "1")
5900         (const_string "*")))
5901    (set_attr "mode" "<MODE>")])
5902
5903 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5904 (define_insn "*addsi_2_zext"
5905   [(set (reg FLAGS_REG)
5906         (compare
5907           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5908                    (match_operand:SI 2 "x86_64_general_operand" "rme"))
5909           (const_int 0)))
5910    (set (match_operand:DI 0 "register_operand" "=r")
5911         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5912   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5913    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5914 {
5915   switch (get_attr_type (insn))
5916     {
5917     case TYPE_INCDEC:
5918       if (operands[2] == const1_rtx)
5919         return "inc{l}\t%k0";
5920       else
5921         {
5922           gcc_assert (operands[2] == constm1_rtx);
5923           return "dec{l}\t%k0";
5924         }
5925
5926     default:
5927       if (x86_maybe_negate_const_int (&operands[2], SImode))
5928         return "sub{l}\t{%2, %k0|%k0, %2}";
5929
5930       return "add{l}\t{%2, %k0|%k0, %2}";
5931     }
5932 }
5933   [(set (attr "type")
5934      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5935         (const_string "incdec")
5936         (const_string "alu")))
5937    (set (attr "length_immediate")
5938       (if_then_else
5939         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5940         (const_string "1")
5941         (const_string "*")))
5942    (set_attr "mode" "SI")])
5943
5944 (define_insn "*add<mode>_3"
5945   [(set (reg FLAGS_REG)
5946         (compare
5947           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5948           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5949    (clobber (match_scratch:SWI 0 "=<r>"))]
5950   "ix86_match_ccmode (insn, CCZmode)
5951    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5952 {
5953   switch (get_attr_type (insn))
5954     {
5955     case TYPE_INCDEC:
5956       if (operands[2] == const1_rtx)
5957         return "inc{<imodesuffix>}\t%0";
5958       else
5959         {
5960           gcc_assert (operands[2] == constm1_rtx);
5961           return "dec{<imodesuffix>}\t%0";
5962         }
5963
5964     default:
5965       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5966         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5967
5968       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5969     }
5970 }
5971   [(set (attr "type")
5972      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5973         (const_string "incdec")
5974         (const_string "alu")))
5975    (set (attr "length_immediate")
5976       (if_then_else
5977         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5978         (const_string "1")
5979         (const_string "*")))
5980    (set_attr "mode" "<MODE>")])
5981
5982 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5983 (define_insn "*addsi_3_zext"
5984   [(set (reg FLAGS_REG)
5985         (compare
5986           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5987           (match_operand:SI 1 "nonimmediate_operand" "%0")))
5988    (set (match_operand:DI 0 "register_operand" "=r")
5989         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5990   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5991    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5992 {
5993   switch (get_attr_type (insn))
5994     {
5995     case TYPE_INCDEC:
5996       if (operands[2] == const1_rtx)
5997         return "inc{l}\t%k0";
5998       else
5999         {
6000           gcc_assert (operands[2] == constm1_rtx);
6001           return "dec{l}\t%k0";
6002         }
6003
6004     default:
6005       if (x86_maybe_negate_const_int (&operands[2], SImode))
6006         return "sub{l}\t{%2, %k0|%k0, %2}";
6007
6008       return "add{l}\t{%2, %k0|%k0, %2}";
6009     }
6010 }
6011   [(set (attr "type")
6012      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6013         (const_string "incdec")
6014         (const_string "alu")))
6015    (set (attr "length_immediate")
6016       (if_then_else
6017         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6018         (const_string "1")
6019         (const_string "*")))
6020    (set_attr "mode" "SI")])
6021
6022 ; For comparisons against 1, -1 and 128, we may generate better code
6023 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6024 ; is matched then.  We can't accept general immediate, because for
6025 ; case of overflows,  the result is messed up.
6026 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6027 ; only for comparisons not depending on it.
6028
6029 (define_insn "*adddi_4"
6030   [(set (reg FLAGS_REG)
6031         (compare
6032           (match_operand:DI 1 "nonimmediate_operand" "0")
6033           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6034    (clobber (match_scratch:DI 0 "=rm"))]
6035   "TARGET_64BIT
6036    && ix86_match_ccmode (insn, CCGCmode)"
6037 {
6038   switch (get_attr_type (insn))
6039     {
6040     case TYPE_INCDEC:
6041       if (operands[2] == constm1_rtx)
6042         return "inc{q}\t%0";
6043       else
6044         {
6045           gcc_assert (operands[2] == const1_rtx);
6046           return "dec{q}\t%0";
6047         }
6048
6049     default:
6050       if (x86_maybe_negate_const_int (&operands[2], DImode))
6051         return "add{q}\t{%2, %0|%0, %2}";
6052
6053       return "sub{q}\t{%2, %0|%0, %2}";
6054     }
6055 }
6056   [(set (attr "type")
6057      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6058         (const_string "incdec")
6059         (const_string "alu")))
6060    (set (attr "length_immediate")
6061       (if_then_else
6062         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6063         (const_string "1")
6064         (const_string "*")))
6065    (set_attr "mode" "DI")])
6066
6067 ; For comparisons against 1, -1 and 128, we may generate better code
6068 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6069 ; is matched then.  We can't accept general immediate, because for
6070 ; case of overflows,  the result is messed up.
6071 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6072 ; only for comparisons not depending on it.
6073
6074 (define_insn "*add<mode>_4"
6075   [(set (reg FLAGS_REG)
6076         (compare
6077           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6078           (match_operand:SWI124 2 "const_int_operand" "n")))
6079    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6080   "ix86_match_ccmode (insn, CCGCmode)"
6081 {
6082   switch (get_attr_type (insn))
6083     {
6084     case TYPE_INCDEC:
6085       if (operands[2] == constm1_rtx)
6086         return "inc{<imodesuffix>}\t%0";
6087       else
6088         {
6089           gcc_assert (operands[2] == const1_rtx);
6090           return "dec{<imodesuffix>}\t%0";
6091         }
6092
6093     default:
6094       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6095         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6096
6097       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6098     }
6099 }
6100   [(set (attr "type")
6101      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6102         (const_string "incdec")
6103         (const_string "alu")))
6104    (set (attr "length_immediate")
6105       (if_then_else
6106         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6107         (const_string "1")
6108         (const_string "*")))
6109    (set_attr "mode" "<MODE>")])
6110
6111 (define_insn "*add<mode>_5"
6112   [(set (reg FLAGS_REG)
6113         (compare
6114           (plus:SWI
6115             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6116             (match_operand:SWI 2 "<general_operand>" "<g>"))
6117           (const_int 0)))
6118    (clobber (match_scratch:SWI 0 "=<r>"))]
6119   "ix86_match_ccmode (insn, CCGOCmode)
6120    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6121 {
6122   switch (get_attr_type (insn))
6123     {
6124     case TYPE_INCDEC:
6125       if (operands[2] == const1_rtx)
6126         return "inc{<imodesuffix>}\t%0";
6127       else
6128         {
6129           gcc_assert (operands[2] == constm1_rtx);
6130           return "dec{<imodesuffix>}\t%0";
6131         }
6132
6133     default:
6134       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6135         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6136
6137       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6138     }
6139 }
6140   [(set (attr "type")
6141      (if_then_else (match_operand:SWI 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" "<MODE>")])
6150
6151 (define_insn "*addqi_ext_1_rex64"
6152   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6153                          (const_int 8)
6154                          (const_int 8))
6155         (plus:SI
6156           (zero_extract:SI
6157             (match_operand 1 "ext_register_operand" "0")
6158             (const_int 8)
6159             (const_int 8))
6160           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6161    (clobber (reg:CC FLAGS_REG))]
6162   "TARGET_64BIT"
6163 {
6164   switch (get_attr_type (insn))
6165     {
6166     case TYPE_INCDEC:
6167       if (operands[2] == const1_rtx)
6168         return "inc{b}\t%h0";
6169       else
6170         {
6171           gcc_assert (operands[2] == constm1_rtx);
6172           return "dec{b}\t%h0";
6173         }
6174
6175     default:
6176       return "add{b}\t{%2, %h0|%h0, %2}";
6177     }
6178 }
6179   [(set (attr "type")
6180      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6181         (const_string "incdec")
6182         (const_string "alu")))
6183    (set_attr "modrm" "1")
6184    (set_attr "mode" "QI")])
6185
6186 (define_insn "addqi_ext_1"
6187   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6188                          (const_int 8)
6189                          (const_int 8))
6190         (plus:SI
6191           (zero_extract:SI
6192             (match_operand 1 "ext_register_operand" "0")
6193             (const_int 8)
6194             (const_int 8))
6195           (match_operand:QI 2 "general_operand" "Qmn")))
6196    (clobber (reg:CC FLAGS_REG))]
6197   "!TARGET_64BIT"
6198 {
6199   switch (get_attr_type (insn))
6200     {
6201     case TYPE_INCDEC:
6202       if (operands[2] == const1_rtx)
6203         return "inc{b}\t%h0";
6204       else
6205         {
6206           gcc_assert (operands[2] == constm1_rtx);
6207           return "dec{b}\t%h0";
6208         }
6209
6210     default:
6211       return "add{b}\t{%2, %h0|%h0, %2}";
6212     }
6213 }
6214   [(set (attr "type")
6215      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6216         (const_string "incdec")
6217         (const_string "alu")))
6218    (set_attr "modrm" "1")
6219    (set_attr "mode" "QI")])
6220
6221 (define_insn "*addqi_ext_2"
6222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6223                          (const_int 8)
6224                          (const_int 8))
6225         (plus:SI
6226           (zero_extract:SI
6227             (match_operand 1 "ext_register_operand" "%0")
6228             (const_int 8)
6229             (const_int 8))
6230           (zero_extract:SI
6231             (match_operand 2 "ext_register_operand" "Q")
6232             (const_int 8)
6233             (const_int 8))))
6234    (clobber (reg:CC FLAGS_REG))]
6235   ""
6236   "add{b}\t{%h2, %h0|%h0, %h2}"
6237   [(set_attr "type" "alu")
6238    (set_attr "mode" "QI")])
6239
6240 ;; The lea patterns for modes less than 32 bits need to be matched by
6241 ;; several insns converted to real lea by splitters.
6242
6243 (define_insn_and_split "*lea_general_1"
6244   [(set (match_operand 0 "register_operand" "=r")
6245         (plus (plus (match_operand 1 "index_register_operand" "l")
6246                     (match_operand 2 "register_operand" "r"))
6247               (match_operand 3 "immediate_operand" "i")))]
6248   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6249    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6250    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6251    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6252    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6253        || GET_MODE (operands[3]) == VOIDmode)"
6254   "#"
6255   "&& reload_completed"
6256   [(const_int 0)]
6257 {
6258   enum machine_mode mode = SImode;
6259   rtx pat;
6260
6261   operands[0] = gen_lowpart (mode, operands[0]);
6262   operands[1] = gen_lowpart (mode, operands[1]);
6263   operands[2] = gen_lowpart (mode, operands[2]);
6264   operands[3] = gen_lowpart (mode, operands[3]);
6265
6266   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6267                       operands[3]);
6268
6269   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6270   DONE;
6271 }
6272   [(set_attr "type" "lea")
6273    (set_attr "mode" "SI")])
6274
6275 (define_insn_and_split "*lea_general_2"
6276   [(set (match_operand 0 "register_operand" "=r")
6277         (plus (mult (match_operand 1 "index_register_operand" "l")
6278                     (match_operand 2 "const248_operand" "n"))
6279               (match_operand 3 "nonmemory_operand" "ri")))]
6280   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6281    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6282    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6283    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6284        || GET_MODE (operands[3]) == VOIDmode)"
6285   "#"
6286   "&& reload_completed"
6287   [(const_int 0)]
6288 {
6289   enum machine_mode mode = SImode;
6290   rtx pat;
6291
6292   operands[0] = gen_lowpart (mode, operands[0]);
6293   operands[1] = gen_lowpart (mode, operands[1]);
6294   operands[3] = gen_lowpart (mode, operands[3]);
6295
6296   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6297                       operands[3]);
6298
6299   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6300   DONE;
6301 }
6302   [(set_attr "type" "lea")
6303    (set_attr "mode" "SI")])
6304
6305 (define_insn_and_split "*lea_general_3"
6306   [(set (match_operand 0 "register_operand" "=r")
6307         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6308                           (match_operand 2 "const248_operand" "n"))
6309                     (match_operand 3 "register_operand" "r"))
6310               (match_operand 4 "immediate_operand" "i")))]
6311   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6312    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6313    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6314    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6315   "#"
6316   "&& reload_completed"
6317   [(const_int 0)]
6318 {
6319   enum machine_mode mode = SImode;
6320   rtx pat;
6321
6322   operands[0] = gen_lowpart (mode, operands[0]);
6323   operands[1] = gen_lowpart (mode, operands[1]);
6324   operands[3] = gen_lowpart (mode, operands[3]);
6325   operands[4] = gen_lowpart (mode, operands[4]);
6326
6327   pat = gen_rtx_PLUS (mode,
6328                       gen_rtx_PLUS (mode,
6329                                     gen_rtx_MULT (mode, operands[1],
6330                                                         operands[2]),
6331                                     operands[3]),
6332                       operands[4]);
6333
6334   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6335   DONE;
6336 }
6337   [(set_attr "type" "lea")
6338    (set_attr "mode" "SI")])
6339
6340 (define_insn_and_split "*lea_general_4"
6341   [(set (match_operand 0 "register_operand" "=r")
6342         (any_or (ashift
6343                   (match_operand 1 "index_register_operand" "l")
6344                   (match_operand 2 "const_int_operand" "n"))
6345                 (match_operand 3 "const_int_operand" "n")))]
6346   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6347       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6348     || GET_MODE (operands[0]) == SImode
6349     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6350    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6351    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6352    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6353        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6354   "#"
6355   "&& reload_completed"
6356   [(const_int 0)]
6357 {
6358   enum machine_mode mode = GET_MODE (operands[0]);
6359   rtx pat;
6360
6361   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6362     { 
6363       mode = SImode; 
6364       operands[0] = gen_lowpart (mode, operands[0]);
6365       operands[1] = gen_lowpart (mode, operands[1]);
6366     }
6367
6368   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6369
6370   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6371                        INTVAL (operands[3]));
6372
6373   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6374   DONE;
6375 }
6376   [(set_attr "type" "lea")
6377    (set (attr "mode")
6378       (if_then_else (match_operand:DI 0 "" "")
6379         (const_string "DI")
6380         (const_string "SI")))])
6381 \f
6382 ;; Subtract instructions
6383
6384 (define_expand "sub<mode>3"
6385   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6386         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6387                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6388   ""
6389   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6390
6391 (define_insn_and_split "*sub<dwi>3_doubleword"
6392   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6393         (minus:<DWI>
6394           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6395           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6396    (clobber (reg:CC FLAGS_REG))]
6397   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6398   "#"
6399   "reload_completed"
6400   [(parallel [(set (reg:CC FLAGS_REG)
6401                    (compare:CC (match_dup 1) (match_dup 2)))
6402               (set (match_dup 0)
6403                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6404    (parallel [(set (match_dup 3)
6405                    (minus:DWIH
6406                      (match_dup 4)
6407                      (plus:DWIH
6408                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6409                        (match_dup 5))))
6410               (clobber (reg:CC FLAGS_REG))])]
6411   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6412
6413 (define_insn "*sub<mode>_1"
6414   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6415         (minus:SWI
6416           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6417           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6418    (clobber (reg:CC FLAGS_REG))]
6419   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6420   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6421   [(set_attr "type" "alu")
6422    (set_attr "mode" "<MODE>")])
6423
6424 (define_insn "*subsi_1_zext"
6425   [(set (match_operand:DI 0 "register_operand" "=r")
6426         (zero_extend:DI
6427           (minus:SI (match_operand:SI 1 "register_operand" "0")
6428                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6431   "sub{l}\t{%2, %k0|%k0, %2}"
6432   [(set_attr "type" "alu")
6433    (set_attr "mode" "SI")])
6434
6435 (define_insn "*subqi_1_slp"
6436   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6437         (minus:QI (match_dup 0)
6438                   (match_operand:QI 1 "general_operand" "qn,qm")))
6439    (clobber (reg:CC FLAGS_REG))]
6440   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6441    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6442   "sub{b}\t{%1, %0|%0, %1}"
6443   [(set_attr "type" "alu1")
6444    (set_attr "mode" "QI")])
6445
6446 (define_insn "*sub<mode>_2"
6447   [(set (reg FLAGS_REG)
6448         (compare
6449           (minus:SWI
6450             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6451             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6452           (const_int 0)))
6453    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6454         (minus:SWI (match_dup 1) (match_dup 2)))]
6455   "ix86_match_ccmode (insn, CCGOCmode)
6456    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6457   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6458   [(set_attr "type" "alu")
6459    (set_attr "mode" "<MODE>")])
6460
6461 (define_insn "*subsi_2_zext"
6462   [(set (reg FLAGS_REG)
6463         (compare
6464           (minus:SI (match_operand:SI 1 "register_operand" "0")
6465                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6466           (const_int 0)))
6467    (set (match_operand:DI 0 "register_operand" "=r")
6468         (zero_extend:DI
6469           (minus:SI (match_dup 1)
6470                     (match_dup 2))))]
6471   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6472    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6473   "sub{l}\t{%2, %k0|%k0, %2}"
6474   [(set_attr "type" "alu")
6475    (set_attr "mode" "SI")])
6476
6477 (define_insn "*sub<mode>_3"
6478   [(set (reg FLAGS_REG)
6479         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6480                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6481    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6482         (minus:SWI (match_dup 1) (match_dup 2)))]
6483   "ix86_match_ccmode (insn, CCmode)
6484    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6485   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6486   [(set_attr "type" "alu")
6487    (set_attr "mode" "<MODE>")])
6488
6489 (define_insn "*subsi_3_zext"
6490   [(set (reg FLAGS_REG)
6491         (compare (match_operand:SI 1 "register_operand" "0")
6492                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6493    (set (match_operand:DI 0 "register_operand" "=r")
6494         (zero_extend:DI
6495           (minus:SI (match_dup 1)
6496                     (match_dup 2))))]
6497   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6498    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6499   "sub{l}\t{%2, %1|%1, %2}"
6500   [(set_attr "type" "alu")
6501    (set_attr "mode" "SI")])
6502 \f
6503 ;; Add with carry and subtract with borrow
6504
6505 (define_expand "<plusminus_insn><mode>3_carry"
6506   [(parallel
6507     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6508           (plusminus:SWI
6509             (match_operand:SWI 1 "nonimmediate_operand" "")
6510             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6511                        [(match_operand 3 "flags_reg_operand" "")
6512                         (const_int 0)])
6513                       (match_operand:SWI 2 "<general_operand>" ""))))
6514      (clobber (reg:CC FLAGS_REG))])]
6515   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6516
6517 (define_insn "*<plusminus_insn><mode>3_carry"
6518   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6519         (plusminus:SWI
6520           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6521           (plus:SWI
6522             (match_operator 3 "ix86_carry_flag_operator"
6523              [(reg FLAGS_REG) (const_int 0)])
6524             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6525    (clobber (reg:CC FLAGS_REG))]
6526   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6527   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6528   [(set_attr "type" "alu")
6529    (set_attr "use_carry" "1")
6530    (set_attr "pent_pair" "pu")
6531    (set_attr "mode" "<MODE>")])
6532
6533 (define_insn "*addsi3_carry_zext"
6534   [(set (match_operand:DI 0 "register_operand" "=r")
6535         (zero_extend:DI
6536           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6537                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6538                              [(reg FLAGS_REG) (const_int 0)])
6539                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6540    (clobber (reg:CC FLAGS_REG))]
6541   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6542   "adc{l}\t{%2, %k0|%k0, %2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "use_carry" "1")
6545    (set_attr "pent_pair" "pu")
6546    (set_attr "mode" "SI")])
6547
6548 (define_insn "*subsi3_carry_zext"
6549   [(set (match_operand:DI 0 "register_operand" "=r")
6550         (zero_extend:DI
6551           (minus:SI (match_operand:SI 1 "register_operand" "0")
6552                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6553                               [(reg FLAGS_REG) (const_int 0)])
6554                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6555    (clobber (reg:CC FLAGS_REG))]
6556   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6557   "sbb{l}\t{%2, %k0|%k0, %2}"
6558   [(set_attr "type" "alu")
6559    (set_attr "pent_pair" "pu")
6560    (set_attr "mode" "SI")])
6561 \f
6562 ;; Overflow setting add and subtract instructions
6563
6564 (define_insn "*add<mode>3_cconly_overflow"
6565   [(set (reg:CCC FLAGS_REG)
6566         (compare:CCC
6567           (plus:SWI
6568             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6569             (match_operand:SWI 2 "<general_operand>" "<g>"))
6570           (match_dup 1)))
6571    (clobber (match_scratch:SWI 0 "=<r>"))]
6572   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6573   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6574   [(set_attr "type" "alu")
6575    (set_attr "mode" "<MODE>")])
6576
6577 (define_insn "*sub<mode>3_cconly_overflow"
6578   [(set (reg:CCC FLAGS_REG)
6579         (compare:CCC
6580           (minus:SWI
6581             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6582             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6583           (match_dup 0)))]
6584   ""
6585   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6586   [(set_attr "type" "icmp")
6587    (set_attr "mode" "<MODE>")])
6588
6589 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6590   [(set (reg:CCC FLAGS_REG)
6591         (compare:CCC
6592             (plusminus:SWI
6593                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6594                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6595             (match_dup 1)))
6596    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6597         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6598   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6599   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6600   [(set_attr "type" "alu")
6601    (set_attr "mode" "<MODE>")])
6602
6603 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6604   [(set (reg:CCC FLAGS_REG)
6605         (compare:CCC
6606           (plusminus:SI
6607             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6608             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6609           (match_dup 1)))
6610    (set (match_operand:DI 0 "register_operand" "=r")
6611         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6612   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6613   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "mode" "SI")])
6616
6617 ;; The patterns that match these are at the end of this file.
6618
6619 (define_expand "<plusminus_insn>xf3"
6620   [(set (match_operand:XF 0 "register_operand" "")
6621         (plusminus:XF
6622           (match_operand:XF 1 "register_operand" "")
6623           (match_operand:XF 2 "register_operand" "")))]
6624   "TARGET_80387")
6625
6626 (define_expand "<plusminus_insn><mode>3"
6627   [(set (match_operand:MODEF 0 "register_operand" "")
6628         (plusminus:MODEF
6629           (match_operand:MODEF 1 "register_operand" "")
6630           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6631   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6632     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6633 \f
6634 ;; Multiply instructions
6635
6636 (define_expand "mul<mode>3"
6637   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6638                    (mult:SWIM248
6639                      (match_operand:SWIM248 1 "register_operand" "")
6640                      (match_operand:SWIM248 2 "<general_operand>" "")))
6641               (clobber (reg:CC FLAGS_REG))])])
6642
6643 (define_expand "mulqi3"
6644   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6645                    (mult:QI
6646                      (match_operand:QI 1 "register_operand" "")
6647                      (match_operand:QI 2 "nonimmediate_operand" "")))
6648               (clobber (reg:CC FLAGS_REG))])]
6649   "TARGET_QIMODE_MATH")
6650
6651 ;; On AMDFAM10
6652 ;; IMUL reg32/64, reg32/64, imm8        Direct
6653 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6654 ;; IMUL reg32/64, reg32/64, imm32       Direct
6655 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6656 ;; IMUL reg32/64, reg32/64              Direct
6657 ;; IMUL reg32/64, mem32/64              Direct
6658 ;;
6659 ;; On BDVER1, all above IMULs use DirectPath
6660
6661 (define_insn "*mul<mode>3_1"
6662   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6663         (mult:SWI48
6664           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6665           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6666    (clobber (reg:CC FLAGS_REG))]
6667   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6668   "@
6669    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6670    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6671    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6672   [(set_attr "type" "imul")
6673    (set_attr "prefix_0f" "0,0,1")
6674    (set (attr "athlon_decode")
6675         (cond [(eq_attr "cpu" "athlon")
6676                   (const_string "vector")
6677                (eq_attr "alternative" "1")
6678                   (const_string "vector")
6679                (and (eq_attr "alternative" "2")
6680                     (match_operand 1 "memory_operand" ""))
6681                   (const_string "vector")]
6682               (const_string "direct")))
6683    (set (attr "amdfam10_decode")
6684         (cond [(and (eq_attr "alternative" "0,1")
6685                     (match_operand 1 "memory_operand" ""))
6686                   (const_string "vector")]
6687               (const_string "direct")))
6688    (set_attr "bdver1_decode" "direct")
6689    (set_attr "mode" "<MODE>")])
6690
6691 (define_insn "*mulsi3_1_zext"
6692   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6693         (zero_extend:DI
6694           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6695                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6696    (clobber (reg:CC FLAGS_REG))]
6697   "TARGET_64BIT
6698    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6699   "@
6700    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6701    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6702    imul{l}\t{%2, %k0|%k0, %2}"
6703   [(set_attr "type" "imul")
6704    (set_attr "prefix_0f" "0,0,1")
6705    (set (attr "athlon_decode")
6706         (cond [(eq_attr "cpu" "athlon")
6707                   (const_string "vector")
6708                (eq_attr "alternative" "1")
6709                   (const_string "vector")
6710                (and (eq_attr "alternative" "2")
6711                     (match_operand 1 "memory_operand" ""))
6712                   (const_string "vector")]
6713               (const_string "direct")))
6714    (set (attr "amdfam10_decode")
6715         (cond [(and (eq_attr "alternative" "0,1")
6716                     (match_operand 1 "memory_operand" ""))
6717                   (const_string "vector")]
6718               (const_string "direct")))
6719    (set_attr "bdver1_decode" "direct")
6720    (set_attr "mode" "SI")])
6721
6722 ;; On AMDFAM10
6723 ;; IMUL reg16, reg16, imm8      VectorPath
6724 ;; IMUL reg16, mem16, imm8      VectorPath
6725 ;; IMUL reg16, reg16, imm16     VectorPath
6726 ;; IMUL reg16, mem16, imm16     VectorPath
6727 ;; IMUL reg16, reg16            Direct
6728 ;; IMUL reg16, mem16            Direct
6729 ;;
6730 ;; On BDVER1, all HI MULs use DoublePath
6731
6732 (define_insn "*mulhi3_1"
6733   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6734         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6735                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6736    (clobber (reg:CC FLAGS_REG))]
6737   "TARGET_HIMODE_MATH
6738    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6739   "@
6740    imul{w}\t{%2, %1, %0|%0, %1, %2}
6741    imul{w}\t{%2, %1, %0|%0, %1, %2}
6742    imul{w}\t{%2, %0|%0, %2}"
6743   [(set_attr "type" "imul")
6744    (set_attr "prefix_0f" "0,0,1")
6745    (set (attr "athlon_decode")
6746         (cond [(eq_attr "cpu" "athlon")
6747                   (const_string "vector")
6748                (eq_attr "alternative" "1,2")
6749                   (const_string "vector")]
6750               (const_string "direct")))
6751    (set (attr "amdfam10_decode")
6752         (cond [(eq_attr "alternative" "0,1")
6753                   (const_string "vector")]
6754               (const_string "direct")))
6755    (set_attr "bdver1_decode" "double")
6756    (set_attr "mode" "HI")])
6757
6758 ;;On AMDFAM10 and BDVER1
6759 ;; MUL reg8     Direct
6760 ;; MUL mem8     Direct
6761
6762 (define_insn "*mulqi3_1"
6763   [(set (match_operand:QI 0 "register_operand" "=a")
6764         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6765                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6766    (clobber (reg:CC FLAGS_REG))]
6767   "TARGET_QIMODE_MATH
6768    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6769   "mul{b}\t%2"
6770   [(set_attr "type" "imul")
6771    (set_attr "length_immediate" "0")
6772    (set (attr "athlon_decode")
6773      (if_then_else (eq_attr "cpu" "athlon")
6774         (const_string "vector")
6775         (const_string "direct")))
6776    (set_attr "amdfam10_decode" "direct")
6777    (set_attr "bdver1_decode" "direct")
6778    (set_attr "mode" "QI")])
6779
6780 (define_expand "<u>mul<mode><dwi>3"
6781   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6782                    (mult:<DWI>
6783                      (any_extend:<DWI>
6784                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6785                      (any_extend:<DWI>
6786                        (match_operand:DWIH 2 "register_operand" ""))))
6787               (clobber (reg:CC FLAGS_REG))])])
6788
6789 (define_expand "<u>mulqihi3"
6790   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6791                    (mult:HI
6792                      (any_extend:HI
6793                        (match_operand:QI 1 "nonimmediate_operand" ""))
6794                      (any_extend:HI
6795                        (match_operand:QI 2 "register_operand" ""))))
6796               (clobber (reg:CC FLAGS_REG))])]
6797   "TARGET_QIMODE_MATH")
6798
6799 (define_insn "*<u>mul<mode><dwi>3_1"
6800   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6801         (mult:<DWI>
6802           (any_extend:<DWI>
6803             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6804           (any_extend:<DWI>
6805             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6806    (clobber (reg:CC FLAGS_REG))]
6807   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6808   "<sgnprefix>mul{<imodesuffix>}\t%2"
6809   [(set_attr "type" "imul")
6810    (set_attr "length_immediate" "0")
6811    (set (attr "athlon_decode")
6812      (if_then_else (eq_attr "cpu" "athlon")
6813         (const_string "vector")
6814         (const_string "double")))
6815    (set_attr "amdfam10_decode" "double")
6816    (set_attr "bdver1_decode" "direct")
6817    (set_attr "mode" "<MODE>")])
6818
6819 (define_insn "*<u>mulqihi3_1"
6820   [(set (match_operand:HI 0 "register_operand" "=a")
6821         (mult:HI
6822           (any_extend:HI
6823             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6824           (any_extend:HI
6825             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6826    (clobber (reg:CC FLAGS_REG))]
6827   "TARGET_QIMODE_MATH
6828    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6829   "<sgnprefix>mul{b}\t%2"
6830   [(set_attr "type" "imul")
6831    (set_attr "length_immediate" "0")
6832    (set (attr "athlon_decode")
6833      (if_then_else (eq_attr "cpu" "athlon")
6834         (const_string "vector")
6835         (const_string "direct")))
6836    (set_attr "amdfam10_decode" "direct")
6837    (set_attr "bdver1_decode" "direct")
6838    (set_attr "mode" "QI")])
6839
6840 (define_expand "<s>mul<mode>3_highpart"
6841   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6842                    (truncate:SWI48
6843                      (lshiftrt:<DWI>
6844                        (mult:<DWI>
6845                          (any_extend:<DWI>
6846                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6847                          (any_extend:<DWI>
6848                            (match_operand:SWI48 2 "register_operand" "")))
6849                        (match_dup 4))))
6850               (clobber (match_scratch:SWI48 3 ""))
6851               (clobber (reg:CC FLAGS_REG))])]
6852   ""
6853   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6854
6855 (define_insn "*<s>muldi3_highpart_1"
6856   [(set (match_operand:DI 0 "register_operand" "=d")
6857         (truncate:DI
6858           (lshiftrt:TI
6859             (mult:TI
6860               (any_extend:TI
6861                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6862               (any_extend:TI
6863                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6864             (const_int 64))))
6865    (clobber (match_scratch:DI 3 "=1"))
6866    (clobber (reg:CC FLAGS_REG))]
6867   "TARGET_64BIT
6868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6869   "<sgnprefix>mul{q}\t%2"
6870   [(set_attr "type" "imul")
6871    (set_attr "length_immediate" "0")
6872    (set (attr "athlon_decode")
6873      (if_then_else (eq_attr "cpu" "athlon")
6874         (const_string "vector")
6875         (const_string "double")))
6876    (set_attr "amdfam10_decode" "double")
6877    (set_attr "bdver1_decode" "direct")
6878    (set_attr "mode" "DI")])
6879
6880 (define_insn "*<s>mulsi3_highpart_1"
6881   [(set (match_operand:SI 0 "register_operand" "=d")
6882         (truncate:SI
6883           (lshiftrt:DI
6884             (mult:DI
6885               (any_extend:DI
6886                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6887               (any_extend:DI
6888                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6889             (const_int 32))))
6890    (clobber (match_scratch:SI 3 "=1"))
6891    (clobber (reg:CC FLAGS_REG))]
6892   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6893   "<sgnprefix>mul{l}\t%2"
6894   [(set_attr "type" "imul")
6895    (set_attr "length_immediate" "0")
6896    (set (attr "athlon_decode")
6897      (if_then_else (eq_attr "cpu" "athlon")
6898         (const_string "vector")
6899         (const_string "double")))
6900    (set_attr "amdfam10_decode" "double")
6901    (set_attr "bdver1_decode" "direct")
6902    (set_attr "mode" "SI")])
6903
6904 (define_insn "*<s>mulsi3_highpart_zext"
6905   [(set (match_operand:DI 0 "register_operand" "=d")
6906         (zero_extend:DI (truncate:SI
6907           (lshiftrt:DI
6908             (mult:DI (any_extend:DI
6909                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6910                      (any_extend:DI
6911                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6912             (const_int 32)))))
6913    (clobber (match_scratch:SI 3 "=1"))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "TARGET_64BIT
6916    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917   "<sgnprefix>mul{l}\t%2"
6918   [(set_attr "type" "imul")
6919    (set_attr "length_immediate" "0")
6920    (set (attr "athlon_decode")
6921      (if_then_else (eq_attr "cpu" "athlon")
6922         (const_string "vector")
6923         (const_string "double")))
6924    (set_attr "amdfam10_decode" "double")
6925    (set_attr "bdver1_decode" "direct")
6926    (set_attr "mode" "SI")])
6927
6928 ;; The patterns that match these are at the end of this file.
6929
6930 (define_expand "mulxf3"
6931   [(set (match_operand:XF 0 "register_operand" "")
6932         (mult:XF (match_operand:XF 1 "register_operand" "")
6933                  (match_operand:XF 2 "register_operand" "")))]
6934   "TARGET_80387")
6935
6936 (define_expand "mul<mode>3"
6937   [(set (match_operand:MODEF 0 "register_operand" "")
6938         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6939                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6940   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6941     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6942 \f
6943 ;; Divide instructions
6944
6945 ;; The patterns that match these are at the end of this file.
6946
6947 (define_expand "divxf3"
6948   [(set (match_operand:XF 0 "register_operand" "")
6949         (div:XF (match_operand:XF 1 "register_operand" "")
6950                 (match_operand:XF 2 "register_operand" "")))]
6951   "TARGET_80387")
6952
6953 (define_expand "divdf3"
6954   [(set (match_operand:DF 0 "register_operand" "")
6955         (div:DF (match_operand:DF 1 "register_operand" "")
6956                 (match_operand:DF 2 "nonimmediate_operand" "")))]
6957    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6958     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6959
6960 (define_expand "divsf3"
6961   [(set (match_operand:SF 0 "register_operand" "")
6962         (div:SF (match_operand:SF 1 "register_operand" "")
6963                 (match_operand:SF 2 "nonimmediate_operand" "")))]
6964   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6965     || TARGET_SSE_MATH"
6966 {
6967   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
6968       && flag_finite_math_only && !flag_trapping_math
6969       && flag_unsafe_math_optimizations)
6970     {
6971       ix86_emit_swdivsf (operands[0], operands[1],
6972                          operands[2], SFmode);
6973       DONE;
6974     }
6975 })
6976 \f
6977 ;; Divmod instructions.
6978
6979 (define_expand "divmod<mode>4"
6980   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6981                    (div:SWIM248
6982                      (match_operand:SWIM248 1 "register_operand" "")
6983                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
6984               (set (match_operand:SWIM248 3 "register_operand" "")
6985                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6986               (clobber (reg:CC FLAGS_REG))])])
6987
6988 ;; Split with 8bit unsigned divide:
6989 ;;      if (dividend an divisor are in [0-255])
6990 ;;         use 8bit unsigned integer divide
6991 ;;       else
6992 ;;         use original integer divide
6993 (define_split
6994   [(set (match_operand:SWI48 0 "register_operand" "")
6995         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
6996                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
6997    (set (match_operand:SWI48 1 "register_operand" "")
6998         (mod:SWI48 (match_dup 2) (match_dup 3)))
6999    (clobber (reg:CC FLAGS_REG))]
7000   "TARGET_USE_8BIT_IDIV
7001    && TARGET_QIMODE_MATH
7002    && can_create_pseudo_p ()
7003    && !optimize_insn_for_size_p ()"
7004   [(const_int 0)]
7005   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7006
7007 (define_insn_and_split "divmod<mode>4_1"
7008   [(set (match_operand:SWI48 0 "register_operand" "=a")
7009         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7010                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7011    (set (match_operand:SWI48 1 "register_operand" "=&d")
7012         (mod:SWI48 (match_dup 2) (match_dup 3)))
7013    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7014    (clobber (reg:CC FLAGS_REG))]
7015   ""
7016   "#"
7017   "reload_completed"
7018   [(parallel [(set (match_dup 1)
7019                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7020               (clobber (reg:CC FLAGS_REG))])
7021    (parallel [(set (match_dup 0)
7022                    (div:SWI48 (match_dup 2) (match_dup 3)))
7023               (set (match_dup 1)
7024                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7025               (use (match_dup 1))
7026               (clobber (reg:CC FLAGS_REG))])]
7027 {
7028   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7029
7030   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7031     operands[4] = operands[2];
7032   else
7033     {
7034       /* Avoid use of cltd in favor of a mov+shift.  */
7035       emit_move_insn (operands[1], operands[2]);
7036       operands[4] = operands[1];
7037     }
7038 }
7039   [(set_attr "type" "multi")
7040    (set_attr "mode" "<MODE>")])
7041
7042 (define_insn_and_split "*divmod<mode>4"
7043   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7044         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7045                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7046    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7047         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7048    (clobber (reg:CC FLAGS_REG))]
7049   ""
7050   "#"
7051   "reload_completed"
7052   [(parallel [(set (match_dup 1)
7053                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7054               (clobber (reg:CC FLAGS_REG))])
7055    (parallel [(set (match_dup 0)
7056                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7057               (set (match_dup 1)
7058                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7059               (use (match_dup 1))
7060               (clobber (reg:CC FLAGS_REG))])]
7061 {
7062   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7063
7064   if (<MODE>mode != HImode
7065       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7066     operands[4] = operands[2];
7067   else
7068     {
7069       /* Avoid use of cltd in favor of a mov+shift.  */
7070       emit_move_insn (operands[1], operands[2]);
7071       operands[4] = operands[1];
7072     }
7073 }
7074   [(set_attr "type" "multi")
7075    (set_attr "mode" "<MODE>")])
7076
7077 (define_insn "*divmod<mode>4_noext"
7078   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7079         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7080                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7081    (set (match_operand:SWIM248 1 "register_operand" "=d")
7082         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7083    (use (match_operand:SWIM248 4 "register_operand" "1"))
7084    (clobber (reg:CC FLAGS_REG))]
7085   ""
7086   "idiv{<imodesuffix>}\t%3"
7087   [(set_attr "type" "idiv")
7088    (set_attr "mode" "<MODE>")])
7089
7090 (define_expand "divmodqi4"
7091   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7092                    (div:QI
7093                      (match_operand:QI 1 "register_operand" "")
7094                      (match_operand:QI 2 "nonimmediate_operand" "")))
7095               (set (match_operand:QI 3 "register_operand" "")
7096                    (mod:QI (match_dup 1) (match_dup 2)))
7097               (clobber (reg:CC FLAGS_REG))])]
7098   "TARGET_QIMODE_MATH"
7099 {
7100   rtx div, mod, insn;
7101   rtx tmp0, tmp1;
7102   
7103   tmp0 = gen_reg_rtx (HImode);
7104   tmp1 = gen_reg_rtx (HImode);
7105
7106   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7107      in AX.  */
7108   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7109   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7110
7111   /* Extract remainder from AH.  */
7112   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7113   insn = emit_move_insn (operands[3], tmp1);
7114
7115   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7116   set_unique_reg_note (insn, REG_EQUAL, mod);
7117
7118   /* Extract quotient from AL.  */
7119   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7120
7121   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7122   set_unique_reg_note (insn, REG_EQUAL, div);
7123
7124   DONE;
7125 })
7126
7127 ;; Divide AX by r/m8, with result stored in
7128 ;; AL <- Quotient
7129 ;; AH <- Remainder
7130 ;; Change div/mod to HImode and extend the second argument to HImode
7131 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7132 ;; combine may fail.
7133 (define_insn "divmodhiqi3"
7134   [(set (match_operand:HI 0 "register_operand" "=a")
7135         (ior:HI
7136           (ashift:HI
7137             (zero_extend:HI
7138               (truncate:QI
7139                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7140                         (sign_extend:HI
7141                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7142             (const_int 8))
7143           (zero_extend:HI
7144             (truncate:QI
7145               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7146    (clobber (reg:CC FLAGS_REG))]
7147   "TARGET_QIMODE_MATH"
7148   "idiv{b}\t%2"
7149   [(set_attr "type" "idiv")
7150    (set_attr "mode" "QI")])
7151
7152 (define_expand "udivmod<mode>4"
7153   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7154                    (udiv:SWIM248
7155                      (match_operand:SWIM248 1 "register_operand" "")
7156                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7157               (set (match_operand:SWIM248 3 "register_operand" "")
7158                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7159               (clobber (reg:CC FLAGS_REG))])])
7160
7161 ;; Split with 8bit unsigned divide:
7162 ;;      if (dividend an divisor are in [0-255])
7163 ;;         use 8bit unsigned integer divide
7164 ;;       else
7165 ;;         use original integer divide
7166 (define_split
7167   [(set (match_operand:SWI48 0 "register_operand" "")
7168         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7169                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7170    (set (match_operand:SWI48 1 "register_operand" "")
7171         (umod:SWI48 (match_dup 2) (match_dup 3)))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "TARGET_USE_8BIT_IDIV
7174    && TARGET_QIMODE_MATH
7175    && can_create_pseudo_p ()
7176    && !optimize_insn_for_size_p ()"
7177   [(const_int 0)]
7178   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7179
7180 (define_insn_and_split "udivmod<mode>4_1"
7181   [(set (match_operand:SWI48 0 "register_operand" "=a")
7182         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7183                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7184    (set (match_operand:SWI48 1 "register_operand" "=&d")
7185         (umod:SWI48 (match_dup 2) (match_dup 3)))
7186    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7187    (clobber (reg:CC FLAGS_REG))]
7188   ""
7189   "#"
7190   "reload_completed"
7191   [(set (match_dup 1) (const_int 0))
7192    (parallel [(set (match_dup 0)
7193                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7194               (set (match_dup 1)
7195                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7196               (use (match_dup 1))
7197               (clobber (reg:CC FLAGS_REG))])]
7198   ""
7199   [(set_attr "type" "multi")
7200    (set_attr "mode" "<MODE>")])
7201
7202 (define_insn_and_split "*udivmod<mode>4"
7203   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7204         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7205                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7206    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7207         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7208    (clobber (reg:CC FLAGS_REG))]
7209   ""
7210   "#"
7211   "reload_completed"
7212   [(set (match_dup 1) (const_int 0))
7213    (parallel [(set (match_dup 0)
7214                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7215               (set (match_dup 1)
7216                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7217               (use (match_dup 1))
7218               (clobber (reg:CC FLAGS_REG))])]
7219   ""
7220   [(set_attr "type" "multi")
7221    (set_attr "mode" "<MODE>")])
7222
7223 (define_insn "*udivmod<mode>4_noext"
7224   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7225         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7226                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7227    (set (match_operand:SWIM248 1 "register_operand" "=d")
7228         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7229    (use (match_operand:SWIM248 4 "register_operand" "1"))
7230    (clobber (reg:CC FLAGS_REG))]
7231   ""
7232   "div{<imodesuffix>}\t%3"
7233   [(set_attr "type" "idiv")
7234    (set_attr "mode" "<MODE>")])
7235
7236 (define_expand "udivmodqi4"
7237   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7238                    (udiv:QI
7239                      (match_operand:QI 1 "register_operand" "")
7240                      (match_operand:QI 2 "nonimmediate_operand" "")))
7241               (set (match_operand:QI 3 "register_operand" "")
7242                    (umod:QI (match_dup 1) (match_dup 2)))
7243               (clobber (reg:CC FLAGS_REG))])]
7244   "TARGET_QIMODE_MATH"
7245 {
7246   rtx div, mod, insn;
7247   rtx tmp0, tmp1;
7248   
7249   tmp0 = gen_reg_rtx (HImode);
7250   tmp1 = gen_reg_rtx (HImode);
7251
7252   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7253      in AX.  */
7254   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7255   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7256
7257   /* Extract remainder from AH.  */
7258   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7259   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7260   insn = emit_move_insn (operands[3], tmp1);
7261
7262   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7263   set_unique_reg_note (insn, REG_EQUAL, mod);
7264
7265   /* Extract quotient from AL.  */
7266   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7267
7268   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7269   set_unique_reg_note (insn, REG_EQUAL, div);
7270
7271   DONE;
7272 })
7273
7274 (define_insn "udivmodhiqi3"
7275   [(set (match_operand:HI 0 "register_operand" "=a")
7276         (ior:HI
7277           (ashift:HI
7278             (zero_extend:HI
7279               (truncate:QI
7280                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7281                         (zero_extend:HI
7282                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7283             (const_int 8))
7284           (zero_extend:HI
7285             (truncate:QI
7286               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7287    (clobber (reg:CC FLAGS_REG))]
7288   "TARGET_QIMODE_MATH"
7289   "div{b}\t%2"
7290   [(set_attr "type" "idiv")
7291    (set_attr "mode" "QI")])
7292
7293 ;; We cannot use div/idiv for double division, because it causes
7294 ;; "division by zero" on the overflow and that's not what we expect
7295 ;; from truncate.  Because true (non truncating) double division is
7296 ;; never generated, we can't create this insn anyway.
7297 ;
7298 ;(define_insn ""
7299 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7300 ;       (truncate:SI
7301 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7302 ;                  (zero_extend:DI
7303 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7304 ;   (set (match_operand:SI 3 "register_operand" "=d")
7305 ;       (truncate:SI
7306 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7307 ;   (clobber (reg:CC FLAGS_REG))]
7308 ;  ""
7309 ;  "div{l}\t{%2, %0|%0, %2}"
7310 ;  [(set_attr "type" "idiv")])
7311 \f
7312 ;;- Logical AND instructions
7313
7314 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7315 ;; Note that this excludes ah.
7316
7317 (define_expand "testsi_ccno_1"
7318   [(set (reg:CCNO FLAGS_REG)
7319         (compare:CCNO
7320           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7321                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7322           (const_int 0)))])
7323
7324 (define_expand "testqi_ccz_1"
7325   [(set (reg:CCZ FLAGS_REG)
7326         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7327                              (match_operand:QI 1 "nonmemory_operand" ""))
7328                  (const_int 0)))])
7329
7330 (define_expand "testdi_ccno_1"
7331   [(set (reg:CCNO FLAGS_REG)
7332         (compare:CCNO
7333           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7334                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7335           (const_int 0)))]
7336   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7337
7338 (define_insn "*testdi_1"
7339   [(set (reg FLAGS_REG)
7340         (compare
7341          (and:DI
7342           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7343           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7344          (const_int 0)))]
7345   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7346    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7347   "@
7348    test{l}\t{%k1, %k0|%k0, %k1}
7349    test{l}\t{%k1, %k0|%k0, %k1}
7350    test{q}\t{%1, %0|%0, %1}
7351    test{q}\t{%1, %0|%0, %1}
7352    test{q}\t{%1, %0|%0, %1}"
7353   [(set_attr "type" "test")
7354    (set_attr "modrm" "0,1,0,1,1")
7355    (set_attr "mode" "SI,SI,DI,DI,DI")])
7356
7357 (define_insn "*testqi_1_maybe_si"
7358   [(set (reg FLAGS_REG)
7359         (compare
7360           (and:QI
7361             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7362             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7363           (const_int 0)))]
7364    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7365     && ix86_match_ccmode (insn,
7366                          CONST_INT_P (operands[1])
7367                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7368 {
7369   if (which_alternative == 3)
7370     {
7371       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7372         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7373       return "test{l}\t{%1, %k0|%k0, %1}";
7374     }
7375   return "test{b}\t{%1, %0|%0, %1}";
7376 }
7377   [(set_attr "type" "test")
7378    (set_attr "modrm" "0,1,1,1")
7379    (set_attr "mode" "QI,QI,QI,SI")
7380    (set_attr "pent_pair" "uv,np,uv,np")])
7381
7382 (define_insn "*test<mode>_1"
7383   [(set (reg FLAGS_REG)
7384         (compare
7385          (and:SWI124
7386           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7387           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7388          (const_int 0)))]
7389   "ix86_match_ccmode (insn, CCNOmode)
7390    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7391   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7392   [(set_attr "type" "test")
7393    (set_attr "modrm" "0,1,1")
7394    (set_attr "mode" "<MODE>")
7395    (set_attr "pent_pair" "uv,np,uv")])
7396
7397 (define_expand "testqi_ext_ccno_0"
7398   [(set (reg:CCNO FLAGS_REG)
7399         (compare:CCNO
7400           (and:SI
7401             (zero_extract:SI
7402               (match_operand 0 "ext_register_operand" "")
7403               (const_int 8)
7404               (const_int 8))
7405             (match_operand 1 "const_int_operand" ""))
7406           (const_int 0)))])
7407
7408 (define_insn "*testqi_ext_0"
7409   [(set (reg FLAGS_REG)
7410         (compare
7411           (and:SI
7412             (zero_extract:SI
7413               (match_operand 0 "ext_register_operand" "Q")
7414               (const_int 8)
7415               (const_int 8))
7416             (match_operand 1 "const_int_operand" "n"))
7417           (const_int 0)))]
7418   "ix86_match_ccmode (insn, CCNOmode)"
7419   "test{b}\t{%1, %h0|%h0, %1}"
7420   [(set_attr "type" "test")
7421    (set_attr "mode" "QI")
7422    (set_attr "length_immediate" "1")
7423    (set_attr "modrm" "1")
7424    (set_attr "pent_pair" "np")])
7425
7426 (define_insn "*testqi_ext_1_rex64"
7427   [(set (reg FLAGS_REG)
7428         (compare
7429           (and:SI
7430             (zero_extract:SI
7431               (match_operand 0 "ext_register_operand" "Q")
7432               (const_int 8)
7433               (const_int 8))
7434             (zero_extend:SI
7435               (match_operand:QI 1 "register_operand" "Q")))
7436           (const_int 0)))]
7437   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7438   "test{b}\t{%1, %h0|%h0, %1}"
7439   [(set_attr "type" "test")
7440    (set_attr "mode" "QI")])
7441
7442 (define_insn "*testqi_ext_1"
7443   [(set (reg FLAGS_REG)
7444         (compare
7445           (and:SI
7446             (zero_extract:SI
7447               (match_operand 0 "ext_register_operand" "Q")
7448               (const_int 8)
7449               (const_int 8))
7450             (zero_extend:SI
7451               (match_operand:QI 1 "general_operand" "Qm")))
7452           (const_int 0)))]
7453   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7454   "test{b}\t{%1, %h0|%h0, %1}"
7455   [(set_attr "type" "test")
7456    (set_attr "mode" "QI")])
7457
7458 (define_insn "*testqi_ext_2"
7459   [(set (reg FLAGS_REG)
7460         (compare
7461           (and:SI
7462             (zero_extract:SI
7463               (match_operand 0 "ext_register_operand" "Q")
7464               (const_int 8)
7465               (const_int 8))
7466             (zero_extract:SI
7467               (match_operand 1 "ext_register_operand" "Q")
7468               (const_int 8)
7469               (const_int 8)))
7470           (const_int 0)))]
7471   "ix86_match_ccmode (insn, CCNOmode)"
7472   "test{b}\t{%h1, %h0|%h0, %h1}"
7473   [(set_attr "type" "test")
7474    (set_attr "mode" "QI")])
7475
7476 (define_insn "*testqi_ext_3_rex64"
7477   [(set (reg FLAGS_REG)
7478         (compare (zero_extract:DI
7479                    (match_operand 0 "nonimmediate_operand" "rm")
7480                    (match_operand:DI 1 "const_int_operand" "")
7481                    (match_operand:DI 2 "const_int_operand" ""))
7482                  (const_int 0)))]
7483   "TARGET_64BIT
7484    && ix86_match_ccmode (insn, CCNOmode)
7485    && INTVAL (operands[1]) > 0
7486    && INTVAL (operands[2]) >= 0
7487    /* Ensure that resulting mask is zero or sign extended operand.  */
7488    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7489        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7490            && INTVAL (operands[1]) > 32))
7491    && (GET_MODE (operands[0]) == SImode
7492        || GET_MODE (operands[0]) == DImode
7493        || GET_MODE (operands[0]) == HImode
7494        || GET_MODE (operands[0]) == QImode)"
7495   "#")
7496
7497 ;; Combine likes to form bit extractions for some tests.  Humor it.
7498 (define_insn "*testqi_ext_3"
7499   [(set (reg FLAGS_REG)
7500         (compare (zero_extract:SI
7501                    (match_operand 0 "nonimmediate_operand" "rm")
7502                    (match_operand:SI 1 "const_int_operand" "")
7503                    (match_operand:SI 2 "const_int_operand" ""))
7504                  (const_int 0)))]
7505   "ix86_match_ccmode (insn, CCNOmode)
7506    && INTVAL (operands[1]) > 0
7507    && INTVAL (operands[2]) >= 0
7508    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7509    && (GET_MODE (operands[0]) == SImode
7510        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7511        || GET_MODE (operands[0]) == HImode
7512        || GET_MODE (operands[0]) == QImode)"
7513   "#")
7514
7515 (define_split
7516   [(set (match_operand 0 "flags_reg_operand" "")
7517         (match_operator 1 "compare_operator"
7518           [(zero_extract
7519              (match_operand 2 "nonimmediate_operand" "")
7520              (match_operand 3 "const_int_operand" "")
7521              (match_operand 4 "const_int_operand" ""))
7522            (const_int 0)]))]
7523   "ix86_match_ccmode (insn, CCNOmode)"
7524   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7525 {
7526   rtx val = operands[2];
7527   HOST_WIDE_INT len = INTVAL (operands[3]);
7528   HOST_WIDE_INT pos = INTVAL (operands[4]);
7529   HOST_WIDE_INT mask;
7530   enum machine_mode mode, submode;
7531
7532   mode = GET_MODE (val);
7533   if (MEM_P (val))
7534     {
7535       /* ??? Combine likes to put non-volatile mem extractions in QImode
7536          no matter the size of the test.  So find a mode that works.  */
7537       if (! MEM_VOLATILE_P (val))
7538         {
7539           mode = smallest_mode_for_size (pos + len, MODE_INT);
7540           val = adjust_address (val, mode, 0);
7541         }
7542     }
7543   else if (GET_CODE (val) == SUBREG
7544            && (submode = GET_MODE (SUBREG_REG (val)),
7545                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7546            && pos + len <= GET_MODE_BITSIZE (submode)
7547            && GET_MODE_CLASS (submode) == MODE_INT)
7548     {
7549       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7550       mode = submode;
7551       val = SUBREG_REG (val);
7552     }
7553   else if (mode == HImode && pos + len <= 8)
7554     {
7555       /* Small HImode tests can be converted to QImode.  */
7556       mode = QImode;
7557       val = gen_lowpart (QImode, val);
7558     }
7559
7560   if (len == HOST_BITS_PER_WIDE_INT)
7561     mask = -1;
7562   else
7563     mask = ((HOST_WIDE_INT)1 << len) - 1;
7564   mask <<= pos;
7565
7566   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7567 })
7568
7569 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7570 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7571 ;; this is relatively important trick.
7572 ;; Do the conversion only post-reload to avoid limiting of the register class
7573 ;; to QI regs.
7574 (define_split
7575   [(set (match_operand 0 "flags_reg_operand" "")
7576         (match_operator 1 "compare_operator"
7577           [(and (match_operand 2 "register_operand" "")
7578                 (match_operand 3 "const_int_operand" ""))
7579            (const_int 0)]))]
7580    "reload_completed
7581     && QI_REG_P (operands[2])
7582     && GET_MODE (operands[2]) != QImode
7583     && ((ix86_match_ccmode (insn, CCZmode)
7584          && !(INTVAL (operands[3]) & ~(255 << 8)))
7585         || (ix86_match_ccmode (insn, CCNOmode)
7586             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7587   [(set (match_dup 0)
7588         (match_op_dup 1
7589           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7590                    (match_dup 3))
7591            (const_int 0)]))]
7592   "operands[2] = gen_lowpart (SImode, operands[2]);
7593    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7594
7595 (define_split
7596   [(set (match_operand 0 "flags_reg_operand" "")
7597         (match_operator 1 "compare_operator"
7598           [(and (match_operand 2 "nonimmediate_operand" "")
7599                 (match_operand 3 "const_int_operand" ""))
7600            (const_int 0)]))]
7601    "reload_completed
7602     && GET_MODE (operands[2]) != QImode
7603     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7604     && ((ix86_match_ccmode (insn, CCZmode)
7605          && !(INTVAL (operands[3]) & ~255))
7606         || (ix86_match_ccmode (insn, CCNOmode)
7607             && !(INTVAL (operands[3]) & ~127)))"
7608   [(set (match_dup 0)
7609         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7610                          (const_int 0)]))]
7611   "operands[2] = gen_lowpart (QImode, operands[2]);
7612    operands[3] = gen_lowpart (QImode, operands[3]);")
7613
7614 ;; %%% This used to optimize known byte-wide and operations to memory,
7615 ;; and sometimes to QImode registers.  If this is considered useful,
7616 ;; it should be done with splitters.
7617
7618 (define_expand "and<mode>3"
7619   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7620         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7621                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7622   ""
7623   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7624
7625 (define_insn "*anddi_1"
7626   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7627         (and:DI
7628          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7629          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7630    (clobber (reg:CC FLAGS_REG))]
7631   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7632 {
7633   switch (get_attr_type (insn))
7634     {
7635     case TYPE_IMOVX:
7636       {
7637         enum machine_mode mode;
7638
7639         gcc_assert (CONST_INT_P (operands[2]));
7640         if (INTVAL (operands[2]) == 0xff)
7641           mode = QImode;
7642         else
7643           {
7644             gcc_assert (INTVAL (operands[2]) == 0xffff);
7645             mode = HImode;
7646           }
7647
7648         operands[1] = gen_lowpart (mode, operands[1]);
7649         if (mode == QImode)
7650           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7651         else
7652           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7653       }
7654
7655     default:
7656       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7657       if (get_attr_mode (insn) == MODE_SI)
7658         return "and{l}\t{%k2, %k0|%k0, %k2}";
7659       else
7660         return "and{q}\t{%2, %0|%0, %2}";
7661     }
7662 }
7663   [(set_attr "type" "alu,alu,alu,imovx")
7664    (set_attr "length_immediate" "*,*,*,0")
7665    (set (attr "prefix_rex")
7666      (if_then_else
7667        (and (eq_attr "type" "imovx")
7668             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7669                  (match_operand 1 "ext_QIreg_operand" "")))
7670        (const_string "1")
7671        (const_string "*")))
7672    (set_attr "mode" "SI,DI,DI,SI")])
7673
7674 (define_insn "*andsi_1"
7675   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7676         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7677                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7678    (clobber (reg:CC FLAGS_REG))]
7679   "ix86_binary_operator_ok (AND, SImode, operands)"
7680 {
7681   switch (get_attr_type (insn))
7682     {
7683     case TYPE_IMOVX:
7684       {
7685         enum machine_mode mode;
7686
7687         gcc_assert (CONST_INT_P (operands[2]));
7688         if (INTVAL (operands[2]) == 0xff)
7689           mode = QImode;
7690         else
7691           {
7692             gcc_assert (INTVAL (operands[2]) == 0xffff);
7693             mode = HImode;
7694           }
7695
7696         operands[1] = gen_lowpart (mode, operands[1]);
7697         if (mode == QImode)
7698           return "movz{bl|x}\t{%1, %0|%0, %1}";
7699         else
7700           return "movz{wl|x}\t{%1, %0|%0, %1}";
7701       }
7702
7703     default:
7704       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705       return "and{l}\t{%2, %0|%0, %2}";
7706     }
7707 }
7708   [(set_attr "type" "alu,alu,imovx")
7709    (set (attr "prefix_rex")
7710      (if_then_else
7711        (and (eq_attr "type" "imovx")
7712             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7713                  (match_operand 1 "ext_QIreg_operand" "")))
7714        (const_string "1")
7715        (const_string "*")))
7716    (set_attr "length_immediate" "*,*,0")
7717    (set_attr "mode" "SI")])
7718
7719 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7720 (define_insn "*andsi_1_zext"
7721   [(set (match_operand:DI 0 "register_operand" "=r")
7722         (zero_extend:DI
7723           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7724                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7725    (clobber (reg:CC FLAGS_REG))]
7726   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7727   "and{l}\t{%2, %k0|%k0, %2}"
7728   [(set_attr "type" "alu")
7729    (set_attr "mode" "SI")])
7730
7731 (define_insn "*andhi_1"
7732   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7733         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7734                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7735    (clobber (reg:CC FLAGS_REG))]
7736   "ix86_binary_operator_ok (AND, HImode, operands)"
7737 {
7738   switch (get_attr_type (insn))
7739     {
7740     case TYPE_IMOVX:
7741       gcc_assert (CONST_INT_P (operands[2]));
7742       gcc_assert (INTVAL (operands[2]) == 0xff);
7743       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7744
7745     default:
7746       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7747
7748       return "and{w}\t{%2, %0|%0, %2}";
7749     }
7750 }
7751   [(set_attr "type" "alu,alu,imovx")
7752    (set_attr "length_immediate" "*,*,0")
7753    (set (attr "prefix_rex")
7754      (if_then_else
7755        (and (eq_attr "type" "imovx")
7756             (match_operand 1 "ext_QIreg_operand" ""))
7757        (const_string "1")
7758        (const_string "*")))
7759    (set_attr "mode" "HI,HI,SI")])
7760
7761 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7762 (define_insn "*andqi_1"
7763   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7764         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7765                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7766    (clobber (reg:CC FLAGS_REG))]
7767   "ix86_binary_operator_ok (AND, QImode, operands)"
7768   "@
7769    and{b}\t{%2, %0|%0, %2}
7770    and{b}\t{%2, %0|%0, %2}
7771    and{l}\t{%k2, %k0|%k0, %k2}"
7772   [(set_attr "type" "alu")
7773    (set_attr "mode" "QI,QI,SI")])
7774
7775 (define_insn "*andqi_1_slp"
7776   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7777         (and:QI (match_dup 0)
7778                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7779    (clobber (reg:CC FLAGS_REG))]
7780   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7781    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7782   "and{b}\t{%1, %0|%0, %1}"
7783   [(set_attr "type" "alu1")
7784    (set_attr "mode" "QI")])
7785
7786 (define_split
7787   [(set (match_operand 0 "register_operand" "")
7788         (and (match_dup 0)
7789              (const_int -65536)))
7790    (clobber (reg:CC FLAGS_REG))]
7791   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7792     || optimize_function_for_size_p (cfun)"
7793   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7794   "operands[1] = gen_lowpart (HImode, operands[0]);")
7795
7796 (define_split
7797   [(set (match_operand 0 "ext_register_operand" "")
7798         (and (match_dup 0)
7799              (const_int -256)))
7800    (clobber (reg:CC FLAGS_REG))]
7801   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7802    && reload_completed"
7803   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7804   "operands[1] = gen_lowpart (QImode, operands[0]);")
7805
7806 (define_split
7807   [(set (match_operand 0 "ext_register_operand" "")
7808         (and (match_dup 0)
7809              (const_int -65281)))
7810    (clobber (reg:CC FLAGS_REG))]
7811   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7812    && reload_completed"
7813   [(parallel [(set (zero_extract:SI (match_dup 0)
7814                                     (const_int 8)
7815                                     (const_int 8))
7816                    (xor:SI
7817                      (zero_extract:SI (match_dup 0)
7818                                       (const_int 8)
7819                                       (const_int 8))
7820                      (zero_extract:SI (match_dup 0)
7821                                       (const_int 8)
7822                                       (const_int 8))))
7823               (clobber (reg:CC FLAGS_REG))])]
7824   "operands[0] = gen_lowpart (SImode, operands[0]);")
7825
7826 (define_insn "*anddi_2"
7827   [(set (reg FLAGS_REG)
7828         (compare
7829          (and:DI
7830           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7831           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7832          (const_int 0)))
7833    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7834         (and:DI (match_dup 1) (match_dup 2)))]
7835   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7836    && ix86_binary_operator_ok (AND, DImode, operands)"
7837   "@
7838    and{l}\t{%k2, %k0|%k0, %k2}
7839    and{q}\t{%2, %0|%0, %2}
7840    and{q}\t{%2, %0|%0, %2}"
7841   [(set_attr "type" "alu")
7842    (set_attr "mode" "SI,DI,DI")])
7843
7844 (define_insn "*andqi_2_maybe_si"
7845   [(set (reg FLAGS_REG)
7846         (compare (and:QI
7847                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7848                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7849                  (const_int 0)))
7850    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7851         (and:QI (match_dup 1) (match_dup 2)))]
7852   "ix86_binary_operator_ok (AND, QImode, operands)
7853    && ix86_match_ccmode (insn,
7854                          CONST_INT_P (operands[2])
7855                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7856 {
7857   if (which_alternative == 2)
7858     {
7859       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7860         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7861       return "and{l}\t{%2, %k0|%k0, %2}";
7862     }
7863   return "and{b}\t{%2, %0|%0, %2}";
7864 }
7865   [(set_attr "type" "alu")
7866    (set_attr "mode" "QI,QI,SI")])
7867
7868 (define_insn "*and<mode>_2"
7869   [(set (reg FLAGS_REG)
7870         (compare (and:SWI124
7871                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7872                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7873                  (const_int 0)))
7874    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7875         (and:SWI124 (match_dup 1) (match_dup 2)))]
7876   "ix86_match_ccmode (insn, CCNOmode)
7877    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7878   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7879   [(set_attr "type" "alu")
7880    (set_attr "mode" "<MODE>")])
7881
7882 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7883 (define_insn "*andsi_2_zext"
7884   [(set (reg FLAGS_REG)
7885         (compare (and:SI
7886                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7887                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7888                  (const_int 0)))
7889    (set (match_operand:DI 0 "register_operand" "=r")
7890         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7891   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7892    && ix86_binary_operator_ok (AND, SImode, operands)"
7893   "and{l}\t{%2, %k0|%k0, %2}"
7894   [(set_attr "type" "alu")
7895    (set_attr "mode" "SI")])
7896
7897 (define_insn "*andqi_2_slp"
7898   [(set (reg FLAGS_REG)
7899         (compare (and:QI
7900                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7901                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7902                  (const_int 0)))
7903    (set (strict_low_part (match_dup 0))
7904         (and:QI (match_dup 0) (match_dup 1)))]
7905   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7906    && ix86_match_ccmode (insn, CCNOmode)
7907    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7908   "and{b}\t{%1, %0|%0, %1}"
7909   [(set_attr "type" "alu1")
7910    (set_attr "mode" "QI")])
7911
7912 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7913 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7914 ;; for a QImode operand, which of course failed.
7915 (define_insn "andqi_ext_0"
7916   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7917                          (const_int 8)
7918                          (const_int 8))
7919         (and:SI
7920           (zero_extract:SI
7921             (match_operand 1 "ext_register_operand" "0")
7922             (const_int 8)
7923             (const_int 8))
7924           (match_operand 2 "const_int_operand" "n")))
7925    (clobber (reg:CC FLAGS_REG))]
7926   ""
7927   "and{b}\t{%2, %h0|%h0, %2}"
7928   [(set_attr "type" "alu")
7929    (set_attr "length_immediate" "1")
7930    (set_attr "modrm" "1")
7931    (set_attr "mode" "QI")])
7932
7933 ;; Generated by peephole translating test to and.  This shows up
7934 ;; often in fp comparisons.
7935 (define_insn "*andqi_ext_0_cc"
7936   [(set (reg FLAGS_REG)
7937         (compare
7938           (and:SI
7939             (zero_extract:SI
7940               (match_operand 1 "ext_register_operand" "0")
7941               (const_int 8)
7942               (const_int 8))
7943             (match_operand 2 "const_int_operand" "n"))
7944           (const_int 0)))
7945    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7946                          (const_int 8)
7947                          (const_int 8))
7948         (and:SI
7949           (zero_extract:SI
7950             (match_dup 1)
7951             (const_int 8)
7952             (const_int 8))
7953           (match_dup 2)))]
7954   "ix86_match_ccmode (insn, CCNOmode)"
7955   "and{b}\t{%2, %h0|%h0, %2}"
7956   [(set_attr "type" "alu")
7957    (set_attr "length_immediate" "1")
7958    (set_attr "modrm" "1")
7959    (set_attr "mode" "QI")])
7960
7961 (define_insn "*andqi_ext_1_rex64"
7962   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7963                          (const_int 8)
7964                          (const_int 8))
7965         (and:SI
7966           (zero_extract:SI
7967             (match_operand 1 "ext_register_operand" "0")
7968             (const_int 8)
7969             (const_int 8))
7970           (zero_extend:SI
7971             (match_operand 2 "ext_register_operand" "Q"))))
7972    (clobber (reg:CC FLAGS_REG))]
7973   "TARGET_64BIT"
7974   "and{b}\t{%2, %h0|%h0, %2}"
7975   [(set_attr "type" "alu")
7976    (set_attr "length_immediate" "0")
7977    (set_attr "mode" "QI")])
7978
7979 (define_insn "*andqi_ext_1"
7980   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7981                          (const_int 8)
7982                          (const_int 8))
7983         (and:SI
7984           (zero_extract:SI
7985             (match_operand 1 "ext_register_operand" "0")
7986             (const_int 8)
7987             (const_int 8))
7988           (zero_extend:SI
7989             (match_operand:QI 2 "general_operand" "Qm"))))
7990    (clobber (reg:CC FLAGS_REG))]
7991   "!TARGET_64BIT"
7992   "and{b}\t{%2, %h0|%h0, %2}"
7993   [(set_attr "type" "alu")
7994    (set_attr "length_immediate" "0")
7995    (set_attr "mode" "QI")])
7996
7997 (define_insn "*andqi_ext_2"
7998   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7999                          (const_int 8)
8000                          (const_int 8))
8001         (and:SI
8002           (zero_extract:SI
8003             (match_operand 1 "ext_register_operand" "%0")
8004             (const_int 8)
8005             (const_int 8))
8006           (zero_extract:SI
8007             (match_operand 2 "ext_register_operand" "Q")
8008             (const_int 8)
8009             (const_int 8))))
8010    (clobber (reg:CC FLAGS_REG))]
8011   ""
8012   "and{b}\t{%h2, %h0|%h0, %h2}"
8013   [(set_attr "type" "alu")
8014    (set_attr "length_immediate" "0")
8015    (set_attr "mode" "QI")])
8016
8017 ;; Convert wide AND instructions with immediate operand to shorter QImode
8018 ;; equivalents when possible.
8019 ;; Don't do the splitting with memory operands, since it introduces risk
8020 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8021 ;; for size, but that can (should?) be handled by generic code instead.
8022 (define_split
8023   [(set (match_operand 0 "register_operand" "")
8024         (and (match_operand 1 "register_operand" "")
8025              (match_operand 2 "const_int_operand" "")))
8026    (clobber (reg:CC FLAGS_REG))]
8027    "reload_completed
8028     && QI_REG_P (operands[0])
8029     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8030     && !(~INTVAL (operands[2]) & ~(255 << 8))
8031     && GET_MODE (operands[0]) != QImode"
8032   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8033                    (and:SI (zero_extract:SI (match_dup 1)
8034                                             (const_int 8) (const_int 8))
8035                            (match_dup 2)))
8036               (clobber (reg:CC FLAGS_REG))])]
8037   "operands[0] = gen_lowpart (SImode, operands[0]);
8038    operands[1] = gen_lowpart (SImode, operands[1]);
8039    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8040
8041 ;; Since AND can be encoded with sign extended immediate, this is only
8042 ;; profitable when 7th bit is not set.
8043 (define_split
8044   [(set (match_operand 0 "register_operand" "")
8045         (and (match_operand 1 "general_operand" "")
8046              (match_operand 2 "const_int_operand" "")))
8047    (clobber (reg:CC FLAGS_REG))]
8048    "reload_completed
8049     && ANY_QI_REG_P (operands[0])
8050     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8051     && !(~INTVAL (operands[2]) & ~255)
8052     && !(INTVAL (operands[2]) & 128)
8053     && GET_MODE (operands[0]) != QImode"
8054   [(parallel [(set (strict_low_part (match_dup 0))
8055                    (and:QI (match_dup 1)
8056                            (match_dup 2)))
8057               (clobber (reg:CC FLAGS_REG))])]
8058   "operands[0] = gen_lowpart (QImode, operands[0]);
8059    operands[1] = gen_lowpart (QImode, operands[1]);
8060    operands[2] = gen_lowpart (QImode, operands[2]);")
8061 \f
8062 ;; Logical inclusive and exclusive OR instructions
8063
8064 ;; %%% This used to optimize known byte-wide and operations to memory.
8065 ;; If this is considered useful, it should be done with splitters.
8066
8067 (define_expand "<code><mode>3"
8068   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8069         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8070                      (match_operand:SWIM 2 "<general_operand>" "")))]
8071   ""
8072   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8073
8074 (define_insn "*<code><mode>_1"
8075   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8076         (any_or:SWI248
8077          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8078          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8079    (clobber (reg:CC FLAGS_REG))]
8080   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8081   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8082   [(set_attr "type" "alu")
8083    (set_attr "mode" "<MODE>")])
8084
8085 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8086 (define_insn "*<code>qi_1"
8087   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8088         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8089                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8090    (clobber (reg:CC FLAGS_REG))]
8091   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8092   "@
8093    <logic>{b}\t{%2, %0|%0, %2}
8094    <logic>{b}\t{%2, %0|%0, %2}
8095    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8096   [(set_attr "type" "alu")
8097    (set_attr "mode" "QI,QI,SI")])
8098
8099 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8100 (define_insn "*<code>si_1_zext"
8101   [(set (match_operand:DI 0 "register_operand" "=r")
8102         (zero_extend:DI
8103          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8104                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8105    (clobber (reg:CC FLAGS_REG))]
8106   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8107   "<logic>{l}\t{%2, %k0|%k0, %2}"
8108   [(set_attr "type" "alu")
8109    (set_attr "mode" "SI")])
8110
8111 (define_insn "*<code>si_1_zext_imm"
8112   [(set (match_operand:DI 0 "register_operand" "=r")
8113         (any_or:DI
8114          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8115          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8116    (clobber (reg:CC FLAGS_REG))]
8117   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8118   "<logic>{l}\t{%2, %k0|%k0, %2}"
8119   [(set_attr "type" "alu")
8120    (set_attr "mode" "SI")])
8121
8122 (define_insn "*<code>qi_1_slp"
8123   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8124         (any_or:QI (match_dup 0)
8125                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8126    (clobber (reg:CC FLAGS_REG))]
8127   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8128    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8129   "<logic>{b}\t{%1, %0|%0, %1}"
8130   [(set_attr "type" "alu1")
8131    (set_attr "mode" "QI")])
8132
8133 (define_insn "*<code><mode>_2"
8134   [(set (reg FLAGS_REG)
8135         (compare (any_or:SWI
8136                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8137                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8138                  (const_int 0)))
8139    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8140         (any_or:SWI (match_dup 1) (match_dup 2)))]
8141   "ix86_match_ccmode (insn, CCNOmode)
8142    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8143   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8144   [(set_attr "type" "alu")
8145    (set_attr "mode" "<MODE>")])
8146
8147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8148 ;; ??? Special case for immediate operand is missing - it is tricky.
8149 (define_insn "*<code>si_2_zext"
8150   [(set (reg FLAGS_REG)
8151         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8152                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8153                  (const_int 0)))
8154    (set (match_operand:DI 0 "register_operand" "=r")
8155         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8156   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8157    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8158   "<logic>{l}\t{%2, %k0|%k0, %2}"
8159   [(set_attr "type" "alu")
8160    (set_attr "mode" "SI")])
8161
8162 (define_insn "*<code>si_2_zext_imm"
8163   [(set (reg FLAGS_REG)
8164         (compare (any_or:SI
8165                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8166                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8167                  (const_int 0)))
8168    (set (match_operand:DI 0 "register_operand" "=r")
8169         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8170   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8171    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8172   "<logic>{l}\t{%2, %k0|%k0, %2}"
8173   [(set_attr "type" "alu")
8174    (set_attr "mode" "SI")])
8175
8176 (define_insn "*<code>qi_2_slp"
8177   [(set (reg FLAGS_REG)
8178         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8179                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8180                  (const_int 0)))
8181    (set (strict_low_part (match_dup 0))
8182         (any_or:QI (match_dup 0) (match_dup 1)))]
8183   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8184    && ix86_match_ccmode (insn, CCNOmode)
8185    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8186   "<logic>{b}\t{%1, %0|%0, %1}"
8187   [(set_attr "type" "alu1")
8188    (set_attr "mode" "QI")])
8189
8190 (define_insn "*<code><mode>_3"
8191   [(set (reg FLAGS_REG)
8192         (compare (any_or:SWI
8193                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8194                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8195                  (const_int 0)))
8196    (clobber (match_scratch:SWI 0 "=<r>"))]
8197   "ix86_match_ccmode (insn, CCNOmode)
8198    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8199   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8200   [(set_attr "type" "alu")
8201    (set_attr "mode" "<MODE>")])
8202
8203 (define_insn "*<code>qi_ext_0"
8204   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8205                          (const_int 8)
8206                          (const_int 8))
8207         (any_or:SI
8208           (zero_extract:SI
8209             (match_operand 1 "ext_register_operand" "0")
8210             (const_int 8)
8211             (const_int 8))
8212           (match_operand 2 "const_int_operand" "n")))
8213    (clobber (reg:CC FLAGS_REG))]
8214   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8215   "<logic>{b}\t{%2, %h0|%h0, %2}"
8216   [(set_attr "type" "alu")
8217    (set_attr "length_immediate" "1")
8218    (set_attr "modrm" "1")
8219    (set_attr "mode" "QI")])
8220
8221 (define_insn "*<code>qi_ext_1_rex64"
8222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8223                          (const_int 8)
8224                          (const_int 8))
8225         (any_or:SI
8226           (zero_extract:SI
8227             (match_operand 1 "ext_register_operand" "0")
8228             (const_int 8)
8229             (const_int 8))
8230           (zero_extend:SI
8231             (match_operand 2 "ext_register_operand" "Q"))))
8232    (clobber (reg:CC FLAGS_REG))]
8233   "TARGET_64BIT
8234    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8235   "<logic>{b}\t{%2, %h0|%h0, %2}"
8236   [(set_attr "type" "alu")
8237    (set_attr "length_immediate" "0")
8238    (set_attr "mode" "QI")])
8239
8240 (define_insn "*<code>qi_ext_1"
8241   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8242                          (const_int 8)
8243                          (const_int 8))
8244         (any_or:SI
8245           (zero_extract:SI
8246             (match_operand 1 "ext_register_operand" "0")
8247             (const_int 8)
8248             (const_int 8))
8249           (zero_extend:SI
8250             (match_operand:QI 2 "general_operand" "Qm"))))
8251    (clobber (reg:CC FLAGS_REG))]
8252   "!TARGET_64BIT
8253    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8254   "<logic>{b}\t{%2, %h0|%h0, %2}"
8255   [(set_attr "type" "alu")
8256    (set_attr "length_immediate" "0")
8257    (set_attr "mode" "QI")])
8258
8259 (define_insn "*<code>qi_ext_2"
8260   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8261                          (const_int 8)
8262                          (const_int 8))
8263         (any_or:SI
8264           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8265                            (const_int 8)
8266                            (const_int 8))
8267           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8268                            (const_int 8)
8269                            (const_int 8))))
8270    (clobber (reg:CC FLAGS_REG))]
8271   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8272   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8273   [(set_attr "type" "alu")
8274    (set_attr "length_immediate" "0")
8275    (set_attr "mode" "QI")])
8276
8277 (define_split
8278   [(set (match_operand 0 "register_operand" "")
8279         (any_or (match_operand 1 "register_operand" "")
8280                 (match_operand 2 "const_int_operand" "")))
8281    (clobber (reg:CC FLAGS_REG))]
8282    "reload_completed
8283     && QI_REG_P (operands[0])
8284     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8285     && !(INTVAL (operands[2]) & ~(255 << 8))
8286     && GET_MODE (operands[0]) != QImode"
8287   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8288                    (any_or:SI (zero_extract:SI (match_dup 1)
8289                                                (const_int 8) (const_int 8))
8290                               (match_dup 2)))
8291               (clobber (reg:CC FLAGS_REG))])]
8292   "operands[0] = gen_lowpart (SImode, operands[0]);
8293    operands[1] = gen_lowpart (SImode, operands[1]);
8294    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8295
8296 ;; Since OR can be encoded with sign extended immediate, this is only
8297 ;; profitable when 7th bit is set.
8298 (define_split
8299   [(set (match_operand 0 "register_operand" "")
8300         (any_or (match_operand 1 "general_operand" "")
8301                 (match_operand 2 "const_int_operand" "")))
8302    (clobber (reg:CC FLAGS_REG))]
8303    "reload_completed
8304     && ANY_QI_REG_P (operands[0])
8305     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8306     && !(INTVAL (operands[2]) & ~255)
8307     && (INTVAL (operands[2]) & 128)
8308     && GET_MODE (operands[0]) != QImode"
8309   [(parallel [(set (strict_low_part (match_dup 0))
8310                    (any_or:QI (match_dup 1)
8311                               (match_dup 2)))
8312               (clobber (reg:CC FLAGS_REG))])]
8313   "operands[0] = gen_lowpart (QImode, operands[0]);
8314    operands[1] = gen_lowpart (QImode, operands[1]);
8315    operands[2] = gen_lowpart (QImode, operands[2]);")
8316
8317 (define_expand "xorqi_cc_ext_1"
8318   [(parallel [
8319      (set (reg:CCNO FLAGS_REG)
8320           (compare:CCNO
8321             (xor:SI
8322               (zero_extract:SI
8323                 (match_operand 1 "ext_register_operand" "")
8324                 (const_int 8)
8325                 (const_int 8))
8326               (match_operand:QI 2 "general_operand" ""))
8327             (const_int 0)))
8328      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8329                            (const_int 8)
8330                            (const_int 8))
8331           (xor:SI
8332             (zero_extract:SI
8333              (match_dup 1)
8334              (const_int 8)
8335              (const_int 8))
8336             (match_dup 2)))])])
8337
8338 (define_insn "*xorqi_cc_ext_1_rex64"
8339   [(set (reg FLAGS_REG)
8340         (compare
8341           (xor:SI
8342             (zero_extract:SI
8343               (match_operand 1 "ext_register_operand" "0")
8344               (const_int 8)
8345               (const_int 8))
8346             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8347           (const_int 0)))
8348    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8349                          (const_int 8)
8350                          (const_int 8))
8351         (xor:SI
8352           (zero_extract:SI
8353            (match_dup 1)
8354            (const_int 8)
8355            (const_int 8))
8356           (match_dup 2)))]
8357   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8358   "xor{b}\t{%2, %h0|%h0, %2}"
8359   [(set_attr "type" "alu")
8360    (set_attr "modrm" "1")
8361    (set_attr "mode" "QI")])
8362
8363 (define_insn "*xorqi_cc_ext_1"
8364   [(set (reg FLAGS_REG)
8365         (compare
8366           (xor:SI
8367             (zero_extract:SI
8368               (match_operand 1 "ext_register_operand" "0")
8369               (const_int 8)
8370               (const_int 8))
8371             (match_operand:QI 2 "general_operand" "qmn"))
8372           (const_int 0)))
8373    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8374                          (const_int 8)
8375                          (const_int 8))
8376         (xor:SI
8377           (zero_extract:SI
8378            (match_dup 1)
8379            (const_int 8)
8380            (const_int 8))
8381           (match_dup 2)))]
8382   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8383   "xor{b}\t{%2, %h0|%h0, %2}"
8384   [(set_attr "type" "alu")
8385    (set_attr "modrm" "1")
8386    (set_attr "mode" "QI")])
8387 \f
8388 ;; Negation instructions
8389
8390 (define_expand "neg<mode>2"
8391   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8392         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8393   ""
8394   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8395
8396 (define_insn_and_split "*neg<dwi>2_doubleword"
8397   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8398         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8399    (clobber (reg:CC FLAGS_REG))]
8400   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8401   "#"
8402   "reload_completed"
8403   [(parallel
8404     [(set (reg:CCZ FLAGS_REG)
8405           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8406      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8407    (parallel
8408     [(set (match_dup 2)
8409           (plus:DWIH (match_dup 3)
8410                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8411                                 (const_int 0))))
8412      (clobber (reg:CC FLAGS_REG))])
8413    (parallel
8414     [(set (match_dup 2)
8415           (neg:DWIH (match_dup 2)))
8416      (clobber (reg:CC FLAGS_REG))])]
8417   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8418
8419 (define_insn "*neg<mode>2_1"
8420   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8421         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8422    (clobber (reg:CC FLAGS_REG))]
8423   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8424   "neg{<imodesuffix>}\t%0"
8425   [(set_attr "type" "negnot")
8426    (set_attr "mode" "<MODE>")])
8427
8428 ;; Combine is quite creative about this pattern.
8429 (define_insn "*negsi2_1_zext"
8430   [(set (match_operand:DI 0 "register_operand" "=r")
8431         (lshiftrt:DI
8432           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8433                              (const_int 32)))
8434         (const_int 32)))
8435    (clobber (reg:CC FLAGS_REG))]
8436   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8437   "neg{l}\t%k0"
8438   [(set_attr "type" "negnot")
8439    (set_attr "mode" "SI")])
8440
8441 ;; The problem with neg is that it does not perform (compare x 0),
8442 ;; it really performs (compare 0 x), which leaves us with the zero
8443 ;; flag being the only useful item.
8444
8445 (define_insn "*neg<mode>2_cmpz"
8446   [(set (reg:CCZ FLAGS_REG)
8447         (compare:CCZ
8448           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8449                    (const_int 0)))
8450    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8451         (neg:SWI (match_dup 1)))]
8452   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8453   "neg{<imodesuffix>}\t%0"
8454   [(set_attr "type" "negnot")
8455    (set_attr "mode" "<MODE>")])
8456
8457 (define_insn "*negsi2_cmpz_zext"
8458   [(set (reg:CCZ FLAGS_REG)
8459         (compare:CCZ
8460           (lshiftrt:DI
8461             (neg:DI (ashift:DI
8462                       (match_operand:DI 1 "register_operand" "0")
8463                       (const_int 32)))
8464             (const_int 32))
8465           (const_int 0)))
8466    (set (match_operand:DI 0 "register_operand" "=r")
8467         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8468                                         (const_int 32)))
8469                      (const_int 32)))]
8470   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8471   "neg{l}\t%k0"
8472   [(set_attr "type" "negnot")
8473    (set_attr "mode" "SI")])
8474
8475 ;; Changing of sign for FP values is doable using integer unit too.
8476
8477 (define_expand "<code><mode>2"
8478   [(set (match_operand:X87MODEF 0 "register_operand" "")
8479         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8480   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8481   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8482
8483 (define_insn "*absneg<mode>2_mixed"
8484   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8485         (match_operator:MODEF 3 "absneg_operator"
8486           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8487    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8488    (clobber (reg:CC FLAGS_REG))]
8489   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8490   "#")
8491
8492 (define_insn "*absneg<mode>2_sse"
8493   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8494         (match_operator:MODEF 3 "absneg_operator"
8495           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8496    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8499   "#")
8500
8501 (define_insn "*absneg<mode>2_i387"
8502   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8503         (match_operator:X87MODEF 3 "absneg_operator"
8504           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8505    (use (match_operand 2 "" ""))
8506    (clobber (reg:CC FLAGS_REG))]
8507   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8508   "#")
8509
8510 (define_expand "<code>tf2"
8511   [(set (match_operand:TF 0 "register_operand" "")
8512         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8513   "TARGET_SSE2"
8514   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8515
8516 (define_insn "*absnegtf2_sse"
8517   [(set (match_operand:TF 0 "register_operand" "=x,x")
8518         (match_operator:TF 3 "absneg_operator"
8519           [(match_operand:TF 1 "register_operand" "0,x")]))
8520    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8521    (clobber (reg:CC FLAGS_REG))]
8522   "TARGET_SSE2"
8523   "#")
8524
8525 ;; Splitters for fp abs and neg.
8526
8527 (define_split
8528   [(set (match_operand 0 "fp_register_operand" "")
8529         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8530    (use (match_operand 2 "" ""))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "reload_completed"
8533   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8534
8535 (define_split
8536   [(set (match_operand 0 "register_operand" "")
8537         (match_operator 3 "absneg_operator"
8538           [(match_operand 1 "register_operand" "")]))
8539    (use (match_operand 2 "nonimmediate_operand" ""))
8540    (clobber (reg:CC FLAGS_REG))]
8541   "reload_completed && SSE_REG_P (operands[0])"
8542   [(set (match_dup 0) (match_dup 3))]
8543 {
8544   enum machine_mode mode = GET_MODE (operands[0]);
8545   enum machine_mode vmode = GET_MODE (operands[2]);
8546   rtx tmp;
8547
8548   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8549   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8550   if (operands_match_p (operands[0], operands[2]))
8551     {
8552       tmp = operands[1];
8553       operands[1] = operands[2];
8554       operands[2] = tmp;
8555     }
8556   if (GET_CODE (operands[3]) == ABS)
8557     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8558   else
8559     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8560   operands[3] = tmp;
8561 })
8562
8563 (define_split
8564   [(set (match_operand:SF 0 "register_operand" "")
8565         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8566    (use (match_operand:V4SF 2 "" ""))
8567    (clobber (reg:CC FLAGS_REG))]
8568   "reload_completed"
8569   [(parallel [(set (match_dup 0) (match_dup 1))
8570               (clobber (reg:CC FLAGS_REG))])]
8571 {
8572   rtx tmp;
8573   operands[0] = gen_lowpart (SImode, operands[0]);
8574   if (GET_CODE (operands[1]) == ABS)
8575     {
8576       tmp = gen_int_mode (0x7fffffff, SImode);
8577       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8578     }
8579   else
8580     {
8581       tmp = gen_int_mode (0x80000000, SImode);
8582       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8583     }
8584   operands[1] = tmp;
8585 })
8586
8587 (define_split
8588   [(set (match_operand:DF 0 "register_operand" "")
8589         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8590    (use (match_operand 2 "" ""))
8591    (clobber (reg:CC FLAGS_REG))]
8592   "reload_completed"
8593   [(parallel [(set (match_dup 0) (match_dup 1))
8594               (clobber (reg:CC FLAGS_REG))])]
8595 {
8596   rtx tmp;
8597   if (TARGET_64BIT)
8598     {
8599       tmp = gen_lowpart (DImode, operands[0]);
8600       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8601       operands[0] = tmp;
8602
8603       if (GET_CODE (operands[1]) == ABS)
8604         tmp = const0_rtx;
8605       else
8606         tmp = gen_rtx_NOT (DImode, tmp);
8607     }
8608   else
8609     {
8610       operands[0] = gen_highpart (SImode, operands[0]);
8611       if (GET_CODE (operands[1]) == ABS)
8612         {
8613           tmp = gen_int_mode (0x7fffffff, SImode);
8614           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8615         }
8616       else
8617         {
8618           tmp = gen_int_mode (0x80000000, SImode);
8619           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8620         }
8621     }
8622   operands[1] = tmp;
8623 })
8624
8625 (define_split
8626   [(set (match_operand:XF 0 "register_operand" "")
8627         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8628    (use (match_operand 2 "" ""))
8629    (clobber (reg:CC FLAGS_REG))]
8630   "reload_completed"
8631   [(parallel [(set (match_dup 0) (match_dup 1))
8632               (clobber (reg:CC FLAGS_REG))])]
8633 {
8634   rtx tmp;
8635   operands[0] = gen_rtx_REG (SImode,
8636                              true_regnum (operands[0])
8637                              + (TARGET_64BIT ? 1 : 2));
8638   if (GET_CODE (operands[1]) == ABS)
8639     {
8640       tmp = GEN_INT (0x7fff);
8641       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8642     }
8643   else
8644     {
8645       tmp = GEN_INT (0x8000);
8646       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8647     }
8648   operands[1] = tmp;
8649 })
8650
8651 ;; Conditionalize these after reload. If they match before reload, we
8652 ;; lose the clobber and ability to use integer instructions.
8653
8654 (define_insn "*<code><mode>2_1"
8655   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8656         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8657   "TARGET_80387
8658    && (reload_completed
8659        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8660   "f<absneg_mnemonic>"
8661   [(set_attr "type" "fsgn")
8662    (set_attr "mode" "<MODE>")])
8663
8664 (define_insn "*<code>extendsfdf2"
8665   [(set (match_operand:DF 0 "register_operand" "=f")
8666         (absneg:DF (float_extend:DF
8667                      (match_operand:SF 1 "register_operand" "0"))))]
8668   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8669   "f<absneg_mnemonic>"
8670   [(set_attr "type" "fsgn")
8671    (set_attr "mode" "DF")])
8672
8673 (define_insn "*<code>extendsfxf2"
8674   [(set (match_operand:XF 0 "register_operand" "=f")
8675         (absneg:XF (float_extend:XF
8676                      (match_operand:SF 1 "register_operand" "0"))))]
8677   "TARGET_80387"
8678   "f<absneg_mnemonic>"
8679   [(set_attr "type" "fsgn")
8680    (set_attr "mode" "XF")])
8681
8682 (define_insn "*<code>extenddfxf2"
8683   [(set (match_operand:XF 0 "register_operand" "=f")
8684         (absneg:XF (float_extend:XF
8685                      (match_operand:DF 1 "register_operand" "0"))))]
8686   "TARGET_80387"
8687   "f<absneg_mnemonic>"
8688   [(set_attr "type" "fsgn")
8689    (set_attr "mode" "XF")])
8690
8691 ;; Copysign instructions
8692
8693 (define_mode_iterator CSGNMODE [SF DF TF])
8694 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8695
8696 (define_expand "copysign<mode>3"
8697   [(match_operand:CSGNMODE 0 "register_operand" "")
8698    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8699    (match_operand:CSGNMODE 2 "register_operand" "")]
8700   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8701    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8702   "ix86_expand_copysign (operands); DONE;")
8703
8704 (define_insn_and_split "copysign<mode>3_const"
8705   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8706         (unspec:CSGNMODE
8707           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8708            (match_operand:CSGNMODE 2 "register_operand" "0")
8709            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8710           UNSPEC_COPYSIGN))]
8711   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8712    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8713   "#"
8714   "&& reload_completed"
8715   [(const_int 0)]
8716   "ix86_split_copysign_const (operands); DONE;")
8717
8718 (define_insn "copysign<mode>3_var"
8719   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8720         (unspec:CSGNMODE
8721           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8722            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8723            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8724            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8725           UNSPEC_COPYSIGN))
8726    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8727   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8728    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8729   "#")
8730
8731 (define_split
8732   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8733         (unspec:CSGNMODE
8734           [(match_operand:CSGNMODE 2 "register_operand" "")
8735            (match_operand:CSGNMODE 3 "register_operand" "")
8736            (match_operand:<CSGNVMODE> 4 "" "")
8737            (match_operand:<CSGNVMODE> 5 "" "")]
8738           UNSPEC_COPYSIGN))
8739    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8740   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8741     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8742    && reload_completed"
8743   [(const_int 0)]
8744   "ix86_split_copysign_var (operands); DONE;")
8745 \f
8746 ;; One complement instructions
8747
8748 (define_expand "one_cmpl<mode>2"
8749   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8750         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8751   ""
8752   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8753
8754 (define_insn "*one_cmpl<mode>2_1"
8755   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8756         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8757   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8758   "not{<imodesuffix>}\t%0"
8759   [(set_attr "type" "negnot")
8760    (set_attr "mode" "<MODE>")])
8761
8762 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8763 (define_insn "*one_cmplqi2_1"
8764   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8765         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8766   "ix86_unary_operator_ok (NOT, QImode, operands)"
8767   "@
8768    not{b}\t%0
8769    not{l}\t%k0"
8770   [(set_attr "type" "negnot")
8771    (set_attr "mode" "QI,SI")])
8772
8773 ;; ??? Currently never generated - xor is used instead.
8774 (define_insn "*one_cmplsi2_1_zext"
8775   [(set (match_operand:DI 0 "register_operand" "=r")
8776         (zero_extend:DI
8777           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8778   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8779   "not{l}\t%k0"
8780   [(set_attr "type" "negnot")
8781    (set_attr "mode" "SI")])
8782
8783 (define_insn "*one_cmpl<mode>2_2"
8784   [(set (reg FLAGS_REG)
8785         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8786                  (const_int 0)))
8787    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8788         (not:SWI (match_dup 1)))]
8789   "ix86_match_ccmode (insn, CCNOmode)
8790    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8791   "#"
8792   [(set_attr "type" "alu1")
8793    (set_attr "mode" "<MODE>")])
8794
8795 (define_split
8796   [(set (match_operand 0 "flags_reg_operand" "")
8797         (match_operator 2 "compare_operator"
8798           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8799            (const_int 0)]))
8800    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8801         (not:SWI (match_dup 3)))]
8802   "ix86_match_ccmode (insn, CCNOmode)"
8803   [(parallel [(set (match_dup 0)
8804                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8805                                     (const_int 0)]))
8806               (set (match_dup 1)
8807                    (xor:SWI (match_dup 3) (const_int -1)))])])
8808
8809 ;; ??? Currently never generated - xor is used instead.
8810 (define_insn "*one_cmplsi2_2_zext"
8811   [(set (reg FLAGS_REG)
8812         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8813                  (const_int 0)))
8814    (set (match_operand:DI 0 "register_operand" "=r")
8815         (zero_extend:DI (not:SI (match_dup 1))))]
8816   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8817    && ix86_unary_operator_ok (NOT, SImode, operands)"
8818   "#"
8819   [(set_attr "type" "alu1")
8820    (set_attr "mode" "SI")])
8821
8822 (define_split
8823   [(set (match_operand 0 "flags_reg_operand" "")
8824         (match_operator 2 "compare_operator"
8825           [(not:SI (match_operand:SI 3 "register_operand" ""))
8826            (const_int 0)]))
8827    (set (match_operand:DI 1 "register_operand" "")
8828         (zero_extend:DI (not:SI (match_dup 3))))]
8829   "ix86_match_ccmode (insn, CCNOmode)"
8830   [(parallel [(set (match_dup 0)
8831                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8832                                     (const_int 0)]))
8833               (set (match_dup 1)
8834                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8835 \f
8836 ;; Shift instructions
8837
8838 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8839 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8840 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8841 ;; from the assembler input.
8842 ;;
8843 ;; This instruction shifts the target reg/mem as usual, but instead of
8844 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8845 ;; is a left shift double, bits are taken from the high order bits of
8846 ;; reg, else if the insn is a shift right double, bits are taken from the
8847 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8848 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8849 ;;
8850 ;; Since sh[lr]d does not change the `reg' operand, that is done
8851 ;; separately, making all shifts emit pairs of shift double and normal
8852 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8853 ;; support a 63 bit shift, each shift where the count is in a reg expands
8854 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8855 ;;
8856 ;; If the shift count is a constant, we need never emit more than one
8857 ;; shift pair, instead using moves and sign extension for counts greater
8858 ;; than 31.
8859
8860 (define_expand "ashl<mode>3"
8861   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8862         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8863                       (match_operand:QI 2 "nonmemory_operand" "")))]
8864   ""
8865   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8866
8867 (define_insn "*ashl<mode>3_doubleword"
8868   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8869         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8870                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8871    (clobber (reg:CC FLAGS_REG))]
8872   ""
8873   "#"
8874   [(set_attr "type" "multi")])
8875
8876 (define_split
8877   [(set (match_operand:DWI 0 "register_operand" "")
8878         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8879                     (match_operand:QI 2 "nonmemory_operand" "")))
8880    (clobber (reg:CC FLAGS_REG))]
8881   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8882   [(const_int 0)]
8883   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8884
8885 ;; By default we don't ask for a scratch register, because when DWImode
8886 ;; values are manipulated, registers are already at a premium.  But if
8887 ;; we have one handy, we won't turn it away.
8888
8889 (define_peephole2
8890   [(match_scratch:DWIH 3 "r")
8891    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8892                    (ashift:<DWI>
8893                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8894                      (match_operand:QI 2 "nonmemory_operand" "")))
8895               (clobber (reg:CC FLAGS_REG))])
8896    (match_dup 3)]
8897   "TARGET_CMOVE"
8898   [(const_int 0)]
8899   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8900
8901 (define_insn "x86_64_shld"
8902   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8903         (ior:DI (ashift:DI (match_dup 0)
8904                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8905                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8906                   (minus:QI (const_int 64) (match_dup 2)))))
8907    (clobber (reg:CC FLAGS_REG))]
8908   "TARGET_64BIT"
8909   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8910   [(set_attr "type" "ishift")
8911    (set_attr "prefix_0f" "1")
8912    (set_attr "mode" "DI")
8913    (set_attr "athlon_decode" "vector")
8914    (set_attr "amdfam10_decode" "vector")
8915    (set_attr "bdver1_decode" "vector")])
8916
8917 (define_insn "x86_shld"
8918   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8919         (ior:SI (ashift:SI (match_dup 0)
8920                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8921                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8922                   (minus:QI (const_int 32) (match_dup 2)))))
8923    (clobber (reg:CC FLAGS_REG))]
8924   ""
8925   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8926   [(set_attr "type" "ishift")
8927    (set_attr "prefix_0f" "1")
8928    (set_attr "mode" "SI")
8929    (set_attr "pent_pair" "np")
8930    (set_attr "athlon_decode" "vector")
8931    (set_attr "amdfam10_decode" "vector")
8932    (set_attr "bdver1_decode" "vector")])
8933
8934 (define_expand "x86_shift<mode>_adj_1"
8935   [(set (reg:CCZ FLAGS_REG)
8936         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8937                              (match_dup 4))
8938                      (const_int 0)))
8939    (set (match_operand:SWI48 0 "register_operand" "")
8940         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8941                             (match_operand:SWI48 1 "register_operand" "")
8942                             (match_dup 0)))
8943    (set (match_dup 1)
8944         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8945                             (match_operand:SWI48 3 "register_operand" "r")
8946                             (match_dup 1)))]
8947   "TARGET_CMOVE"
8948   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8949
8950 (define_expand "x86_shift<mode>_adj_2"
8951   [(use (match_operand:SWI48 0 "register_operand" ""))
8952    (use (match_operand:SWI48 1 "register_operand" ""))
8953    (use (match_operand:QI 2 "register_operand" ""))]
8954   ""
8955 {
8956   rtx label = gen_label_rtx ();
8957   rtx tmp;
8958
8959   emit_insn (gen_testqi_ccz_1 (operands[2],
8960                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8961
8962   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8963   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8964   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8965                               gen_rtx_LABEL_REF (VOIDmode, label),
8966                               pc_rtx);
8967   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8968   JUMP_LABEL (tmp) = label;
8969
8970   emit_move_insn (operands[0], operands[1]);
8971   ix86_expand_clear (operands[1]);
8972
8973   emit_label (label);
8974   LABEL_NUSES (label) = 1;
8975
8976   DONE;
8977 })
8978
8979 ;; Avoid useless masking of count operand.
8980 (define_insn_and_split "*ashl<mode>3_mask"
8981   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8982         (ashift:SWI48
8983           (match_operand:SWI48 1 "nonimmediate_operand" "0")
8984           (subreg:QI
8985             (and:SI
8986               (match_operand:SI 2 "nonimmediate_operand" "c")
8987               (match_operand:SI 3 "const_int_operand" "n")) 0)))
8988    (clobber (reg:CC FLAGS_REG))]
8989   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8990    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8991       == GET_MODE_BITSIZE (<MODE>mode)-1"
8992   "#"
8993   "&& 1"
8994   [(parallel [(set (match_dup 0)
8995                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
8996               (clobber (reg:CC FLAGS_REG))])]
8997 {
8998   if (can_create_pseudo_p ())
8999     operands [2] = force_reg (SImode, operands[2]);
9000
9001   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9002 }
9003   [(set_attr "type" "ishift")
9004    (set_attr "mode" "<MODE>")])
9005
9006 (define_insn "*ashl<mode>3_1"
9007   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9008         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9009                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9010    (clobber (reg:CC FLAGS_REG))]
9011   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9012 {
9013   switch (get_attr_type (insn))
9014     {
9015     case TYPE_LEA:
9016       return "#";
9017
9018     case TYPE_ALU:
9019       gcc_assert (operands[2] == const1_rtx);
9020       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9021       return "add{<imodesuffix>}\t%0, %0";
9022
9023     default:
9024       if (operands[2] == const1_rtx
9025           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9026         return "sal{<imodesuffix>}\t%0";
9027       else
9028         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9029     }
9030 }
9031   [(set (attr "type")
9032      (cond [(eq_attr "alternative" "1")
9033               (const_string "lea")
9034             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9035                           (const_int 0))
9036                       (match_operand 0 "register_operand" ""))
9037                  (match_operand 2 "const1_operand" ""))
9038               (const_string "alu")
9039            ]
9040            (const_string "ishift")))
9041    (set (attr "length_immediate")
9042      (if_then_else
9043        (ior (eq_attr "type" "alu")
9044             (and (eq_attr "type" "ishift")
9045                  (and (match_operand 2 "const1_operand" "")
9046                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9047                           (const_int 0)))))
9048        (const_string "0")
9049        (const_string "*")))
9050    (set_attr "mode" "<MODE>")])
9051
9052 (define_insn "*ashlsi3_1_zext"
9053   [(set (match_operand:DI 0 "register_operand" "=r,r")
9054         (zero_extend:DI
9055           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9056                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9057    (clobber (reg:CC FLAGS_REG))]
9058   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9059 {
9060   switch (get_attr_type (insn))
9061     {
9062     case TYPE_LEA:
9063       return "#";
9064
9065     case TYPE_ALU:
9066       gcc_assert (operands[2] == const1_rtx);
9067       return "add{l}\t%k0, %k0";
9068
9069     default:
9070       if (operands[2] == const1_rtx
9071           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9072         return "sal{l}\t%k0";
9073       else
9074         return "sal{l}\t{%2, %k0|%k0, %2}";
9075     }
9076 }
9077   [(set (attr "type")
9078      (cond [(eq_attr "alternative" "1")
9079               (const_string "lea")
9080             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9081                      (const_int 0))
9082                  (match_operand 2 "const1_operand" ""))
9083               (const_string "alu")
9084            ]
9085            (const_string "ishift")))
9086    (set (attr "length_immediate")
9087      (if_then_else
9088        (ior (eq_attr "type" "alu")
9089             (and (eq_attr "type" "ishift")
9090                  (and (match_operand 2 "const1_operand" "")
9091                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9092                           (const_int 0)))))
9093        (const_string "0")
9094        (const_string "*")))
9095    (set_attr "mode" "SI")])
9096
9097 (define_insn "*ashlhi3_1"
9098   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9099         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9100                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9101    (clobber (reg:CC FLAGS_REG))]
9102   "TARGET_PARTIAL_REG_STALL
9103    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9104 {
9105   switch (get_attr_type (insn))
9106     {
9107     case TYPE_ALU:
9108       gcc_assert (operands[2] == const1_rtx);
9109       return "add{w}\t%0, %0";
9110
9111     default:
9112       if (operands[2] == const1_rtx
9113           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9114         return "sal{w}\t%0";
9115       else
9116         return "sal{w}\t{%2, %0|%0, %2}";
9117     }
9118 }
9119   [(set (attr "type")
9120      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9121                           (const_int 0))
9122                       (match_operand 0 "register_operand" ""))
9123                  (match_operand 2 "const1_operand" ""))
9124               (const_string "alu")
9125            ]
9126            (const_string "ishift")))
9127    (set (attr "length_immediate")
9128      (if_then_else
9129        (ior (eq_attr "type" "alu")
9130             (and (eq_attr "type" "ishift")
9131                  (and (match_operand 2 "const1_operand" "")
9132                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9133                           (const_int 0)))))
9134        (const_string "0")
9135        (const_string "*")))
9136    (set_attr "mode" "HI")])
9137
9138 (define_insn "*ashlhi3_1_lea"
9139   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9140         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9141                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9142    (clobber (reg:CC FLAGS_REG))]
9143   "!TARGET_PARTIAL_REG_STALL
9144    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9145 {
9146   switch (get_attr_type (insn))
9147     {
9148     case TYPE_LEA:
9149       return "#";
9150
9151     case TYPE_ALU:
9152       gcc_assert (operands[2] == const1_rtx);
9153       return "add{w}\t%0, %0";
9154
9155     default:
9156       if (operands[2] == const1_rtx
9157           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9158         return "sal{w}\t%0";
9159       else
9160         return "sal{w}\t{%2, %0|%0, %2}";
9161     }
9162 }
9163   [(set (attr "type")
9164      (cond [(eq_attr "alternative" "1")
9165               (const_string "lea")
9166             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9167                           (const_int 0))
9168                       (match_operand 0 "register_operand" ""))
9169                  (match_operand 2 "const1_operand" ""))
9170               (const_string "alu")
9171            ]
9172            (const_string "ishift")))
9173    (set (attr "length_immediate")
9174      (if_then_else
9175        (ior (eq_attr "type" "alu")
9176             (and (eq_attr "type" "ishift")
9177                  (and (match_operand 2 "const1_operand" "")
9178                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9179                           (const_int 0)))))
9180        (const_string "0")
9181        (const_string "*")))
9182    (set_attr "mode" "HI,SI")])
9183
9184 (define_insn "*ashlqi3_1"
9185   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9186         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9187                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9188    (clobber (reg:CC FLAGS_REG))]
9189   "TARGET_PARTIAL_REG_STALL
9190    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9191 {
9192   switch (get_attr_type (insn))
9193     {
9194     case TYPE_ALU:
9195       gcc_assert (operands[2] == const1_rtx);
9196       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9197         return "add{l}\t%k0, %k0";
9198       else
9199         return "add{b}\t%0, %0";
9200
9201     default:
9202       if (operands[2] == const1_rtx
9203           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9204         {
9205           if (get_attr_mode (insn) == MODE_SI)
9206             return "sal{l}\t%k0";
9207           else
9208             return "sal{b}\t%0";
9209         }
9210       else
9211         {
9212           if (get_attr_mode (insn) == MODE_SI)
9213             return "sal{l}\t{%2, %k0|%k0, %2}";
9214           else
9215             return "sal{b}\t{%2, %0|%0, %2}";
9216         }
9217     }
9218 }
9219   [(set (attr "type")
9220      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9221                           (const_int 0))
9222                       (match_operand 0 "register_operand" ""))
9223                  (match_operand 2 "const1_operand" ""))
9224               (const_string "alu")
9225            ]
9226            (const_string "ishift")))
9227    (set (attr "length_immediate")
9228      (if_then_else
9229        (ior (eq_attr "type" "alu")
9230             (and (eq_attr "type" "ishift")
9231                  (and (match_operand 2 "const1_operand" "")
9232                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9233                           (const_int 0)))))
9234        (const_string "0")
9235        (const_string "*")))
9236    (set_attr "mode" "QI,SI")])
9237
9238 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9239 (define_insn "*ashlqi3_1_lea"
9240   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9241         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9242                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9243    (clobber (reg:CC FLAGS_REG))]
9244   "!TARGET_PARTIAL_REG_STALL
9245    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9246 {
9247   switch (get_attr_type (insn))
9248     {
9249     case TYPE_LEA:
9250       return "#";
9251
9252     case TYPE_ALU:
9253       gcc_assert (operands[2] == const1_rtx);
9254       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9255         return "add{l}\t%k0, %k0";
9256       else
9257         return "add{b}\t%0, %0";
9258
9259     default:
9260       if (operands[2] == const1_rtx
9261           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9262         {
9263           if (get_attr_mode (insn) == MODE_SI)
9264             return "sal{l}\t%k0";
9265           else
9266             return "sal{b}\t%0";
9267         }
9268       else
9269         {
9270           if (get_attr_mode (insn) == MODE_SI)
9271             return "sal{l}\t{%2, %k0|%k0, %2}";
9272           else
9273             return "sal{b}\t{%2, %0|%0, %2}";
9274         }
9275     }
9276 }
9277   [(set (attr "type")
9278      (cond [(eq_attr "alternative" "2")
9279               (const_string "lea")
9280             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9281                           (const_int 0))
9282                       (match_operand 0 "register_operand" ""))
9283                  (match_operand 2 "const1_operand" ""))
9284               (const_string "alu")
9285            ]
9286            (const_string "ishift")))
9287    (set (attr "length_immediate")
9288      (if_then_else
9289        (ior (eq_attr "type" "alu")
9290             (and (eq_attr "type" "ishift")
9291                  (and (match_operand 2 "const1_operand" "")
9292                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9293                           (const_int 0)))))
9294        (const_string "0")
9295        (const_string "*")))
9296    (set_attr "mode" "QI,SI,SI")])
9297
9298 (define_insn "*ashlqi3_1_slp"
9299   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9300         (ashift:QI (match_dup 0)
9301                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9302    (clobber (reg:CC FLAGS_REG))]
9303   "(optimize_function_for_size_p (cfun)
9304     || !TARGET_PARTIAL_FLAG_REG_STALL
9305     || (operands[1] == const1_rtx
9306         && (TARGET_SHIFT1
9307             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9308 {
9309   switch (get_attr_type (insn))
9310     {
9311     case TYPE_ALU:
9312       gcc_assert (operands[1] == const1_rtx);
9313       return "add{b}\t%0, %0";
9314
9315     default:
9316       if (operands[1] == const1_rtx
9317           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9318         return "sal{b}\t%0";
9319       else
9320         return "sal{b}\t{%1, %0|%0, %1}";
9321     }
9322 }
9323   [(set (attr "type")
9324      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9325                           (const_int 0))
9326                       (match_operand 0 "register_operand" ""))
9327                  (match_operand 1 "const1_operand" ""))
9328               (const_string "alu")
9329            ]
9330            (const_string "ishift1")))
9331    (set (attr "length_immediate")
9332      (if_then_else
9333        (ior (eq_attr "type" "alu")
9334             (and (eq_attr "type" "ishift1")
9335                  (and (match_operand 1 "const1_operand" "")
9336                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9337                           (const_int 0)))))
9338        (const_string "0")
9339        (const_string "*")))
9340    (set_attr "mode" "QI")])
9341
9342 ;; Convert ashift to the lea pattern to avoid flags dependency.
9343 (define_split
9344   [(set (match_operand 0 "register_operand" "")
9345         (ashift (match_operand 1 "index_register_operand" "")
9346                 (match_operand:QI 2 "const_int_operand" "")))
9347    (clobber (reg:CC FLAGS_REG))]
9348   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9349    && reload_completed
9350    && true_regnum (operands[0]) != true_regnum (operands[1])"
9351   [(const_int 0)]
9352 {
9353   enum machine_mode mode = GET_MODE (operands[0]);
9354   rtx pat;
9355
9356   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9357     { 
9358       mode = SImode; 
9359       operands[0] = gen_lowpart (mode, operands[0]);
9360       operands[1] = gen_lowpart (mode, operands[1]);
9361     }
9362
9363   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9364
9365   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9366
9367   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9368   DONE;
9369 })
9370
9371 ;; Convert ashift to the lea pattern to avoid flags dependency.
9372 (define_split
9373   [(set (match_operand:DI 0 "register_operand" "")
9374         (zero_extend:DI
9375           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9376                      (match_operand:QI 2 "const_int_operand" ""))))
9377    (clobber (reg:CC FLAGS_REG))]
9378   "TARGET_64BIT && reload_completed
9379    && true_regnum (operands[0]) != true_regnum (operands[1])"
9380   [(set (match_dup 0)
9381         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9382 {
9383   operands[1] = gen_lowpart (DImode, operands[1]);
9384   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9385 })
9386
9387 ;; This pattern can't accept a variable shift count, since shifts by
9388 ;; zero don't affect the flags.  We assume that shifts by constant
9389 ;; zero are optimized away.
9390 (define_insn "*ashl<mode>3_cmp"
9391   [(set (reg FLAGS_REG)
9392         (compare
9393           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9394                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9395           (const_int 0)))
9396    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9397         (ashift:SWI (match_dup 1) (match_dup 2)))]
9398   "(optimize_function_for_size_p (cfun)
9399     || !TARGET_PARTIAL_FLAG_REG_STALL
9400     || (operands[2] == const1_rtx
9401         && (TARGET_SHIFT1
9402             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9403    && ix86_match_ccmode (insn, CCGOCmode)
9404    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9405 {
9406   switch (get_attr_type (insn))
9407     {
9408     case TYPE_ALU:
9409       gcc_assert (operands[2] == const1_rtx);
9410       return "add{<imodesuffix>}\t%0, %0";
9411
9412     default:
9413       if (operands[2] == const1_rtx
9414           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9415         return "sal{<imodesuffix>}\t%0";
9416       else
9417         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9418     }
9419 }
9420   [(set (attr "type")
9421      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9422                           (const_int 0))
9423                       (match_operand 0 "register_operand" ""))
9424                  (match_operand 2 "const1_operand" ""))
9425               (const_string "alu")
9426            ]
9427            (const_string "ishift")))
9428    (set (attr "length_immediate")
9429      (if_then_else
9430        (ior (eq_attr "type" "alu")
9431             (and (eq_attr "type" "ishift")
9432                  (and (match_operand 2 "const1_operand" "")
9433                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9434                           (const_int 0)))))
9435        (const_string "0")
9436        (const_string "*")))
9437    (set_attr "mode" "<MODE>")])
9438
9439 (define_insn "*ashlsi3_cmp_zext"
9440   [(set (reg FLAGS_REG)
9441         (compare
9442           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9443                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9444           (const_int 0)))
9445    (set (match_operand:DI 0 "register_operand" "=r")
9446         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9447   "TARGET_64BIT
9448    && (optimize_function_for_size_p (cfun)
9449        || !TARGET_PARTIAL_FLAG_REG_STALL
9450        || (operands[2] == const1_rtx
9451            && (TARGET_SHIFT1
9452                || TARGET_DOUBLE_WITH_ADD)))
9453    && ix86_match_ccmode (insn, CCGOCmode)
9454    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9455 {
9456   switch (get_attr_type (insn))
9457     {
9458     case TYPE_ALU:
9459       gcc_assert (operands[2] == const1_rtx);
9460       return "add{l}\t%k0, %k0";
9461
9462     default:
9463       if (operands[2] == const1_rtx
9464           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465         return "sal{l}\t%k0";
9466       else
9467         return "sal{l}\t{%2, %k0|%k0, %2}";
9468     }
9469 }
9470   [(set (attr "type")
9471      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9472                      (const_int 0))
9473                  (match_operand 2 "const1_operand" ""))
9474               (const_string "alu")
9475            ]
9476            (const_string "ishift")))
9477    (set (attr "length_immediate")
9478      (if_then_else
9479        (ior (eq_attr "type" "alu")
9480             (and (eq_attr "type" "ishift")
9481                  (and (match_operand 2 "const1_operand" "")
9482                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9483                           (const_int 0)))))
9484        (const_string "0")
9485        (const_string "*")))
9486    (set_attr "mode" "SI")])
9487
9488 (define_insn "*ashl<mode>3_cconly"
9489   [(set (reg FLAGS_REG)
9490         (compare
9491           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9492                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9493           (const_int 0)))
9494    (clobber (match_scratch:SWI 0 "=<r>"))]
9495   "(optimize_function_for_size_p (cfun)
9496     || !TARGET_PARTIAL_FLAG_REG_STALL
9497     || (operands[2] == const1_rtx
9498         && (TARGET_SHIFT1
9499             || TARGET_DOUBLE_WITH_ADD)))
9500    && ix86_match_ccmode (insn, CCGOCmode)"
9501 {
9502   switch (get_attr_type (insn))
9503     {
9504     case TYPE_ALU:
9505       gcc_assert (operands[2] == const1_rtx);
9506       return "add{<imodesuffix>}\t%0, %0";
9507
9508     default:
9509       if (operands[2] == const1_rtx
9510           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9511         return "sal{<imodesuffix>}\t%0";
9512       else
9513         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9514     }
9515 }
9516   [(set (attr "type")
9517      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9518                           (const_int 0))
9519                       (match_operand 0 "register_operand" ""))
9520                  (match_operand 2 "const1_operand" ""))
9521               (const_string "alu")
9522            ]
9523            (const_string "ishift")))
9524    (set (attr "length_immediate")
9525      (if_then_else
9526        (ior (eq_attr "type" "alu")
9527             (and (eq_attr "type" "ishift")
9528                  (and (match_operand 2 "const1_operand" "")
9529                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9530                           (const_int 0)))))
9531        (const_string "0")
9532        (const_string "*")))
9533    (set_attr "mode" "<MODE>")])
9534
9535 ;; See comment above `ashl<mode>3' about how this works.
9536
9537 (define_expand "<shiftrt_insn><mode>3"
9538   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9539         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9540                            (match_operand:QI 2 "nonmemory_operand" "")))]
9541   ""
9542   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9543
9544 ;; Avoid useless masking of count operand.
9545 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9546   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9547         (any_shiftrt:SWI48
9548           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9549           (subreg:QI
9550             (and:SI
9551               (match_operand:SI 2 "nonimmediate_operand" "c")
9552               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9553    (clobber (reg:CC FLAGS_REG))]
9554   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9555    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9556       == GET_MODE_BITSIZE (<MODE>mode)-1"
9557   "#"
9558   "&& 1"
9559   [(parallel [(set (match_dup 0)
9560                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9561               (clobber (reg:CC FLAGS_REG))])]
9562 {
9563   if (can_create_pseudo_p ())
9564     operands [2] = force_reg (SImode, operands[2]);
9565
9566   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9567 }
9568   [(set_attr "type" "ishift")
9569    (set_attr "mode" "<MODE>")])
9570
9571 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9572   [(set (match_operand:DWI 0 "register_operand" "=r")
9573         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9574                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9575    (clobber (reg:CC FLAGS_REG))]
9576   ""
9577   "#"
9578   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9579   [(const_int 0)]
9580   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9581   [(set_attr "type" "multi")])
9582
9583 ;; By default we don't ask for a scratch register, because when DWImode
9584 ;; values are manipulated, registers are already at a premium.  But if
9585 ;; we have one handy, we won't turn it away.
9586
9587 (define_peephole2
9588   [(match_scratch:DWIH 3 "r")
9589    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9590                    (any_shiftrt:<DWI>
9591                      (match_operand:<DWI> 1 "register_operand" "")
9592                      (match_operand:QI 2 "nonmemory_operand" "")))
9593               (clobber (reg:CC FLAGS_REG))])
9594    (match_dup 3)]
9595   "TARGET_CMOVE"
9596   [(const_int 0)]
9597   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9598
9599 (define_insn "x86_64_shrd"
9600   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9601         (ior:DI (ashiftrt:DI (match_dup 0)
9602                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9603                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9604                   (minus:QI (const_int 64) (match_dup 2)))))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "TARGET_64BIT"
9607   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9608   [(set_attr "type" "ishift")
9609    (set_attr "prefix_0f" "1")
9610    (set_attr "mode" "DI")
9611    (set_attr "athlon_decode" "vector")
9612    (set_attr "amdfam10_decode" "vector")
9613    (set_attr "bdver1_decode" "vector")])
9614
9615 (define_insn "x86_shrd"
9616   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9617         (ior:SI (ashiftrt:SI (match_dup 0)
9618                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9619                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9620                   (minus:QI (const_int 32) (match_dup 2)))))
9621    (clobber (reg:CC FLAGS_REG))]
9622   ""
9623   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9624   [(set_attr "type" "ishift")
9625    (set_attr "prefix_0f" "1")
9626    (set_attr "mode" "SI")
9627    (set_attr "pent_pair" "np")
9628    (set_attr "athlon_decode" "vector")
9629    (set_attr "amdfam10_decode" "vector")
9630    (set_attr "bdver1_decode" "vector")])
9631
9632 (define_insn "ashrdi3_cvt"
9633   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9634         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9635                      (match_operand:QI 2 "const_int_operand" "")))
9636    (clobber (reg:CC FLAGS_REG))]
9637   "TARGET_64BIT && INTVAL (operands[2]) == 63
9638    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9639    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9640   "@
9641    {cqto|cqo}
9642    sar{q}\t{%2, %0|%0, %2}"
9643   [(set_attr "type" "imovx,ishift")
9644    (set_attr "prefix_0f" "0,*")
9645    (set_attr "length_immediate" "0,*")
9646    (set_attr "modrm" "0,1")
9647    (set_attr "mode" "DI")])
9648
9649 (define_insn "ashrsi3_cvt"
9650   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9651         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9652                      (match_operand:QI 2 "const_int_operand" "")))
9653    (clobber (reg:CC FLAGS_REG))]
9654   "INTVAL (operands[2]) == 31
9655    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9656    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9657   "@
9658    {cltd|cdq}
9659    sar{l}\t{%2, %0|%0, %2}"
9660   [(set_attr "type" "imovx,ishift")
9661    (set_attr "prefix_0f" "0,*")
9662    (set_attr "length_immediate" "0,*")
9663    (set_attr "modrm" "0,1")
9664    (set_attr "mode" "SI")])
9665
9666 (define_insn "*ashrsi3_cvt_zext"
9667   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9668         (zero_extend:DI
9669           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9670                        (match_operand:QI 2 "const_int_operand" ""))))
9671    (clobber (reg:CC FLAGS_REG))]
9672   "TARGET_64BIT && INTVAL (operands[2]) == 31
9673    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9674    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9675   "@
9676    {cltd|cdq}
9677    sar{l}\t{%2, %k0|%k0, %2}"
9678   [(set_attr "type" "imovx,ishift")
9679    (set_attr "prefix_0f" "0,*")
9680    (set_attr "length_immediate" "0,*")
9681    (set_attr "modrm" "0,1")
9682    (set_attr "mode" "SI")])
9683
9684 (define_expand "x86_shift<mode>_adj_3"
9685   [(use (match_operand:SWI48 0 "register_operand" ""))
9686    (use (match_operand:SWI48 1 "register_operand" ""))
9687    (use (match_operand:QI 2 "register_operand" ""))]
9688   ""
9689 {
9690   rtx label = gen_label_rtx ();
9691   rtx tmp;
9692
9693   emit_insn (gen_testqi_ccz_1 (operands[2],
9694                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9695
9696   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9697   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9698   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9699                               gen_rtx_LABEL_REF (VOIDmode, label),
9700                               pc_rtx);
9701   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9702   JUMP_LABEL (tmp) = label;
9703
9704   emit_move_insn (operands[0], operands[1]);
9705   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9706                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9707   emit_label (label);
9708   LABEL_NUSES (label) = 1;
9709
9710   DONE;
9711 })
9712
9713 (define_insn "*<shiftrt_insn><mode>3_1"
9714   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9715         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9716                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9719 {
9720   if (operands[2] == const1_rtx
9721       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9722     return "<shiftrt>{<imodesuffix>}\t%0";
9723   else
9724     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9725 }
9726   [(set_attr "type" "ishift")
9727    (set (attr "length_immediate")
9728      (if_then_else
9729        (and (match_operand 2 "const1_operand" "")
9730             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9731                 (const_int 0)))
9732        (const_string "0")
9733        (const_string "*")))
9734    (set_attr "mode" "<MODE>")])
9735
9736 (define_insn "*<shiftrt_insn>si3_1_zext"
9737   [(set (match_operand:DI 0 "register_operand" "=r")
9738         (zero_extend:DI
9739           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9740                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9741    (clobber (reg:CC FLAGS_REG))]
9742   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9743 {
9744   if (operands[2] == const1_rtx
9745       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9746     return "<shiftrt>{l}\t%k0";
9747   else
9748     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9749 }
9750   [(set_attr "type" "ishift")
9751    (set (attr "length_immediate")
9752      (if_then_else
9753        (and (match_operand 2 "const1_operand" "")
9754             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9755                 (const_int 0)))
9756        (const_string "0")
9757        (const_string "*")))
9758    (set_attr "mode" "SI")])
9759
9760 (define_insn "*<shiftrt_insn>qi3_1_slp"
9761   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9762         (any_shiftrt:QI (match_dup 0)
9763                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9764    (clobber (reg:CC FLAGS_REG))]
9765   "(optimize_function_for_size_p (cfun)
9766     || !TARGET_PARTIAL_REG_STALL
9767     || (operands[1] == const1_rtx
9768         && TARGET_SHIFT1))"
9769 {
9770   if (operands[1] == const1_rtx
9771       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9772     return "<shiftrt>{b}\t%0";
9773   else
9774     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9775 }
9776   [(set_attr "type" "ishift1")
9777    (set (attr "length_immediate")
9778      (if_then_else
9779        (and (match_operand 1 "const1_operand" "")
9780             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9781                 (const_int 0)))
9782        (const_string "0")
9783        (const_string "*")))
9784    (set_attr "mode" "QI")])
9785
9786 ;; This pattern can't accept a variable shift count, since shifts by
9787 ;; zero don't affect the flags.  We assume that shifts by constant
9788 ;; zero are optimized away.
9789 (define_insn "*<shiftrt_insn><mode>3_cmp"
9790   [(set (reg FLAGS_REG)
9791         (compare
9792           (any_shiftrt:SWI
9793             (match_operand:SWI 1 "nonimmediate_operand" "0")
9794             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9795           (const_int 0)))
9796    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9797         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9798   "(optimize_function_for_size_p (cfun)
9799     || !TARGET_PARTIAL_FLAG_REG_STALL
9800     || (operands[2] == const1_rtx
9801         && TARGET_SHIFT1))
9802    && ix86_match_ccmode (insn, CCGOCmode)
9803    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9804 {
9805   if (operands[2] == const1_rtx
9806       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9807     return "<shiftrt>{<imodesuffix>}\t%0";
9808   else
9809     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9810 }
9811   [(set_attr "type" "ishift")
9812    (set (attr "length_immediate")
9813      (if_then_else
9814        (and (match_operand 2 "const1_operand" "")
9815             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9816                 (const_int 0)))
9817        (const_string "0")
9818        (const_string "*")))
9819    (set_attr "mode" "<MODE>")])
9820
9821 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9822   [(set (reg FLAGS_REG)
9823         (compare
9824           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9825                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9826           (const_int 0)))
9827    (set (match_operand:DI 0 "register_operand" "=r")
9828         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9829   "TARGET_64BIT
9830    && (optimize_function_for_size_p (cfun)
9831        || !TARGET_PARTIAL_FLAG_REG_STALL
9832        || (operands[2] == const1_rtx
9833            && TARGET_SHIFT1))
9834    && ix86_match_ccmode (insn, CCGOCmode)
9835    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9836 {
9837   if (operands[2] == const1_rtx
9838       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9839     return "<shiftrt>{l}\t%k0";
9840   else
9841     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9842 }
9843   [(set_attr "type" "ishift")
9844    (set (attr "length_immediate")
9845      (if_then_else
9846        (and (match_operand 2 "const1_operand" "")
9847             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9848                 (const_int 0)))
9849        (const_string "0")
9850        (const_string "*")))
9851    (set_attr "mode" "SI")])
9852
9853 (define_insn "*<shiftrt_insn><mode>3_cconly"
9854   [(set (reg FLAGS_REG)
9855         (compare
9856           (any_shiftrt:SWI
9857             (match_operand:SWI 1 "register_operand" "0")
9858             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9859           (const_int 0)))
9860    (clobber (match_scratch:SWI 0 "=<r>"))]
9861   "(optimize_function_for_size_p (cfun)
9862     || !TARGET_PARTIAL_FLAG_REG_STALL
9863     || (operands[2] == const1_rtx
9864         && TARGET_SHIFT1))
9865    && ix86_match_ccmode (insn, CCGOCmode)"
9866 {
9867   if (operands[2] == const1_rtx
9868       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869     return "<shiftrt>{<imodesuffix>}\t%0";
9870   else
9871     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9872 }
9873   [(set_attr "type" "ishift")
9874    (set (attr "length_immediate")
9875      (if_then_else
9876        (and (match_operand 2 "const1_operand" "")
9877             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9878                 (const_int 0)))
9879        (const_string "0")
9880        (const_string "*")))
9881    (set_attr "mode" "<MODE>")])
9882 \f
9883 ;; Rotate instructions
9884
9885 (define_expand "<rotate_insn>ti3"
9886   [(set (match_operand:TI 0 "register_operand" "")
9887         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9888                        (match_operand:QI 2 "nonmemory_operand" "")))]
9889   "TARGET_64BIT"
9890 {
9891   if (const_1_to_63_operand (operands[2], VOIDmode))
9892     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9893                 (operands[0], operands[1], operands[2]));
9894   else
9895     FAIL;
9896
9897   DONE;
9898 })
9899
9900 (define_expand "<rotate_insn>di3"
9901   [(set (match_operand:DI 0 "shiftdi_operand" "")
9902         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9903                        (match_operand:QI 2 "nonmemory_operand" "")))]
9904  ""
9905 {
9906   if (TARGET_64BIT)
9907     ix86_expand_binary_operator (<CODE>, DImode, operands);
9908   else if (const_1_to_31_operand (operands[2], VOIDmode))
9909     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9910                 (operands[0], operands[1], operands[2]));
9911   else
9912     FAIL;
9913
9914   DONE;
9915 })
9916
9917 (define_expand "<rotate_insn><mode>3"
9918   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9919         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9920                             (match_operand:QI 2 "nonmemory_operand" "")))]
9921   ""
9922   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9923
9924 ;; Avoid useless masking of count operand.
9925 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9926   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9927         (any_rotate:SWI48
9928           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9929           (subreg:QI
9930             (and:SI
9931               (match_operand:SI 2 "nonimmediate_operand" "c")
9932               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9933    (clobber (reg:CC FLAGS_REG))]
9934   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9935    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9936       == GET_MODE_BITSIZE (<MODE>mode)-1"
9937   "#"
9938   "&& 1"
9939   [(parallel [(set (match_dup 0)
9940                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9941               (clobber (reg:CC FLAGS_REG))])]
9942 {
9943   if (can_create_pseudo_p ())
9944     operands [2] = force_reg (SImode, operands[2]);
9945
9946   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9947 }
9948   [(set_attr "type" "rotate")
9949    (set_attr "mode" "<MODE>")])
9950
9951 ;; Implement rotation using two double-precision
9952 ;; shift instructions and a scratch register.
9953
9954 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9955  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9956        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9957                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9958   (clobber (reg:CC FLAGS_REG))
9959   (clobber (match_scratch:DWIH 3 "=&r"))]
9960  ""
9961  "#"
9962  "reload_completed"
9963  [(set (match_dup 3) (match_dup 4))
9964   (parallel
9965    [(set (match_dup 4)
9966          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9967                    (lshiftrt:DWIH (match_dup 5)
9968                                   (minus:QI (match_dup 6) (match_dup 2)))))
9969     (clobber (reg:CC FLAGS_REG))])
9970   (parallel
9971    [(set (match_dup 5)
9972          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9973                    (lshiftrt:DWIH (match_dup 3)
9974                                   (minus:QI (match_dup 6) (match_dup 2)))))
9975     (clobber (reg:CC FLAGS_REG))])]
9976 {
9977   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9978
9979   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9980 })
9981
9982 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9983  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9984        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9985                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9986   (clobber (reg:CC FLAGS_REG))
9987   (clobber (match_scratch:DWIH 3 "=&r"))]
9988  ""
9989  "#"
9990  "reload_completed"
9991  [(set (match_dup 3) (match_dup 4))
9992   (parallel
9993    [(set (match_dup 4)
9994          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9995                    (ashift:DWIH (match_dup 5)
9996                                 (minus:QI (match_dup 6) (match_dup 2)))))
9997     (clobber (reg:CC FLAGS_REG))])
9998   (parallel
9999    [(set (match_dup 5)
10000          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10001                    (ashift:DWIH (match_dup 3)
10002                                 (minus:QI (match_dup 6) (match_dup 2)))))
10003     (clobber (reg:CC FLAGS_REG))])]
10004 {
10005   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10006
10007   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10008 })
10009
10010 (define_insn "*<rotate_insn><mode>3_1"
10011   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10012         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10013                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10014    (clobber (reg:CC FLAGS_REG))]
10015   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10016 {
10017   if (operands[2] == const1_rtx
10018       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10019     return "<rotate>{<imodesuffix>}\t%0";
10020   else
10021     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10022 }
10023   [(set_attr "type" "rotate")
10024    (set (attr "length_immediate")
10025      (if_then_else
10026        (and (match_operand 2 "const1_operand" "")
10027             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10028                 (const_int 0)))
10029        (const_string "0")
10030        (const_string "*")))
10031    (set_attr "mode" "<MODE>")])
10032
10033 (define_insn "*<rotate_insn>si3_1_zext"
10034   [(set (match_operand:DI 0 "register_operand" "=r")
10035         (zero_extend:DI
10036           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10037                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10038    (clobber (reg:CC FLAGS_REG))]
10039   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10040 {
10041     if (operands[2] == const1_rtx
10042         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10043     return "<rotate>{l}\t%k0";
10044   else
10045     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10046 }
10047   [(set_attr "type" "rotate")
10048    (set (attr "length_immediate")
10049      (if_then_else
10050        (and (match_operand 2 "const1_operand" "")
10051             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10052                 (const_int 0)))
10053        (const_string "0")
10054        (const_string "*")))
10055    (set_attr "mode" "SI")])
10056
10057 (define_insn "*<rotate_insn>qi3_1_slp"
10058   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10059         (any_rotate:QI (match_dup 0)
10060                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10061    (clobber (reg:CC FLAGS_REG))]
10062   "(optimize_function_for_size_p (cfun)
10063     || !TARGET_PARTIAL_REG_STALL
10064     || (operands[1] == const1_rtx
10065         && TARGET_SHIFT1))"
10066 {
10067   if (operands[1] == const1_rtx
10068       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10069     return "<rotate>{b}\t%0";
10070   else
10071     return "<rotate>{b}\t{%1, %0|%0, %1}";
10072 }
10073   [(set_attr "type" "rotate1")
10074    (set (attr "length_immediate")
10075      (if_then_else
10076        (and (match_operand 1 "const1_operand" "")
10077             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10078                 (const_int 0)))
10079        (const_string "0")
10080        (const_string "*")))
10081    (set_attr "mode" "QI")])
10082
10083 (define_split
10084  [(set (match_operand:HI 0 "register_operand" "")
10085        (any_rotate:HI (match_dup 0) (const_int 8)))
10086   (clobber (reg:CC FLAGS_REG))]
10087  "reload_completed
10088   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10089  [(parallel [(set (strict_low_part (match_dup 0))
10090                   (bswap:HI (match_dup 0)))
10091              (clobber (reg:CC FLAGS_REG))])])
10092 \f
10093 ;; Bit set / bit test instructions
10094
10095 (define_expand "extv"
10096   [(set (match_operand:SI 0 "register_operand" "")
10097         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10098                          (match_operand:SI 2 "const8_operand" "")
10099                          (match_operand:SI 3 "const8_operand" "")))]
10100   ""
10101 {
10102   /* Handle extractions from %ah et al.  */
10103   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10104     FAIL;
10105
10106   /* From mips.md: extract_bit_field doesn't verify that our source
10107      matches the predicate, so check it again here.  */
10108   if (! ext_register_operand (operands[1], VOIDmode))
10109     FAIL;
10110 })
10111
10112 (define_expand "extzv"
10113   [(set (match_operand:SI 0 "register_operand" "")
10114         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10115                          (match_operand:SI 2 "const8_operand" "")
10116                          (match_operand:SI 3 "const8_operand" "")))]
10117   ""
10118 {
10119   /* Handle extractions from %ah et al.  */
10120   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10121     FAIL;
10122
10123   /* From mips.md: extract_bit_field doesn't verify that our source
10124      matches the predicate, so check it again here.  */
10125   if (! ext_register_operand (operands[1], VOIDmode))
10126     FAIL;
10127 })
10128
10129 (define_expand "insv"
10130   [(set (zero_extract (match_operand 0 "register_operand" "")
10131                       (match_operand 1 "const_int_operand" "")
10132                       (match_operand 2 "const_int_operand" ""))
10133         (match_operand 3 "register_operand" ""))]
10134   ""
10135 {
10136   rtx (*gen_mov_insv_1) (rtx, rtx);
10137
10138   if (ix86_expand_pinsr (operands))
10139     DONE;
10140
10141   /* Handle insertions to %ah et al.  */
10142   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10143     FAIL;
10144
10145   /* From mips.md: insert_bit_field doesn't verify that our source
10146      matches the predicate, so check it again here.  */
10147   if (! ext_register_operand (operands[0], VOIDmode))
10148     FAIL;
10149
10150   gen_mov_insv_1 = (TARGET_64BIT
10151                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10152
10153   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10154   DONE;
10155 })
10156
10157 ;; %%% bts, btr, btc, bt.
10158 ;; In general these instructions are *slow* when applied to memory,
10159 ;; since they enforce atomic operation.  When applied to registers,
10160 ;; it depends on the cpu implementation.  They're never faster than
10161 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10162 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10163 ;; within the instruction itself, so operating on bits in the high
10164 ;; 32-bits of a register becomes easier.
10165 ;;
10166 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10167 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10168 ;; negdf respectively, so they can never be disabled entirely.
10169
10170 (define_insn "*btsq"
10171   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10172                          (const_int 1)
10173                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10174         (const_int 1))
10175    (clobber (reg:CC FLAGS_REG))]
10176   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10177   "bts{q}\t{%1, %0|%0, %1}"
10178   [(set_attr "type" "alu1")
10179    (set_attr "prefix_0f" "1")
10180    (set_attr "mode" "DI")])
10181
10182 (define_insn "*btrq"
10183   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10184                          (const_int 1)
10185                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10186         (const_int 0))
10187    (clobber (reg:CC FLAGS_REG))]
10188   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10189   "btr{q}\t{%1, %0|%0, %1}"
10190   [(set_attr "type" "alu1")
10191    (set_attr "prefix_0f" "1")
10192    (set_attr "mode" "DI")])
10193
10194 (define_insn "*btcq"
10195   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10196                          (const_int 1)
10197                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10198         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10199    (clobber (reg:CC FLAGS_REG))]
10200   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10201   "btc{q}\t{%1, %0|%0, %1}"
10202   [(set_attr "type" "alu1")
10203    (set_attr "prefix_0f" "1")
10204    (set_attr "mode" "DI")])
10205
10206 ;; Allow Nocona to avoid these instructions if a register is available.
10207
10208 (define_peephole2
10209   [(match_scratch:DI 2 "r")
10210    (parallel [(set (zero_extract:DI
10211                      (match_operand:DI 0 "register_operand" "")
10212                      (const_int 1)
10213                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10214                    (const_int 1))
10215               (clobber (reg:CC FLAGS_REG))])]
10216   "TARGET_64BIT && !TARGET_USE_BT"
10217   [(const_int 0)]
10218 {
10219   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10220   rtx op1;
10221
10222   if (HOST_BITS_PER_WIDE_INT >= 64)
10223     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10224   else if (i < HOST_BITS_PER_WIDE_INT)
10225     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10226   else
10227     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10228
10229   op1 = immed_double_const (lo, hi, DImode);
10230   if (i >= 31)
10231     {
10232       emit_move_insn (operands[2], op1);
10233       op1 = operands[2];
10234     }
10235
10236   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10237   DONE;
10238 })
10239
10240 (define_peephole2
10241   [(match_scratch:DI 2 "r")
10242    (parallel [(set (zero_extract:DI
10243                      (match_operand:DI 0 "register_operand" "")
10244                      (const_int 1)
10245                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10246                    (const_int 0))
10247               (clobber (reg:CC FLAGS_REG))])]
10248   "TARGET_64BIT && !TARGET_USE_BT"
10249   [(const_int 0)]
10250 {
10251   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10252   rtx op1;
10253
10254   if (HOST_BITS_PER_WIDE_INT >= 64)
10255     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10256   else if (i < HOST_BITS_PER_WIDE_INT)
10257     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10258   else
10259     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10260
10261   op1 = immed_double_const (~lo, ~hi, DImode);
10262   if (i >= 32)
10263     {
10264       emit_move_insn (operands[2], op1);
10265       op1 = operands[2];
10266     }
10267
10268   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10269   DONE;
10270 })
10271
10272 (define_peephole2
10273   [(match_scratch:DI 2 "r")
10274    (parallel [(set (zero_extract:DI
10275                      (match_operand:DI 0 "register_operand" "")
10276                      (const_int 1)
10277                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10278               (not:DI (zero_extract:DI
10279                         (match_dup 0) (const_int 1) (match_dup 1))))
10280               (clobber (reg:CC FLAGS_REG))])]
10281   "TARGET_64BIT && !TARGET_USE_BT"
10282   [(const_int 0)]
10283 {
10284   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10285   rtx op1;
10286
10287   if (HOST_BITS_PER_WIDE_INT >= 64)
10288     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10289   else if (i < HOST_BITS_PER_WIDE_INT)
10290     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10291   else
10292     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10293
10294   op1 = immed_double_const (lo, hi, DImode);
10295   if (i >= 31)
10296     {
10297       emit_move_insn (operands[2], op1);
10298       op1 = operands[2];
10299     }
10300
10301   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10302   DONE;
10303 })
10304
10305 (define_insn "*bt<mode>"
10306   [(set (reg:CCC FLAGS_REG)
10307         (compare:CCC
10308           (zero_extract:SWI48
10309             (match_operand:SWI48 0 "register_operand" "r")
10310             (const_int 1)
10311             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10312           (const_int 0)))]
10313   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10314   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10315   [(set_attr "type" "alu1")
10316    (set_attr "prefix_0f" "1")
10317    (set_attr "mode" "<MODE>")])
10318 \f
10319 ;; Store-flag instructions.
10320
10321 ;; For all sCOND expanders, also expand the compare or test insn that
10322 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10323
10324 (define_insn_and_split "*setcc_di_1"
10325   [(set (match_operand:DI 0 "register_operand" "=q")
10326         (match_operator:DI 1 "ix86_comparison_operator"
10327           [(reg FLAGS_REG) (const_int 0)]))]
10328   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10329   "#"
10330   "&& reload_completed"
10331   [(set (match_dup 2) (match_dup 1))
10332    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10333 {
10334   PUT_MODE (operands[1], QImode);
10335   operands[2] = gen_lowpart (QImode, operands[0]);
10336 })
10337
10338 (define_insn_and_split "*setcc_si_1_and"
10339   [(set (match_operand:SI 0 "register_operand" "=q")
10340         (match_operator:SI 1 "ix86_comparison_operator"
10341           [(reg FLAGS_REG) (const_int 0)]))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "!TARGET_PARTIAL_REG_STALL
10344    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10345   "#"
10346   "&& reload_completed"
10347   [(set (match_dup 2) (match_dup 1))
10348    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10349               (clobber (reg:CC FLAGS_REG))])]
10350 {
10351   PUT_MODE (operands[1], QImode);
10352   operands[2] = gen_lowpart (QImode, operands[0]);
10353 })
10354
10355 (define_insn_and_split "*setcc_si_1_movzbl"
10356   [(set (match_operand:SI 0 "register_operand" "=q")
10357         (match_operator:SI 1 "ix86_comparison_operator"
10358           [(reg FLAGS_REG) (const_int 0)]))]
10359   "!TARGET_PARTIAL_REG_STALL
10360    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10361   "#"
10362   "&& reload_completed"
10363   [(set (match_dup 2) (match_dup 1))
10364    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10365 {
10366   PUT_MODE (operands[1], QImode);
10367   operands[2] = gen_lowpart (QImode, operands[0]);
10368 })
10369
10370 (define_insn "*setcc_qi"
10371   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10372         (match_operator:QI 1 "ix86_comparison_operator"
10373           [(reg FLAGS_REG) (const_int 0)]))]
10374   ""
10375   "set%C1\t%0"
10376   [(set_attr "type" "setcc")
10377    (set_attr "mode" "QI")])
10378
10379 (define_insn "*setcc_qi_slp"
10380   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10381         (match_operator:QI 1 "ix86_comparison_operator"
10382           [(reg FLAGS_REG) (const_int 0)]))]
10383   ""
10384   "set%C1\t%0"
10385   [(set_attr "type" "setcc")
10386    (set_attr "mode" "QI")])
10387
10388 ;; In general it is not safe to assume too much about CCmode registers,
10389 ;; so simplify-rtx stops when it sees a second one.  Under certain
10390 ;; conditions this is safe on x86, so help combine not create
10391 ;;
10392 ;;      seta    %al
10393 ;;      testb   %al, %al
10394 ;;      sete    %al
10395
10396 (define_split
10397   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10398         (ne:QI (match_operator 1 "ix86_comparison_operator"
10399                  [(reg FLAGS_REG) (const_int 0)])
10400             (const_int 0)))]
10401   ""
10402   [(set (match_dup 0) (match_dup 1))]
10403   "PUT_MODE (operands[1], QImode);")
10404
10405 (define_split
10406   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10407         (ne:QI (match_operator 1 "ix86_comparison_operator"
10408                  [(reg FLAGS_REG) (const_int 0)])
10409             (const_int 0)))]
10410   ""
10411   [(set (match_dup 0) (match_dup 1))]
10412   "PUT_MODE (operands[1], QImode);")
10413
10414 (define_split
10415   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10416         (eq:QI (match_operator 1 "ix86_comparison_operator"
10417                  [(reg FLAGS_REG) (const_int 0)])
10418             (const_int 0)))]
10419   ""
10420   [(set (match_dup 0) (match_dup 1))]
10421 {
10422   rtx new_op1 = copy_rtx (operands[1]);
10423   operands[1] = new_op1;
10424   PUT_MODE (new_op1, QImode);
10425   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10426                                              GET_MODE (XEXP (new_op1, 0))));
10427
10428   /* Make sure that (a) the CCmode we have for the flags is strong
10429      enough for the reversed compare or (b) we have a valid FP compare.  */
10430   if (! ix86_comparison_operator (new_op1, VOIDmode))
10431     FAIL;
10432 })
10433
10434 (define_split
10435   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10436         (eq:QI (match_operator 1 "ix86_comparison_operator"
10437                  [(reg FLAGS_REG) (const_int 0)])
10438             (const_int 0)))]
10439   ""
10440   [(set (match_dup 0) (match_dup 1))]
10441 {
10442   rtx new_op1 = copy_rtx (operands[1]);
10443   operands[1] = new_op1;
10444   PUT_MODE (new_op1, QImode);
10445   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10446                                              GET_MODE (XEXP (new_op1, 0))));
10447
10448   /* Make sure that (a) the CCmode we have for the flags is strong
10449      enough for the reversed compare or (b) we have a valid FP compare.  */
10450   if (! ix86_comparison_operator (new_op1, VOIDmode))
10451     FAIL;
10452 })
10453
10454 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10455 ;; subsequent logical operations are used to imitate conditional moves.
10456 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10457 ;; it directly.
10458
10459 (define_insn "setcc_<mode>_sse"
10460   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10461         (match_operator:MODEF 3 "sse_comparison_operator"
10462           [(match_operand:MODEF 1 "register_operand" "0,x")
10463            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10464   "SSE_FLOAT_MODE_P (<MODE>mode)"
10465   "@
10466    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10467    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10468   [(set_attr "isa" "noavx,avx")
10469    (set_attr "type" "ssecmp")
10470    (set_attr "length_immediate" "1")
10471    (set_attr "prefix" "orig,vex")
10472    (set_attr "mode" "<MODE>")])
10473 \f
10474 ;; Basic conditional jump instructions.
10475 ;; We ignore the overflow flag for signed branch instructions.
10476
10477 (define_insn "*jcc_1"
10478   [(set (pc)
10479         (if_then_else (match_operator 1 "ix86_comparison_operator"
10480                                       [(reg FLAGS_REG) (const_int 0)])
10481                       (label_ref (match_operand 0 "" ""))
10482                       (pc)))]
10483   ""
10484   "%+j%C1\t%l0"
10485   [(set_attr "type" "ibr")
10486    (set_attr "modrm" "0")
10487    (set (attr "length")
10488            (if_then_else (and (ge (minus (match_dup 0) (pc))
10489                                   (const_int -126))
10490                               (lt (minus (match_dup 0) (pc))
10491                                   (const_int 128)))
10492              (const_int 2)
10493              (const_int 6)))])
10494
10495 (define_insn "*jcc_2"
10496   [(set (pc)
10497         (if_then_else (match_operator 1 "ix86_comparison_operator"
10498                                       [(reg FLAGS_REG) (const_int 0)])
10499                       (pc)
10500                       (label_ref (match_operand 0 "" ""))))]
10501   ""
10502   "%+j%c1\t%l0"
10503   [(set_attr "type" "ibr")
10504    (set_attr "modrm" "0")
10505    (set (attr "length")
10506            (if_then_else (and (ge (minus (match_dup 0) (pc))
10507                                   (const_int -126))
10508                               (lt (minus (match_dup 0) (pc))
10509                                   (const_int 128)))
10510              (const_int 2)
10511              (const_int 6)))])
10512
10513 ;; In general it is not safe to assume too much about CCmode registers,
10514 ;; so simplify-rtx stops when it sees a second one.  Under certain
10515 ;; conditions this is safe on x86, so help combine not create
10516 ;;
10517 ;;      seta    %al
10518 ;;      testb   %al, %al
10519 ;;      je      Lfoo
10520
10521 (define_split
10522   [(set (pc)
10523         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10524                                       [(reg FLAGS_REG) (const_int 0)])
10525                           (const_int 0))
10526                       (label_ref (match_operand 1 "" ""))
10527                       (pc)))]
10528   ""
10529   [(set (pc)
10530         (if_then_else (match_dup 0)
10531                       (label_ref (match_dup 1))
10532                       (pc)))]
10533   "PUT_MODE (operands[0], VOIDmode);")
10534
10535 (define_split
10536   [(set (pc)
10537         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10538                                       [(reg FLAGS_REG) (const_int 0)])
10539                           (const_int 0))
10540                       (label_ref (match_operand 1 "" ""))
10541                       (pc)))]
10542   ""
10543   [(set (pc)
10544         (if_then_else (match_dup 0)
10545                       (label_ref (match_dup 1))
10546                       (pc)))]
10547 {
10548   rtx new_op0 = copy_rtx (operands[0]);
10549   operands[0] = new_op0;
10550   PUT_MODE (new_op0, VOIDmode);
10551   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10552                                              GET_MODE (XEXP (new_op0, 0))));
10553
10554   /* Make sure that (a) the CCmode we have for the flags is strong
10555      enough for the reversed compare or (b) we have a valid FP compare.  */
10556   if (! ix86_comparison_operator (new_op0, VOIDmode))
10557     FAIL;
10558 })
10559
10560 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10561 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10562 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10563 ;; appropriate modulo of the bit offset value.
10564
10565 (define_insn_and_split "*jcc_bt<mode>"
10566   [(set (pc)
10567         (if_then_else (match_operator 0 "bt_comparison_operator"
10568                         [(zero_extract:SWI48
10569                            (match_operand:SWI48 1 "register_operand" "r")
10570                            (const_int 1)
10571                            (zero_extend:SI
10572                              (match_operand:QI 2 "register_operand" "r")))
10573                          (const_int 0)])
10574                       (label_ref (match_operand 3 "" ""))
10575                       (pc)))
10576    (clobber (reg:CC FLAGS_REG))]
10577   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10578   "#"
10579   "&& 1"
10580   [(set (reg:CCC FLAGS_REG)
10581         (compare:CCC
10582           (zero_extract:SWI48
10583             (match_dup 1)
10584             (const_int 1)
10585             (match_dup 2))
10586           (const_int 0)))
10587    (set (pc)
10588         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10589                       (label_ref (match_dup 3))
10590                       (pc)))]
10591 {
10592   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10593
10594   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10595 })
10596
10597 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10598 ;; also for DImode, this is what combine produces.
10599 (define_insn_and_split "*jcc_bt<mode>_mask"
10600   [(set (pc)
10601         (if_then_else (match_operator 0 "bt_comparison_operator"
10602                         [(zero_extract:SWI48
10603                            (match_operand:SWI48 1 "register_operand" "r")
10604                            (const_int 1)
10605                            (and:SI
10606                              (match_operand:SI 2 "register_operand" "r")
10607                              (match_operand:SI 3 "const_int_operand" "n")))])
10608                       (label_ref (match_operand 4 "" ""))
10609                       (pc)))
10610    (clobber (reg:CC FLAGS_REG))]
10611   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10612    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10613       == GET_MODE_BITSIZE (<MODE>mode)-1"
10614   "#"
10615   "&& 1"
10616   [(set (reg:CCC FLAGS_REG)
10617         (compare:CCC
10618           (zero_extract:SWI48
10619             (match_dup 1)
10620             (const_int 1)
10621             (match_dup 2))
10622           (const_int 0)))
10623    (set (pc)
10624         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10625                       (label_ref (match_dup 4))
10626                       (pc)))]
10627 {
10628   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10629
10630   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10631 })
10632
10633 (define_insn_and_split "*jcc_btsi_1"
10634   [(set (pc)
10635         (if_then_else (match_operator 0 "bt_comparison_operator"
10636                         [(and:SI
10637                            (lshiftrt:SI
10638                              (match_operand:SI 1 "register_operand" "r")
10639                              (match_operand:QI 2 "register_operand" "r"))
10640                            (const_int 1))
10641                          (const_int 0)])
10642                       (label_ref (match_operand 3 "" ""))
10643                       (pc)))
10644    (clobber (reg:CC FLAGS_REG))]
10645   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10646   "#"
10647   "&& 1"
10648   [(set (reg:CCC FLAGS_REG)
10649         (compare:CCC
10650           (zero_extract:SI
10651             (match_dup 1)
10652             (const_int 1)
10653             (match_dup 2))
10654           (const_int 0)))
10655    (set (pc)
10656         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10657                       (label_ref (match_dup 3))
10658                       (pc)))]
10659 {
10660   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10661
10662   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10663 })
10664
10665 ;; avoid useless masking of bit offset operand
10666 (define_insn_and_split "*jcc_btsi_mask_1"
10667   [(set (pc)
10668         (if_then_else
10669           (match_operator 0 "bt_comparison_operator"
10670             [(and:SI
10671                (lshiftrt:SI
10672                  (match_operand:SI 1 "register_operand" "r")
10673                  (subreg:QI
10674                    (and:SI
10675                      (match_operand:SI 2 "register_operand" "r")
10676                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10677                (const_int 1))
10678              (const_int 0)])
10679           (label_ref (match_operand 4 "" ""))
10680           (pc)))
10681    (clobber (reg:CC FLAGS_REG))]
10682   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10683    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10684   "#"
10685   "&& 1"
10686   [(set (reg:CCC FLAGS_REG)
10687         (compare:CCC
10688           (zero_extract:SI
10689             (match_dup 1)
10690             (const_int 1)
10691             (match_dup 2))
10692           (const_int 0)))
10693    (set (pc)
10694         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10695                       (label_ref (match_dup 4))
10696                       (pc)))]
10697   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10698
10699 ;; Define combination compare-and-branch fp compare instructions to help
10700 ;; combine.
10701
10702 (define_insn "*fp_jcc_1_387"
10703   [(set (pc)
10704         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10705                         [(match_operand 1 "register_operand" "f")
10706                          (match_operand 2 "nonimmediate_operand" "fm")])
10707           (label_ref (match_operand 3 "" ""))
10708           (pc)))
10709    (clobber (reg:CCFP FPSR_REG))
10710    (clobber (reg:CCFP FLAGS_REG))
10711    (clobber (match_scratch:HI 4 "=a"))]
10712   "TARGET_80387
10713    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10714    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10715    && SELECT_CC_MODE (GET_CODE (operands[0]),
10716                       operands[1], operands[2]) == CCFPmode
10717    && !TARGET_CMOVE"
10718   "#")
10719
10720 (define_insn "*fp_jcc_1r_387"
10721   [(set (pc)
10722         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10723                         [(match_operand 1 "register_operand" "f")
10724                          (match_operand 2 "nonimmediate_operand" "fm")])
10725           (pc)
10726           (label_ref (match_operand 3 "" ""))))
10727    (clobber (reg:CCFP FPSR_REG))
10728    (clobber (reg:CCFP FLAGS_REG))
10729    (clobber (match_scratch:HI 4 "=a"))]
10730   "TARGET_80387
10731    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10732    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10733    && SELECT_CC_MODE (GET_CODE (operands[0]),
10734                       operands[1], operands[2]) == CCFPmode
10735    && !TARGET_CMOVE"
10736   "#")
10737
10738 (define_insn "*fp_jcc_2_387"
10739   [(set (pc)
10740         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10741                         [(match_operand 1 "register_operand" "f")
10742                          (match_operand 2 "register_operand" "f")])
10743           (label_ref (match_operand 3 "" ""))
10744           (pc)))
10745    (clobber (reg:CCFP FPSR_REG))
10746    (clobber (reg:CCFP FLAGS_REG))
10747    (clobber (match_scratch:HI 4 "=a"))]
10748   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10749    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10750    && !TARGET_CMOVE"
10751   "#")
10752
10753 (define_insn "*fp_jcc_2r_387"
10754   [(set (pc)
10755         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10756                         [(match_operand 1 "register_operand" "f")
10757                          (match_operand 2 "register_operand" "f")])
10758           (pc)
10759           (label_ref (match_operand 3 "" ""))))
10760    (clobber (reg:CCFP FPSR_REG))
10761    (clobber (reg:CCFP FLAGS_REG))
10762    (clobber (match_scratch:HI 4 "=a"))]
10763   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10764    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10765    && !TARGET_CMOVE"
10766   "#")
10767
10768 (define_insn "*fp_jcc_3_387"
10769   [(set (pc)
10770         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10771                         [(match_operand 1 "register_operand" "f")
10772                          (match_operand 2 "const0_operand" "")])
10773           (label_ref (match_operand 3 "" ""))
10774           (pc)))
10775    (clobber (reg:CCFP FPSR_REG))
10776    (clobber (reg:CCFP FLAGS_REG))
10777    (clobber (match_scratch:HI 4 "=a"))]
10778   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10779    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10780    && SELECT_CC_MODE (GET_CODE (operands[0]),
10781                       operands[1], operands[2]) == CCFPmode
10782    && !TARGET_CMOVE"
10783   "#")
10784
10785 (define_split
10786   [(set (pc)
10787         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10788                         [(match_operand 1 "register_operand" "")
10789                          (match_operand 2 "nonimmediate_operand" "")])
10790           (match_operand 3 "" "")
10791           (match_operand 4 "" "")))
10792    (clobber (reg:CCFP FPSR_REG))
10793    (clobber (reg:CCFP FLAGS_REG))]
10794   "reload_completed"
10795   [(const_int 0)]
10796 {
10797   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10798                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10799   DONE;
10800 })
10801
10802 (define_split
10803   [(set (pc)
10804         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10805                         [(match_operand 1 "register_operand" "")
10806                          (match_operand 2 "general_operand" "")])
10807           (match_operand 3 "" "")
10808           (match_operand 4 "" "")))
10809    (clobber (reg:CCFP FPSR_REG))
10810    (clobber (reg:CCFP FLAGS_REG))
10811    (clobber (match_scratch:HI 5 "=a"))]
10812   "reload_completed"
10813   [(const_int 0)]
10814 {
10815   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10816                         operands[3], operands[4], operands[5], NULL_RTX);
10817   DONE;
10818 })
10819
10820 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10821 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10822 ;; with a precedence over other operators and is always put in the first
10823 ;; place. Swap condition and operands to match ficom instruction.
10824
10825 (define_insn "*fp_jcc_4_<mode>_387"
10826   [(set (pc)
10827         (if_then_else
10828           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10829             [(match_operator 1 "float_operator"
10830               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10831              (match_operand 3 "register_operand" "f,f")])
10832           (label_ref (match_operand 4 "" ""))
10833           (pc)))
10834    (clobber (reg:CCFP FPSR_REG))
10835    (clobber (reg:CCFP FLAGS_REG))
10836    (clobber (match_scratch:HI 5 "=a,a"))]
10837   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10838    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10839    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10840    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10841    && !TARGET_CMOVE"
10842   "#")
10843
10844 (define_split
10845   [(set (pc)
10846         (if_then_else
10847           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10848             [(match_operator 1 "float_operator"
10849               [(match_operand:SWI24 2 "memory_operand" "")])
10850              (match_operand 3 "register_operand" "")])
10851           (match_operand 4 "" "")
10852           (match_operand 5 "" "")))
10853    (clobber (reg:CCFP FPSR_REG))
10854    (clobber (reg:CCFP FLAGS_REG))
10855    (clobber (match_scratch:HI 6 "=a"))]
10856   "reload_completed"
10857   [(const_int 0)]
10858 {
10859   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10860
10861   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10862                         operands[3], operands[7],
10863                         operands[4], operands[5], operands[6], NULL_RTX);
10864   DONE;
10865 })
10866
10867 ;; %%% Kill this when reload knows how to do it.
10868 (define_split
10869   [(set (pc)
10870         (if_then_else
10871           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10872             [(match_operator 1 "float_operator"
10873               [(match_operand:SWI24 2 "register_operand" "")])
10874              (match_operand 3 "register_operand" "")])
10875           (match_operand 4 "" "")
10876           (match_operand 5 "" "")))
10877    (clobber (reg:CCFP FPSR_REG))
10878    (clobber (reg:CCFP FLAGS_REG))
10879    (clobber (match_scratch:HI 6 "=a"))]
10880   "reload_completed"
10881   [(const_int 0)]
10882 {
10883   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10884   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10885
10886   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10887                         operands[3], operands[7],
10888                         operands[4], operands[5], operands[6], operands[2]);
10889   DONE;
10890 })
10891 \f
10892 ;; Unconditional and other jump instructions
10893
10894 (define_insn "jump"
10895   [(set (pc)
10896         (label_ref (match_operand 0 "" "")))]
10897   ""
10898   "jmp\t%l0"
10899   [(set_attr "type" "ibr")
10900    (set (attr "length")
10901            (if_then_else (and (ge (minus (match_dup 0) (pc))
10902                                   (const_int -126))
10903                               (lt (minus (match_dup 0) (pc))
10904                                   (const_int 128)))
10905              (const_int 2)
10906              (const_int 5)))
10907    (set_attr "modrm" "0")])
10908
10909 (define_expand "indirect_jump"
10910   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
10911
10912 (define_insn "*indirect_jump"
10913   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
10914   ""
10915   "jmp\t%A0"
10916   [(set_attr "type" "ibr")
10917    (set_attr "length_immediate" "0")])
10918
10919 (define_expand "tablejump"
10920   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
10921               (use (label_ref (match_operand 1 "" "")))])]
10922   ""
10923 {
10924   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10925      relative.  Convert the relative address to an absolute address.  */
10926   if (flag_pic)
10927     {
10928       rtx op0, op1;
10929       enum rtx_code code;
10930
10931       /* We can't use @GOTOFF for text labels on VxWorks;
10932          see gotoff_operand.  */
10933       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10934         {
10935           code = PLUS;
10936           op0 = operands[0];
10937           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10938         }
10939       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10940         {
10941           code = PLUS;
10942           op0 = operands[0];
10943           op1 = pic_offset_table_rtx;
10944         }
10945       else
10946         {
10947           code = MINUS;
10948           op0 = pic_offset_table_rtx;
10949           op1 = operands[0];
10950         }
10951
10952       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10953                                          OPTAB_DIRECT);
10954     }
10955   else if (TARGET_X32)
10956     operands[0] = convert_memory_address (Pmode, operands[0]);
10957 })
10958
10959 (define_insn "*tablejump_1"
10960   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
10961    (use (label_ref (match_operand 1 "" "")))]
10962   ""
10963   "jmp\t%A0"
10964   [(set_attr "type" "ibr")
10965    (set_attr "length_immediate" "0")])
10966 \f
10967 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10968
10969 (define_peephole2
10970   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10971    (set (match_operand:QI 1 "register_operand" "")
10972         (match_operator:QI 2 "ix86_comparison_operator"
10973           [(reg FLAGS_REG) (const_int 0)]))
10974    (set (match_operand 3 "q_regs_operand" "")
10975         (zero_extend (match_dup 1)))]
10976   "(peep2_reg_dead_p (3, operands[1])
10977     || operands_match_p (operands[1], operands[3]))
10978    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10979   [(set (match_dup 4) (match_dup 0))
10980    (set (strict_low_part (match_dup 5))
10981         (match_dup 2))]
10982 {
10983   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10984   operands[5] = gen_lowpart (QImode, operands[3]);
10985   ix86_expand_clear (operands[3]);
10986 })
10987
10988 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
10989
10990 (define_peephole2
10991   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10992    (set (match_operand:QI 1 "register_operand" "")
10993         (match_operator:QI 2 "ix86_comparison_operator"
10994           [(reg FLAGS_REG) (const_int 0)]))
10995    (parallel [(set (match_operand 3 "q_regs_operand" "")
10996                    (zero_extend (match_dup 1)))
10997               (clobber (reg:CC FLAGS_REG))])]
10998   "(peep2_reg_dead_p (3, operands[1])
10999     || operands_match_p (operands[1], operands[3]))
11000    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11001   [(set (match_dup 4) (match_dup 0))
11002    (set (strict_low_part (match_dup 5))
11003         (match_dup 2))]
11004 {
11005   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11006   operands[5] = gen_lowpart (QImode, operands[3]);
11007   ix86_expand_clear (operands[3]);
11008 })
11009 \f
11010 ;; Call instructions.
11011
11012 ;; The predicates normally associated with named expanders are not properly
11013 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11014 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11015
11016 ;; P6 processors will jump to the address after the decrement when %esp
11017 ;; is used as a call operand, so they will execute return address as a code.
11018 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11019
11020 ;; Register constraint for call instruction.
11021 (define_mode_attr c [(SI "l") (DI "r")])
11022
11023 ;; Call subroutine returning no value.
11024
11025 (define_expand "call"
11026   [(call (match_operand:QI 0 "" "")
11027          (match_operand 1 "" ""))
11028    (use (match_operand 2 "" ""))]
11029   ""
11030 {
11031   ix86_expand_call (NULL, operands[0], operands[1],
11032                     operands[2], NULL, false);
11033   DONE;
11034 })
11035
11036 (define_expand "sibcall"
11037   [(call (match_operand:QI 0 "" "")
11038          (match_operand 1 "" ""))
11039    (use (match_operand 2 "" ""))]
11040   ""
11041 {
11042   ix86_expand_call (NULL, operands[0], operands[1],
11043                     operands[2], NULL, true);
11044   DONE;
11045 })
11046
11047 (define_insn_and_split "*call_vzeroupper"
11048   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11049          (match_operand 1 "" ""))
11050    (unspec [(match_operand 2 "const_int_operand" "")]
11051            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11052   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11053   "#"
11054   "&& reload_completed"
11055   [(const_int 0)]
11056   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11057   [(set_attr "type" "call")])
11058
11059 (define_insn "*call"
11060   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11061          (match_operand 1 "" ""))]
11062   "!SIBLING_CALL_P (insn)"
11063   "* return ix86_output_call_insn (insn, operands[0]);"
11064   [(set_attr "type" "call")])
11065
11066 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11067   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11068          (match_operand 1 "" ""))
11069    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11070    (clobber (reg:TI XMM6_REG))
11071    (clobber (reg:TI XMM7_REG))
11072    (clobber (reg:TI XMM8_REG))
11073    (clobber (reg:TI XMM9_REG))
11074    (clobber (reg:TI XMM10_REG))
11075    (clobber (reg:TI XMM11_REG))
11076    (clobber (reg:TI XMM12_REG))
11077    (clobber (reg:TI XMM13_REG))
11078    (clobber (reg:TI XMM14_REG))
11079    (clobber (reg:TI XMM15_REG))
11080    (clobber (reg:DI SI_REG))
11081    (clobber (reg:DI DI_REG))
11082    (unspec [(match_operand 2 "const_int_operand" "")]
11083            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11084   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11085   "#"
11086   "&& reload_completed"
11087   [(const_int 0)]
11088   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11089   [(set_attr "type" "call")])
11090
11091 (define_insn "*call_rex64_ms_sysv"
11092   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11093          (match_operand 1 "" ""))
11094    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11095    (clobber (reg:TI XMM6_REG))
11096    (clobber (reg:TI XMM7_REG))
11097    (clobber (reg:TI XMM8_REG))
11098    (clobber (reg:TI XMM9_REG))
11099    (clobber (reg:TI XMM10_REG))
11100    (clobber (reg:TI XMM11_REG))
11101    (clobber (reg:TI XMM12_REG))
11102    (clobber (reg:TI XMM13_REG))
11103    (clobber (reg:TI XMM14_REG))
11104    (clobber (reg:TI XMM15_REG))
11105    (clobber (reg:DI SI_REG))
11106    (clobber (reg:DI DI_REG))]
11107   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11108   "* return ix86_output_call_insn (insn, operands[0]);"
11109   [(set_attr "type" "call")])
11110
11111 (define_insn_and_split "*sibcall_vzeroupper"
11112   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11113          (match_operand 1 "" ""))
11114    (unspec [(match_operand 2 "const_int_operand" "")]
11115            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11116   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11117   "#"
11118   "&& reload_completed"
11119   [(const_int 0)]
11120   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11121   [(set_attr "type" "call")])
11122
11123 (define_insn "*sibcall"
11124   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11125          (match_operand 1 "" ""))]
11126   "SIBLING_CALL_P (insn)"
11127   "* return ix86_output_call_insn (insn, operands[0]);"
11128   [(set_attr "type" "call")])
11129
11130 (define_expand "call_pop"
11131   [(parallel [(call (match_operand:QI 0 "" "")
11132                     (match_operand:SI 1 "" ""))
11133               (set (reg:SI SP_REG)
11134                    (plus:SI (reg:SI SP_REG)
11135                             (match_operand:SI 3 "" "")))])]
11136   "!TARGET_64BIT"
11137 {
11138   ix86_expand_call (NULL, operands[0], operands[1],
11139                     operands[2], operands[3], false);
11140   DONE;
11141 })
11142
11143 (define_insn_and_split "*call_pop_vzeroupper"
11144   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11145          (match_operand:SI 1 "" ""))
11146    (set (reg:SI SP_REG)
11147         (plus:SI (reg:SI SP_REG)
11148                  (match_operand:SI 2 "immediate_operand" "i")))
11149    (unspec [(match_operand 3 "const_int_operand" "")]
11150            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11151   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11152   "#"
11153   "&& reload_completed"
11154   [(const_int 0)]
11155   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11156   [(set_attr "type" "call")])
11157
11158 (define_insn "*call_pop"
11159   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11160          (match_operand 1 "" ""))
11161    (set (reg:SI SP_REG)
11162         (plus:SI (reg:SI SP_REG)
11163                  (match_operand:SI 2 "immediate_operand" "i")))]
11164   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11165   "* return ix86_output_call_insn (insn, operands[0]);"
11166   [(set_attr "type" "call")])
11167
11168 (define_insn_and_split "*sibcall_pop_vzeroupper"
11169   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11170          (match_operand 1 "" ""))
11171    (set (reg:SI SP_REG)
11172         (plus:SI (reg:SI SP_REG)
11173                  (match_operand:SI 2 "immediate_operand" "i")))
11174    (unspec [(match_operand 3 "const_int_operand" "")]
11175            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11176   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11177   "#"
11178   "&& reload_completed"
11179   [(const_int 0)]
11180   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11181   [(set_attr "type" "call")])
11182
11183 (define_insn "*sibcall_pop"
11184   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11185          (match_operand 1 "" ""))
11186    (set (reg:SI SP_REG)
11187         (plus:SI (reg:SI SP_REG)
11188                  (match_operand:SI 2 "immediate_operand" "i")))]
11189   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11190   "* return ix86_output_call_insn (insn, operands[0]);"
11191   [(set_attr "type" "call")])
11192
11193 ;; Call subroutine, returning value in operand 0
11194
11195 (define_expand "call_value"
11196   [(set (match_operand 0 "" "")
11197         (call (match_operand:QI 1 "" "")
11198               (match_operand 2 "" "")))
11199    (use (match_operand 3 "" ""))]
11200   ""
11201 {
11202   ix86_expand_call (operands[0], operands[1], operands[2],
11203                     operands[3], NULL, false);
11204   DONE;
11205 })
11206
11207 (define_expand "sibcall_value"
11208   [(set (match_operand 0 "" "")
11209         (call (match_operand:QI 1 "" "")
11210               (match_operand 2 "" "")))
11211    (use (match_operand 3 "" ""))]
11212   ""
11213 {
11214   ix86_expand_call (operands[0], operands[1], operands[2],
11215                     operands[3], NULL, true);
11216   DONE;
11217 })
11218
11219 (define_insn_and_split "*call_value_vzeroupper"
11220   [(set (match_operand 0 "" "")
11221         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11222               (match_operand 2 "" "")))
11223    (unspec [(match_operand 3 "const_int_operand" "")]
11224            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11225   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11226   "#"
11227   "&& reload_completed"
11228   [(const_int 0)]
11229   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11230   [(set_attr "type" "callv")])
11231
11232 (define_insn "*call_value"
11233   [(set (match_operand 0 "" "")
11234         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11235               (match_operand 2 "" "")))]
11236   "!SIBLING_CALL_P (insn)"
11237   "* return ix86_output_call_insn (insn, operands[1]);"
11238   [(set_attr "type" "callv")])
11239
11240 (define_insn_and_split "*sibcall_value_vzeroupper"
11241   [(set (match_operand 0 "" "")
11242         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11243               (match_operand 2 "" "")))
11244    (unspec [(match_operand 3 "const_int_operand" "")]
11245            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11246   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11247   "#"
11248   "&& reload_completed"
11249   [(const_int 0)]
11250   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11251   [(set_attr "type" "callv")])
11252
11253 (define_insn "*sibcall_value"
11254   [(set (match_operand 0 "" "")
11255         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11256               (match_operand 2 "" "")))]
11257   "SIBLING_CALL_P (insn)"
11258   "* return ix86_output_call_insn (insn, operands[1]);"
11259   [(set_attr "type" "callv")])
11260
11261 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11262   [(set (match_operand 0 "" "")
11263         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11264               (match_operand 2 "" "")))
11265    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11266    (clobber (reg:TI XMM6_REG))
11267    (clobber (reg:TI XMM7_REG))
11268    (clobber (reg:TI XMM8_REG))
11269    (clobber (reg:TI XMM9_REG))
11270    (clobber (reg:TI XMM10_REG))
11271    (clobber (reg:TI XMM11_REG))
11272    (clobber (reg:TI XMM12_REG))
11273    (clobber (reg:TI XMM13_REG))
11274    (clobber (reg:TI XMM14_REG))
11275    (clobber (reg:TI XMM15_REG))
11276    (clobber (reg:DI SI_REG))
11277    (clobber (reg:DI DI_REG))
11278    (unspec [(match_operand 3 "const_int_operand" "")]
11279            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11280   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11281   "#"
11282   "&& reload_completed"
11283   [(const_int 0)]
11284   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11285   [(set_attr "type" "callv")])
11286
11287 (define_insn "*call_value_rex64_ms_sysv"
11288   [(set (match_operand 0 "" "")
11289         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11290               (match_operand 2 "" "")))
11291    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11292    (clobber (reg:TI XMM6_REG))
11293    (clobber (reg:TI XMM7_REG))
11294    (clobber (reg:TI XMM8_REG))
11295    (clobber (reg:TI XMM9_REG))
11296    (clobber (reg:TI XMM10_REG))
11297    (clobber (reg:TI XMM11_REG))
11298    (clobber (reg:TI XMM12_REG))
11299    (clobber (reg:TI XMM13_REG))
11300    (clobber (reg:TI XMM14_REG))
11301    (clobber (reg:TI XMM15_REG))
11302    (clobber (reg:DI SI_REG))
11303    (clobber (reg:DI DI_REG))]
11304   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11305   "* return ix86_output_call_insn (insn, operands[1]);"
11306   [(set_attr "type" "callv")])
11307
11308 (define_expand "call_value_pop"
11309   [(parallel [(set (match_operand 0 "" "")
11310                    (call (match_operand:QI 1 "" "")
11311                          (match_operand:SI 2 "" "")))
11312               (set (reg:SI SP_REG)
11313                    (plus:SI (reg:SI SP_REG)
11314                             (match_operand:SI 4 "" "")))])]
11315   "!TARGET_64BIT"
11316 {
11317   ix86_expand_call (operands[0], operands[1], operands[2],
11318                     operands[3], operands[4], false);
11319   DONE;
11320 })
11321
11322 (define_insn_and_split "*call_value_pop_vzeroupper"
11323   [(set (match_operand 0 "" "")
11324         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11325               (match_operand 2 "" "")))
11326    (set (reg:SI SP_REG)
11327         (plus:SI (reg:SI SP_REG)
11328                  (match_operand:SI 3 "immediate_operand" "i")))
11329    (unspec [(match_operand 4 "const_int_operand" "")]
11330            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11331   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11332   "#"
11333   "&& reload_completed"
11334   [(const_int 0)]
11335   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11336   [(set_attr "type" "callv")])
11337
11338 (define_insn "*call_value_pop"
11339   [(set (match_operand 0 "" "")
11340         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11341               (match_operand 2 "" "")))
11342    (set (reg:SI SP_REG)
11343         (plus:SI (reg:SI SP_REG)
11344                  (match_operand:SI 3 "immediate_operand" "i")))]
11345   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11346   "* return ix86_output_call_insn (insn, operands[1]);"
11347   [(set_attr "type" "callv")])
11348
11349 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11350   [(set (match_operand 0 "" "")
11351         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11352               (match_operand 2 "" "")))
11353    (set (reg:SI SP_REG)
11354         (plus:SI (reg:SI SP_REG)
11355                  (match_operand:SI 3 "immediate_operand" "i")))
11356    (unspec [(match_operand 4 "const_int_operand" "")]
11357            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11358   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11359   "#"
11360   "&& reload_completed"
11361   [(const_int 0)]
11362   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11363   [(set_attr "type" "callv")])
11364
11365 (define_insn "*sibcall_value_pop"
11366   [(set (match_operand 0 "" "")
11367         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11368               (match_operand 2 "" "")))
11369    (set (reg:SI SP_REG)
11370         (plus:SI (reg:SI SP_REG)
11371                  (match_operand:SI 3 "immediate_operand" "i")))]
11372   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11373   "* return ix86_output_call_insn (insn, operands[1]);"
11374   [(set_attr "type" "callv")])
11375
11376 ;; Call subroutine returning any type.
11377
11378 (define_expand "untyped_call"
11379   [(parallel [(call (match_operand 0 "" "")
11380                     (const_int 0))
11381               (match_operand 1 "" "")
11382               (match_operand 2 "" "")])]
11383   ""
11384 {
11385   int i;
11386
11387   /* In order to give reg-stack an easier job in validating two
11388      coprocessor registers as containing a possible return value,
11389      simply pretend the untyped call returns a complex long double
11390      value. 
11391
11392      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11393      and should have the default ABI.  */
11394
11395   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11396                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11397                     operands[0], const0_rtx,
11398                     GEN_INT ((TARGET_64BIT
11399                               ? (ix86_abi == SYSV_ABI
11400                                  ? X86_64_SSE_REGPARM_MAX
11401                                  : X86_64_MS_SSE_REGPARM_MAX)
11402                               : X86_32_SSE_REGPARM_MAX)
11403                              - 1),
11404                     NULL, false);
11405
11406   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11407     {
11408       rtx set = XVECEXP (operands[2], 0, i);
11409       emit_move_insn (SET_DEST (set), SET_SRC (set));
11410     }
11411
11412   /* The optimizer does not know that the call sets the function value
11413      registers we stored in the result block.  We avoid problems by
11414      claiming that all hard registers are used and clobbered at this
11415      point.  */
11416   emit_insn (gen_blockage ());
11417
11418   DONE;
11419 })
11420 \f
11421 ;; Prologue and epilogue instructions
11422
11423 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11424 ;; all of memory.  This blocks insns from being moved across this point.
11425
11426 (define_insn "blockage"
11427   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11428   ""
11429   ""
11430   [(set_attr "length" "0")])
11431
11432 ;; Do not schedule instructions accessing memory across this point.
11433
11434 (define_expand "memory_blockage"
11435   [(set (match_dup 0)
11436         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11437   ""
11438 {
11439   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11440   MEM_VOLATILE_P (operands[0]) = 1;
11441 })
11442
11443 (define_insn "*memory_blockage"
11444   [(set (match_operand:BLK 0 "" "")
11445         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11446   ""
11447   ""
11448   [(set_attr "length" "0")])
11449
11450 ;; As USE insns aren't meaningful after reload, this is used instead
11451 ;; to prevent deleting instructions setting registers for PIC code
11452 (define_insn "prologue_use"
11453   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11454   ""
11455   ""
11456   [(set_attr "length" "0")])
11457
11458 ;; Insn emitted into the body of a function to return from a function.
11459 ;; This is only done if the function's epilogue is known to be simple.
11460 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11461
11462 (define_expand "return"
11463   [(return)]
11464   "ix86_can_use_return_insn_p ()"
11465 {
11466   if (crtl->args.pops_args)
11467     {
11468       rtx popc = GEN_INT (crtl->args.pops_args);
11469       emit_jump_insn (gen_return_pop_internal (popc));
11470       DONE;
11471     }
11472 })
11473
11474 (define_insn "return_internal"
11475   [(return)]
11476   "reload_completed"
11477   "ret"
11478   [(set_attr "length" "1")
11479    (set_attr "atom_unit" "jeu")
11480    (set_attr "length_immediate" "0")
11481    (set_attr "modrm" "0")])
11482
11483 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11484 ;; instruction Athlon and K8 have.
11485
11486 (define_insn "return_internal_long"
11487   [(return)
11488    (unspec [(const_int 0)] UNSPEC_REP)]
11489   "reload_completed"
11490   "rep\;ret"
11491   [(set_attr "length" "2")
11492    (set_attr "atom_unit" "jeu")
11493    (set_attr "length_immediate" "0")
11494    (set_attr "prefix_rep" "1")
11495    (set_attr "modrm" "0")])
11496
11497 (define_insn "return_pop_internal"
11498   [(return)
11499    (use (match_operand:SI 0 "const_int_operand" ""))]
11500   "reload_completed"
11501   "ret\t%0"
11502   [(set_attr "length" "3")
11503    (set_attr "atom_unit" "jeu")
11504    (set_attr "length_immediate" "2")
11505    (set_attr "modrm" "0")])
11506
11507 (define_insn "return_indirect_internal"
11508   [(return)
11509    (use (match_operand:SI 0 "register_operand" "r"))]
11510   "reload_completed"
11511   "jmp\t%A0"
11512   [(set_attr "type" "ibr")
11513    (set_attr "length_immediate" "0")])
11514
11515 (define_insn "nop"
11516   [(const_int 0)]
11517   ""
11518   "nop"
11519   [(set_attr "length" "1")
11520    (set_attr "length_immediate" "0")
11521    (set_attr "modrm" "0")])
11522
11523 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11524 (define_insn "nops"
11525   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11526                     UNSPECV_NOPS)]
11527   "reload_completed"
11528 {
11529   int num = INTVAL (operands[0]);
11530
11531   gcc_assert (num >= 1 && num <= 8);
11532
11533   while (num--)
11534     fputs ("\tnop\n", asm_out_file);
11535
11536   return "";
11537 }
11538   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11539    (set_attr "length_immediate" "0")
11540    (set_attr "modrm" "0")])
11541
11542 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11543 ;; branch prediction penalty for the third jump in a 16-byte
11544 ;; block on K8.
11545
11546 (define_insn "pad"
11547   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11548   ""
11549 {
11550 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11551   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11552 #else
11553   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11554      The align insn is used to avoid 3 jump instructions in the row to improve
11555      branch prediction and the benefits hardly outweigh the cost of extra 8
11556      nops on the average inserted by full alignment pseudo operation.  */
11557 #endif
11558   return "";
11559 }
11560   [(set_attr "length" "16")])
11561
11562 (define_expand "prologue"
11563   [(const_int 0)]
11564   ""
11565   "ix86_expand_prologue (); DONE;")
11566
11567 (define_insn "set_got"
11568   [(set (match_operand:SI 0 "register_operand" "=r")
11569         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11570    (clobber (reg:CC FLAGS_REG))]
11571   "!TARGET_64BIT"
11572   "* return output_set_got (operands[0], NULL_RTX);"
11573   [(set_attr "type" "multi")
11574    (set_attr "length" "12")])
11575
11576 (define_insn "set_got_labelled"
11577   [(set (match_operand:SI 0 "register_operand" "=r")
11578         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11579          UNSPEC_SET_GOT))
11580    (clobber (reg:CC FLAGS_REG))]
11581   "!TARGET_64BIT"
11582   "* return output_set_got (operands[0], operands[1]);"
11583   [(set_attr "type" "multi")
11584    (set_attr "length" "12")])
11585
11586 (define_insn "set_got_rex64"
11587   [(set (match_operand:DI 0 "register_operand" "=r")
11588         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11589   "TARGET_64BIT"
11590   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11591   [(set_attr "type" "lea")
11592    (set_attr "length_address" "4")
11593    (set_attr "mode" "DI")])
11594
11595 (define_insn "set_rip_rex64"
11596   [(set (match_operand:DI 0 "register_operand" "=r")
11597         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11598   "TARGET_64BIT"
11599   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11600   [(set_attr "type" "lea")
11601    (set_attr "length_address" "4")
11602    (set_attr "mode" "DI")])
11603
11604 (define_insn "set_got_offset_rex64"
11605   [(set (match_operand:DI 0 "register_operand" "=r")
11606         (unspec:DI
11607           [(label_ref (match_operand 1 "" ""))]
11608           UNSPEC_SET_GOT_OFFSET))]
11609   "TARGET_LP64"
11610   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11611   [(set_attr "type" "imov")
11612    (set_attr "length_immediate" "0")
11613    (set_attr "length_address" "8")
11614    (set_attr "mode" "DI")])
11615
11616 (define_expand "epilogue"
11617   [(const_int 0)]
11618   ""
11619   "ix86_expand_epilogue (1); DONE;")
11620
11621 (define_expand "sibcall_epilogue"
11622   [(const_int 0)]
11623   ""
11624   "ix86_expand_epilogue (0); DONE;")
11625
11626 (define_expand "eh_return"
11627   [(use (match_operand 0 "register_operand" ""))]
11628   ""
11629 {
11630   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11631
11632   /* Tricky bit: we write the address of the handler to which we will
11633      be returning into someone else's stack frame, one word below the
11634      stack address we wish to restore.  */
11635   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11636   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11637   tmp = gen_rtx_MEM (Pmode, tmp);
11638   emit_move_insn (tmp, ra);
11639
11640   emit_jump_insn (gen_eh_return_internal ());
11641   emit_barrier ();
11642   DONE;
11643 })
11644
11645 (define_insn_and_split "eh_return_internal"
11646   [(eh_return)]
11647   ""
11648   "#"
11649   "epilogue_completed"
11650   [(const_int 0)]
11651   "ix86_expand_epilogue (2); DONE;")
11652
11653 (define_insn "leave"
11654   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11655    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11656    (clobber (mem:BLK (scratch)))]
11657   "!TARGET_64BIT"
11658   "leave"
11659   [(set_attr "type" "leave")])
11660
11661 (define_insn "leave_rex64"
11662   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11663    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11664    (clobber (mem:BLK (scratch)))]
11665   "TARGET_64BIT"
11666   "leave"
11667   [(set_attr "type" "leave")])
11668 \f
11669 ;; Handle -fsplit-stack.
11670
11671 (define_expand "split_stack_prologue"
11672   [(const_int 0)]
11673   ""
11674 {
11675   ix86_expand_split_stack_prologue ();
11676   DONE;
11677 })
11678
11679 ;; In order to support the call/return predictor, we use a return
11680 ;; instruction which the middle-end doesn't see.
11681 (define_insn "split_stack_return"
11682   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11683                      UNSPECV_SPLIT_STACK_RETURN)]
11684   ""
11685 {
11686   if (operands[0] == const0_rtx)
11687     return "ret";
11688   else
11689     return "ret\t%0";
11690 }
11691   [(set_attr "atom_unit" "jeu")
11692    (set_attr "modrm" "0")
11693    (set (attr "length")
11694         (if_then_else (match_operand:SI 0 "const0_operand" "")
11695                       (const_int 1)
11696                       (const_int 3)))
11697    (set (attr "length_immediate")
11698         (if_then_else (match_operand:SI 0 "const0_operand" "")
11699                       (const_int 0)
11700                       (const_int 2)))])
11701
11702 ;; If there are operand 0 bytes available on the stack, jump to
11703 ;; operand 1.
11704
11705 (define_expand "split_stack_space_check"
11706   [(set (pc) (if_then_else
11707               (ltu (minus (reg SP_REG)
11708                           (match_operand 0 "register_operand" ""))
11709                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11710               (label_ref (match_operand 1 "" ""))
11711               (pc)))]
11712   ""
11713 {
11714   rtx reg, size, limit;
11715
11716   reg = gen_reg_rtx (Pmode);
11717   size = force_reg (Pmode, operands[0]);
11718   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11719   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11720                           UNSPEC_STACK_CHECK);
11721   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11722   ix86_expand_branch (GEU, reg, limit, operands[1]);
11723
11724   DONE;
11725 })
11726 \f
11727 ;; Bit manipulation instructions.
11728
11729 (define_expand "ffs<mode>2"
11730   [(set (match_dup 2) (const_int -1))
11731    (parallel [(set (reg:CCZ FLAGS_REG)
11732                    (compare:CCZ
11733                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11734                      (const_int 0)))
11735               (set (match_operand:SWI48 0 "register_operand" "")
11736                    (ctz:SWI48 (match_dup 1)))])
11737    (set (match_dup 0) (if_then_else:SWI48
11738                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11739                         (match_dup 2)
11740                         (match_dup 0)))
11741    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11742               (clobber (reg:CC FLAGS_REG))])]
11743   ""
11744 {
11745   if (<MODE>mode == SImode && !TARGET_CMOVE)
11746     {
11747       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11748       DONE;
11749     }
11750   operands[2] = gen_reg_rtx (<MODE>mode);
11751 })
11752
11753 (define_insn_and_split "ffssi2_no_cmove"
11754   [(set (match_operand:SI 0 "register_operand" "=r")
11755         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11756    (clobber (match_scratch:SI 2 "=&q"))
11757    (clobber (reg:CC FLAGS_REG))]
11758   "!TARGET_CMOVE"
11759   "#"
11760   "&& reload_completed"
11761   [(parallel [(set (reg:CCZ FLAGS_REG)
11762                    (compare:CCZ (match_dup 1) (const_int 0)))
11763               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11764    (set (strict_low_part (match_dup 3))
11765         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11766    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11767               (clobber (reg:CC FLAGS_REG))])
11768    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11769               (clobber (reg:CC FLAGS_REG))])
11770    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11771               (clobber (reg:CC FLAGS_REG))])]
11772 {
11773   operands[3] = gen_lowpart (QImode, operands[2]);
11774   ix86_expand_clear (operands[2]);
11775 })
11776
11777 (define_insn "*ffs<mode>_1"
11778   [(set (reg:CCZ FLAGS_REG)
11779         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11780                      (const_int 0)))
11781    (set (match_operand:SWI48 0 "register_operand" "=r")
11782         (ctz:SWI48 (match_dup 1)))]
11783   ""
11784   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11785   [(set_attr "type" "alu1")
11786    (set_attr "prefix_0f" "1")
11787    (set_attr "mode" "<MODE>")])
11788
11789 (define_insn "ctz<mode>2"
11790   [(set (match_operand:SWI248 0 "register_operand" "=r")
11791         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11792    (clobber (reg:CC FLAGS_REG))]
11793   ""
11794 {
11795   if (TARGET_BMI)
11796     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11797   else
11798     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11799 }
11800   [(set_attr "type" "alu1")
11801    (set_attr "prefix_0f" "1")
11802    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11803    (set_attr "mode" "<MODE>")])
11804
11805 (define_expand "clz<mode>2"
11806   [(parallel
11807      [(set (match_operand:SWI248 0 "register_operand" "")
11808            (minus:SWI248
11809              (match_dup 2)
11810              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11811       (clobber (reg:CC FLAGS_REG))])
11812    (parallel
11813      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11814       (clobber (reg:CC FLAGS_REG))])]
11815   ""
11816 {
11817   if (TARGET_LZCNT)
11818     {
11819       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11820       DONE;
11821     }
11822   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11823 })
11824
11825 (define_insn "clz<mode>2_lzcnt"
11826   [(set (match_operand:SWI248 0 "register_operand" "=r")
11827         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11828    (clobber (reg:CC FLAGS_REG))]
11829   "TARGET_LZCNT"
11830   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11831   [(set_attr "prefix_rep" "1")
11832    (set_attr "type" "bitmanip")
11833    (set_attr "mode" "<MODE>")])
11834
11835 ;; BMI instructions.
11836 (define_insn "*bmi_andn_<mode>"
11837   [(set (match_operand:SWI48 0 "register_operand" "=r")
11838         (and:SWI48
11839           (not:SWI48
11840             (match_operand:SWI48 1 "register_operand" "r"))
11841             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11842    (clobber (reg:CC FLAGS_REG))]
11843   "TARGET_BMI"
11844   "andn\t{%2, %1, %0|%0, %1, %2}"
11845   [(set_attr "type" "bitmanip")
11846    (set_attr "mode" "<MODE>")])
11847
11848 (define_insn "bmi_bextr_<mode>"
11849   [(set (match_operand:SWI48 0 "register_operand" "=r")
11850         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11851                        (match_operand:SWI48 2 "register_operand" "r")]
11852                        UNSPEC_BEXTR))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "TARGET_BMI"
11855   "bextr\t{%2, %1, %0|%0, %1, %2}"
11856   [(set_attr "type" "bitmanip")
11857    (set_attr "mode" "<MODE>")])
11858
11859 (define_insn "*bmi_blsi_<mode>"
11860   [(set (match_operand:SWI48 0 "register_operand" "=r")
11861         (and:SWI48
11862           (neg:SWI48
11863             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11864           (match_dup 1)))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_BMI"
11867   "blsi\t{%1, %0|%0, %1}"
11868   [(set_attr "type" "bitmanip")
11869    (set_attr "mode" "<MODE>")])
11870
11871 (define_insn "*bmi_blsmsk_<mode>"
11872   [(set (match_operand:SWI48 0 "register_operand" "=r")
11873         (xor:SWI48
11874           (plus:SWI48
11875             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11876             (const_int -1))
11877           (match_dup 1)))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_BMI"
11880   "blsmsk\t{%1, %0|%0, %1}"
11881   [(set_attr "type" "bitmanip")
11882    (set_attr "mode" "<MODE>")])
11883
11884 (define_insn "*bmi_blsr_<mode>"
11885   [(set (match_operand:SWI48 0 "register_operand" "=r")
11886         (and:SWI48
11887           (plus:SWI48
11888             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11889             (const_int -1))
11890           (match_dup 1)))
11891    (clobber (reg:CC FLAGS_REG))]
11892    "TARGET_BMI"
11893    "blsr\t{%1, %0|%0, %1}"
11894   [(set_attr "type" "bitmanip")
11895    (set_attr "mode" "<MODE>")])
11896
11897 ;; TBM instructions.
11898 (define_insn "tbm_bextri_<mode>"
11899   [(set (match_operand:SWI48 0 "register_operand" "=r")
11900         (zero_extract:SWI48
11901           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11902           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11903           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11904    (clobber (reg:CC FLAGS_REG))]
11905    "TARGET_TBM"
11906 {
11907   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11908   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11909 }
11910   [(set_attr "type" "bitmanip")
11911    (set_attr "mode" "<MODE>")])
11912
11913 (define_insn "*tbm_blcfill_<mode>"
11914   [(set (match_operand:SWI48 0 "register_operand" "=r")
11915         (and:SWI48
11916           (plus:SWI48
11917             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11918             (const_int 1))
11919           (match_dup 1)))
11920    (clobber (reg:CC FLAGS_REG))]
11921    "TARGET_TBM"
11922    "blcfill\t{%1, %0|%0, %1}"
11923   [(set_attr "type" "bitmanip")
11924    (set_attr "mode" "<MODE>")])
11925
11926 (define_insn "*tbm_blci_<mode>"
11927   [(set (match_operand:SWI48 0 "register_operand" "=r")
11928         (ior:SWI48
11929           (not:SWI48
11930             (plus:SWI48
11931               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11932               (const_int 1)))
11933           (match_dup 1)))
11934    (clobber (reg:CC FLAGS_REG))]
11935    "TARGET_TBM"
11936    "blci\t{%1, %0|%0, %1}"
11937   [(set_attr "type" "bitmanip")
11938    (set_attr "mode" "<MODE>")])
11939
11940 (define_insn "*tbm_blcic_<mode>"
11941   [(set (match_operand:SWI48 0 "register_operand" "=r")
11942         (and:SWI48
11943           (plus:SWI48
11944             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11945             (const_int 1))
11946           (not:SWI48
11947             (match_dup 1))))
11948    (clobber (reg:CC FLAGS_REG))]
11949    "TARGET_TBM"
11950    "blcic\t{%1, %0|%0, %1}"
11951   [(set_attr "type" "bitmanip")
11952    (set_attr "mode" "<MODE>")])
11953
11954 (define_insn "*tbm_blcmsk_<mode>"
11955   [(set (match_operand:SWI48 0 "register_operand" "=r")
11956         (xor:SWI48
11957           (plus:SWI48
11958             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11959             (const_int 1))
11960           (match_dup 1)))
11961    (clobber (reg:CC FLAGS_REG))]
11962    "TARGET_TBM"
11963    "blcmsk\t{%1, %0|%0, %1}"
11964   [(set_attr "type" "bitmanip")
11965    (set_attr "mode" "<MODE>")])
11966
11967 (define_insn "*tbm_blcs_<mode>"
11968   [(set (match_operand:SWI48 0 "register_operand" "=r")
11969         (ior:SWI48
11970           (plus:SWI48
11971             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11972             (const_int 1))
11973           (match_dup 1)))
11974    (clobber (reg:CC FLAGS_REG))]
11975    "TARGET_TBM"
11976    "blcs\t{%1, %0|%0, %1}"
11977   [(set_attr "type" "bitmanip")
11978    (set_attr "mode" "<MODE>")])
11979
11980 (define_insn "*tbm_blsfill_<mode>"
11981   [(set (match_operand:SWI48 0 "register_operand" "=r")
11982         (ior:SWI48
11983           (plus:SWI48
11984             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11985             (const_int -1))
11986           (match_dup 1)))
11987    (clobber (reg:CC FLAGS_REG))]
11988    "TARGET_TBM"
11989    "blsfill\t{%1, %0|%0, %1}"
11990   [(set_attr "type" "bitmanip")
11991    (set_attr "mode" "<MODE>")])
11992
11993 (define_insn "*tbm_blsic_<mode>"
11994   [(set (match_operand:SWI48 0 "register_operand" "=r")
11995         (ior:SWI48
11996           (plus:SWI48
11997             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11998             (const_int -1))
11999           (not:SWI48
12000             (match_dup 1))))
12001    (clobber (reg:CC FLAGS_REG))]
12002    "TARGET_TBM"
12003    "blsic\t{%1, %0|%0, %1}"
12004   [(set_attr "type" "bitmanip")
12005    (set_attr "mode" "<MODE>")])
12006
12007 (define_insn "*tbm_t1mskc_<mode>"
12008   [(set (match_operand:SWI48 0 "register_operand" "=r")
12009         (ior:SWI48
12010           (plus:SWI48
12011             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12012             (const_int 1))
12013           (not:SWI48
12014             (match_dup 1))))
12015    (clobber (reg:CC FLAGS_REG))]
12016    "TARGET_TBM"
12017    "t1mskc\t{%1, %0|%0, %1}"
12018   [(set_attr "type" "bitmanip")
12019    (set_attr "mode" "<MODE>")])
12020
12021 (define_insn "*tbm_tzmsk_<mode>"
12022   [(set (match_operand:SWI48 0 "register_operand" "=r")
12023         (and:SWI48
12024           (plus:SWI48
12025             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12026             (const_int -1))
12027           (not:SWI48
12028             (match_dup 1))))
12029    (clobber (reg:CC FLAGS_REG))]
12030    "TARGET_TBM"
12031    "tzmsk\t{%1, %0|%0, %1}"
12032   [(set_attr "type" "bitmanip")
12033    (set_attr "mode" "<MODE>")])
12034
12035 (define_insn "bsr_rex64"
12036   [(set (match_operand:DI 0 "register_operand" "=r")
12037         (minus:DI (const_int 63)
12038                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12039    (clobber (reg:CC FLAGS_REG))]
12040   "TARGET_64BIT"
12041   "bsr{q}\t{%1, %0|%0, %1}"
12042   [(set_attr "type" "alu1")
12043    (set_attr "prefix_0f" "1")
12044    (set_attr "mode" "DI")])
12045
12046 (define_insn "bsr"
12047   [(set (match_operand:SI 0 "register_operand" "=r")
12048         (minus:SI (const_int 31)
12049                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12050    (clobber (reg:CC FLAGS_REG))]
12051   ""
12052   "bsr{l}\t{%1, %0|%0, %1}"
12053   [(set_attr "type" "alu1")
12054    (set_attr "prefix_0f" "1")
12055    (set_attr "mode" "SI")])
12056
12057 (define_insn "*bsrhi"
12058   [(set (match_operand:HI 0 "register_operand" "=r")
12059         (minus:HI (const_int 15)
12060                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12061    (clobber (reg:CC FLAGS_REG))]
12062   ""
12063   "bsr{w}\t{%1, %0|%0, %1}"
12064   [(set_attr "type" "alu1")
12065    (set_attr "prefix_0f" "1")
12066    (set_attr "mode" "HI")])
12067
12068 (define_insn "popcount<mode>2"
12069   [(set (match_operand:SWI248 0 "register_operand" "=r")
12070         (popcount:SWI248
12071           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12072    (clobber (reg:CC FLAGS_REG))]
12073   "TARGET_POPCNT"
12074 {
12075 #if TARGET_MACHO
12076   return "popcnt\t{%1, %0|%0, %1}";
12077 #else
12078   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12079 #endif
12080 }
12081   [(set_attr "prefix_rep" "1")
12082    (set_attr "type" "bitmanip")
12083    (set_attr "mode" "<MODE>")])
12084
12085 (define_insn "*popcount<mode>2_cmp"
12086   [(set (reg FLAGS_REG)
12087         (compare
12088           (popcount:SWI248
12089             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12090           (const_int 0)))
12091    (set (match_operand:SWI248 0 "register_operand" "=r")
12092         (popcount:SWI248 (match_dup 1)))]
12093   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12094 {
12095 #if TARGET_MACHO
12096   return "popcnt\t{%1, %0|%0, %1}";
12097 #else
12098   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12099 #endif
12100 }
12101   [(set_attr "prefix_rep" "1")
12102    (set_attr "type" "bitmanip")
12103    (set_attr "mode" "<MODE>")])
12104
12105 (define_insn "*popcountsi2_cmp_zext"
12106   [(set (reg FLAGS_REG)
12107         (compare
12108           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12109           (const_int 0)))
12110    (set (match_operand:DI 0 "register_operand" "=r")
12111         (zero_extend:DI(popcount:SI (match_dup 1))))]
12112   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12113 {
12114 #if TARGET_MACHO
12115   return "popcnt\t{%1, %0|%0, %1}";
12116 #else
12117   return "popcnt{l}\t{%1, %0|%0, %1}";
12118 #endif
12119 }
12120   [(set_attr "prefix_rep" "1")
12121    (set_attr "type" "bitmanip")
12122    (set_attr "mode" "SI")])
12123
12124 (define_expand "bswap<mode>2"
12125   [(set (match_operand:SWI48 0 "register_operand" "")
12126         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12127   ""
12128 {
12129   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12130     {
12131       rtx x = operands[0];
12132
12133       emit_move_insn (x, operands[1]);
12134       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12135       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12136       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12137       DONE;
12138     }
12139 })
12140
12141 (define_insn "*bswap<mode>2_movbe"
12142   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12143         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12144   "TARGET_MOVBE
12145    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12146   "@
12147     bswap\t%0
12148     movbe\t{%1, %0|%0, %1}
12149     movbe\t{%1, %0|%0, %1}"
12150   [(set_attr "type" "bitmanip,imov,imov")
12151    (set_attr "modrm" "0,1,1")
12152    (set_attr "prefix_0f" "*,1,1")
12153    (set_attr "prefix_extra" "*,1,1")
12154    (set_attr "mode" "<MODE>")])
12155
12156 (define_insn "*bswap<mode>2_1"
12157   [(set (match_operand:SWI48 0 "register_operand" "=r")
12158         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12159   "TARGET_BSWAP"
12160   "bswap\t%0"
12161   [(set_attr "type" "bitmanip")
12162    (set_attr "modrm" "0")
12163    (set_attr "mode" "<MODE>")])
12164
12165 (define_insn "*bswaphi_lowpart_1"
12166   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12167         (bswap:HI (match_dup 0)))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12170   "@
12171     xchg{b}\t{%h0, %b0|%b0, %h0}
12172     rol{w}\t{$8, %0|%0, 8}"
12173   [(set_attr "length" "2,4")
12174    (set_attr "mode" "QI,HI")])
12175
12176 (define_insn "bswaphi_lowpart"
12177   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12178         (bswap:HI (match_dup 0)))
12179    (clobber (reg:CC FLAGS_REG))]
12180   ""
12181   "rol{w}\t{$8, %0|%0, 8}"
12182   [(set_attr "length" "4")
12183    (set_attr "mode" "HI")])
12184
12185 (define_expand "paritydi2"
12186   [(set (match_operand:DI 0 "register_operand" "")
12187         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12188   "! TARGET_POPCNT"
12189 {
12190   rtx scratch = gen_reg_rtx (QImode);
12191   rtx cond;
12192
12193   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12194                                 NULL_RTX, operands[1]));
12195
12196   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12197                          gen_rtx_REG (CCmode, FLAGS_REG),
12198                          const0_rtx);
12199   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12200
12201   if (TARGET_64BIT)
12202     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12203   else
12204     {
12205       rtx tmp = gen_reg_rtx (SImode);
12206
12207       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12208       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12209     }
12210   DONE;
12211 })
12212
12213 (define_expand "paritysi2"
12214   [(set (match_operand:SI 0 "register_operand" "")
12215         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12216   "! TARGET_POPCNT"
12217 {
12218   rtx scratch = gen_reg_rtx (QImode);
12219   rtx cond;
12220
12221   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12222
12223   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12224                          gen_rtx_REG (CCmode, FLAGS_REG),
12225                          const0_rtx);
12226   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12227
12228   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12229   DONE;
12230 })
12231
12232 (define_insn_and_split "paritydi2_cmp"
12233   [(set (reg:CC FLAGS_REG)
12234         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12235                    UNSPEC_PARITY))
12236    (clobber (match_scratch:DI 0 "=r"))
12237    (clobber (match_scratch:SI 1 "=&r"))
12238    (clobber (match_scratch:HI 2 "=Q"))]
12239   "! TARGET_POPCNT"
12240   "#"
12241   "&& reload_completed"
12242   [(parallel
12243      [(set (match_dup 1)
12244            (xor:SI (match_dup 1) (match_dup 4)))
12245       (clobber (reg:CC FLAGS_REG))])
12246    (parallel
12247      [(set (reg:CC FLAGS_REG)
12248            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12249       (clobber (match_dup 1))
12250       (clobber (match_dup 2))])]
12251 {
12252   operands[4] = gen_lowpart (SImode, operands[3]);
12253
12254   if (TARGET_64BIT)
12255     {
12256       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12257       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12258     }
12259   else
12260     operands[1] = gen_highpart (SImode, operands[3]);
12261 })
12262
12263 (define_insn_and_split "paritysi2_cmp"
12264   [(set (reg:CC FLAGS_REG)
12265         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12266                    UNSPEC_PARITY))
12267    (clobber (match_scratch:SI 0 "=r"))
12268    (clobber (match_scratch:HI 1 "=&Q"))]
12269   "! TARGET_POPCNT"
12270   "#"
12271   "&& reload_completed"
12272   [(parallel
12273      [(set (match_dup 1)
12274            (xor:HI (match_dup 1) (match_dup 3)))
12275       (clobber (reg:CC FLAGS_REG))])
12276    (parallel
12277      [(set (reg:CC FLAGS_REG)
12278            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12279       (clobber (match_dup 1))])]
12280 {
12281   operands[3] = gen_lowpart (HImode, operands[2]);
12282
12283   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12284   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12285 })
12286
12287 (define_insn "*parityhi2_cmp"
12288   [(set (reg:CC FLAGS_REG)
12289         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12290                    UNSPEC_PARITY))
12291    (clobber (match_scratch:HI 0 "=Q"))]
12292   "! TARGET_POPCNT"
12293   "xor{b}\t{%h0, %b0|%b0, %h0}"
12294   [(set_attr "length" "2")
12295    (set_attr "mode" "HI")])
12296 \f
12297 ;; Thread-local storage patterns for ELF.
12298 ;;
12299 ;; Note that these code sequences must appear exactly as shown
12300 ;; in order to allow linker relaxation.
12301
12302 (define_insn "*tls_global_dynamic_32_gnu"
12303   [(set (match_operand:SI 0 "register_operand" "=a")
12304         (unspec:SI
12305          [(match_operand:SI 1 "register_operand" "b")
12306           (match_operand:SI 2 "tls_symbolic_operand" "")
12307           (match_operand:SI 3 "constant_call_address_operand" "z")]
12308          UNSPEC_TLS_GD))
12309    (clobber (match_scratch:SI 4 "=d"))
12310    (clobber (match_scratch:SI 5 "=c"))
12311    (clobber (reg:CC FLAGS_REG))]
12312   "!TARGET_64BIT && TARGET_GNU_TLS"
12313 {
12314   output_asm_insn
12315     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12316   if (TARGET_SUN_TLS)
12317 #ifdef HAVE_AS_IX86_TLSGDPLT
12318     return "call\t%a2@tlsgdplt";
12319 #else
12320     return "call\t%p3@plt";
12321 #endif
12322   return "call\t%P3";
12323 }
12324   [(set_attr "type" "multi")
12325    (set_attr "length" "12")])
12326
12327 (define_expand "tls_global_dynamic_32"
12328   [(parallel
12329     [(set (match_operand:SI 0 "register_operand" "")
12330           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12331                       (match_operand:SI 1 "tls_symbolic_operand" "")
12332                       (match_operand:SI 3 "constant_call_address_operand" "")]
12333                      UNSPEC_TLS_GD))
12334      (clobber (match_scratch:SI 4 ""))
12335      (clobber (match_scratch:SI 5 ""))
12336      (clobber (reg:CC FLAGS_REG))])])
12337
12338 (define_insn "*tls_global_dynamic_64"
12339   [(set (match_operand:DI 0 "register_operand" "=a")
12340         (call:DI
12341          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12342          (match_operand:DI 3 "" "")))
12343    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12344               UNSPEC_TLS_GD)]
12345   "TARGET_64BIT"
12346 {
12347   if (!TARGET_X32)
12348     fputs (ASM_BYTE "0x66\n", asm_out_file);
12349   output_asm_insn
12350     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12351   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12352   fputs ("\trex64\n", asm_out_file);
12353   if (TARGET_SUN_TLS)
12354     return "call\t%p2@plt";
12355   return "call\t%P2";
12356 }
12357   [(set_attr "type" "multi")
12358    (set (attr "length")
12359         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12360
12361 (define_expand "tls_global_dynamic_64"
12362   [(parallel
12363     [(set (match_operand:DI 0 "register_operand" "")
12364           (call:DI
12365            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12366            (const_int 0)))
12367      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12368                 UNSPEC_TLS_GD)])])
12369
12370 (define_insn "*tls_local_dynamic_base_32_gnu"
12371   [(set (match_operand:SI 0 "register_operand" "=a")
12372         (unspec:SI
12373          [(match_operand:SI 1 "register_operand" "b")
12374           (match_operand:SI 2 "constant_call_address_operand" "z")]
12375          UNSPEC_TLS_LD_BASE))
12376    (clobber (match_scratch:SI 3 "=d"))
12377    (clobber (match_scratch:SI 4 "=c"))
12378    (clobber (reg:CC FLAGS_REG))]
12379   "!TARGET_64BIT && TARGET_GNU_TLS"
12380 {
12381   output_asm_insn
12382     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12383   if (TARGET_SUN_TLS)
12384 #ifdef HAVE_AS_IX86_TLSLDMPLT
12385     return "call\t%&@tlsldmplt";
12386 #else
12387     return "call\t%p2@plt";
12388 #endif
12389   return "call\t%P2";
12390 }
12391   [(set_attr "type" "multi")
12392    (set_attr "length" "11")])
12393
12394 (define_expand "tls_local_dynamic_base_32"
12395   [(parallel
12396      [(set (match_operand:SI 0 "register_operand" "")
12397            (unspec:SI
12398             [(match_operand:SI 1 "register_operand" "")
12399              (match_operand:SI 2 "constant_call_address_operand" "")]
12400             UNSPEC_TLS_LD_BASE))
12401       (clobber (match_scratch:SI 3 ""))
12402       (clobber (match_scratch:SI 4 ""))
12403       (clobber (reg:CC FLAGS_REG))])])
12404
12405 (define_insn "*tls_local_dynamic_base_64"
12406   [(set (match_operand:DI 0 "register_operand" "=a")
12407         (call:DI
12408          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12409          (match_operand:DI 2 "" "")))
12410    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12411   "TARGET_64BIT"
12412 {
12413   output_asm_insn
12414     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12415   if (TARGET_SUN_TLS)
12416     return "call\t%p1@plt";
12417   return "call\t%P1";
12418 }
12419   [(set_attr "type" "multi")
12420    (set_attr "length" "12")])
12421
12422 (define_expand "tls_local_dynamic_base_64"
12423   [(parallel
12424      [(set (match_operand:DI 0 "register_operand" "")
12425            (call:DI
12426             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12427             (const_int 0)))
12428       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12429
12430 ;; Local dynamic of a single variable is a lose.  Show combine how
12431 ;; to convert that back to global dynamic.
12432
12433 (define_insn_and_split "*tls_local_dynamic_32_once"
12434   [(set (match_operand:SI 0 "register_operand" "=a")
12435         (plus:SI
12436          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12437                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12438                     UNSPEC_TLS_LD_BASE)
12439          (const:SI (unspec:SI
12440                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12441                     UNSPEC_DTPOFF))))
12442    (clobber (match_scratch:SI 4 "=d"))
12443    (clobber (match_scratch:SI 5 "=c"))
12444    (clobber (reg:CC FLAGS_REG))]
12445   ""
12446   "#"
12447   ""
12448   [(parallel
12449      [(set (match_dup 0)
12450            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12451                       UNSPEC_TLS_GD))
12452       (clobber (match_dup 4))
12453       (clobber (match_dup 5))
12454       (clobber (reg:CC FLAGS_REG))])])
12455
12456 ;; Segment register for the thread base ptr load
12457 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12458
12459 ;; Load and add the thread base pointer from %<tp_seg>:0.
12460 (define_insn "*load_tp_x32"
12461   [(set (match_operand:SI 0 "register_operand" "=r")
12462         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12463   "TARGET_X32"
12464   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12465   [(set_attr "type" "imov")
12466    (set_attr "modrm" "0")
12467    (set_attr "length" "7")
12468    (set_attr "memory" "load")
12469    (set_attr "imm_disp" "false")])
12470
12471 (define_insn "*load_tp_x32_zext"
12472   [(set (match_operand:DI 0 "register_operand" "=r")
12473         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12474   "TARGET_X32"
12475   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12476   [(set_attr "type" "imov")
12477    (set_attr "modrm" "0")
12478    (set_attr "length" "7")
12479    (set_attr "memory" "load")
12480    (set_attr "imm_disp" "false")])
12481
12482 (define_insn "*load_tp_<mode>"
12483   [(set (match_operand:P 0 "register_operand" "=r")
12484         (unspec:P [(const_int 0)] UNSPEC_TP))]
12485   "!TARGET_X32"
12486   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12487   [(set_attr "type" "imov")
12488    (set_attr "modrm" "0")
12489    (set_attr "length" "7")
12490    (set_attr "memory" "load")
12491    (set_attr "imm_disp" "false")])
12492
12493 (define_insn "*add_tp_x32"
12494   [(set (match_operand:SI 0 "register_operand" "=r")
12495         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12496                  (match_operand:SI 1 "register_operand" "0")))
12497    (clobber (reg:CC FLAGS_REG))]
12498   "TARGET_X32"
12499   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12500   [(set_attr "type" "alu")
12501    (set_attr "modrm" "0")
12502    (set_attr "length" "7")
12503    (set_attr "memory" "load")
12504    (set_attr "imm_disp" "false")])
12505
12506 (define_insn "*add_tp_x32_zext"
12507   [(set (match_operand:DI 0 "register_operand" "=r")
12508         (zero_extend:DI
12509           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12510                    (match_operand:SI 1 "register_operand" "0"))))
12511    (clobber (reg:CC FLAGS_REG))]
12512   "TARGET_X32"
12513   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12514   [(set_attr "type" "alu")
12515    (set_attr "modrm" "0")
12516    (set_attr "length" "7")
12517    (set_attr "memory" "load")
12518    (set_attr "imm_disp" "false")])
12519
12520 (define_insn "*add_tp_<mode>"
12521   [(set (match_operand:P 0 "register_operand" "=r")
12522         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12523                 (match_operand:P 1 "register_operand" "0")))
12524    (clobber (reg:CC FLAGS_REG))]
12525   "!TARGET_X32"
12526   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12527   [(set_attr "type" "alu")
12528    (set_attr "modrm" "0")
12529    (set_attr "length" "7")
12530    (set_attr "memory" "load")
12531    (set_attr "imm_disp" "false")])
12532
12533 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12534 ;; %rax as destination of the initial executable code sequence.
12535 (define_insn "tls_initial_exec_64_sun"
12536   [(set (match_operand:DI 0 "register_operand" "=a")
12537         (unspec:DI
12538          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12539          UNSPEC_TLS_IE_SUN))
12540    (clobber (reg:CC FLAGS_REG))]
12541   "TARGET_64BIT && TARGET_SUN_TLS"
12542 {
12543   output_asm_insn
12544     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12545   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12546 }
12547   [(set_attr "type" "multi")])
12548
12549 ;; GNU2 TLS patterns can be split.
12550
12551 (define_expand "tls_dynamic_gnu2_32"
12552   [(set (match_dup 3)
12553         (plus:SI (match_operand:SI 2 "register_operand" "")
12554                  (const:SI
12555                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12556                              UNSPEC_TLSDESC))))
12557    (parallel
12558     [(set (match_operand:SI 0 "register_operand" "")
12559           (unspec:SI [(match_dup 1) (match_dup 3)
12560                       (match_dup 2) (reg:SI SP_REG)]
12561                       UNSPEC_TLSDESC))
12562      (clobber (reg:CC FLAGS_REG))])]
12563   "!TARGET_64BIT && TARGET_GNU2_TLS"
12564 {
12565   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12566   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12567 })
12568
12569 (define_insn "*tls_dynamic_gnu2_lea_32"
12570   [(set (match_operand:SI 0 "register_operand" "=r")
12571         (plus:SI (match_operand:SI 1 "register_operand" "b")
12572                  (const:SI
12573                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12574                               UNSPEC_TLSDESC))))]
12575   "!TARGET_64BIT && TARGET_GNU2_TLS"
12576   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12577   [(set_attr "type" "lea")
12578    (set_attr "mode" "SI")
12579    (set_attr "length" "6")
12580    (set_attr "length_address" "4")])
12581
12582 (define_insn "*tls_dynamic_gnu2_call_32"
12583   [(set (match_operand:SI 0 "register_operand" "=a")
12584         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12585                     (match_operand:SI 2 "register_operand" "0")
12586                     ;; we have to make sure %ebx still points to the GOT
12587                     (match_operand:SI 3 "register_operand" "b")
12588                     (reg:SI SP_REG)]
12589                    UNSPEC_TLSDESC))
12590    (clobber (reg:CC FLAGS_REG))]
12591   "!TARGET_64BIT && TARGET_GNU2_TLS"
12592   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12593   [(set_attr "type" "call")
12594    (set_attr "length" "2")
12595    (set_attr "length_address" "0")])
12596
12597 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12598   [(set (match_operand:SI 0 "register_operand" "=&a")
12599         (plus:SI
12600          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12601                      (match_operand:SI 4 "" "")
12602                      (match_operand:SI 2 "register_operand" "b")
12603                      (reg:SI SP_REG)]
12604                     UNSPEC_TLSDESC)
12605          (const:SI (unspec:SI
12606                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12607                     UNSPEC_DTPOFF))))
12608    (clobber (reg:CC FLAGS_REG))]
12609   "!TARGET_64BIT && TARGET_GNU2_TLS"
12610   "#"
12611   ""
12612   [(set (match_dup 0) (match_dup 5))]
12613 {
12614   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12615   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12616 })
12617
12618 (define_expand "tls_dynamic_gnu2_64"
12619   [(set (match_dup 2)
12620         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12621                    UNSPEC_TLSDESC))
12622    (parallel
12623     [(set (match_operand:DI 0 "register_operand" "")
12624           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12625                      UNSPEC_TLSDESC))
12626      (clobber (reg:CC FLAGS_REG))])]
12627   "TARGET_64BIT && TARGET_GNU2_TLS"
12628 {
12629   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12630   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12631 })
12632
12633 (define_insn "*tls_dynamic_gnu2_lea_64"
12634   [(set (match_operand:DI 0 "register_operand" "=r")
12635         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12636                    UNSPEC_TLSDESC))]
12637   "TARGET_64BIT && TARGET_GNU2_TLS"
12638   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12639   [(set_attr "type" "lea")
12640    (set_attr "mode" "DI")
12641    (set_attr "length" "7")
12642    (set_attr "length_address" "4")])
12643
12644 (define_insn "*tls_dynamic_gnu2_call_64"
12645   [(set (match_operand:DI 0 "register_operand" "=a")
12646         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12647                     (match_operand:DI 2 "register_operand" "0")
12648                     (reg:DI SP_REG)]
12649                    UNSPEC_TLSDESC))
12650    (clobber (reg:CC FLAGS_REG))]
12651   "TARGET_64BIT && TARGET_GNU2_TLS"
12652   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12653   [(set_attr "type" "call")
12654    (set_attr "length" "2")
12655    (set_attr "length_address" "0")])
12656
12657 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12658   [(set (match_operand:DI 0 "register_operand" "=&a")
12659         (plus:DI
12660          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12661                      (match_operand:DI 3 "" "")
12662                      (reg:DI SP_REG)]
12663                     UNSPEC_TLSDESC)
12664          (const:DI (unspec:DI
12665                     [(match_operand 1 "tls_symbolic_operand" "")]
12666                     UNSPEC_DTPOFF))))
12667    (clobber (reg:CC FLAGS_REG))]
12668   "TARGET_64BIT && TARGET_GNU2_TLS"
12669   "#"
12670   ""
12671   [(set (match_dup 0) (match_dup 4))]
12672 {
12673   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12674   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12675 })
12676 \f
12677 ;; These patterns match the binary 387 instructions for addM3, subM3,
12678 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12679 ;; SFmode.  The first is the normal insn, the second the same insn but
12680 ;; with one operand a conversion, and the third the same insn but with
12681 ;; the other operand a conversion.  The conversion may be SFmode or
12682 ;; SImode if the target mode DFmode, but only SImode if the target mode
12683 ;; is SFmode.
12684
12685 ;; Gcc is slightly more smart about handling normal two address instructions
12686 ;; so use special patterns for add and mull.
12687
12688 (define_insn "*fop_<mode>_comm_mixed"
12689   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12690         (match_operator:MODEF 3 "binary_fp_operator"
12691           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12692            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12693   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12694    && COMMUTATIVE_ARITH_P (operands[3])
12695    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12696   "* return output_387_binary_op (insn, operands);"
12697   [(set (attr "type")
12698         (if_then_else (eq_attr "alternative" "1,2")
12699            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12700               (const_string "ssemul")
12701               (const_string "sseadd"))
12702            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12703               (const_string "fmul")
12704               (const_string "fop"))))
12705    (set_attr "isa" "*,noavx,avx")
12706    (set_attr "prefix" "orig,orig,vex")
12707    (set_attr "mode" "<MODE>")])
12708
12709 (define_insn "*fop_<mode>_comm_sse"
12710   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12711         (match_operator:MODEF 3 "binary_fp_operator"
12712           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12713            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12714   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12715    && COMMUTATIVE_ARITH_P (operands[3])
12716    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12717   "* return output_387_binary_op (insn, operands);"
12718   [(set (attr "type")
12719         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12720            (const_string "ssemul")
12721            (const_string "sseadd")))
12722    (set_attr "isa" "noavx,avx")
12723    (set_attr "prefix" "orig,vex")
12724    (set_attr "mode" "<MODE>")])
12725
12726 (define_insn "*fop_<mode>_comm_i387"
12727   [(set (match_operand:MODEF 0 "register_operand" "=f")
12728         (match_operator:MODEF 3 "binary_fp_operator"
12729           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12730            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12731   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12732    && COMMUTATIVE_ARITH_P (operands[3])
12733    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12734   "* return output_387_binary_op (insn, operands);"
12735   [(set (attr "type")
12736         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12737            (const_string "fmul")
12738            (const_string "fop")))
12739    (set_attr "mode" "<MODE>")])
12740
12741 (define_insn "*fop_<mode>_1_mixed"
12742   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12743         (match_operator:MODEF 3 "binary_fp_operator"
12744           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12745            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12746   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12747    && !COMMUTATIVE_ARITH_P (operands[3])
12748    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12749   "* return output_387_binary_op (insn, operands);"
12750   [(set (attr "type")
12751         (cond [(and (eq_attr "alternative" "2,3")
12752                     (match_operand:MODEF 3 "mult_operator" ""))
12753                  (const_string "ssemul")
12754                (and (eq_attr "alternative" "2,3")
12755                     (match_operand:MODEF 3 "div_operator" ""))
12756                  (const_string "ssediv")
12757                (eq_attr "alternative" "2,3")
12758                  (const_string "sseadd")
12759                (match_operand:MODEF 3 "mult_operator" "")
12760                  (const_string "fmul")
12761                (match_operand:MODEF 3 "div_operator" "")
12762                  (const_string "fdiv")
12763               ]
12764               (const_string "fop")))
12765    (set_attr "isa" "*,*,noavx,avx")
12766    (set_attr "prefix" "orig,orig,orig,vex")
12767    (set_attr "mode" "<MODE>")])
12768
12769 (define_insn "*rcpsf2_sse"
12770   [(set (match_operand:SF 0 "register_operand" "=x")
12771         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12772                    UNSPEC_RCP))]
12773   "TARGET_SSE_MATH"
12774   "%vrcpss\t{%1, %d0|%d0, %1}"
12775   [(set_attr "type" "sse")
12776    (set_attr "atom_sse_attr" "rcp")
12777    (set_attr "prefix" "maybe_vex")
12778    (set_attr "mode" "SF")])
12779
12780 (define_insn "*fop_<mode>_1_sse"
12781   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12782         (match_operator:MODEF 3 "binary_fp_operator"
12783           [(match_operand:MODEF 1 "register_operand" "0,x")
12784            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12785   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12786    && !COMMUTATIVE_ARITH_P (operands[3])"
12787   "* return output_387_binary_op (insn, operands);"
12788   [(set (attr "type")
12789         (cond [(match_operand:MODEF 3 "mult_operator" "")
12790                  (const_string "ssemul")
12791                (match_operand:MODEF 3 "div_operator" "")
12792                  (const_string "ssediv")
12793               ]
12794               (const_string "sseadd")))
12795    (set_attr "isa" "noavx,avx")
12796    (set_attr "prefix" "orig,vex")
12797    (set_attr "mode" "<MODE>")])
12798
12799 ;; This pattern is not fully shadowed by the pattern above.
12800 (define_insn "*fop_<mode>_1_i387"
12801   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12802         (match_operator:MODEF 3 "binary_fp_operator"
12803           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12804            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12805   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12806    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12807    && !COMMUTATIVE_ARITH_P (operands[3])
12808    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12809   "* return output_387_binary_op (insn, operands);"
12810   [(set (attr "type")
12811         (cond [(match_operand:MODEF 3 "mult_operator" "")
12812                  (const_string "fmul")
12813                (match_operand:MODEF 3 "div_operator" "")
12814                  (const_string "fdiv")
12815               ]
12816               (const_string "fop")))
12817    (set_attr "mode" "<MODE>")])
12818
12819 ;; ??? Add SSE splitters for these!
12820 (define_insn "*fop_<MODEF:mode>_2_i387"
12821   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12822         (match_operator:MODEF 3 "binary_fp_operator"
12823           [(float:MODEF
12824              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12825            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12826   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12827    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12828    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12829   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12830   [(set (attr "type")
12831         (cond [(match_operand:MODEF 3 "mult_operator" "")
12832                  (const_string "fmul")
12833                (match_operand:MODEF 3 "div_operator" "")
12834                  (const_string "fdiv")
12835               ]
12836               (const_string "fop")))
12837    (set_attr "fp_int_src" "true")
12838    (set_attr "mode" "<SWI24:MODE>")])
12839
12840 (define_insn "*fop_<MODEF:mode>_3_i387"
12841   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12842         (match_operator:MODEF 3 "binary_fp_operator"
12843           [(match_operand:MODEF 1 "register_operand" "0,0")
12844            (float:MODEF
12845              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12846   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12847    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12848    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12849   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12850   [(set (attr "type")
12851         (cond [(match_operand:MODEF 3 "mult_operator" "")
12852                  (const_string "fmul")
12853                (match_operand:MODEF 3 "div_operator" "")
12854                  (const_string "fdiv")
12855               ]
12856               (const_string "fop")))
12857    (set_attr "fp_int_src" "true")
12858    (set_attr "mode" "<MODE>")])
12859
12860 (define_insn "*fop_df_4_i387"
12861   [(set (match_operand:DF 0 "register_operand" "=f,f")
12862         (match_operator:DF 3 "binary_fp_operator"
12863            [(float_extend:DF
12864              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12865             (match_operand:DF 2 "register_operand" "0,f")]))]
12866   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12867    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12869   "* return output_387_binary_op (insn, operands);"
12870   [(set (attr "type")
12871         (cond [(match_operand:DF 3 "mult_operator" "")
12872                  (const_string "fmul")
12873                (match_operand:DF 3 "div_operator" "")
12874                  (const_string "fdiv")
12875               ]
12876               (const_string "fop")))
12877    (set_attr "mode" "SF")])
12878
12879 (define_insn "*fop_df_5_i387"
12880   [(set (match_operand:DF 0 "register_operand" "=f,f")
12881         (match_operator:DF 3 "binary_fp_operator"
12882           [(match_operand:DF 1 "register_operand" "0,f")
12883            (float_extend:DF
12884             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12885   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12886    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12887   "* return output_387_binary_op (insn, operands);"
12888   [(set (attr "type")
12889         (cond [(match_operand:DF 3 "mult_operator" "")
12890                  (const_string "fmul")
12891                (match_operand:DF 3 "div_operator" "")
12892                  (const_string "fdiv")
12893               ]
12894               (const_string "fop")))
12895    (set_attr "mode" "SF")])
12896
12897 (define_insn "*fop_df_6_i387"
12898   [(set (match_operand:DF 0 "register_operand" "=f,f")
12899         (match_operator:DF 3 "binary_fp_operator"
12900           [(float_extend:DF
12901             (match_operand:SF 1 "register_operand" "0,f"))
12902            (float_extend:DF
12903             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12904   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12905    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12906   "* return output_387_binary_op (insn, operands);"
12907   [(set (attr "type")
12908         (cond [(match_operand:DF 3 "mult_operator" "")
12909                  (const_string "fmul")
12910                (match_operand:DF 3 "div_operator" "")
12911                  (const_string "fdiv")
12912               ]
12913               (const_string "fop")))
12914    (set_attr "mode" "SF")])
12915
12916 (define_insn "*fop_xf_comm_i387"
12917   [(set (match_operand:XF 0 "register_operand" "=f")
12918         (match_operator:XF 3 "binary_fp_operator"
12919                         [(match_operand:XF 1 "register_operand" "%0")
12920                          (match_operand:XF 2 "register_operand" "f")]))]
12921   "TARGET_80387
12922    && COMMUTATIVE_ARITH_P (operands[3])"
12923   "* return output_387_binary_op (insn, operands);"
12924   [(set (attr "type")
12925         (if_then_else (match_operand:XF 3 "mult_operator" "")
12926            (const_string "fmul")
12927            (const_string "fop")))
12928    (set_attr "mode" "XF")])
12929
12930 (define_insn "*fop_xf_1_i387"
12931   [(set (match_operand:XF 0 "register_operand" "=f,f")
12932         (match_operator:XF 3 "binary_fp_operator"
12933                         [(match_operand:XF 1 "register_operand" "0,f")
12934                          (match_operand:XF 2 "register_operand" "f,0")]))]
12935   "TARGET_80387
12936    && !COMMUTATIVE_ARITH_P (operands[3])"
12937   "* return output_387_binary_op (insn, operands);"
12938   [(set (attr "type")
12939         (cond [(match_operand:XF 3 "mult_operator" "")
12940                  (const_string "fmul")
12941                (match_operand:XF 3 "div_operator" "")
12942                  (const_string "fdiv")
12943               ]
12944               (const_string "fop")))
12945    (set_attr "mode" "XF")])
12946
12947 (define_insn "*fop_xf_2_i387"
12948   [(set (match_operand:XF 0 "register_operand" "=f,f")
12949         (match_operator:XF 3 "binary_fp_operator"
12950           [(float:XF
12951              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12952            (match_operand:XF 2 "register_operand" "0,0")]))]
12953   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12954   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12955   [(set (attr "type")
12956         (cond [(match_operand:XF 3 "mult_operator" "")
12957                  (const_string "fmul")
12958                (match_operand:XF 3 "div_operator" "")
12959                  (const_string "fdiv")
12960               ]
12961               (const_string "fop")))
12962    (set_attr "fp_int_src" "true")
12963    (set_attr "mode" "<MODE>")])
12964
12965 (define_insn "*fop_xf_3_i387"
12966   [(set (match_operand:XF 0 "register_operand" "=f,f")
12967         (match_operator:XF 3 "binary_fp_operator"
12968           [(match_operand:XF 1 "register_operand" "0,0")
12969            (float:XF
12970              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12971   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12972   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12973   [(set (attr "type")
12974         (cond [(match_operand:XF 3 "mult_operator" "")
12975                  (const_string "fmul")
12976                (match_operand:XF 3 "div_operator" "")
12977                  (const_string "fdiv")
12978               ]
12979               (const_string "fop")))
12980    (set_attr "fp_int_src" "true")
12981    (set_attr "mode" "<MODE>")])
12982
12983 (define_insn "*fop_xf_4_i387"
12984   [(set (match_operand:XF 0 "register_operand" "=f,f")
12985         (match_operator:XF 3 "binary_fp_operator"
12986            [(float_extend:XF
12987               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12988             (match_operand:XF 2 "register_operand" "0,f")]))]
12989   "TARGET_80387"
12990   "* return output_387_binary_op (insn, operands);"
12991   [(set (attr "type")
12992         (cond [(match_operand:XF 3 "mult_operator" "")
12993                  (const_string "fmul")
12994                (match_operand:XF 3 "div_operator" "")
12995                  (const_string "fdiv")
12996               ]
12997               (const_string "fop")))
12998    (set_attr "mode" "<MODE>")])
12999
13000 (define_insn "*fop_xf_5_i387"
13001   [(set (match_operand:XF 0 "register_operand" "=f,f")
13002         (match_operator:XF 3 "binary_fp_operator"
13003           [(match_operand:XF 1 "register_operand" "0,f")
13004            (float_extend:XF
13005              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13006   "TARGET_80387"
13007   "* return output_387_binary_op (insn, operands);"
13008   [(set (attr "type")
13009         (cond [(match_operand:XF 3 "mult_operator" "")
13010                  (const_string "fmul")
13011                (match_operand:XF 3 "div_operator" "")
13012                  (const_string "fdiv")
13013               ]
13014               (const_string "fop")))
13015    (set_attr "mode" "<MODE>")])
13016
13017 (define_insn "*fop_xf_6_i387"
13018   [(set (match_operand:XF 0 "register_operand" "=f,f")
13019         (match_operator:XF 3 "binary_fp_operator"
13020           [(float_extend:XF
13021              (match_operand:MODEF 1 "register_operand" "0,f"))
13022            (float_extend:XF
13023              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13024   "TARGET_80387"
13025   "* return output_387_binary_op (insn, operands);"
13026   [(set (attr "type")
13027         (cond [(match_operand:XF 3 "mult_operator" "")
13028                  (const_string "fmul")
13029                (match_operand:XF 3 "div_operator" "")
13030                  (const_string "fdiv")
13031               ]
13032               (const_string "fop")))
13033    (set_attr "mode" "<MODE>")])
13034
13035 (define_split
13036   [(set (match_operand 0 "register_operand" "")
13037         (match_operator 3 "binary_fp_operator"
13038            [(float (match_operand:SWI24 1 "register_operand" ""))
13039             (match_operand 2 "register_operand" "")]))]
13040   "reload_completed
13041    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13042    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13043   [(const_int 0)]
13044 {
13045   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13046   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13047   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13048                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13049                                           GET_MODE (operands[3]),
13050                                           operands[4],
13051                                           operands[2])));
13052   ix86_free_from_memory (GET_MODE (operands[1]));
13053   DONE;
13054 })
13055
13056 (define_split
13057   [(set (match_operand 0 "register_operand" "")
13058         (match_operator 3 "binary_fp_operator"
13059            [(match_operand 1 "register_operand" "")
13060             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13061   "reload_completed
13062    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13063    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13064   [(const_int 0)]
13065 {
13066   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13067   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13068   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13069                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13070                                           GET_MODE (operands[3]),
13071                                           operands[1],
13072                                           operands[4])));
13073   ix86_free_from_memory (GET_MODE (operands[2]));
13074   DONE;
13075 })
13076 \f
13077 ;; FPU special functions.
13078
13079 ;; This pattern implements a no-op XFmode truncation for
13080 ;; all fancy i386 XFmode math functions.
13081
13082 (define_insn "truncxf<mode>2_i387_noop_unspec"
13083   [(set (match_operand:MODEF 0 "register_operand" "=f")
13084         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13085         UNSPEC_TRUNC_NOOP))]
13086   "TARGET_USE_FANCY_MATH_387"
13087   "* return output_387_reg_move (insn, operands);"
13088   [(set_attr "type" "fmov")
13089    (set_attr "mode" "<MODE>")])
13090
13091 (define_insn "sqrtxf2"
13092   [(set (match_operand:XF 0 "register_operand" "=f")
13093         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13094   "TARGET_USE_FANCY_MATH_387"
13095   "fsqrt"
13096   [(set_attr "type" "fpspc")
13097    (set_attr "mode" "XF")
13098    (set_attr "athlon_decode" "direct")
13099    (set_attr "amdfam10_decode" "direct")
13100    (set_attr "bdver1_decode" "direct")])
13101
13102 (define_insn "sqrt_extend<mode>xf2_i387"
13103   [(set (match_operand:XF 0 "register_operand" "=f")
13104         (sqrt:XF
13105           (float_extend:XF
13106             (match_operand:MODEF 1 "register_operand" "0"))))]
13107   "TARGET_USE_FANCY_MATH_387"
13108   "fsqrt"
13109   [(set_attr "type" "fpspc")
13110    (set_attr "mode" "XF")
13111    (set_attr "athlon_decode" "direct")
13112    (set_attr "amdfam10_decode" "direct")
13113    (set_attr "bdver1_decode" "direct")])
13114
13115 (define_insn "*rsqrtsf2_sse"
13116   [(set (match_operand:SF 0 "register_operand" "=x")
13117         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13118                    UNSPEC_RSQRT))]
13119   "TARGET_SSE_MATH"
13120   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13121   [(set_attr "type" "sse")
13122    (set_attr "atom_sse_attr" "rcp")
13123    (set_attr "prefix" "maybe_vex")
13124    (set_attr "mode" "SF")])
13125
13126 (define_expand "rsqrtsf2"
13127   [(set (match_operand:SF 0 "register_operand" "")
13128         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13129                    UNSPEC_RSQRT))]
13130   "TARGET_SSE_MATH"
13131 {
13132   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13133   DONE;
13134 })
13135
13136 (define_insn "*sqrt<mode>2_sse"
13137   [(set (match_operand:MODEF 0 "register_operand" "=x")
13138         (sqrt:MODEF
13139           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13140   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13141   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13142   [(set_attr "type" "sse")
13143    (set_attr "atom_sse_attr" "sqrt")
13144    (set_attr "prefix" "maybe_vex")
13145    (set_attr "mode" "<MODE>")
13146    (set_attr "athlon_decode" "*")
13147    (set_attr "amdfam10_decode" "*")
13148    (set_attr "bdver1_decode" "*")])
13149
13150 (define_expand "sqrt<mode>2"
13151   [(set (match_operand:MODEF 0 "register_operand" "")
13152         (sqrt:MODEF
13153           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13154   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13155    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13156 {
13157   if (<MODE>mode == SFmode
13158       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13159       && flag_finite_math_only && !flag_trapping_math
13160       && flag_unsafe_math_optimizations)
13161     {
13162       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13163       DONE;
13164     }
13165
13166   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13167     {
13168       rtx op0 = gen_reg_rtx (XFmode);
13169       rtx op1 = force_reg (<MODE>mode, operands[1]);
13170
13171       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13172       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13173       DONE;
13174    }
13175 })
13176
13177 (define_insn "fpremxf4_i387"
13178   [(set (match_operand:XF 0 "register_operand" "=f")
13179         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13180                     (match_operand:XF 3 "register_operand" "1")]
13181                    UNSPEC_FPREM_F))
13182    (set (match_operand:XF 1 "register_operand" "=u")
13183         (unspec:XF [(match_dup 2) (match_dup 3)]
13184                    UNSPEC_FPREM_U))
13185    (set (reg:CCFP FPSR_REG)
13186         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13187                      UNSPEC_C2_FLAG))]
13188   "TARGET_USE_FANCY_MATH_387"
13189   "fprem"
13190   [(set_attr "type" "fpspc")
13191    (set_attr "mode" "XF")])
13192
13193 (define_expand "fmodxf3"
13194   [(use (match_operand:XF 0 "register_operand" ""))
13195    (use (match_operand:XF 1 "general_operand" ""))
13196    (use (match_operand:XF 2 "general_operand" ""))]
13197   "TARGET_USE_FANCY_MATH_387"
13198 {
13199   rtx label = gen_label_rtx ();
13200
13201   rtx op1 = gen_reg_rtx (XFmode);
13202   rtx op2 = gen_reg_rtx (XFmode);
13203
13204   emit_move_insn (op2, operands[2]);
13205   emit_move_insn (op1, operands[1]);
13206
13207   emit_label (label);
13208   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13209   ix86_emit_fp_unordered_jump (label);
13210   LABEL_NUSES (label) = 1;
13211
13212   emit_move_insn (operands[0], op1);
13213   DONE;
13214 })
13215
13216 (define_expand "fmod<mode>3"
13217   [(use (match_operand:MODEF 0 "register_operand" ""))
13218    (use (match_operand:MODEF 1 "general_operand" ""))
13219    (use (match_operand:MODEF 2 "general_operand" ""))]
13220   "TARGET_USE_FANCY_MATH_387"
13221 {
13222   rtx (*gen_truncxf) (rtx, rtx);
13223
13224   rtx label = gen_label_rtx ();
13225
13226   rtx op1 = gen_reg_rtx (XFmode);
13227   rtx op2 = gen_reg_rtx (XFmode);
13228
13229   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13230   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13231
13232   emit_label (label);
13233   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13234   ix86_emit_fp_unordered_jump (label);
13235   LABEL_NUSES (label) = 1;
13236
13237   /* Truncate the result properly for strict SSE math.  */
13238   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13239       && !TARGET_MIX_SSE_I387)
13240     gen_truncxf = gen_truncxf<mode>2;
13241   else
13242     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13243
13244   emit_insn (gen_truncxf (operands[0], op1));
13245   DONE;
13246 })
13247
13248 (define_insn "fprem1xf4_i387"
13249   [(set (match_operand:XF 0 "register_operand" "=f")
13250         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13251                     (match_operand:XF 3 "register_operand" "1")]
13252                    UNSPEC_FPREM1_F))
13253    (set (match_operand:XF 1 "register_operand" "=u")
13254         (unspec:XF [(match_dup 2) (match_dup 3)]
13255                    UNSPEC_FPREM1_U))
13256    (set (reg:CCFP FPSR_REG)
13257         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13258                      UNSPEC_C2_FLAG))]
13259   "TARGET_USE_FANCY_MATH_387"
13260   "fprem1"
13261   [(set_attr "type" "fpspc")
13262    (set_attr "mode" "XF")])
13263
13264 (define_expand "remainderxf3"
13265   [(use (match_operand:XF 0 "register_operand" ""))
13266    (use (match_operand:XF 1 "general_operand" ""))
13267    (use (match_operand:XF 2 "general_operand" ""))]
13268   "TARGET_USE_FANCY_MATH_387"
13269 {
13270   rtx label = gen_label_rtx ();
13271
13272   rtx op1 = gen_reg_rtx (XFmode);
13273   rtx op2 = gen_reg_rtx (XFmode);
13274
13275   emit_move_insn (op2, operands[2]);
13276   emit_move_insn (op1, operands[1]);
13277
13278   emit_label (label);
13279   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13280   ix86_emit_fp_unordered_jump (label);
13281   LABEL_NUSES (label) = 1;
13282
13283   emit_move_insn (operands[0], op1);
13284   DONE;
13285 })
13286
13287 (define_expand "remainder<mode>3"
13288   [(use (match_operand:MODEF 0 "register_operand" ""))
13289    (use (match_operand:MODEF 1 "general_operand" ""))
13290    (use (match_operand:MODEF 2 "general_operand" ""))]
13291   "TARGET_USE_FANCY_MATH_387"
13292 {
13293   rtx (*gen_truncxf) (rtx, rtx);
13294
13295   rtx label = gen_label_rtx ();
13296
13297   rtx op1 = gen_reg_rtx (XFmode);
13298   rtx op2 = gen_reg_rtx (XFmode);
13299
13300   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13301   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13302
13303   emit_label (label);
13304
13305   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13306   ix86_emit_fp_unordered_jump (label);
13307   LABEL_NUSES (label) = 1;
13308
13309   /* Truncate the result properly for strict SSE math.  */
13310   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13311       && !TARGET_MIX_SSE_I387)
13312     gen_truncxf = gen_truncxf<mode>2;
13313   else
13314     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13315
13316   emit_insn (gen_truncxf (operands[0], op1));
13317   DONE;
13318 })
13319
13320 (define_insn "*sinxf2_i387"
13321   [(set (match_operand:XF 0 "register_operand" "=f")
13322         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13323   "TARGET_USE_FANCY_MATH_387
13324    && flag_unsafe_math_optimizations"
13325   "fsin"
13326   [(set_attr "type" "fpspc")
13327    (set_attr "mode" "XF")])
13328
13329 (define_insn "*sin_extend<mode>xf2_i387"
13330   [(set (match_operand:XF 0 "register_operand" "=f")
13331         (unspec:XF [(float_extend:XF
13332                       (match_operand:MODEF 1 "register_operand" "0"))]
13333                    UNSPEC_SIN))]
13334   "TARGET_USE_FANCY_MATH_387
13335    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13336        || TARGET_MIX_SSE_I387)
13337    && flag_unsafe_math_optimizations"
13338   "fsin"
13339   [(set_attr "type" "fpspc")
13340    (set_attr "mode" "XF")])
13341
13342 (define_insn "*cosxf2_i387"
13343   [(set (match_operand:XF 0 "register_operand" "=f")
13344         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13345   "TARGET_USE_FANCY_MATH_387
13346    && flag_unsafe_math_optimizations"
13347   "fcos"
13348   [(set_attr "type" "fpspc")
13349    (set_attr "mode" "XF")])
13350
13351 (define_insn "*cos_extend<mode>xf2_i387"
13352   [(set (match_operand:XF 0 "register_operand" "=f")
13353         (unspec:XF [(float_extend:XF
13354                       (match_operand:MODEF 1 "register_operand" "0"))]
13355                    UNSPEC_COS))]
13356   "TARGET_USE_FANCY_MATH_387
13357    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13358        || TARGET_MIX_SSE_I387)
13359    && flag_unsafe_math_optimizations"
13360   "fcos"
13361   [(set_attr "type" "fpspc")
13362    (set_attr "mode" "XF")])
13363
13364 ;; When sincos pattern is defined, sin and cos builtin functions will be
13365 ;; expanded to sincos pattern with one of its outputs left unused.
13366 ;; CSE pass will figure out if two sincos patterns can be combined,
13367 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13368 ;; depending on the unused output.
13369
13370 (define_insn "sincosxf3"
13371   [(set (match_operand:XF 0 "register_operand" "=f")
13372         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13373                    UNSPEC_SINCOS_COS))
13374    (set (match_operand:XF 1 "register_operand" "=u")
13375         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13376   "TARGET_USE_FANCY_MATH_387
13377    && flag_unsafe_math_optimizations"
13378   "fsincos"
13379   [(set_attr "type" "fpspc")
13380    (set_attr "mode" "XF")])
13381
13382 (define_split
13383   [(set (match_operand:XF 0 "register_operand" "")
13384         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13385                    UNSPEC_SINCOS_COS))
13386    (set (match_operand:XF 1 "register_operand" "")
13387         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13388   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13389    && can_create_pseudo_p ()"
13390   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13391
13392 (define_split
13393   [(set (match_operand:XF 0 "register_operand" "")
13394         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13395                    UNSPEC_SINCOS_COS))
13396    (set (match_operand:XF 1 "register_operand" "")
13397         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13398   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13399    && can_create_pseudo_p ()"
13400   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13401
13402 (define_insn "sincos_extend<mode>xf3_i387"
13403   [(set (match_operand:XF 0 "register_operand" "=f")
13404         (unspec:XF [(float_extend:XF
13405                       (match_operand:MODEF 2 "register_operand" "0"))]
13406                    UNSPEC_SINCOS_COS))
13407    (set (match_operand:XF 1 "register_operand" "=u")
13408         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13409   "TARGET_USE_FANCY_MATH_387
13410    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13411        || TARGET_MIX_SSE_I387)
13412    && flag_unsafe_math_optimizations"
13413   "fsincos"
13414   [(set_attr "type" "fpspc")
13415    (set_attr "mode" "XF")])
13416
13417 (define_split
13418   [(set (match_operand:XF 0 "register_operand" "")
13419         (unspec:XF [(float_extend:XF
13420                       (match_operand:MODEF 2 "register_operand" ""))]
13421                    UNSPEC_SINCOS_COS))
13422    (set (match_operand:XF 1 "register_operand" "")
13423         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13424   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13425    && can_create_pseudo_p ()"
13426   [(set (match_dup 1)
13427         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13428
13429 (define_split
13430   [(set (match_operand:XF 0 "register_operand" "")
13431         (unspec:XF [(float_extend:XF
13432                       (match_operand:MODEF 2 "register_operand" ""))]
13433                    UNSPEC_SINCOS_COS))
13434    (set (match_operand:XF 1 "register_operand" "")
13435         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13436   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13437    && can_create_pseudo_p ()"
13438   [(set (match_dup 0)
13439         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13440
13441 (define_expand "sincos<mode>3"
13442   [(use (match_operand:MODEF 0 "register_operand" ""))
13443    (use (match_operand:MODEF 1 "register_operand" ""))
13444    (use (match_operand:MODEF 2 "register_operand" ""))]
13445   "TARGET_USE_FANCY_MATH_387
13446    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13447        || TARGET_MIX_SSE_I387)
13448    && flag_unsafe_math_optimizations"
13449 {
13450   rtx op0 = gen_reg_rtx (XFmode);
13451   rtx op1 = gen_reg_rtx (XFmode);
13452
13453   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13454   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13455   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13456   DONE;
13457 })
13458
13459 (define_insn "fptanxf4_i387"
13460   [(set (match_operand:XF 0 "register_operand" "=f")
13461         (match_operand:XF 3 "const_double_operand" "F"))
13462    (set (match_operand:XF 1 "register_operand" "=u")
13463         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13464                    UNSPEC_TAN))]
13465   "TARGET_USE_FANCY_MATH_387
13466    && flag_unsafe_math_optimizations
13467    && standard_80387_constant_p (operands[3]) == 2"
13468   "fptan"
13469   [(set_attr "type" "fpspc")
13470    (set_attr "mode" "XF")])
13471
13472 (define_insn "fptan_extend<mode>xf4_i387"
13473   [(set (match_operand:MODEF 0 "register_operand" "=f")
13474         (match_operand:MODEF 3 "const_double_operand" "F"))
13475    (set (match_operand:XF 1 "register_operand" "=u")
13476         (unspec:XF [(float_extend:XF
13477                       (match_operand:MODEF 2 "register_operand" "0"))]
13478                    UNSPEC_TAN))]
13479   "TARGET_USE_FANCY_MATH_387
13480    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13481        || TARGET_MIX_SSE_I387)
13482    && flag_unsafe_math_optimizations
13483    && standard_80387_constant_p (operands[3]) == 2"
13484   "fptan"
13485   [(set_attr "type" "fpspc")
13486    (set_attr "mode" "XF")])
13487
13488 (define_expand "tanxf2"
13489   [(use (match_operand:XF 0 "register_operand" ""))
13490    (use (match_operand:XF 1 "register_operand" ""))]
13491   "TARGET_USE_FANCY_MATH_387
13492    && flag_unsafe_math_optimizations"
13493 {
13494   rtx one = gen_reg_rtx (XFmode);
13495   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13496
13497   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13498   DONE;
13499 })
13500
13501 (define_expand "tan<mode>2"
13502   [(use (match_operand:MODEF 0 "register_operand" ""))
13503    (use (match_operand:MODEF 1 "register_operand" ""))]
13504   "TARGET_USE_FANCY_MATH_387
13505    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13506        || TARGET_MIX_SSE_I387)
13507    && flag_unsafe_math_optimizations"
13508 {
13509   rtx op0 = gen_reg_rtx (XFmode);
13510
13511   rtx one = gen_reg_rtx (<MODE>mode);
13512   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13513
13514   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13515                                              operands[1], op2));
13516   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13517   DONE;
13518 })
13519
13520 (define_insn "*fpatanxf3_i387"
13521   [(set (match_operand:XF 0 "register_operand" "=f")
13522         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13523                     (match_operand:XF 2 "register_operand" "u")]
13524                    UNSPEC_FPATAN))
13525    (clobber (match_scratch:XF 3 "=2"))]
13526   "TARGET_USE_FANCY_MATH_387
13527    && flag_unsafe_math_optimizations"
13528   "fpatan"
13529   [(set_attr "type" "fpspc")
13530    (set_attr "mode" "XF")])
13531
13532 (define_insn "fpatan_extend<mode>xf3_i387"
13533   [(set (match_operand:XF 0 "register_operand" "=f")
13534         (unspec:XF [(float_extend:XF
13535                       (match_operand:MODEF 1 "register_operand" "0"))
13536                     (float_extend:XF
13537                       (match_operand:MODEF 2 "register_operand" "u"))]
13538                    UNSPEC_FPATAN))
13539    (clobber (match_scratch:XF 3 "=2"))]
13540   "TARGET_USE_FANCY_MATH_387
13541    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13542        || TARGET_MIX_SSE_I387)
13543    && flag_unsafe_math_optimizations"
13544   "fpatan"
13545   [(set_attr "type" "fpspc")
13546    (set_attr "mode" "XF")])
13547
13548 (define_expand "atan2xf3"
13549   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13550                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13551                                (match_operand:XF 1 "register_operand" "")]
13552                               UNSPEC_FPATAN))
13553               (clobber (match_scratch:XF 3 ""))])]
13554   "TARGET_USE_FANCY_MATH_387
13555    && flag_unsafe_math_optimizations")
13556
13557 (define_expand "atan2<mode>3"
13558   [(use (match_operand:MODEF 0 "register_operand" ""))
13559    (use (match_operand:MODEF 1 "register_operand" ""))
13560    (use (match_operand:MODEF 2 "register_operand" ""))]
13561   "TARGET_USE_FANCY_MATH_387
13562    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13563        || TARGET_MIX_SSE_I387)
13564    && flag_unsafe_math_optimizations"
13565 {
13566   rtx op0 = gen_reg_rtx (XFmode);
13567
13568   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13569   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13570   DONE;
13571 })
13572
13573 (define_expand "atanxf2"
13574   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13575                    (unspec:XF [(match_dup 2)
13576                                (match_operand:XF 1 "register_operand" "")]
13577                               UNSPEC_FPATAN))
13578               (clobber (match_scratch:XF 3 ""))])]
13579   "TARGET_USE_FANCY_MATH_387
13580    && flag_unsafe_math_optimizations"
13581 {
13582   operands[2] = gen_reg_rtx (XFmode);
13583   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13584 })
13585
13586 (define_expand "atan<mode>2"
13587   [(use (match_operand:MODEF 0 "register_operand" ""))
13588    (use (match_operand:MODEF 1 "register_operand" ""))]
13589   "TARGET_USE_FANCY_MATH_387
13590    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13591        || TARGET_MIX_SSE_I387)
13592    && flag_unsafe_math_optimizations"
13593 {
13594   rtx op0 = gen_reg_rtx (XFmode);
13595
13596   rtx op2 = gen_reg_rtx (<MODE>mode);
13597   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13598
13599   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13600   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13601   DONE;
13602 })
13603
13604 (define_expand "asinxf2"
13605   [(set (match_dup 2)
13606         (mult:XF (match_operand:XF 1 "register_operand" "")
13607                  (match_dup 1)))
13608    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13609    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13610    (parallel [(set (match_operand:XF 0 "register_operand" "")
13611                    (unspec:XF [(match_dup 5) (match_dup 1)]
13612                               UNSPEC_FPATAN))
13613               (clobber (match_scratch:XF 6 ""))])]
13614   "TARGET_USE_FANCY_MATH_387
13615    && flag_unsafe_math_optimizations"
13616 {
13617   int i;
13618
13619   if (optimize_insn_for_size_p ())
13620     FAIL;
13621
13622   for (i = 2; i < 6; i++)
13623     operands[i] = gen_reg_rtx (XFmode);
13624
13625   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13626 })
13627
13628 (define_expand "asin<mode>2"
13629   [(use (match_operand:MODEF 0 "register_operand" ""))
13630    (use (match_operand:MODEF 1 "general_operand" ""))]
13631  "TARGET_USE_FANCY_MATH_387
13632    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13633        || TARGET_MIX_SSE_I387)
13634    && flag_unsafe_math_optimizations"
13635 {
13636   rtx op0 = gen_reg_rtx (XFmode);
13637   rtx op1 = gen_reg_rtx (XFmode);
13638
13639   if (optimize_insn_for_size_p ())
13640     FAIL;
13641
13642   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13643   emit_insn (gen_asinxf2 (op0, op1));
13644   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13645   DONE;
13646 })
13647
13648 (define_expand "acosxf2"
13649   [(set (match_dup 2)
13650         (mult:XF (match_operand:XF 1 "register_operand" "")
13651                  (match_dup 1)))
13652    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13653    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13654    (parallel [(set (match_operand:XF 0 "register_operand" "")
13655                    (unspec:XF [(match_dup 1) (match_dup 5)]
13656                               UNSPEC_FPATAN))
13657               (clobber (match_scratch:XF 6 ""))])]
13658   "TARGET_USE_FANCY_MATH_387
13659    && flag_unsafe_math_optimizations"
13660 {
13661   int i;
13662
13663   if (optimize_insn_for_size_p ())
13664     FAIL;
13665
13666   for (i = 2; i < 6; i++)
13667     operands[i] = gen_reg_rtx (XFmode);
13668
13669   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13670 })
13671
13672 (define_expand "acos<mode>2"
13673   [(use (match_operand:MODEF 0 "register_operand" ""))
13674    (use (match_operand:MODEF 1 "general_operand" ""))]
13675  "TARGET_USE_FANCY_MATH_387
13676    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13677        || TARGET_MIX_SSE_I387)
13678    && flag_unsafe_math_optimizations"
13679 {
13680   rtx op0 = gen_reg_rtx (XFmode);
13681   rtx op1 = gen_reg_rtx (XFmode);
13682
13683   if (optimize_insn_for_size_p ())
13684     FAIL;
13685
13686   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13687   emit_insn (gen_acosxf2 (op0, op1));
13688   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13689   DONE;
13690 })
13691
13692 (define_insn "fyl2xxf3_i387"
13693   [(set (match_operand:XF 0 "register_operand" "=f")
13694         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13695                     (match_operand:XF 2 "register_operand" "u")]
13696                    UNSPEC_FYL2X))
13697    (clobber (match_scratch:XF 3 "=2"))]
13698   "TARGET_USE_FANCY_MATH_387
13699    && flag_unsafe_math_optimizations"
13700   "fyl2x"
13701   [(set_attr "type" "fpspc")
13702    (set_attr "mode" "XF")])
13703
13704 (define_insn "fyl2x_extend<mode>xf3_i387"
13705   [(set (match_operand:XF 0 "register_operand" "=f")
13706         (unspec:XF [(float_extend:XF
13707                       (match_operand:MODEF 1 "register_operand" "0"))
13708                     (match_operand:XF 2 "register_operand" "u")]
13709                    UNSPEC_FYL2X))
13710    (clobber (match_scratch:XF 3 "=2"))]
13711   "TARGET_USE_FANCY_MATH_387
13712    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13713        || TARGET_MIX_SSE_I387)
13714    && flag_unsafe_math_optimizations"
13715   "fyl2x"
13716   [(set_attr "type" "fpspc")
13717    (set_attr "mode" "XF")])
13718
13719 (define_expand "logxf2"
13720   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13721                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13722                                (match_dup 2)] UNSPEC_FYL2X))
13723               (clobber (match_scratch:XF 3 ""))])]
13724   "TARGET_USE_FANCY_MATH_387
13725    && flag_unsafe_math_optimizations"
13726 {
13727   operands[2] = gen_reg_rtx (XFmode);
13728   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13729 })
13730
13731 (define_expand "log<mode>2"
13732   [(use (match_operand:MODEF 0 "register_operand" ""))
13733    (use (match_operand:MODEF 1 "register_operand" ""))]
13734   "TARGET_USE_FANCY_MATH_387
13735    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13736        || TARGET_MIX_SSE_I387)
13737    && flag_unsafe_math_optimizations"
13738 {
13739   rtx op0 = gen_reg_rtx (XFmode);
13740
13741   rtx op2 = gen_reg_rtx (XFmode);
13742   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13743
13744   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13745   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13746   DONE;
13747 })
13748
13749 (define_expand "log10xf2"
13750   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13751                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13752                                (match_dup 2)] UNSPEC_FYL2X))
13753               (clobber (match_scratch:XF 3 ""))])]
13754   "TARGET_USE_FANCY_MATH_387
13755    && flag_unsafe_math_optimizations"
13756 {
13757   operands[2] = gen_reg_rtx (XFmode);
13758   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13759 })
13760
13761 (define_expand "log10<mode>2"
13762   [(use (match_operand:MODEF 0 "register_operand" ""))
13763    (use (match_operand:MODEF 1 "register_operand" ""))]
13764   "TARGET_USE_FANCY_MATH_387
13765    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13766        || TARGET_MIX_SSE_I387)
13767    && flag_unsafe_math_optimizations"
13768 {
13769   rtx op0 = gen_reg_rtx (XFmode);
13770
13771   rtx op2 = gen_reg_rtx (XFmode);
13772   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13773
13774   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13775   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13776   DONE;
13777 })
13778
13779 (define_expand "log2xf2"
13780   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13781                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13782                                (match_dup 2)] UNSPEC_FYL2X))
13783               (clobber (match_scratch:XF 3 ""))])]
13784   "TARGET_USE_FANCY_MATH_387
13785    && flag_unsafe_math_optimizations"
13786 {
13787   operands[2] = gen_reg_rtx (XFmode);
13788   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13789 })
13790
13791 (define_expand "log2<mode>2"
13792   [(use (match_operand:MODEF 0 "register_operand" ""))
13793    (use (match_operand:MODEF 1 "register_operand" ""))]
13794   "TARGET_USE_FANCY_MATH_387
13795    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13796        || TARGET_MIX_SSE_I387)
13797    && flag_unsafe_math_optimizations"
13798 {
13799   rtx op0 = gen_reg_rtx (XFmode);
13800
13801   rtx op2 = gen_reg_rtx (XFmode);
13802   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13803
13804   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13805   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13806   DONE;
13807 })
13808
13809 (define_insn "fyl2xp1xf3_i387"
13810   [(set (match_operand:XF 0 "register_operand" "=f")
13811         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13812                     (match_operand:XF 2 "register_operand" "u")]
13813                    UNSPEC_FYL2XP1))
13814    (clobber (match_scratch:XF 3 "=2"))]
13815   "TARGET_USE_FANCY_MATH_387
13816    && flag_unsafe_math_optimizations"
13817   "fyl2xp1"
13818   [(set_attr "type" "fpspc")
13819    (set_attr "mode" "XF")])
13820
13821 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13822   [(set (match_operand:XF 0 "register_operand" "=f")
13823         (unspec:XF [(float_extend:XF
13824                       (match_operand:MODEF 1 "register_operand" "0"))
13825                     (match_operand:XF 2 "register_operand" "u")]
13826                    UNSPEC_FYL2XP1))
13827    (clobber (match_scratch:XF 3 "=2"))]
13828   "TARGET_USE_FANCY_MATH_387
13829    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13830        || TARGET_MIX_SSE_I387)
13831    && flag_unsafe_math_optimizations"
13832   "fyl2xp1"
13833   [(set_attr "type" "fpspc")
13834    (set_attr "mode" "XF")])
13835
13836 (define_expand "log1pxf2"
13837   [(use (match_operand:XF 0 "register_operand" ""))
13838    (use (match_operand:XF 1 "register_operand" ""))]
13839   "TARGET_USE_FANCY_MATH_387
13840    && flag_unsafe_math_optimizations"
13841 {
13842   if (optimize_insn_for_size_p ())
13843     FAIL;
13844
13845   ix86_emit_i387_log1p (operands[0], operands[1]);
13846   DONE;
13847 })
13848
13849 (define_expand "log1p<mode>2"
13850   [(use (match_operand:MODEF 0 "register_operand" ""))
13851    (use (match_operand:MODEF 1 "register_operand" ""))]
13852   "TARGET_USE_FANCY_MATH_387
13853    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13854        || TARGET_MIX_SSE_I387)
13855    && flag_unsafe_math_optimizations"
13856 {
13857   rtx op0;
13858
13859   if (optimize_insn_for_size_p ())
13860     FAIL;
13861
13862   op0 = gen_reg_rtx (XFmode);
13863
13864   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13865
13866   ix86_emit_i387_log1p (op0, operands[1]);
13867   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13868   DONE;
13869 })
13870
13871 (define_insn "fxtractxf3_i387"
13872   [(set (match_operand:XF 0 "register_operand" "=f")
13873         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13874                    UNSPEC_XTRACT_FRACT))
13875    (set (match_operand:XF 1 "register_operand" "=u")
13876         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13877   "TARGET_USE_FANCY_MATH_387
13878    && flag_unsafe_math_optimizations"
13879   "fxtract"
13880   [(set_attr "type" "fpspc")
13881    (set_attr "mode" "XF")])
13882
13883 (define_insn "fxtract_extend<mode>xf3_i387"
13884   [(set (match_operand:XF 0 "register_operand" "=f")
13885         (unspec:XF [(float_extend:XF
13886                       (match_operand:MODEF 2 "register_operand" "0"))]
13887                    UNSPEC_XTRACT_FRACT))
13888    (set (match_operand:XF 1 "register_operand" "=u")
13889         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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   "fxtract"
13895   [(set_attr "type" "fpspc")
13896    (set_attr "mode" "XF")])
13897
13898 (define_expand "logbxf2"
13899   [(parallel [(set (match_dup 2)
13900                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13901                               UNSPEC_XTRACT_FRACT))
13902               (set (match_operand:XF 0 "register_operand" "")
13903                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13904   "TARGET_USE_FANCY_MATH_387
13905    && flag_unsafe_math_optimizations"
13906   "operands[2] = gen_reg_rtx (XFmode);")
13907
13908 (define_expand "logb<mode>2"
13909   [(use (match_operand:MODEF 0 "register_operand" ""))
13910    (use (match_operand:MODEF 1 "register_operand" ""))]
13911   "TARGET_USE_FANCY_MATH_387
13912    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13913        || TARGET_MIX_SSE_I387)
13914    && flag_unsafe_math_optimizations"
13915 {
13916   rtx op0 = gen_reg_rtx (XFmode);
13917   rtx op1 = gen_reg_rtx (XFmode);
13918
13919   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13920   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13921   DONE;
13922 })
13923
13924 (define_expand "ilogbxf2"
13925   [(use (match_operand:SI 0 "register_operand" ""))
13926    (use (match_operand:XF 1 "register_operand" ""))]
13927   "TARGET_USE_FANCY_MATH_387
13928    && flag_unsafe_math_optimizations"
13929 {
13930   rtx op0, op1;
13931
13932   if (optimize_insn_for_size_p ())
13933     FAIL;
13934
13935   op0 = gen_reg_rtx (XFmode);
13936   op1 = gen_reg_rtx (XFmode);
13937
13938   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13939   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13940   DONE;
13941 })
13942
13943 (define_expand "ilogb<mode>2"
13944   [(use (match_operand:SI 0 "register_operand" ""))
13945    (use (match_operand:MODEF 1 "register_operand" ""))]
13946   "TARGET_USE_FANCY_MATH_387
13947    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13948        || TARGET_MIX_SSE_I387)
13949    && flag_unsafe_math_optimizations"
13950 {
13951   rtx op0, op1;
13952
13953   if (optimize_insn_for_size_p ())
13954     FAIL;
13955
13956   op0 = gen_reg_rtx (XFmode);
13957   op1 = gen_reg_rtx (XFmode);
13958
13959   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13960   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13961   DONE;
13962 })
13963
13964 (define_insn "*f2xm1xf2_i387"
13965   [(set (match_operand:XF 0 "register_operand" "=f")
13966         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13967                    UNSPEC_F2XM1))]
13968   "TARGET_USE_FANCY_MATH_387
13969    && flag_unsafe_math_optimizations"
13970   "f2xm1"
13971   [(set_attr "type" "fpspc")
13972    (set_attr "mode" "XF")])
13973
13974 (define_insn "*fscalexf4_i387"
13975   [(set (match_operand:XF 0 "register_operand" "=f")
13976         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13977                     (match_operand:XF 3 "register_operand" "1")]
13978                    UNSPEC_FSCALE_FRACT))
13979    (set (match_operand:XF 1 "register_operand" "=u")
13980         (unspec:XF [(match_dup 2) (match_dup 3)]
13981                    UNSPEC_FSCALE_EXP))]
13982   "TARGET_USE_FANCY_MATH_387
13983    && flag_unsafe_math_optimizations"
13984   "fscale"
13985   [(set_attr "type" "fpspc")
13986    (set_attr "mode" "XF")])
13987
13988 (define_expand "expNcorexf3"
13989   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13990                                (match_operand:XF 2 "register_operand" "")))
13991    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13992    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13993    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13994    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13995    (parallel [(set (match_operand:XF 0 "register_operand" "")
13996                    (unspec:XF [(match_dup 8) (match_dup 4)]
13997                               UNSPEC_FSCALE_FRACT))
13998               (set (match_dup 9)
13999                    (unspec:XF [(match_dup 8) (match_dup 4)]
14000                               UNSPEC_FSCALE_EXP))])]
14001   "TARGET_USE_FANCY_MATH_387
14002    && flag_unsafe_math_optimizations"
14003 {
14004   int i;
14005
14006   if (optimize_insn_for_size_p ())
14007     FAIL;
14008
14009   for (i = 3; i < 10; i++)
14010     operands[i] = gen_reg_rtx (XFmode);
14011
14012   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14013 })
14014
14015 (define_expand "expxf2"
14016   [(use (match_operand:XF 0 "register_operand" ""))
14017    (use (match_operand:XF 1 "register_operand" ""))]
14018   "TARGET_USE_FANCY_MATH_387
14019    && flag_unsafe_math_optimizations"
14020 {
14021   rtx op2;
14022
14023   if (optimize_insn_for_size_p ())
14024     FAIL;
14025
14026   op2 = gen_reg_rtx (XFmode);
14027   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14028
14029   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14030   DONE;
14031 })
14032
14033 (define_expand "exp<mode>2"
14034   [(use (match_operand:MODEF 0 "register_operand" ""))
14035    (use (match_operand:MODEF 1 "general_operand" ""))]
14036  "TARGET_USE_FANCY_MATH_387
14037    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14038        || TARGET_MIX_SSE_I387)
14039    && flag_unsafe_math_optimizations"
14040 {
14041   rtx op0, op1;
14042
14043   if (optimize_insn_for_size_p ())
14044     FAIL;
14045
14046   op0 = gen_reg_rtx (XFmode);
14047   op1 = gen_reg_rtx (XFmode);
14048
14049   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14050   emit_insn (gen_expxf2 (op0, op1));
14051   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14052   DONE;
14053 })
14054
14055 (define_expand "exp10xf2"
14056   [(use (match_operand:XF 0 "register_operand" ""))
14057    (use (match_operand:XF 1 "register_operand" ""))]
14058   "TARGET_USE_FANCY_MATH_387
14059    && flag_unsafe_math_optimizations"
14060 {
14061   rtx op2;
14062
14063   if (optimize_insn_for_size_p ())
14064     FAIL;
14065
14066   op2 = gen_reg_rtx (XFmode);
14067   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14068
14069   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14070   DONE;
14071 })
14072
14073 (define_expand "exp10<mode>2"
14074   [(use (match_operand:MODEF 0 "register_operand" ""))
14075    (use (match_operand:MODEF 1 "general_operand" ""))]
14076  "TARGET_USE_FANCY_MATH_387
14077    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14078        || TARGET_MIX_SSE_I387)
14079    && flag_unsafe_math_optimizations"
14080 {
14081   rtx op0, op1;
14082
14083   if (optimize_insn_for_size_p ())
14084     FAIL;
14085
14086   op0 = gen_reg_rtx (XFmode);
14087   op1 = gen_reg_rtx (XFmode);
14088
14089   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14090   emit_insn (gen_exp10xf2 (op0, op1));
14091   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14092   DONE;
14093 })
14094
14095 (define_expand "exp2xf2"
14096   [(use (match_operand:XF 0 "register_operand" ""))
14097    (use (match_operand:XF 1 "register_operand" ""))]
14098   "TARGET_USE_FANCY_MATH_387
14099    && flag_unsafe_math_optimizations"
14100 {
14101   rtx op2;
14102
14103   if (optimize_insn_for_size_p ())
14104     FAIL;
14105
14106   op2 = gen_reg_rtx (XFmode);
14107   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14108
14109   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14110   DONE;
14111 })
14112
14113 (define_expand "exp2<mode>2"
14114   [(use (match_operand:MODEF 0 "register_operand" ""))
14115    (use (match_operand:MODEF 1 "general_operand" ""))]
14116  "TARGET_USE_FANCY_MATH_387
14117    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118        || TARGET_MIX_SSE_I387)
14119    && flag_unsafe_math_optimizations"
14120 {
14121   rtx op0, op1;
14122
14123   if (optimize_insn_for_size_p ())
14124     FAIL;
14125
14126   op0 = gen_reg_rtx (XFmode);
14127   op1 = gen_reg_rtx (XFmode);
14128
14129   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14130   emit_insn (gen_exp2xf2 (op0, op1));
14131   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14132   DONE;
14133 })
14134
14135 (define_expand "expm1xf2"
14136   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14137                                (match_dup 2)))
14138    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14139    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14140    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14141    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14142    (parallel [(set (match_dup 7)
14143                    (unspec:XF [(match_dup 6) (match_dup 4)]
14144                               UNSPEC_FSCALE_FRACT))
14145               (set (match_dup 8)
14146                    (unspec:XF [(match_dup 6) (match_dup 4)]
14147                               UNSPEC_FSCALE_EXP))])
14148    (parallel [(set (match_dup 10)
14149                    (unspec:XF [(match_dup 9) (match_dup 8)]
14150                               UNSPEC_FSCALE_FRACT))
14151               (set (match_dup 11)
14152                    (unspec:XF [(match_dup 9) (match_dup 8)]
14153                               UNSPEC_FSCALE_EXP))])
14154    (set (match_dup 12) (minus:XF (match_dup 10)
14155                                  (float_extend:XF (match_dup 13))))
14156    (set (match_operand:XF 0 "register_operand" "")
14157         (plus:XF (match_dup 12) (match_dup 7)))]
14158   "TARGET_USE_FANCY_MATH_387
14159    && flag_unsafe_math_optimizations"
14160 {
14161   int i;
14162
14163   if (optimize_insn_for_size_p ())
14164     FAIL;
14165
14166   for (i = 2; i < 13; i++)
14167     operands[i] = gen_reg_rtx (XFmode);
14168
14169   operands[13]
14170     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14171
14172   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14173 })
14174
14175 (define_expand "expm1<mode>2"
14176   [(use (match_operand:MODEF 0 "register_operand" ""))
14177    (use (match_operand:MODEF 1 "general_operand" ""))]
14178  "TARGET_USE_FANCY_MATH_387
14179    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14180        || TARGET_MIX_SSE_I387)
14181    && flag_unsafe_math_optimizations"
14182 {
14183   rtx op0, op1;
14184
14185   if (optimize_insn_for_size_p ())
14186     FAIL;
14187
14188   op0 = gen_reg_rtx (XFmode);
14189   op1 = gen_reg_rtx (XFmode);
14190
14191   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14192   emit_insn (gen_expm1xf2 (op0, op1));
14193   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14194   DONE;
14195 })
14196
14197 (define_expand "ldexpxf3"
14198   [(set (match_dup 3)
14199         (float:XF (match_operand:SI 2 "register_operand" "")))
14200    (parallel [(set (match_operand:XF 0 " register_operand" "")
14201                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14202                                (match_dup 3)]
14203                               UNSPEC_FSCALE_FRACT))
14204               (set (match_dup 4)
14205                    (unspec:XF [(match_dup 1) (match_dup 3)]
14206                               UNSPEC_FSCALE_EXP))])]
14207   "TARGET_USE_FANCY_MATH_387
14208    && flag_unsafe_math_optimizations"
14209 {
14210   if (optimize_insn_for_size_p ())
14211     FAIL;
14212
14213   operands[3] = gen_reg_rtx (XFmode);
14214   operands[4] = gen_reg_rtx (XFmode);
14215 })
14216
14217 (define_expand "ldexp<mode>3"
14218   [(use (match_operand:MODEF 0 "register_operand" ""))
14219    (use (match_operand:MODEF 1 "general_operand" ""))
14220    (use (match_operand:SI 2 "register_operand" ""))]
14221  "TARGET_USE_FANCY_MATH_387
14222    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14223        || TARGET_MIX_SSE_I387)
14224    && flag_unsafe_math_optimizations"
14225 {
14226   rtx op0, op1;
14227
14228   if (optimize_insn_for_size_p ())
14229     FAIL;
14230
14231   op0 = gen_reg_rtx (XFmode);
14232   op1 = gen_reg_rtx (XFmode);
14233
14234   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14235   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14236   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14237   DONE;
14238 })
14239
14240 (define_expand "scalbxf3"
14241   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14242                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14243                                (match_operand:XF 2 "register_operand" "")]
14244                               UNSPEC_FSCALE_FRACT))
14245               (set (match_dup 3)
14246                    (unspec:XF [(match_dup 1) (match_dup 2)]
14247                               UNSPEC_FSCALE_EXP))])]
14248   "TARGET_USE_FANCY_MATH_387
14249    && flag_unsafe_math_optimizations"
14250 {
14251   if (optimize_insn_for_size_p ())
14252     FAIL;
14253
14254   operands[3] = gen_reg_rtx (XFmode);
14255 })
14256
14257 (define_expand "scalb<mode>3"
14258   [(use (match_operand:MODEF 0 "register_operand" ""))
14259    (use (match_operand:MODEF 1 "general_operand" ""))
14260    (use (match_operand:MODEF 2 "general_operand" ""))]
14261  "TARGET_USE_FANCY_MATH_387
14262    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263        || TARGET_MIX_SSE_I387)
14264    && flag_unsafe_math_optimizations"
14265 {
14266   rtx op0, op1, op2;
14267
14268   if (optimize_insn_for_size_p ())
14269     FAIL;
14270
14271   op0 = gen_reg_rtx (XFmode);
14272   op1 = gen_reg_rtx (XFmode);
14273   op2 = gen_reg_rtx (XFmode);
14274
14275   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14276   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14277   emit_insn (gen_scalbxf3 (op0, op1, op2));
14278   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14279   DONE;
14280 })
14281
14282 (define_expand "significandxf2"
14283   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14284                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14285                               UNSPEC_XTRACT_FRACT))
14286               (set (match_dup 2)
14287                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14288   "TARGET_USE_FANCY_MATH_387
14289    && flag_unsafe_math_optimizations"
14290   "operands[2] = gen_reg_rtx (XFmode);")
14291
14292 (define_expand "significand<mode>2"
14293   [(use (match_operand:MODEF 0 "register_operand" ""))
14294    (use (match_operand:MODEF 1 "register_operand" ""))]
14295   "TARGET_USE_FANCY_MATH_387
14296    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14297        || TARGET_MIX_SSE_I387)
14298    && flag_unsafe_math_optimizations"
14299 {
14300   rtx op0 = gen_reg_rtx (XFmode);
14301   rtx op1 = gen_reg_rtx (XFmode);
14302
14303   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14304   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14305   DONE;
14306 })
14307 \f
14308
14309 (define_insn "sse4_1_round<mode>2"
14310   [(set (match_operand:MODEF 0 "register_operand" "=x")
14311         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14312                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14313                       UNSPEC_ROUND))]
14314   "TARGET_ROUND"
14315   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14316   [(set_attr "type" "ssecvt")
14317    (set_attr "prefix_extra" "1")
14318    (set_attr "prefix" "maybe_vex")
14319    (set_attr "mode" "<MODE>")])
14320
14321 (define_insn "rintxf2"
14322   [(set (match_operand:XF 0 "register_operand" "=f")
14323         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14324                    UNSPEC_FRNDINT))]
14325   "TARGET_USE_FANCY_MATH_387
14326    && flag_unsafe_math_optimizations"
14327   "frndint"
14328   [(set_attr "type" "fpspc")
14329    (set_attr "mode" "XF")])
14330
14331 (define_expand "rint<mode>2"
14332   [(use (match_operand:MODEF 0 "register_operand" ""))
14333    (use (match_operand:MODEF 1 "register_operand" ""))]
14334   "(TARGET_USE_FANCY_MATH_387
14335     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14336         || TARGET_MIX_SSE_I387)
14337     && flag_unsafe_math_optimizations)
14338    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14339        && !flag_trapping_math)"
14340 {
14341   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14342       && !flag_trapping_math)
14343     {
14344       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14345         FAIL;
14346       if (TARGET_ROUND)
14347         emit_insn (gen_sse4_1_round<mode>2
14348                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14349       else
14350         ix86_expand_rint (operand0, operand1);
14351     }
14352   else
14353     {
14354       rtx op0 = gen_reg_rtx (XFmode);
14355       rtx op1 = gen_reg_rtx (XFmode);
14356
14357       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14358       emit_insn (gen_rintxf2 (op0, op1));
14359
14360       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14361     }
14362   DONE;
14363 })
14364
14365 (define_expand "round<mode>2"
14366   [(match_operand:MODEF 0 "register_operand" "")
14367    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14368   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14369    && !flag_trapping_math && !flag_rounding_math"
14370 {
14371   if (optimize_insn_for_size_p ())
14372     FAIL;
14373   if (TARGET_64BIT || (<MODE>mode != DFmode))
14374     ix86_expand_round (operand0, operand1);
14375   else
14376     ix86_expand_rounddf_32 (operand0, operand1);
14377   DONE;
14378 })
14379
14380 (define_insn_and_split "*fistdi2_1"
14381   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14382         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14383                    UNSPEC_FIST))]
14384   "TARGET_USE_FANCY_MATH_387
14385    && can_create_pseudo_p ()"
14386   "#"
14387   "&& 1"
14388   [(const_int 0)]
14389 {
14390   if (memory_operand (operands[0], VOIDmode))
14391     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14392   else
14393     {
14394       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14395       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14396                                          operands[2]));
14397     }
14398   DONE;
14399 }
14400   [(set_attr "type" "fpspc")
14401    (set_attr "mode" "DI")])
14402
14403 (define_insn "fistdi2"
14404   [(set (match_operand:DI 0 "memory_operand" "=m")
14405         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14406                    UNSPEC_FIST))
14407    (clobber (match_scratch:XF 2 "=&1f"))]
14408   "TARGET_USE_FANCY_MATH_387"
14409   "* return output_fix_trunc (insn, operands, false);"
14410   [(set_attr "type" "fpspc")
14411    (set_attr "mode" "DI")])
14412
14413 (define_insn "fistdi2_with_temp"
14414   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14415         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14416                    UNSPEC_FIST))
14417    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14418    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14419   "TARGET_USE_FANCY_MATH_387"
14420   "#"
14421   [(set_attr "type" "fpspc")
14422    (set_attr "mode" "DI")])
14423
14424 (define_split
14425   [(set (match_operand:DI 0 "register_operand" "")
14426         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14427                    UNSPEC_FIST))
14428    (clobber (match_operand:DI 2 "memory_operand" ""))
14429    (clobber (match_scratch 3 ""))]
14430   "reload_completed"
14431   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14432               (clobber (match_dup 3))])
14433    (set (match_dup 0) (match_dup 2))])
14434
14435 (define_split
14436   [(set (match_operand:DI 0 "memory_operand" "")
14437         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14438                    UNSPEC_FIST))
14439    (clobber (match_operand:DI 2 "memory_operand" ""))
14440    (clobber (match_scratch 3 ""))]
14441   "reload_completed"
14442   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14443               (clobber (match_dup 3))])])
14444
14445 (define_insn_and_split "*fist<mode>2_1"
14446   [(set (match_operand:SWI24 0 "register_operand" "")
14447         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14448                       UNSPEC_FIST))]
14449   "TARGET_USE_FANCY_MATH_387
14450    && can_create_pseudo_p ()"
14451   "#"
14452   "&& 1"
14453   [(const_int 0)]
14454 {
14455   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14456   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14457                                         operands[2]));
14458   DONE;
14459 }
14460   [(set_attr "type" "fpspc")
14461    (set_attr "mode" "<MODE>")])
14462
14463 (define_insn "fist<mode>2"
14464   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14465         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14466                       UNSPEC_FIST))]
14467   "TARGET_USE_FANCY_MATH_387"
14468   "* return output_fix_trunc (insn, operands, false);"
14469   [(set_attr "type" "fpspc")
14470    (set_attr "mode" "<MODE>")])
14471
14472 (define_insn "fist<mode>2_with_temp"
14473   [(set (match_operand:SWI24 0 "register_operand" "=r")
14474         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14475                       UNSPEC_FIST))
14476    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14477   "TARGET_USE_FANCY_MATH_387"
14478   "#"
14479   [(set_attr "type" "fpspc")
14480    (set_attr "mode" "<MODE>")])
14481
14482 (define_split
14483   [(set (match_operand:SWI24 0 "register_operand" "")
14484         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14485                       UNSPEC_FIST))
14486    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14487   "reload_completed"
14488   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14489    (set (match_dup 0) (match_dup 2))])
14490
14491 (define_split
14492   [(set (match_operand:SWI24 0 "memory_operand" "")
14493         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14494                       UNSPEC_FIST))
14495    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14496   "reload_completed"
14497   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14498
14499 (define_expand "lrintxf<mode>2"
14500   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14501      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14502                      UNSPEC_FIST))]
14503   "TARGET_USE_FANCY_MATH_387")
14504
14505 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14506   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14507      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14508                         UNSPEC_FIX_NOTRUNC))]
14509   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14510    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14511
14512 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14513   [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14514    (match_operand:MODEF 1 "register_operand" "")]
14515   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14516    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14517    && !flag_trapping_math && !flag_rounding_math"
14518 {
14519   if (optimize_insn_for_size_p ())
14520     FAIL;
14521   ix86_expand_lround (operand0, operand1);
14522   DONE;
14523 })
14524
14525 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14526 (define_insn_and_split "frndintxf2_floor"
14527   [(set (match_operand:XF 0 "register_operand" "")
14528         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14529          UNSPEC_FRNDINT_FLOOR))
14530    (clobber (reg:CC FLAGS_REG))]
14531   "TARGET_USE_FANCY_MATH_387
14532    && flag_unsafe_math_optimizations
14533    && can_create_pseudo_p ()"
14534   "#"
14535   "&& 1"
14536   [(const_int 0)]
14537 {
14538   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14539
14540   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14541   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14542
14543   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14544                                         operands[2], operands[3]));
14545   DONE;
14546 }
14547   [(set_attr "type" "frndint")
14548    (set_attr "i387_cw" "floor")
14549    (set_attr "mode" "XF")])
14550
14551 (define_insn "frndintxf2_floor_i387"
14552   [(set (match_operand:XF 0 "register_operand" "=f")
14553         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14554          UNSPEC_FRNDINT_FLOOR))
14555    (use (match_operand:HI 2 "memory_operand" "m"))
14556    (use (match_operand:HI 3 "memory_operand" "m"))]
14557   "TARGET_USE_FANCY_MATH_387
14558    && flag_unsafe_math_optimizations"
14559   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14560   [(set_attr "type" "frndint")
14561    (set_attr "i387_cw" "floor")
14562    (set_attr "mode" "XF")])
14563
14564 (define_expand "floorxf2"
14565   [(use (match_operand:XF 0 "register_operand" ""))
14566    (use (match_operand:XF 1 "register_operand" ""))]
14567   "TARGET_USE_FANCY_MATH_387
14568    && flag_unsafe_math_optimizations"
14569 {
14570   if (optimize_insn_for_size_p ())
14571     FAIL;
14572   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14573   DONE;
14574 })
14575
14576 (define_expand "floor<mode>2"
14577   [(use (match_operand:MODEF 0 "register_operand" ""))
14578    (use (match_operand:MODEF 1 "register_operand" ""))]
14579   "(TARGET_USE_FANCY_MATH_387
14580     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14581         || TARGET_MIX_SSE_I387)
14582     && flag_unsafe_math_optimizations)
14583    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14584        && !flag_trapping_math)"
14585 {
14586   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14587       && !flag_trapping_math
14588       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14589     {
14590       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14591         FAIL;
14592       if (TARGET_ROUND)
14593         emit_insn (gen_sse4_1_round<mode>2
14594                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14595       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14596         ix86_expand_floorceil (operand0, operand1, true);
14597       else
14598         ix86_expand_floorceildf_32 (operand0, operand1, true);
14599     }
14600   else
14601     {
14602       rtx op0, op1;
14603
14604       if (optimize_insn_for_size_p ())
14605         FAIL;
14606
14607       op0 = gen_reg_rtx (XFmode);
14608       op1 = gen_reg_rtx (XFmode);
14609       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14610       emit_insn (gen_frndintxf2_floor (op0, op1));
14611
14612       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14613     }
14614   DONE;
14615 })
14616
14617 (define_insn_and_split "*fist<mode>2_floor_1"
14618   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14619         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14620                         UNSPEC_FIST_FLOOR))
14621    (clobber (reg:CC FLAGS_REG))]
14622   "TARGET_USE_FANCY_MATH_387
14623    && flag_unsafe_math_optimizations
14624    && can_create_pseudo_p ()"
14625   "#"
14626   "&& 1"
14627   [(const_int 0)]
14628 {
14629   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14630
14631   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14632   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14633   if (memory_operand (operands[0], VOIDmode))
14634     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14635                                       operands[2], operands[3]));
14636   else
14637     {
14638       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14639       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14640                                                   operands[2], operands[3],
14641                                                   operands[4]));
14642     }
14643   DONE;
14644 }
14645   [(set_attr "type" "fistp")
14646    (set_attr "i387_cw" "floor")
14647    (set_attr "mode" "<MODE>")])
14648
14649 (define_insn "fistdi2_floor"
14650   [(set (match_operand:DI 0 "memory_operand" "=m")
14651         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14652                    UNSPEC_FIST_FLOOR))
14653    (use (match_operand:HI 2 "memory_operand" "m"))
14654    (use (match_operand:HI 3 "memory_operand" "m"))
14655    (clobber (match_scratch:XF 4 "=&1f"))]
14656   "TARGET_USE_FANCY_MATH_387
14657    && flag_unsafe_math_optimizations"
14658   "* return output_fix_trunc (insn, operands, false);"
14659   [(set_attr "type" "fistp")
14660    (set_attr "i387_cw" "floor")
14661    (set_attr "mode" "DI")])
14662
14663 (define_insn "fistdi2_floor_with_temp"
14664   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14665         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14666                    UNSPEC_FIST_FLOOR))
14667    (use (match_operand:HI 2 "memory_operand" "m,m"))
14668    (use (match_operand:HI 3 "memory_operand" "m,m"))
14669    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14670    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14671   "TARGET_USE_FANCY_MATH_387
14672    && flag_unsafe_math_optimizations"
14673   "#"
14674   [(set_attr "type" "fistp")
14675    (set_attr "i387_cw" "floor")
14676    (set_attr "mode" "DI")])
14677
14678 (define_split
14679   [(set (match_operand:DI 0 "register_operand" "")
14680         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14681                    UNSPEC_FIST_FLOOR))
14682    (use (match_operand:HI 2 "memory_operand" ""))
14683    (use (match_operand:HI 3 "memory_operand" ""))
14684    (clobber (match_operand:DI 4 "memory_operand" ""))
14685    (clobber (match_scratch 5 ""))]
14686   "reload_completed"
14687   [(parallel [(set (match_dup 4)
14688                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14689               (use (match_dup 2))
14690               (use (match_dup 3))
14691               (clobber (match_dup 5))])
14692    (set (match_dup 0) (match_dup 4))])
14693
14694 (define_split
14695   [(set (match_operand:DI 0 "memory_operand" "")
14696         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14697                    UNSPEC_FIST_FLOOR))
14698    (use (match_operand:HI 2 "memory_operand" ""))
14699    (use (match_operand:HI 3 "memory_operand" ""))
14700    (clobber (match_operand:DI 4 "memory_operand" ""))
14701    (clobber (match_scratch 5 ""))]
14702   "reload_completed"
14703   [(parallel [(set (match_dup 0)
14704                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14705               (use (match_dup 2))
14706               (use (match_dup 3))
14707               (clobber (match_dup 5))])])
14708
14709 (define_insn "fist<mode>2_floor"
14710   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14711         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14712                       UNSPEC_FIST_FLOOR))
14713    (use (match_operand:HI 2 "memory_operand" "m"))
14714    (use (match_operand:HI 3 "memory_operand" "m"))]
14715   "TARGET_USE_FANCY_MATH_387
14716    && flag_unsafe_math_optimizations"
14717   "* return output_fix_trunc (insn, operands, false);"
14718   [(set_attr "type" "fistp")
14719    (set_attr "i387_cw" "floor")
14720    (set_attr "mode" "<MODE>")])
14721
14722 (define_insn "fist<mode>2_floor_with_temp"
14723   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14724         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14725                       UNSPEC_FIST_FLOOR))
14726    (use (match_operand:HI 2 "memory_operand" "m,m"))
14727    (use (match_operand:HI 3 "memory_operand" "m,m"))
14728    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14729   "TARGET_USE_FANCY_MATH_387
14730    && flag_unsafe_math_optimizations"
14731   "#"
14732   [(set_attr "type" "fistp")
14733    (set_attr "i387_cw" "floor")
14734    (set_attr "mode" "<MODE>")])
14735
14736 (define_split
14737   [(set (match_operand:SWI24 0 "register_operand" "")
14738         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14739                       UNSPEC_FIST_FLOOR))
14740    (use (match_operand:HI 2 "memory_operand" ""))
14741    (use (match_operand:HI 3 "memory_operand" ""))
14742    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14743   "reload_completed"
14744   [(parallel [(set (match_dup 4)
14745                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14746               (use (match_dup 2))
14747               (use (match_dup 3))])
14748    (set (match_dup 0) (match_dup 4))])
14749
14750 (define_split
14751   [(set (match_operand:SWI24 0 "memory_operand" "")
14752         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14753                       UNSPEC_FIST_FLOOR))
14754    (use (match_operand:HI 2 "memory_operand" ""))
14755    (use (match_operand:HI 3 "memory_operand" ""))
14756    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14757   "reload_completed"
14758   [(parallel [(set (match_dup 0)
14759                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14760               (use (match_dup 2))
14761               (use (match_dup 3))])])
14762
14763 (define_expand "lfloorxf<mode>2"
14764   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14765                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14766                                    UNSPEC_FIST_FLOOR))
14767               (clobber (reg:CC FLAGS_REG))])]
14768   "TARGET_USE_FANCY_MATH_387
14769    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14770    && flag_unsafe_math_optimizations")
14771
14772 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14773   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14774    (match_operand:MODEF 1 "register_operand" "")]
14775   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14776    && !flag_trapping_math"
14777 {
14778   if (TARGET_64BIT && optimize_insn_for_size_p ())
14779     FAIL;
14780   ix86_expand_lfloorceil (operand0, operand1, true);
14781   DONE;
14782 })
14783
14784 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14785 (define_insn_and_split "frndintxf2_ceil"
14786   [(set (match_operand:XF 0 "register_operand" "")
14787         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14788          UNSPEC_FRNDINT_CEIL))
14789    (clobber (reg:CC FLAGS_REG))]
14790   "TARGET_USE_FANCY_MATH_387
14791    && flag_unsafe_math_optimizations
14792    && can_create_pseudo_p ()"
14793   "#"
14794   "&& 1"
14795   [(const_int 0)]
14796 {
14797   ix86_optimize_mode_switching[I387_CEIL] = 1;
14798
14799   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14800   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14801
14802   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14803                                        operands[2], operands[3]));
14804   DONE;
14805 }
14806   [(set_attr "type" "frndint")
14807    (set_attr "i387_cw" "ceil")
14808    (set_attr "mode" "XF")])
14809
14810 (define_insn "frndintxf2_ceil_i387"
14811   [(set (match_operand:XF 0 "register_operand" "=f")
14812         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14813          UNSPEC_FRNDINT_CEIL))
14814    (use (match_operand:HI 2 "memory_operand" "m"))
14815    (use (match_operand:HI 3 "memory_operand" "m"))]
14816   "TARGET_USE_FANCY_MATH_387
14817    && flag_unsafe_math_optimizations"
14818   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14819   [(set_attr "type" "frndint")
14820    (set_attr "i387_cw" "ceil")
14821    (set_attr "mode" "XF")])
14822
14823 (define_expand "ceilxf2"
14824   [(use (match_operand:XF 0 "register_operand" ""))
14825    (use (match_operand:XF 1 "register_operand" ""))]
14826   "TARGET_USE_FANCY_MATH_387
14827    && flag_unsafe_math_optimizations"
14828 {
14829   if (optimize_insn_for_size_p ())
14830     FAIL;
14831   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14832   DONE;
14833 })
14834
14835 (define_expand "ceil<mode>2"
14836   [(use (match_operand:MODEF 0 "register_operand" ""))
14837    (use (match_operand:MODEF 1 "register_operand" ""))]
14838   "(TARGET_USE_FANCY_MATH_387
14839     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14840         || TARGET_MIX_SSE_I387)
14841     && flag_unsafe_math_optimizations)
14842    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14843        && !flag_trapping_math)"
14844 {
14845   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846       && !flag_trapping_math
14847       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14848     {
14849       if (TARGET_ROUND)
14850         emit_insn (gen_sse4_1_round<mode>2
14851                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14852       else if (optimize_insn_for_size_p ())
14853         FAIL;
14854       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14855         ix86_expand_floorceil (operand0, operand1, false);
14856       else
14857         ix86_expand_floorceildf_32 (operand0, operand1, false);
14858     }
14859   else
14860     {
14861       rtx op0, op1;
14862
14863       if (optimize_insn_for_size_p ())
14864         FAIL;
14865
14866       op0 = gen_reg_rtx (XFmode);
14867       op1 = gen_reg_rtx (XFmode);
14868       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14869       emit_insn (gen_frndintxf2_ceil (op0, op1));
14870
14871       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14872     }
14873   DONE;
14874 })
14875
14876 (define_insn_and_split "*fist<mode>2_ceil_1"
14877   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14878         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14879                         UNSPEC_FIST_CEIL))
14880    (clobber (reg:CC FLAGS_REG))]
14881   "TARGET_USE_FANCY_MATH_387
14882    && flag_unsafe_math_optimizations
14883    && can_create_pseudo_p ()"
14884   "#"
14885   "&& 1"
14886   [(const_int 0)]
14887 {
14888   ix86_optimize_mode_switching[I387_CEIL] = 1;
14889
14890   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14891   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14892   if (memory_operand (operands[0], VOIDmode))
14893     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14894                                      operands[2], operands[3]));
14895   else
14896     {
14897       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14898       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14899                                                  operands[2], operands[3],
14900                                                  operands[4]));
14901     }
14902   DONE;
14903 }
14904   [(set_attr "type" "fistp")
14905    (set_attr "i387_cw" "ceil")
14906    (set_attr "mode" "<MODE>")])
14907
14908 (define_insn "fistdi2_ceil"
14909   [(set (match_operand:DI 0 "memory_operand" "=m")
14910         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14911                    UNSPEC_FIST_CEIL))
14912    (use (match_operand:HI 2 "memory_operand" "m"))
14913    (use (match_operand:HI 3 "memory_operand" "m"))
14914    (clobber (match_scratch:XF 4 "=&1f"))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && flag_unsafe_math_optimizations"
14917   "* return output_fix_trunc (insn, operands, false);"
14918   [(set_attr "type" "fistp")
14919    (set_attr "i387_cw" "ceil")
14920    (set_attr "mode" "DI")])
14921
14922 (define_insn "fistdi2_ceil_with_temp"
14923   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14924         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14925                    UNSPEC_FIST_CEIL))
14926    (use (match_operand:HI 2 "memory_operand" "m,m"))
14927    (use (match_operand:HI 3 "memory_operand" "m,m"))
14928    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14929    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14930   "TARGET_USE_FANCY_MATH_387
14931    && flag_unsafe_math_optimizations"
14932   "#"
14933   [(set_attr "type" "fistp")
14934    (set_attr "i387_cw" "ceil")
14935    (set_attr "mode" "DI")])
14936
14937 (define_split
14938   [(set (match_operand:DI 0 "register_operand" "")
14939         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14940                    UNSPEC_FIST_CEIL))
14941    (use (match_operand:HI 2 "memory_operand" ""))
14942    (use (match_operand:HI 3 "memory_operand" ""))
14943    (clobber (match_operand:DI 4 "memory_operand" ""))
14944    (clobber (match_scratch 5 ""))]
14945   "reload_completed"
14946   [(parallel [(set (match_dup 4)
14947                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14948               (use (match_dup 2))
14949               (use (match_dup 3))
14950               (clobber (match_dup 5))])
14951    (set (match_dup 0) (match_dup 4))])
14952
14953 (define_split
14954   [(set (match_operand:DI 0 "memory_operand" "")
14955         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14956                    UNSPEC_FIST_CEIL))
14957    (use (match_operand:HI 2 "memory_operand" ""))
14958    (use (match_operand:HI 3 "memory_operand" ""))
14959    (clobber (match_operand:DI 4 "memory_operand" ""))
14960    (clobber (match_scratch 5 ""))]
14961   "reload_completed"
14962   [(parallel [(set (match_dup 0)
14963                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14964               (use (match_dup 2))
14965               (use (match_dup 3))
14966               (clobber (match_dup 5))])])
14967
14968 (define_insn "fist<mode>2_ceil"
14969   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14970         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14971                       UNSPEC_FIST_CEIL))
14972    (use (match_operand:HI 2 "memory_operand" "m"))
14973    (use (match_operand:HI 3 "memory_operand" "m"))]
14974   "TARGET_USE_FANCY_MATH_387
14975    && flag_unsafe_math_optimizations"
14976   "* return output_fix_trunc (insn, operands, false);"
14977   [(set_attr "type" "fistp")
14978    (set_attr "i387_cw" "ceil")
14979    (set_attr "mode" "<MODE>")])
14980
14981 (define_insn "fist<mode>2_ceil_with_temp"
14982   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14983         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14984                       UNSPEC_FIST_CEIL))
14985    (use (match_operand:HI 2 "memory_operand" "m,m"))
14986    (use (match_operand:HI 3 "memory_operand" "m,m"))
14987    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14988   "TARGET_USE_FANCY_MATH_387
14989    && flag_unsafe_math_optimizations"
14990   "#"
14991   [(set_attr "type" "fistp")
14992    (set_attr "i387_cw" "ceil")
14993    (set_attr "mode" "<MODE>")])
14994
14995 (define_split
14996   [(set (match_operand:SWI24 0 "register_operand" "")
14997         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14998                       UNSPEC_FIST_CEIL))
14999    (use (match_operand:HI 2 "memory_operand" ""))
15000    (use (match_operand:HI 3 "memory_operand" ""))
15001    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15002   "reload_completed"
15003   [(parallel [(set (match_dup 4)
15004                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15005               (use (match_dup 2))
15006               (use (match_dup 3))])
15007    (set (match_dup 0) (match_dup 4))])
15008
15009 (define_split
15010   [(set (match_operand:SWI24 0 "memory_operand" "")
15011         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15012                       UNSPEC_FIST_CEIL))
15013    (use (match_operand:HI 2 "memory_operand" ""))
15014    (use (match_operand:HI 3 "memory_operand" ""))
15015    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15016   "reload_completed"
15017   [(parallel [(set (match_dup 0)
15018                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15019               (use (match_dup 2))
15020               (use (match_dup 3))])])
15021
15022 (define_expand "lceilxf<mode>2"
15023   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15024                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15025                                    UNSPEC_FIST_CEIL))
15026               (clobber (reg:CC FLAGS_REG))])]
15027   "TARGET_USE_FANCY_MATH_387
15028    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15029    && flag_unsafe_math_optimizations")
15030
15031 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15032   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15033    (match_operand:MODEF 1 "register_operand" "")]
15034   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15035    && !flag_trapping_math"
15036 {
15037   ix86_expand_lfloorceil (operand0, operand1, false);
15038   DONE;
15039 })
15040
15041 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15042 (define_insn_and_split "frndintxf2_trunc"
15043   [(set (match_operand:XF 0 "register_operand" "")
15044         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15045          UNSPEC_FRNDINT_TRUNC))
15046    (clobber (reg:CC FLAGS_REG))]
15047   "TARGET_USE_FANCY_MATH_387
15048    && flag_unsafe_math_optimizations
15049    && can_create_pseudo_p ()"
15050   "#"
15051   "&& 1"
15052   [(const_int 0)]
15053 {
15054   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15055
15056   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15057   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15058
15059   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15060                                         operands[2], operands[3]));
15061   DONE;
15062 }
15063   [(set_attr "type" "frndint")
15064    (set_attr "i387_cw" "trunc")
15065    (set_attr "mode" "XF")])
15066
15067 (define_insn "frndintxf2_trunc_i387"
15068   [(set (match_operand:XF 0 "register_operand" "=f")
15069         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15070          UNSPEC_FRNDINT_TRUNC))
15071    (use (match_operand:HI 2 "memory_operand" "m"))
15072    (use (match_operand:HI 3 "memory_operand" "m"))]
15073   "TARGET_USE_FANCY_MATH_387
15074    && flag_unsafe_math_optimizations"
15075   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15076   [(set_attr "type" "frndint")
15077    (set_attr "i387_cw" "trunc")
15078    (set_attr "mode" "XF")])
15079
15080 (define_expand "btruncxf2"
15081   [(use (match_operand:XF 0 "register_operand" ""))
15082    (use (match_operand:XF 1 "register_operand" ""))]
15083   "TARGET_USE_FANCY_MATH_387
15084    && flag_unsafe_math_optimizations"
15085 {
15086   if (optimize_insn_for_size_p ())
15087     FAIL;
15088   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15089   DONE;
15090 })
15091
15092 (define_expand "btrunc<mode>2"
15093   [(use (match_operand:MODEF 0 "register_operand" ""))
15094    (use (match_operand:MODEF 1 "register_operand" ""))]
15095   "(TARGET_USE_FANCY_MATH_387
15096     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15097         || TARGET_MIX_SSE_I387)
15098     && flag_unsafe_math_optimizations)
15099    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15100        && !flag_trapping_math)"
15101 {
15102   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15103       && !flag_trapping_math
15104       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15105     {
15106       if (TARGET_ROUND)
15107         emit_insn (gen_sse4_1_round<mode>2
15108                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15109       else if (optimize_insn_for_size_p ())
15110         FAIL;
15111       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15112         ix86_expand_trunc (operand0, operand1);
15113       else
15114         ix86_expand_truncdf_32 (operand0, operand1);
15115     }
15116   else
15117     {
15118       rtx op0, op1;
15119
15120       if (optimize_insn_for_size_p ())
15121         FAIL;
15122
15123       op0 = gen_reg_rtx (XFmode);
15124       op1 = gen_reg_rtx (XFmode);
15125       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15126       emit_insn (gen_frndintxf2_trunc (op0, op1));
15127
15128       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15129     }
15130   DONE;
15131 })
15132
15133 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15134 (define_insn_and_split "frndintxf2_mask_pm"
15135   [(set (match_operand:XF 0 "register_operand" "")
15136         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15137          UNSPEC_FRNDINT_MASK_PM))
15138    (clobber (reg:CC FLAGS_REG))]
15139   "TARGET_USE_FANCY_MATH_387
15140    && flag_unsafe_math_optimizations
15141    && can_create_pseudo_p ()"
15142   "#"
15143   "&& 1"
15144   [(const_int 0)]
15145 {
15146   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15147
15148   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15149   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15150
15151   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15152                                           operands[2], operands[3]));
15153   DONE;
15154 }
15155   [(set_attr "type" "frndint")
15156    (set_attr "i387_cw" "mask_pm")
15157    (set_attr "mode" "XF")])
15158
15159 (define_insn "frndintxf2_mask_pm_i387"
15160   [(set (match_operand:XF 0 "register_operand" "=f")
15161         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15162          UNSPEC_FRNDINT_MASK_PM))
15163    (use (match_operand:HI 2 "memory_operand" "m"))
15164    (use (match_operand:HI 3 "memory_operand" "m"))]
15165   "TARGET_USE_FANCY_MATH_387
15166    && flag_unsafe_math_optimizations"
15167   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15168   [(set_attr "type" "frndint")
15169    (set_attr "i387_cw" "mask_pm")
15170    (set_attr "mode" "XF")])
15171
15172 (define_expand "nearbyintxf2"
15173   [(use (match_operand:XF 0 "register_operand" ""))
15174    (use (match_operand:XF 1 "register_operand" ""))]
15175   "TARGET_USE_FANCY_MATH_387
15176    && flag_unsafe_math_optimizations"
15177 {
15178   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15179   DONE;
15180 })
15181
15182 (define_expand "nearbyint<mode>2"
15183   [(use (match_operand:MODEF 0 "register_operand" ""))
15184    (use (match_operand:MODEF 1 "register_operand" ""))]
15185   "TARGET_USE_FANCY_MATH_387
15186    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15187        || TARGET_MIX_SSE_I387)
15188    && flag_unsafe_math_optimizations"
15189 {
15190   rtx op0 = gen_reg_rtx (XFmode);
15191   rtx op1 = gen_reg_rtx (XFmode);
15192
15193   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15194   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15195
15196   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15197   DONE;
15198 })
15199
15200 (define_insn "fxam<mode>2_i387"
15201   [(set (match_operand:HI 0 "register_operand" "=a")
15202         (unspec:HI
15203           [(match_operand:X87MODEF 1 "register_operand" "f")]
15204           UNSPEC_FXAM))]
15205   "TARGET_USE_FANCY_MATH_387"
15206   "fxam\n\tfnstsw\t%0"
15207   [(set_attr "type" "multi")
15208    (set_attr "length" "4")
15209    (set_attr "unit" "i387")
15210    (set_attr "mode" "<MODE>")])
15211
15212 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15213   [(set (match_operand:HI 0 "register_operand" "")
15214         (unspec:HI
15215           [(match_operand:MODEF 1 "memory_operand" "")]
15216           UNSPEC_FXAM_MEM))]
15217   "TARGET_USE_FANCY_MATH_387
15218    && can_create_pseudo_p ()"
15219   "#"
15220   "&& 1"
15221   [(set (match_dup 2)(match_dup 1))
15222    (set (match_dup 0)
15223         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15224 {
15225   operands[2] = gen_reg_rtx (<MODE>mode);
15226
15227   MEM_VOLATILE_P (operands[1]) = 1;
15228 }
15229   [(set_attr "type" "multi")
15230    (set_attr "unit" "i387")
15231    (set_attr "mode" "<MODE>")])
15232
15233 (define_expand "isinfxf2"
15234   [(use (match_operand:SI 0 "register_operand" ""))
15235    (use (match_operand:XF 1 "register_operand" ""))]
15236   "TARGET_USE_FANCY_MATH_387
15237    && TARGET_C99_FUNCTIONS"
15238 {
15239   rtx mask = GEN_INT (0x45);
15240   rtx val = GEN_INT (0x05);
15241
15242   rtx cond;
15243
15244   rtx scratch = gen_reg_rtx (HImode);
15245   rtx res = gen_reg_rtx (QImode);
15246
15247   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15248
15249   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15250   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15251   cond = gen_rtx_fmt_ee (EQ, QImode,
15252                          gen_rtx_REG (CCmode, FLAGS_REG),
15253                          const0_rtx);
15254   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15255   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15256   DONE;
15257 })
15258
15259 (define_expand "isinf<mode>2"
15260   [(use (match_operand:SI 0 "register_operand" ""))
15261    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15262   "TARGET_USE_FANCY_MATH_387
15263    && TARGET_C99_FUNCTIONS
15264    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15265 {
15266   rtx mask = GEN_INT (0x45);
15267   rtx val = GEN_INT (0x05);
15268
15269   rtx cond;
15270
15271   rtx scratch = gen_reg_rtx (HImode);
15272   rtx res = gen_reg_rtx (QImode);
15273
15274   /* Remove excess precision by forcing value through memory. */
15275   if (memory_operand (operands[1], VOIDmode))
15276     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15277   else
15278     {
15279       enum ix86_stack_slot slot = (virtuals_instantiated
15280                                    ? SLOT_TEMP
15281                                    : SLOT_VIRTUAL);
15282       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15283
15284       emit_move_insn (temp, operands[1]);
15285       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15286     }
15287
15288   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15289   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15290   cond = gen_rtx_fmt_ee (EQ, QImode,
15291                          gen_rtx_REG (CCmode, FLAGS_REG),
15292                          const0_rtx);
15293   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15294   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15295   DONE;
15296 })
15297
15298 (define_expand "signbitxf2"
15299   [(use (match_operand:SI 0 "register_operand" ""))
15300    (use (match_operand:XF 1 "register_operand" ""))]
15301   "TARGET_USE_FANCY_MATH_387"
15302 {
15303   rtx scratch = gen_reg_rtx (HImode);
15304
15305   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15306   emit_insn (gen_andsi3 (operands[0],
15307              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15308   DONE;
15309 })
15310
15311 (define_insn "movmsk_df"
15312   [(set (match_operand:SI 0 "register_operand" "=r")
15313         (unspec:SI
15314           [(match_operand:DF 1 "register_operand" "x")]
15315           UNSPEC_MOVMSK))]
15316   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15317   "%vmovmskpd\t{%1, %0|%0, %1}"
15318   [(set_attr "type" "ssemov")
15319    (set_attr "prefix" "maybe_vex")
15320    (set_attr "mode" "DF")])
15321
15322 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15323 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15324 (define_expand "signbitdf2"
15325   [(use (match_operand:SI 0 "register_operand" ""))
15326    (use (match_operand:DF 1 "register_operand" ""))]
15327   "TARGET_USE_FANCY_MATH_387
15328    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15329 {
15330   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15331     {
15332       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15333       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15334     }
15335   else
15336     {
15337       rtx scratch = gen_reg_rtx (HImode);
15338
15339       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15340       emit_insn (gen_andsi3 (operands[0],
15341                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15342     }
15343   DONE;
15344 })
15345
15346 (define_expand "signbitsf2"
15347   [(use (match_operand:SI 0 "register_operand" ""))
15348    (use (match_operand:SF 1 "register_operand" ""))]
15349   "TARGET_USE_FANCY_MATH_387
15350    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15351 {
15352   rtx scratch = gen_reg_rtx (HImode);
15353
15354   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15355   emit_insn (gen_andsi3 (operands[0],
15356              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15357   DONE;
15358 })
15359 \f
15360 ;; Block operation instructions
15361
15362 (define_insn "cld"
15363   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15364   ""
15365   "cld"
15366   [(set_attr "length" "1")
15367    (set_attr "length_immediate" "0")
15368    (set_attr "modrm" "0")])
15369
15370 (define_expand "movmem<mode>"
15371   [(use (match_operand:BLK 0 "memory_operand" ""))
15372    (use (match_operand:BLK 1 "memory_operand" ""))
15373    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15374    (use (match_operand:SWI48 3 "const_int_operand" ""))
15375    (use (match_operand:SI 4 "const_int_operand" ""))
15376    (use (match_operand:SI 5 "const_int_operand" ""))]
15377   ""
15378 {
15379  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15380                          operands[4], operands[5]))
15381    DONE;
15382  else
15383    FAIL;
15384 })
15385
15386 ;; Most CPUs don't like single string operations
15387 ;; Handle this case here to simplify previous expander.
15388
15389 (define_expand "strmov"
15390   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15391    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15392    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15393               (clobber (reg:CC FLAGS_REG))])
15394    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15395               (clobber (reg:CC FLAGS_REG))])]
15396   ""
15397 {
15398   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15399
15400   /* If .md ever supports :P for Pmode, these can be directly
15401      in the pattern above.  */
15402   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15403   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15404
15405   /* Can't use this if the user has appropriated esi or edi.  */
15406   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15407       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15408     {
15409       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15410                                       operands[2], operands[3],
15411                                       operands[5], operands[6]));
15412       DONE;
15413     }
15414
15415   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15416 })
15417
15418 (define_expand "strmov_singleop"
15419   [(parallel [(set (match_operand 1 "memory_operand" "")
15420                    (match_operand 3 "memory_operand" ""))
15421               (set (match_operand 0 "register_operand" "")
15422                    (match_operand 4 "" ""))
15423               (set (match_operand 2 "register_operand" "")
15424                    (match_operand 5 "" ""))])]
15425   ""
15426   "ix86_current_function_needs_cld = 1;")
15427
15428 (define_insn "*strmovdi_rex_1"
15429   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15430         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15431    (set (match_operand:DI 0 "register_operand" "=D")
15432         (plus:DI (match_dup 2)
15433                  (const_int 8)))
15434    (set (match_operand:DI 1 "register_operand" "=S")
15435         (plus:DI (match_dup 3)
15436                  (const_int 8)))]
15437   "TARGET_64BIT
15438    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15439   "movsq"
15440   [(set_attr "type" "str")
15441    (set_attr "memory" "both")
15442    (set_attr "mode" "DI")])
15443
15444 (define_insn "*strmovsi_1"
15445   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15446         (mem:SI (match_operand:P 3 "register_operand" "1")))
15447    (set (match_operand:P 0 "register_operand" "=D")
15448         (plus:P (match_dup 2)
15449                 (const_int 4)))
15450    (set (match_operand:P 1 "register_operand" "=S")
15451         (plus:P (match_dup 3)
15452                 (const_int 4)))]
15453   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15454   "movs{l|d}"
15455   [(set_attr "type" "str")
15456    (set_attr "memory" "both")
15457    (set_attr "mode" "SI")])
15458
15459 (define_insn "*strmovhi_1"
15460   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15461         (mem:HI (match_operand:P 3 "register_operand" "1")))
15462    (set (match_operand:P 0 "register_operand" "=D")
15463         (plus:P (match_dup 2)
15464                 (const_int 2)))
15465    (set (match_operand:P 1 "register_operand" "=S")
15466         (plus:P (match_dup 3)
15467                 (const_int 2)))]
15468   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15469   "movsw"
15470   [(set_attr "type" "str")
15471    (set_attr "memory" "both")
15472    (set_attr "mode" "HI")])
15473
15474 (define_insn "*strmovqi_1"
15475   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15476         (mem:QI (match_operand:P 3 "register_operand" "1")))
15477    (set (match_operand:P 0 "register_operand" "=D")
15478         (plus:P (match_dup 2)
15479                 (const_int 1)))
15480    (set (match_operand:P 1 "register_operand" "=S")
15481         (plus:P (match_dup 3)
15482                 (const_int 1)))]
15483   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15484   "movsb"
15485   [(set_attr "type" "str")
15486    (set_attr "memory" "both")
15487    (set (attr "prefix_rex")
15488         (if_then_else
15489           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15490           (const_string "0")
15491           (const_string "*")))
15492    (set_attr "mode" "QI")])
15493
15494 (define_expand "rep_mov"
15495   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15496               (set (match_operand 0 "register_operand" "")
15497                    (match_operand 5 "" ""))
15498               (set (match_operand 2 "register_operand" "")
15499                    (match_operand 6 "" ""))
15500               (set (match_operand 1 "memory_operand" "")
15501                    (match_operand 3 "memory_operand" ""))
15502               (use (match_dup 4))])]
15503   ""
15504   "ix86_current_function_needs_cld = 1;")
15505
15506 (define_insn "*rep_movdi_rex64"
15507   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15508    (set (match_operand:DI 0 "register_operand" "=D")
15509         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15510                             (const_int 3))
15511                  (match_operand:DI 3 "register_operand" "0")))
15512    (set (match_operand:DI 1 "register_operand" "=S")
15513         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15514                  (match_operand:DI 4 "register_operand" "1")))
15515    (set (mem:BLK (match_dup 3))
15516         (mem:BLK (match_dup 4)))
15517    (use (match_dup 5))]
15518   "TARGET_64BIT
15519    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15520   "rep{%;} movsq"
15521   [(set_attr "type" "str")
15522    (set_attr "prefix_rep" "1")
15523    (set_attr "memory" "both")
15524    (set_attr "mode" "DI")])
15525
15526 (define_insn "*rep_movsi"
15527   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15528    (set (match_operand:P 0 "register_operand" "=D")
15529         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15530                           (const_int 2))
15531                  (match_operand:P 3 "register_operand" "0")))
15532    (set (match_operand:P 1 "register_operand" "=S")
15533         (plus:P (ashift:P (match_dup 5) (const_int 2))
15534                 (match_operand:P 4 "register_operand" "1")))
15535    (set (mem:BLK (match_dup 3))
15536         (mem:BLK (match_dup 4)))
15537    (use (match_dup 5))]
15538   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15539   "rep{%;} movs{l|d}"
15540   [(set_attr "type" "str")
15541    (set_attr "prefix_rep" "1")
15542    (set_attr "memory" "both")
15543    (set_attr "mode" "SI")])
15544
15545 (define_insn "*rep_movqi"
15546   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15547    (set (match_operand:P 0 "register_operand" "=D")
15548         (plus:P (match_operand:P 3 "register_operand" "0")
15549                 (match_operand:P 5 "register_operand" "2")))
15550    (set (match_operand:P 1 "register_operand" "=S")
15551         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15552    (set (mem:BLK (match_dup 3))
15553         (mem:BLK (match_dup 4)))
15554    (use (match_dup 5))]
15555   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15556   "rep{%;} movsb"
15557   [(set_attr "type" "str")
15558    (set_attr "prefix_rep" "1")
15559    (set_attr "memory" "both")
15560    (set_attr "mode" "QI")])
15561
15562 (define_expand "setmem<mode>"
15563    [(use (match_operand:BLK 0 "memory_operand" ""))
15564     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15565     (use (match_operand:QI 2 "nonmemory_operand" ""))
15566     (use (match_operand 3 "const_int_operand" ""))
15567     (use (match_operand:SI 4 "const_int_operand" ""))
15568     (use (match_operand:SI 5 "const_int_operand" ""))]
15569   ""
15570 {
15571  if (ix86_expand_setmem (operands[0], operands[1],
15572                          operands[2], operands[3],
15573                          operands[4], operands[5]))
15574    DONE;
15575  else
15576    FAIL;
15577 })
15578
15579 ;; Most CPUs don't like single string operations
15580 ;; Handle this case here to simplify previous expander.
15581
15582 (define_expand "strset"
15583   [(set (match_operand 1 "memory_operand" "")
15584         (match_operand 2 "register_operand" ""))
15585    (parallel [(set (match_operand 0 "register_operand" "")
15586                    (match_dup 3))
15587               (clobber (reg:CC FLAGS_REG))])]
15588   ""
15589 {
15590   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15591     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15592
15593   /* If .md ever supports :P for Pmode, this can be directly
15594      in the pattern above.  */
15595   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15596                               GEN_INT (GET_MODE_SIZE (GET_MODE
15597                                                       (operands[2]))));
15598   /* Can't use this if the user has appropriated eax or edi.  */
15599   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15600       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15601     {
15602       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15603                                       operands[3]));
15604       DONE;
15605     }
15606 })
15607
15608 (define_expand "strset_singleop"
15609   [(parallel [(set (match_operand 1 "memory_operand" "")
15610                    (match_operand 2 "register_operand" ""))
15611               (set (match_operand 0 "register_operand" "")
15612                    (match_operand 3 "" ""))])]
15613   ""
15614   "ix86_current_function_needs_cld = 1;")
15615
15616 (define_insn "*strsetdi_rex_1"
15617   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15618         (match_operand:DI 2 "register_operand" "a"))
15619    (set (match_operand:DI 0 "register_operand" "=D")
15620         (plus:DI (match_dup 1)
15621                  (const_int 8)))]
15622   "TARGET_64BIT
15623    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15624   "stosq"
15625   [(set_attr "type" "str")
15626    (set_attr "memory" "store")
15627    (set_attr "mode" "DI")])
15628
15629 (define_insn "*strsetsi_1"
15630   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15631         (match_operand:SI 2 "register_operand" "a"))
15632    (set (match_operand:P 0 "register_operand" "=D")
15633         (plus:P (match_dup 1)
15634                 (const_int 4)))]
15635   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15636   "stos{l|d}"
15637   [(set_attr "type" "str")
15638    (set_attr "memory" "store")
15639    (set_attr "mode" "SI")])
15640
15641 (define_insn "*strsethi_1"
15642   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15643         (match_operand:HI 2 "register_operand" "a"))
15644    (set (match_operand:P 0 "register_operand" "=D")
15645         (plus:P (match_dup 1)
15646                 (const_int 2)))]
15647   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15648   "stosw"
15649   [(set_attr "type" "str")
15650    (set_attr "memory" "store")
15651    (set_attr "mode" "HI")])
15652
15653 (define_insn "*strsetqi_1"
15654   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15655         (match_operand:QI 2 "register_operand" "a"))
15656    (set (match_operand:P 0 "register_operand" "=D")
15657         (plus:P (match_dup 1)
15658                 (const_int 1)))]
15659   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15660   "stosb"
15661   [(set_attr "type" "str")
15662    (set_attr "memory" "store")
15663    (set (attr "prefix_rex")
15664         (if_then_else
15665           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15666           (const_string "0")
15667           (const_string "*")))
15668    (set_attr "mode" "QI")])
15669
15670 (define_expand "rep_stos"
15671   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15672               (set (match_operand 0 "register_operand" "")
15673                    (match_operand 4 "" ""))
15674               (set (match_operand 2 "memory_operand" "") (const_int 0))
15675               (use (match_operand 3 "register_operand" ""))
15676               (use (match_dup 1))])]
15677   ""
15678   "ix86_current_function_needs_cld = 1;")
15679
15680 (define_insn "*rep_stosdi_rex64"
15681   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15682    (set (match_operand:DI 0 "register_operand" "=D")
15683         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15684                             (const_int 3))
15685                  (match_operand:DI 3 "register_operand" "0")))
15686    (set (mem:BLK (match_dup 3))
15687         (const_int 0))
15688    (use (match_operand:DI 2 "register_operand" "a"))
15689    (use (match_dup 4))]
15690   "TARGET_64BIT
15691    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15692   "rep{%;} stosq"
15693   [(set_attr "type" "str")
15694    (set_attr "prefix_rep" "1")
15695    (set_attr "memory" "store")
15696    (set_attr "mode" "DI")])
15697
15698 (define_insn "*rep_stossi"
15699   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15700    (set (match_operand:P 0 "register_operand" "=D")
15701         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15702                           (const_int 2))
15703                  (match_operand:P 3 "register_operand" "0")))
15704    (set (mem:BLK (match_dup 3))
15705         (const_int 0))
15706    (use (match_operand:SI 2 "register_operand" "a"))
15707    (use (match_dup 4))]
15708   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15709   "rep{%;} stos{l|d}"
15710   [(set_attr "type" "str")
15711    (set_attr "prefix_rep" "1")
15712    (set_attr "memory" "store")
15713    (set_attr "mode" "SI")])
15714
15715 (define_insn "*rep_stosqi"
15716   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15717    (set (match_operand:P 0 "register_operand" "=D")
15718         (plus:P (match_operand:P 3 "register_operand" "0")
15719                 (match_operand:P 4 "register_operand" "1")))
15720    (set (mem:BLK (match_dup 3))
15721         (const_int 0))
15722    (use (match_operand:QI 2 "register_operand" "a"))
15723    (use (match_dup 4))]
15724   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15725   "rep{%;} stosb"
15726   [(set_attr "type" "str")
15727    (set_attr "prefix_rep" "1")
15728    (set_attr "memory" "store")
15729    (set (attr "prefix_rex")
15730         (if_then_else
15731           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15732           (const_string "0")
15733           (const_string "*")))
15734    (set_attr "mode" "QI")])
15735
15736 (define_expand "cmpstrnsi"
15737   [(set (match_operand:SI 0 "register_operand" "")
15738         (compare:SI (match_operand:BLK 1 "general_operand" "")
15739                     (match_operand:BLK 2 "general_operand" "")))
15740    (use (match_operand 3 "general_operand" ""))
15741    (use (match_operand 4 "immediate_operand" ""))]
15742   ""
15743 {
15744   rtx addr1, addr2, out, outlow, count, countreg, align;
15745
15746   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15747     FAIL;
15748
15749   /* Can't use this if the user has appropriated ecx, esi or edi.  */
15750   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15751     FAIL;
15752
15753   out = operands[0];
15754   if (!REG_P (out))
15755     out = gen_reg_rtx (SImode);
15756
15757   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15758   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15759   if (addr1 != XEXP (operands[1], 0))
15760     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15761   if (addr2 != XEXP (operands[2], 0))
15762     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15763
15764   count = operands[3];
15765   countreg = ix86_zero_extend_to_Pmode (count);
15766
15767   /* %%% Iff we are testing strict equality, we can use known alignment
15768      to good advantage.  This may be possible with combine, particularly
15769      once cc0 is dead.  */
15770   align = operands[4];
15771
15772   if (CONST_INT_P (count))
15773     {
15774       if (INTVAL (count) == 0)
15775         {
15776           emit_move_insn (operands[0], const0_rtx);
15777           DONE;
15778         }
15779       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15780                                      operands[1], operands[2]));
15781     }
15782   else
15783     {
15784       rtx (*gen_cmp) (rtx, rtx);
15785
15786       gen_cmp = (TARGET_64BIT
15787                  ? gen_cmpdi_1 : gen_cmpsi_1);
15788
15789       emit_insn (gen_cmp (countreg, countreg));
15790       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15791                                   operands[1], operands[2]));
15792     }
15793
15794   outlow = gen_lowpart (QImode, out);
15795   emit_insn (gen_cmpintqi (outlow));
15796   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15797
15798   if (operands[0] != out)
15799     emit_move_insn (operands[0], out);
15800
15801   DONE;
15802 })
15803
15804 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15805
15806 (define_expand "cmpintqi"
15807   [(set (match_dup 1)
15808         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15809    (set (match_dup 2)
15810         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15811    (parallel [(set (match_operand:QI 0 "register_operand" "")
15812                    (minus:QI (match_dup 1)
15813                              (match_dup 2)))
15814               (clobber (reg:CC FLAGS_REG))])]
15815   ""
15816 {
15817   operands[1] = gen_reg_rtx (QImode);
15818   operands[2] = gen_reg_rtx (QImode);
15819 })
15820
15821 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15822 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15823
15824 (define_expand "cmpstrnqi_nz_1"
15825   [(parallel [(set (reg:CC FLAGS_REG)
15826                    (compare:CC (match_operand 4 "memory_operand" "")
15827                                (match_operand 5 "memory_operand" "")))
15828               (use (match_operand 2 "register_operand" ""))
15829               (use (match_operand:SI 3 "immediate_operand" ""))
15830               (clobber (match_operand 0 "register_operand" ""))
15831               (clobber (match_operand 1 "register_operand" ""))
15832               (clobber (match_dup 2))])]
15833   ""
15834   "ix86_current_function_needs_cld = 1;")
15835
15836 (define_insn "*cmpstrnqi_nz_1"
15837   [(set (reg:CC FLAGS_REG)
15838         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15839                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15840    (use (match_operand:P 6 "register_operand" "2"))
15841    (use (match_operand:SI 3 "immediate_operand" "i"))
15842    (clobber (match_operand:P 0 "register_operand" "=S"))
15843    (clobber (match_operand:P 1 "register_operand" "=D"))
15844    (clobber (match_operand:P 2 "register_operand" "=c"))]
15845   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15846   "repz{%;} cmpsb"
15847   [(set_attr "type" "str")
15848    (set_attr "mode" "QI")
15849    (set (attr "prefix_rex")
15850         (if_then_else
15851           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15852           (const_string "0")
15853           (const_string "*")))
15854    (set_attr "prefix_rep" "1")])
15855
15856 ;; The same, but the count is not known to not be zero.
15857
15858 (define_expand "cmpstrnqi_1"
15859   [(parallel [(set (reg:CC FLAGS_REG)
15860                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15861                                      (const_int 0))
15862                   (compare:CC (match_operand 4 "memory_operand" "")
15863                               (match_operand 5 "memory_operand" ""))
15864                   (const_int 0)))
15865               (use (match_operand:SI 3 "immediate_operand" ""))
15866               (use (reg:CC FLAGS_REG))
15867               (clobber (match_operand 0 "register_operand" ""))
15868               (clobber (match_operand 1 "register_operand" ""))
15869               (clobber (match_dup 2))])]
15870   ""
15871   "ix86_current_function_needs_cld = 1;")
15872
15873 (define_insn "*cmpstrnqi_1"
15874   [(set (reg:CC FLAGS_REG)
15875         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15876                              (const_int 0))
15877           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15878                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15879           (const_int 0)))
15880    (use (match_operand:SI 3 "immediate_operand" "i"))
15881    (use (reg:CC FLAGS_REG))
15882    (clobber (match_operand:P 0 "register_operand" "=S"))
15883    (clobber (match_operand:P 1 "register_operand" "=D"))
15884    (clobber (match_operand:P 2 "register_operand" "=c"))]
15885   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15886   "repz{%;} cmpsb"
15887   [(set_attr "type" "str")
15888    (set_attr "mode" "QI")
15889    (set (attr "prefix_rex")
15890         (if_then_else
15891           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15892           (const_string "0")
15893           (const_string "*")))
15894    (set_attr "prefix_rep" "1")])
15895
15896 (define_expand "strlen<mode>"
15897   [(set (match_operand:P 0 "register_operand" "")
15898         (unspec:P [(match_operand:BLK 1 "general_operand" "")
15899                    (match_operand:QI 2 "immediate_operand" "")
15900                    (match_operand 3 "immediate_operand" "")]
15901                   UNSPEC_SCAS))]
15902   ""
15903 {
15904  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15905    DONE;
15906  else
15907    FAIL;
15908 })
15909
15910 (define_expand "strlenqi_1"
15911   [(parallel [(set (match_operand 0 "register_operand" "")
15912                    (match_operand 2 "" ""))
15913               (clobber (match_operand 1 "register_operand" ""))
15914               (clobber (reg:CC FLAGS_REG))])]
15915   ""
15916   "ix86_current_function_needs_cld = 1;")
15917
15918 (define_insn "*strlenqi_1"
15919   [(set (match_operand:P 0 "register_operand" "=&c")
15920         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15921                    (match_operand:QI 2 "register_operand" "a")
15922                    (match_operand:P 3 "immediate_operand" "i")
15923                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15924    (clobber (match_operand:P 1 "register_operand" "=D"))
15925    (clobber (reg:CC FLAGS_REG))]
15926   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15927   "repnz{%;} scasb"
15928   [(set_attr "type" "str")
15929    (set_attr "mode" "QI")
15930    (set (attr "prefix_rex")
15931         (if_then_else
15932           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15933           (const_string "0")
15934           (const_string "*")))
15935    (set_attr "prefix_rep" "1")])
15936
15937 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15938 ;; handled in combine, but it is not currently up to the task.
15939 ;; When used for their truth value, the cmpstrn* expanders generate
15940 ;; code like this:
15941 ;;
15942 ;;   repz cmpsb
15943 ;;   seta       %al
15944 ;;   setb       %dl
15945 ;;   cmpb       %al, %dl
15946 ;;   jcc        label
15947 ;;
15948 ;; The intermediate three instructions are unnecessary.
15949
15950 ;; This one handles cmpstrn*_nz_1...
15951 (define_peephole2
15952   [(parallel[
15953      (set (reg:CC FLAGS_REG)
15954           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15955                       (mem:BLK (match_operand 5 "register_operand" ""))))
15956      (use (match_operand 6 "register_operand" ""))
15957      (use (match_operand:SI 3 "immediate_operand" ""))
15958      (clobber (match_operand 0 "register_operand" ""))
15959      (clobber (match_operand 1 "register_operand" ""))
15960      (clobber (match_operand 2 "register_operand" ""))])
15961    (set (match_operand:QI 7 "register_operand" "")
15962         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15963    (set (match_operand:QI 8 "register_operand" "")
15964         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15965    (set (reg FLAGS_REG)
15966         (compare (match_dup 7) (match_dup 8)))
15967   ]
15968   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15969   [(parallel[
15970      (set (reg:CC FLAGS_REG)
15971           (compare:CC (mem:BLK (match_dup 4))
15972                       (mem:BLK (match_dup 5))))
15973      (use (match_dup 6))
15974      (use (match_dup 3))
15975      (clobber (match_dup 0))
15976      (clobber (match_dup 1))
15977      (clobber (match_dup 2))])])
15978
15979 ;; ...and this one handles cmpstrn*_1.
15980 (define_peephole2
15981   [(parallel[
15982      (set (reg:CC FLAGS_REG)
15983           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15984                                (const_int 0))
15985             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15986                         (mem:BLK (match_operand 5 "register_operand" "")))
15987             (const_int 0)))
15988      (use (match_operand:SI 3 "immediate_operand" ""))
15989      (use (reg:CC FLAGS_REG))
15990      (clobber (match_operand 0 "register_operand" ""))
15991      (clobber (match_operand 1 "register_operand" ""))
15992      (clobber (match_operand 2 "register_operand" ""))])
15993    (set (match_operand:QI 7 "register_operand" "")
15994         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15995    (set (match_operand:QI 8 "register_operand" "")
15996         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15997    (set (reg FLAGS_REG)
15998         (compare (match_dup 7) (match_dup 8)))
15999   ]
16000   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16001   [(parallel[
16002      (set (reg:CC FLAGS_REG)
16003           (if_then_else:CC (ne (match_dup 6)
16004                                (const_int 0))
16005             (compare:CC (mem:BLK (match_dup 4))
16006                         (mem:BLK (match_dup 5)))
16007             (const_int 0)))
16008      (use (match_dup 3))
16009      (use (reg:CC FLAGS_REG))
16010      (clobber (match_dup 0))
16011      (clobber (match_dup 1))
16012      (clobber (match_dup 2))])])
16013 \f
16014 ;; Conditional move instructions.
16015
16016 (define_expand "mov<mode>cc"
16017   [(set (match_operand:SWIM 0 "register_operand" "")
16018         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16019                            (match_operand:SWIM 2 "<general_operand>" "")
16020                            (match_operand:SWIM 3 "<general_operand>" "")))]
16021   ""
16022   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16023
16024 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16025 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16026 ;; So just document what we're doing explicitly.
16027
16028 (define_expand "x86_mov<mode>cc_0_m1"
16029   [(parallel
16030     [(set (match_operand:SWI48 0 "register_operand" "")
16031           (if_then_else:SWI48
16032             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16033              [(match_operand 1 "flags_reg_operand" "")
16034               (const_int 0)])
16035             (const_int -1)
16036             (const_int 0)))
16037      (clobber (reg:CC FLAGS_REG))])])
16038
16039 (define_insn "*x86_mov<mode>cc_0_m1"
16040   [(set (match_operand:SWI48 0 "register_operand" "=r")
16041         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16042                              [(reg FLAGS_REG) (const_int 0)])
16043           (const_int -1)
16044           (const_int 0)))
16045    (clobber (reg:CC FLAGS_REG))]
16046   ""
16047   "sbb{<imodesuffix>}\t%0, %0"
16048   ; Since we don't have the proper number of operands for an alu insn,
16049   ; fill in all the blanks.
16050   [(set_attr "type" "alu")
16051    (set_attr "use_carry" "1")
16052    (set_attr "pent_pair" "pu")
16053    (set_attr "memory" "none")
16054    (set_attr "imm_disp" "false")
16055    (set_attr "mode" "<MODE>")
16056    (set_attr "length_immediate" "0")])
16057
16058 (define_insn "*x86_mov<mode>cc_0_m1_se"
16059   [(set (match_operand:SWI48 0 "register_operand" "=r")
16060         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16061                              [(reg FLAGS_REG) (const_int 0)])
16062                             (const_int 1)
16063                             (const_int 0)))
16064    (clobber (reg:CC FLAGS_REG))]
16065   ""
16066   "sbb{<imodesuffix>}\t%0, %0"
16067   [(set_attr "type" "alu")
16068    (set_attr "use_carry" "1")
16069    (set_attr "pent_pair" "pu")
16070    (set_attr "memory" "none")
16071    (set_attr "imm_disp" "false")
16072    (set_attr "mode" "<MODE>")
16073    (set_attr "length_immediate" "0")])
16074
16075 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16076   [(set (match_operand:SWI48 0 "register_operand" "=r")
16077         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16078                     [(reg FLAGS_REG) (const_int 0)])))]
16079   ""
16080   "sbb{<imodesuffix>}\t%0, %0"
16081   [(set_attr "type" "alu")
16082    (set_attr "use_carry" "1")
16083    (set_attr "pent_pair" "pu")
16084    (set_attr "memory" "none")
16085    (set_attr "imm_disp" "false")
16086    (set_attr "mode" "<MODE>")
16087    (set_attr "length_immediate" "0")])
16088
16089 (define_insn "*mov<mode>cc_noc"
16090   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16091         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16092                                [(reg FLAGS_REG) (const_int 0)])
16093           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16094           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16095   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16096   "@
16097    cmov%O2%C1\t{%2, %0|%0, %2}
16098    cmov%O2%c1\t{%3, %0|%0, %3}"
16099   [(set_attr "type" "icmov")
16100    (set_attr "mode" "<MODE>")])
16101
16102 (define_insn_and_split "*movqicc_noc"
16103   [(set (match_operand:QI 0 "register_operand" "=r,r")
16104         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16105                            [(match_operand 4 "flags_reg_operand" "")
16106                             (const_int 0)])
16107                       (match_operand:QI 2 "register_operand" "r,0")
16108                       (match_operand:QI 3 "register_operand" "0,r")))]
16109   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16110   "#"
16111   "&& reload_completed"
16112   [(set (match_dup 0)
16113         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16114                       (match_dup 2)
16115                       (match_dup 3)))]
16116   "operands[0] = gen_lowpart (SImode, operands[0]);
16117    operands[2] = gen_lowpart (SImode, operands[2]);
16118    operands[3] = gen_lowpart (SImode, operands[3]);"
16119   [(set_attr "type" "icmov")
16120    (set_attr "mode" "SI")])
16121
16122 (define_expand "mov<mode>cc"
16123   [(set (match_operand:X87MODEF 0 "register_operand" "")
16124         (if_then_else:X87MODEF
16125           (match_operand 1 "ix86_fp_comparison_operator" "")
16126           (match_operand:X87MODEF 2 "register_operand" "")
16127           (match_operand:X87MODEF 3 "register_operand" "")))]
16128   "(TARGET_80387 && TARGET_CMOVE)
16129    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16130   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16131
16132 (define_insn "*movxfcc_1"
16133   [(set (match_operand:XF 0 "register_operand" "=f,f")
16134         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16135                                 [(reg FLAGS_REG) (const_int 0)])
16136                       (match_operand:XF 2 "register_operand" "f,0")
16137                       (match_operand:XF 3 "register_operand" "0,f")))]
16138   "TARGET_80387 && TARGET_CMOVE"
16139   "@
16140    fcmov%F1\t{%2, %0|%0, %2}
16141    fcmov%f1\t{%3, %0|%0, %3}"
16142   [(set_attr "type" "fcmov")
16143    (set_attr "mode" "XF")])
16144
16145 (define_insn "*movdfcc_1_rex64"
16146   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16147         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16148                                 [(reg FLAGS_REG) (const_int 0)])
16149                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16150                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16151   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16152    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16153   "@
16154    fcmov%F1\t{%2, %0|%0, %2}
16155    fcmov%f1\t{%3, %0|%0, %3}
16156    cmov%O2%C1\t{%2, %0|%0, %2}
16157    cmov%O2%c1\t{%3, %0|%0, %3}"
16158   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16159    (set_attr "mode" "DF,DF,DI,DI")])
16160
16161 (define_insn "*movdfcc_1"
16162   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16163         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16164                                 [(reg FLAGS_REG) (const_int 0)])
16165                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16166                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16167   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16168    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16169   "@
16170    fcmov%F1\t{%2, %0|%0, %2}
16171    fcmov%f1\t{%3, %0|%0, %3}
16172    #
16173    #"
16174   [(set_attr "type" "fcmov,fcmov,multi,multi")
16175    (set_attr "mode" "DF,DF,DI,DI")])
16176
16177 (define_split
16178   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16179         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16180                                 [(match_operand 4 "flags_reg_operand" "")
16181                                  (const_int 0)])
16182                       (match_operand:DF 2 "nonimmediate_operand" "")
16183                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16184   "!TARGET_64BIT && reload_completed"
16185   [(set (match_dup 2)
16186         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16187                       (match_dup 5)
16188                       (match_dup 6)))
16189    (set (match_dup 3)
16190         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16191                       (match_dup 7)
16192                       (match_dup 8)))]
16193 {
16194   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16195   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16196 })
16197
16198 (define_insn "*movsfcc_1_387"
16199   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16200         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16201                                 [(reg FLAGS_REG) (const_int 0)])
16202                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16203                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16204   "TARGET_80387 && TARGET_CMOVE
16205    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16206   "@
16207    fcmov%F1\t{%2, %0|%0, %2}
16208    fcmov%f1\t{%3, %0|%0, %3}
16209    cmov%O2%C1\t{%2, %0|%0, %2}
16210    cmov%O2%c1\t{%3, %0|%0, %3}"
16211   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16212    (set_attr "mode" "SF,SF,SI,SI")])
16213
16214 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16215 ;; the scalar versions to have only XMM registers as operands.
16216
16217 ;; XOP conditional move
16218 (define_insn "*xop_pcmov_<mode>"
16219   [(set (match_operand:MODEF 0 "register_operand" "=x")
16220         (if_then_else:MODEF
16221           (match_operand:MODEF 1 "register_operand" "x")
16222           (match_operand:MODEF 2 "register_operand" "x")
16223           (match_operand:MODEF 3 "register_operand" "x")))]
16224   "TARGET_XOP"
16225   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16226   [(set_attr "type" "sse4arg")])
16227
16228 ;; These versions of the min/max patterns are intentionally ignorant of
16229 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16230 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16231 ;; are undefined in this condition, we're certain this is correct.
16232
16233 (define_insn "<code><mode>3"
16234   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16235         (smaxmin:MODEF
16236           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16237           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16238   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16239   "@
16240    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16241    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16242   [(set_attr "isa" "noavx,avx")
16243    (set_attr "prefix" "orig,vex")
16244    (set_attr "type" "sseadd")
16245    (set_attr "mode" "<MODE>")])
16246
16247 ;; These versions of the min/max patterns implement exactly the operations
16248 ;;   min = (op1 < op2 ? op1 : op2)
16249 ;;   max = (!(op1 < op2) ? op1 : op2)
16250 ;; Their operands are not commutative, and thus they may be used in the
16251 ;; presence of -0.0 and NaN.
16252
16253 (define_insn "*ieee_smin<mode>3"
16254   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16255         (unspec:MODEF
16256           [(match_operand:MODEF 1 "register_operand" "0,x")
16257            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16258          UNSPEC_IEEE_MIN))]
16259   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16260   "@
16261    min<ssemodesuffix>\t{%2, %0|%0, %2}
16262    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16263   [(set_attr "isa" "noavx,avx")
16264    (set_attr "prefix" "orig,vex")
16265    (set_attr "type" "sseadd")
16266    (set_attr "mode" "<MODE>")])
16267
16268 (define_insn "*ieee_smax<mode>3"
16269   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16270         (unspec:MODEF
16271           [(match_operand:MODEF 1 "register_operand" "0,x")
16272            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16273          UNSPEC_IEEE_MAX))]
16274   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16275   "@
16276    max<ssemodesuffix>\t{%2, %0|%0, %2}
16277    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16278   [(set_attr "isa" "noavx,avx")
16279    (set_attr "prefix" "orig,vex")
16280    (set_attr "type" "sseadd")
16281    (set_attr "mode" "<MODE>")])
16282
16283 ;; Make two stack loads independent:
16284 ;;   fld aa              fld aa
16285 ;;   fld %st(0)     ->   fld bb
16286 ;;   fmul bb             fmul %st(1), %st
16287 ;;
16288 ;; Actually we only match the last two instructions for simplicity.
16289 (define_peephole2
16290   [(set (match_operand 0 "fp_register_operand" "")
16291         (match_operand 1 "fp_register_operand" ""))
16292    (set (match_dup 0)
16293         (match_operator 2 "binary_fp_operator"
16294            [(match_dup 0)
16295             (match_operand 3 "memory_operand" "")]))]
16296   "REGNO (operands[0]) != REGNO (operands[1])"
16297   [(set (match_dup 0) (match_dup 3))
16298    (set (match_dup 0) (match_dup 4))]
16299
16300   ;; The % modifier is not operational anymore in peephole2's, so we have to
16301   ;; swap the operands manually in the case of addition and multiplication.
16302   "if (COMMUTATIVE_ARITH_P (operands[2]))
16303      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16304                                    GET_MODE (operands[2]),
16305                                    operands[0], operands[1]);
16306    else
16307      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16308                                    GET_MODE (operands[2]),
16309                                    operands[1], operands[0]);")
16310
16311 ;; Conditional addition patterns
16312 (define_expand "add<mode>cc"
16313   [(match_operand:SWI 0 "register_operand" "")
16314    (match_operand 1 "ordered_comparison_operator" "")
16315    (match_operand:SWI 2 "register_operand" "")
16316    (match_operand:SWI 3 "const_int_operand" "")]
16317   ""
16318   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16319 \f
16320 ;; Misc patterns (?)
16321
16322 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16323 ;; Otherwise there will be nothing to keep
16324 ;;
16325 ;; [(set (reg ebp) (reg esp))]
16326 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16327 ;;  (clobber (eflags)]
16328 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16329 ;;
16330 ;; in proper program order.
16331
16332 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16333   [(set (match_operand:P 0 "register_operand" "=r,r")
16334         (plus:P (match_operand:P 1 "register_operand" "0,r")
16335                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16336    (clobber (reg:CC FLAGS_REG))
16337    (clobber (mem:BLK (scratch)))]
16338   ""
16339 {
16340   switch (get_attr_type (insn))
16341     {
16342     case TYPE_IMOV:
16343       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16344
16345     case TYPE_ALU:
16346       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16347       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16348         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16349
16350       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16351
16352     default:
16353       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16354       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16355     }
16356 }
16357   [(set (attr "type")
16358         (cond [(and (eq_attr "alternative" "0")
16359                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16360                  (const_string "alu")
16361                (match_operand:<MODE> 2 "const0_operand" "")
16362                  (const_string "imov")
16363               ]
16364               (const_string "lea")))
16365    (set (attr "length_immediate")
16366         (cond [(eq_attr "type" "imov")
16367                  (const_string "0")
16368                (and (eq_attr "type" "alu")
16369                     (match_operand 2 "const128_operand" ""))
16370                  (const_string "1")
16371               ]
16372               (const_string "*")))
16373    (set_attr "mode" "<MODE>")])
16374
16375 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16376   [(set (match_operand:P 0 "register_operand" "=r")
16377         (minus:P (match_operand:P 1 "register_operand" "0")
16378                  (match_operand:P 2 "register_operand" "r")))
16379    (clobber (reg:CC FLAGS_REG))
16380    (clobber (mem:BLK (scratch)))]
16381   ""
16382   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16383   [(set_attr "type" "alu")
16384    (set_attr "mode" "<MODE>")])
16385
16386 (define_insn "allocate_stack_worker_probe_<mode>"
16387   [(set (match_operand:P 0 "register_operand" "=a")
16388         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16389                             UNSPECV_STACK_PROBE))
16390    (clobber (reg:CC FLAGS_REG))]
16391   "ix86_target_stack_probe ()"
16392   "call\t___chkstk_ms"
16393   [(set_attr "type" "multi")
16394    (set_attr "length" "5")])
16395
16396 (define_expand "allocate_stack"
16397   [(match_operand 0 "register_operand" "")
16398    (match_operand 1 "general_operand" "")]
16399   "ix86_target_stack_probe ()"
16400 {
16401   rtx x;
16402
16403 #ifndef CHECK_STACK_LIMIT
16404 #define CHECK_STACK_LIMIT 0
16405 #endif
16406
16407   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16408       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16409     {
16410       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16411                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16412       if (x != stack_pointer_rtx)
16413         emit_move_insn (stack_pointer_rtx, x);
16414     }
16415   else
16416     {
16417       x = copy_to_mode_reg (Pmode, operands[1]);
16418       if (TARGET_64BIT)
16419         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16420       else
16421         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16422       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16423                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16424       if (x != stack_pointer_rtx)
16425         emit_move_insn (stack_pointer_rtx, x);
16426     }
16427
16428   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16429   DONE;
16430 })
16431
16432 ;; Use IOR for stack probes, this is shorter.
16433 (define_expand "probe_stack"
16434   [(match_operand 0 "memory_operand" "")]
16435   ""
16436 {
16437   rtx (*gen_ior3) (rtx, rtx, rtx);
16438
16439   gen_ior3 = (GET_MODE (operands[0]) == DImode
16440               ? gen_iordi3 : gen_iorsi3);
16441
16442   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16443   DONE;
16444 })
16445
16446 (define_insn "adjust_stack_and_probe<mode>"
16447   [(set (match_operand:P 0 "register_operand" "=r")
16448         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16449                             UNSPECV_PROBE_STACK_RANGE))
16450    (set (reg:P SP_REG)
16451         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16452    (clobber (reg:CC FLAGS_REG))
16453    (clobber (mem:BLK (scratch)))]
16454   ""
16455   "* return output_adjust_stack_and_probe (operands[0]);"
16456   [(set_attr "type" "multi")])
16457
16458 (define_insn "probe_stack_range<mode>"
16459   [(set (match_operand:P 0 "register_operand" "=r")
16460         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16461                             (match_operand:P 2 "const_int_operand" "n")]
16462                             UNSPECV_PROBE_STACK_RANGE))
16463    (clobber (reg:CC FLAGS_REG))]
16464   ""
16465   "* return output_probe_stack_range (operands[0], operands[2]);"
16466   [(set_attr "type" "multi")])
16467
16468 (define_expand "builtin_setjmp_receiver"
16469   [(label_ref (match_operand 0 "" ""))]
16470   "!TARGET_64BIT && flag_pic"
16471 {
16472 #if TARGET_MACHO
16473   if (TARGET_MACHO)
16474     {
16475       rtx xops[3];
16476       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16477       rtx label_rtx = gen_label_rtx ();
16478       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16479       xops[0] = xops[1] = picreg;
16480       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16481       ix86_expand_binary_operator (MINUS, SImode, xops);
16482     }
16483   else
16484 #endif
16485     emit_insn (gen_set_got (pic_offset_table_rtx));
16486   DONE;
16487 })
16488 \f
16489 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16490
16491 (define_split
16492   [(set (match_operand 0 "register_operand" "")
16493         (match_operator 3 "promotable_binary_operator"
16494            [(match_operand 1 "register_operand" "")
16495             (match_operand 2 "aligned_operand" "")]))
16496    (clobber (reg:CC FLAGS_REG))]
16497   "! TARGET_PARTIAL_REG_STALL && reload_completed
16498    && ((GET_MODE (operands[0]) == HImode
16499         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16500             /* ??? next two lines just !satisfies_constraint_K (...) */
16501             || !CONST_INT_P (operands[2])
16502             || satisfies_constraint_K (operands[2])))
16503        || (GET_MODE (operands[0]) == QImode
16504            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16505   [(parallel [(set (match_dup 0)
16506                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16507               (clobber (reg:CC FLAGS_REG))])]
16508   "operands[0] = gen_lowpart (SImode, operands[0]);
16509    operands[1] = gen_lowpart (SImode, operands[1]);
16510    if (GET_CODE (operands[3]) != ASHIFT)
16511      operands[2] = gen_lowpart (SImode, operands[2]);
16512    PUT_MODE (operands[3], SImode);")
16513
16514 ; Promote the QImode tests, as i386 has encoding of the AND
16515 ; instruction with 32-bit sign-extended immediate and thus the
16516 ; instruction size is unchanged, except in the %eax case for
16517 ; which it is increased by one byte, hence the ! optimize_size.
16518 (define_split
16519   [(set (match_operand 0 "flags_reg_operand" "")
16520         (match_operator 2 "compare_operator"
16521           [(and (match_operand 3 "aligned_operand" "")
16522                 (match_operand 4 "const_int_operand" ""))
16523            (const_int 0)]))
16524    (set (match_operand 1 "register_operand" "")
16525         (and (match_dup 3) (match_dup 4)))]
16526   "! TARGET_PARTIAL_REG_STALL && reload_completed
16527    && optimize_insn_for_speed_p ()
16528    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16529        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16530    /* Ensure that the operand will remain sign-extended immediate.  */
16531    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16532   [(parallel [(set (match_dup 0)
16533                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16534                                     (const_int 0)]))
16535               (set (match_dup 1)
16536                    (and:SI (match_dup 3) (match_dup 4)))])]
16537 {
16538   operands[4]
16539     = gen_int_mode (INTVAL (operands[4])
16540                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16541   operands[1] = gen_lowpart (SImode, operands[1]);
16542   operands[3] = gen_lowpart (SImode, operands[3]);
16543 })
16544
16545 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16546 ; the TEST instruction with 32-bit sign-extended immediate and thus
16547 ; the instruction size would at least double, which is not what we
16548 ; want even with ! optimize_size.
16549 (define_split
16550   [(set (match_operand 0 "flags_reg_operand" "")
16551         (match_operator 1 "compare_operator"
16552           [(and (match_operand:HI 2 "aligned_operand" "")
16553                 (match_operand:HI 3 "const_int_operand" ""))
16554            (const_int 0)]))]
16555   "! TARGET_PARTIAL_REG_STALL && reload_completed
16556    && ! TARGET_FAST_PREFIX
16557    && optimize_insn_for_speed_p ()
16558    /* Ensure that the operand will remain sign-extended immediate.  */
16559    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16560   [(set (match_dup 0)
16561         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16562                          (const_int 0)]))]
16563 {
16564   operands[3]
16565     = gen_int_mode (INTVAL (operands[3])
16566                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16567   operands[2] = gen_lowpart (SImode, operands[2]);
16568 })
16569
16570 (define_split
16571   [(set (match_operand 0 "register_operand" "")
16572         (neg (match_operand 1 "register_operand" "")))
16573    (clobber (reg:CC FLAGS_REG))]
16574   "! TARGET_PARTIAL_REG_STALL && reload_completed
16575    && (GET_MODE (operands[0]) == HImode
16576        || (GET_MODE (operands[0]) == QImode
16577            && (TARGET_PROMOTE_QImode
16578                || optimize_insn_for_size_p ())))"
16579   [(parallel [(set (match_dup 0)
16580                    (neg:SI (match_dup 1)))
16581               (clobber (reg:CC FLAGS_REG))])]
16582   "operands[0] = gen_lowpart (SImode, operands[0]);
16583    operands[1] = gen_lowpart (SImode, operands[1]);")
16584
16585 (define_split
16586   [(set (match_operand 0 "register_operand" "")
16587         (not (match_operand 1 "register_operand" "")))]
16588   "! TARGET_PARTIAL_REG_STALL && reload_completed
16589    && (GET_MODE (operands[0]) == HImode
16590        || (GET_MODE (operands[0]) == QImode
16591            && (TARGET_PROMOTE_QImode
16592                || optimize_insn_for_size_p ())))"
16593   [(set (match_dup 0)
16594         (not:SI (match_dup 1)))]
16595   "operands[0] = gen_lowpart (SImode, operands[0]);
16596    operands[1] = gen_lowpart (SImode, operands[1]);")
16597
16598 (define_split
16599   [(set (match_operand 0 "register_operand" "")
16600         (if_then_else (match_operator 1 "ordered_comparison_operator"
16601                                 [(reg FLAGS_REG) (const_int 0)])
16602                       (match_operand 2 "register_operand" "")
16603                       (match_operand 3 "register_operand" "")))]
16604   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16605    && (GET_MODE (operands[0]) == HImode
16606        || (GET_MODE (operands[0]) == QImode
16607            && (TARGET_PROMOTE_QImode
16608                || optimize_insn_for_size_p ())))"
16609   [(set (match_dup 0)
16610         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16611   "operands[0] = gen_lowpart (SImode, operands[0]);
16612    operands[2] = gen_lowpart (SImode, operands[2]);
16613    operands[3] = gen_lowpart (SImode, operands[3]);")
16614 \f
16615 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16616 ;; transform a complex memory operation into two memory to register operations.
16617
16618 ;; Don't push memory operands
16619 (define_peephole2
16620   [(set (match_operand:SWI 0 "push_operand" "")
16621         (match_operand:SWI 1 "memory_operand" ""))
16622    (match_scratch:SWI 2 "<r>")]
16623   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16624    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16625   [(set (match_dup 2) (match_dup 1))
16626    (set (match_dup 0) (match_dup 2))])
16627
16628 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16629 ;; SImode pushes.
16630 (define_peephole2
16631   [(set (match_operand:SF 0 "push_operand" "")
16632         (match_operand:SF 1 "memory_operand" ""))
16633    (match_scratch:SF 2 "r")]
16634   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16635    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16636   [(set (match_dup 2) (match_dup 1))
16637    (set (match_dup 0) (match_dup 2))])
16638
16639 ;; Don't move an immediate directly to memory when the instruction
16640 ;; gets too big.
16641 (define_peephole2
16642   [(match_scratch:SWI124 1 "<r>")
16643    (set (match_operand:SWI124 0 "memory_operand" "")
16644         (const_int 0))]
16645   "optimize_insn_for_speed_p ()
16646    && !TARGET_USE_MOV0
16647    && TARGET_SPLIT_LONG_MOVES
16648    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16649    && peep2_regno_dead_p (0, FLAGS_REG)"
16650   [(parallel [(set (match_dup 2) (const_int 0))
16651               (clobber (reg:CC FLAGS_REG))])
16652    (set (match_dup 0) (match_dup 1))]
16653   "operands[2] = gen_lowpart (SImode, operands[1]);")
16654
16655 (define_peephole2
16656   [(match_scratch:SWI124 2 "<r>")
16657    (set (match_operand:SWI124 0 "memory_operand" "")
16658         (match_operand:SWI124 1 "immediate_operand" ""))]
16659   "optimize_insn_for_speed_p ()
16660    && TARGET_SPLIT_LONG_MOVES
16661    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16662   [(set (match_dup 2) (match_dup 1))
16663    (set (match_dup 0) (match_dup 2))])
16664
16665 ;; Don't compare memory with zero, load and use a test instead.
16666 (define_peephole2
16667   [(set (match_operand 0 "flags_reg_operand" "")
16668         (match_operator 1 "compare_operator"
16669           [(match_operand:SI 2 "memory_operand" "")
16670            (const_int 0)]))
16671    (match_scratch:SI 3 "r")]
16672   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16673   [(set (match_dup 3) (match_dup 2))
16674    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16675
16676 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16677 ;; Don't split NOTs with a displacement operand, because resulting XOR
16678 ;; will not be pairable anyway.
16679 ;;
16680 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16681 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16682 ;; so this split helps here as well.
16683 ;;
16684 ;; Note: Can't do this as a regular split because we can't get proper
16685 ;; lifetime information then.
16686
16687 (define_peephole2
16688   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16689         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16690   "optimize_insn_for_speed_p ()
16691    && ((TARGET_NOT_UNPAIRABLE
16692         && (!MEM_P (operands[0])
16693             || !memory_displacement_operand (operands[0], <MODE>mode)))
16694        || (TARGET_NOT_VECTORMODE
16695            && long_memory_operand (operands[0], <MODE>mode)))
16696    && peep2_regno_dead_p (0, FLAGS_REG)"
16697   [(parallel [(set (match_dup 0)
16698                    (xor:SWI124 (match_dup 1) (const_int -1)))
16699               (clobber (reg:CC FLAGS_REG))])])
16700
16701 ;; Non pairable "test imm, reg" instructions can be translated to
16702 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16703 ;; byte opcode instead of two, have a short form for byte operands),
16704 ;; so do it for other CPUs as well.  Given that the value was dead,
16705 ;; this should not create any new dependencies.  Pass on the sub-word
16706 ;; versions if we're concerned about partial register stalls.
16707
16708 (define_peephole2
16709   [(set (match_operand 0 "flags_reg_operand" "")
16710         (match_operator 1 "compare_operator"
16711           [(and:SI (match_operand:SI 2 "register_operand" "")
16712                    (match_operand:SI 3 "immediate_operand" ""))
16713            (const_int 0)]))]
16714   "ix86_match_ccmode (insn, CCNOmode)
16715    && (true_regnum (operands[2]) != AX_REG
16716        || satisfies_constraint_K (operands[3]))
16717    && peep2_reg_dead_p (1, operands[2])"
16718   [(parallel
16719      [(set (match_dup 0)
16720            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16721                             (const_int 0)]))
16722       (set (match_dup 2)
16723            (and:SI (match_dup 2) (match_dup 3)))])])
16724
16725 ;; We don't need to handle HImode case, because it will be promoted to SImode
16726 ;; on ! TARGET_PARTIAL_REG_STALL
16727
16728 (define_peephole2
16729   [(set (match_operand 0 "flags_reg_operand" "")
16730         (match_operator 1 "compare_operator"
16731           [(and:QI (match_operand:QI 2 "register_operand" "")
16732                    (match_operand:QI 3 "immediate_operand" ""))
16733            (const_int 0)]))]
16734   "! TARGET_PARTIAL_REG_STALL
16735    && ix86_match_ccmode (insn, CCNOmode)
16736    && true_regnum (operands[2]) != AX_REG
16737    && peep2_reg_dead_p (1, operands[2])"
16738   [(parallel
16739      [(set (match_dup 0)
16740            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16741                             (const_int 0)]))
16742       (set (match_dup 2)
16743            (and:QI (match_dup 2) (match_dup 3)))])])
16744
16745 (define_peephole2
16746   [(set (match_operand 0 "flags_reg_operand" "")
16747         (match_operator 1 "compare_operator"
16748           [(and:SI
16749              (zero_extract:SI
16750                (match_operand 2 "ext_register_operand" "")
16751                (const_int 8)
16752                (const_int 8))
16753              (match_operand 3 "const_int_operand" ""))
16754            (const_int 0)]))]
16755   "! TARGET_PARTIAL_REG_STALL
16756    && ix86_match_ccmode (insn, CCNOmode)
16757    && true_regnum (operands[2]) != AX_REG
16758    && peep2_reg_dead_p (1, operands[2])"
16759   [(parallel [(set (match_dup 0)
16760                    (match_op_dup 1
16761                      [(and:SI
16762                         (zero_extract:SI
16763                           (match_dup 2)
16764                           (const_int 8)
16765                           (const_int 8))
16766                         (match_dup 3))
16767                       (const_int 0)]))
16768               (set (zero_extract:SI (match_dup 2)
16769                                     (const_int 8)
16770                                     (const_int 8))
16771                    (and:SI
16772                      (zero_extract:SI
16773                        (match_dup 2)
16774                        (const_int 8)
16775                        (const_int 8))
16776                      (match_dup 3)))])])
16777
16778 ;; Don't do logical operations with memory inputs.
16779 (define_peephole2
16780   [(match_scratch:SI 2 "r")
16781    (parallel [(set (match_operand:SI 0 "register_operand" "")
16782                    (match_operator:SI 3 "arith_or_logical_operator"
16783                      [(match_dup 0)
16784                       (match_operand:SI 1 "memory_operand" "")]))
16785               (clobber (reg:CC FLAGS_REG))])]
16786   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16787   [(set (match_dup 2) (match_dup 1))
16788    (parallel [(set (match_dup 0)
16789                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16790               (clobber (reg:CC FLAGS_REG))])])
16791
16792 (define_peephole2
16793   [(match_scratch:SI 2 "r")
16794    (parallel [(set (match_operand:SI 0 "register_operand" "")
16795                    (match_operator:SI 3 "arith_or_logical_operator"
16796                      [(match_operand:SI 1 "memory_operand" "")
16797                       (match_dup 0)]))
16798               (clobber (reg:CC FLAGS_REG))])]
16799   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16800   [(set (match_dup 2) (match_dup 1))
16801    (parallel [(set (match_dup 0)
16802                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16803               (clobber (reg:CC FLAGS_REG))])])
16804
16805 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16806 ;; refers to the destination of the load!
16807
16808 (define_peephole2
16809   [(set (match_operand:SI 0 "register_operand" "")
16810         (match_operand:SI 1 "register_operand" ""))
16811    (parallel [(set (match_dup 0)
16812                    (match_operator:SI 3 "commutative_operator"
16813                      [(match_dup 0)
16814                       (match_operand:SI 2 "memory_operand" "")]))
16815               (clobber (reg:CC FLAGS_REG))])]
16816   "REGNO (operands[0]) != REGNO (operands[1])
16817    && GENERAL_REGNO_P (REGNO (operands[0]))
16818    && GENERAL_REGNO_P (REGNO (operands[1]))"
16819   [(set (match_dup 0) (match_dup 4))
16820    (parallel [(set (match_dup 0)
16821                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16822               (clobber (reg:CC FLAGS_REG))])]
16823   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16824
16825 (define_peephole2
16826   [(set (match_operand 0 "register_operand" "")
16827         (match_operand 1 "register_operand" ""))
16828    (set (match_dup 0)
16829                    (match_operator 3 "commutative_operator"
16830                      [(match_dup 0)
16831                       (match_operand 2 "memory_operand" "")]))]
16832   "REGNO (operands[0]) != REGNO (operands[1])
16833    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16834        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16835   [(set (match_dup 0) (match_dup 2))
16836    (set (match_dup 0)
16837         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16838
16839 ; Don't do logical operations with memory outputs
16840 ;
16841 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16842 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16843 ; the same decoder scheduling characteristics as the original.
16844
16845 (define_peephole2
16846   [(match_scratch:SI 2 "r")
16847    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16848                    (match_operator:SI 3 "arith_or_logical_operator"
16849                      [(match_dup 0)
16850                       (match_operand:SI 1 "nonmemory_operand" "")]))
16851               (clobber (reg:CC FLAGS_REG))])]
16852   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16853    /* Do not split stack checking probes.  */
16854    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16855   [(set (match_dup 2) (match_dup 0))
16856    (parallel [(set (match_dup 2)
16857                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16858               (clobber (reg:CC FLAGS_REG))])
16859    (set (match_dup 0) (match_dup 2))])
16860
16861 (define_peephole2
16862   [(match_scratch:SI 2 "r")
16863    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16864                    (match_operator:SI 3 "arith_or_logical_operator"
16865                      [(match_operand:SI 1 "nonmemory_operand" "")
16866                       (match_dup 0)]))
16867               (clobber (reg:CC FLAGS_REG))])]
16868   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16869    /* Do not split stack checking probes.  */
16870    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16871   [(set (match_dup 2) (match_dup 0))
16872    (parallel [(set (match_dup 2)
16873                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16874               (clobber (reg:CC FLAGS_REG))])
16875    (set (match_dup 0) (match_dup 2))])
16876
16877 ;; Attempt to use arith or logical operations with memory outputs with
16878 ;; setting of flags.
16879 (define_peephole2
16880   [(set (match_operand:SWI 0 "register_operand" "")
16881         (match_operand:SWI 1 "memory_operand" ""))
16882    (parallel [(set (match_dup 0)
16883                    (match_operator:SWI 3 "plusminuslogic_operator"
16884                      [(match_dup 0)
16885                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16886               (clobber (reg:CC FLAGS_REG))])
16887    (set (match_dup 1) (match_dup 0))
16888    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16889   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16890    && peep2_reg_dead_p (4, operands[0])
16891    && !reg_overlap_mentioned_p (operands[0], operands[1])
16892    && ix86_match_ccmode (peep2_next_insn (3),
16893                          (GET_CODE (operands[3]) == PLUS
16894                           || GET_CODE (operands[3]) == MINUS)
16895                          ? CCGOCmode : CCNOmode)"
16896   [(parallel [(set (match_dup 4) (match_dup 5))
16897               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16898                                                   (match_dup 2)]))])]
16899   "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16900    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16901                                  copy_rtx (operands[1]),
16902                                  copy_rtx (operands[2]));
16903    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16904                                   operands[5], const0_rtx);")
16905
16906 (define_peephole2
16907   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16908                    (match_operator:SWI 2 "plusminuslogic_operator"
16909                      [(match_dup 0)
16910                       (match_operand:SWI 1 "memory_operand" "")]))
16911               (clobber (reg:CC FLAGS_REG))])
16912    (set (match_dup 1) (match_dup 0))
16913    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16914   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16915    && GET_CODE (operands[2]) != MINUS
16916    && peep2_reg_dead_p (3, operands[0])
16917    && !reg_overlap_mentioned_p (operands[0], operands[1])
16918    && ix86_match_ccmode (peep2_next_insn (2),
16919                          GET_CODE (operands[2]) == PLUS
16920                          ? CCGOCmode : CCNOmode)"
16921   [(parallel [(set (match_dup 3) (match_dup 4))
16922               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16923                                                   (match_dup 0)]))])]
16924   "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16925    operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16926                                  copy_rtx (operands[1]),
16927                                  copy_rtx (operands[0]));
16928    operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16929                                   operands[4], const0_rtx);")
16930
16931 (define_peephole2
16932   [(set (match_operand:SWI12 0 "register_operand" "")
16933         (match_operand:SWI12 1 "memory_operand" ""))
16934    (parallel [(set (match_operand:SI 4 "register_operand" "")
16935                    (match_operator:SI 3 "plusminuslogic_operator"
16936                      [(match_dup 4)
16937                       (match_operand:SI 2 "nonmemory_operand" "")]))
16938               (clobber (reg:CC FLAGS_REG))])
16939    (set (match_dup 1) (match_dup 0))
16940    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16941   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16942    && REG_P (operands[0]) && REG_P (operands[4])
16943    && REGNO (operands[0]) == REGNO (operands[4])
16944    && peep2_reg_dead_p (4, operands[0])
16945    && !reg_overlap_mentioned_p (operands[0], operands[1])
16946    && ix86_match_ccmode (peep2_next_insn (3),
16947                          (GET_CODE (operands[3]) == PLUS
16948                           || GET_CODE (operands[3]) == MINUS)
16949                          ? CCGOCmode : CCNOmode)"
16950   [(parallel [(set (match_dup 4) (match_dup 5))
16951               (set (match_dup 1) (match_dup 6))])]
16952   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16953    operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16954    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16955                                  copy_rtx (operands[1]), operands[2]);
16956    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16957                                   operands[5], const0_rtx);
16958    operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16959                                  copy_rtx (operands[1]),
16960                                  copy_rtx (operands[2]));")
16961
16962 ;; Attempt to always use XOR for zeroing registers.
16963 (define_peephole2
16964   [(set (match_operand 0 "register_operand" "")
16965         (match_operand 1 "const0_operand" ""))]
16966   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16967    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16968    && GENERAL_REG_P (operands[0])
16969    && peep2_regno_dead_p (0, FLAGS_REG)"
16970   [(parallel [(set (match_dup 0) (const_int 0))
16971               (clobber (reg:CC FLAGS_REG))])]
16972   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16973
16974 (define_peephole2
16975   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16976         (const_int 0))]
16977   "(GET_MODE (operands[0]) == QImode
16978     || GET_MODE (operands[0]) == HImode)
16979    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16980    && peep2_regno_dead_p (0, FLAGS_REG)"
16981   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16982               (clobber (reg:CC FLAGS_REG))])])
16983
16984 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16985 (define_peephole2
16986   [(set (match_operand:SWI248 0 "register_operand" "")
16987         (const_int -1))]
16988   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16989    && peep2_regno_dead_p (0, FLAGS_REG)"
16990   [(parallel [(set (match_dup 0) (const_int -1))
16991               (clobber (reg:CC FLAGS_REG))])]
16992 {
16993   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16994     operands[0] = gen_lowpart (SImode, operands[0]);
16995 })
16996
16997 ;; Attempt to convert simple lea to add/shift.
16998 ;; These can be created by move expanders.
16999
17000 (define_peephole2
17001   [(set (match_operand:SWI48 0 "register_operand" "")
17002         (plus:SWI48 (match_dup 0)
17003                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17004   "peep2_regno_dead_p (0, FLAGS_REG)"
17005   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17006               (clobber (reg:CC FLAGS_REG))])])
17007
17008 (define_peephole2
17009   [(set (match_operand:SI 0 "register_operand" "")
17010         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17011                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17012   "TARGET_64BIT
17013    && peep2_regno_dead_p (0, FLAGS_REG)
17014    && REGNO (operands[0]) == REGNO (operands[1])"
17015   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17016               (clobber (reg:CC FLAGS_REG))])]
17017   "operands[2] = gen_lowpart (SImode, operands[2]);")
17018
17019 (define_peephole2
17020   [(set (match_operand:SWI48 0 "register_operand" "")
17021         (mult:SWI48 (match_dup 0)
17022                     (match_operand:SWI48 1 "const_int_operand" "")))]
17023   "exact_log2 (INTVAL (operands[1])) >= 0
17024    && peep2_regno_dead_p (0, FLAGS_REG)"
17025   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17026               (clobber (reg:CC FLAGS_REG))])]
17027   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17028
17029 (define_peephole2
17030   [(set (match_operand:SI 0 "register_operand" "")
17031         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17032                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17033   "TARGET_64BIT
17034    && exact_log2 (INTVAL (operands[2])) >= 0
17035    && REGNO (operands[0]) == REGNO (operands[1])
17036    && peep2_regno_dead_p (0, FLAGS_REG)"
17037   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17038               (clobber (reg:CC FLAGS_REG))])]
17039   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17040
17041 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17042 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17043 ;; On many CPUs it is also faster, since special hardware to avoid esp
17044 ;; dependencies is present.
17045
17046 ;; While some of these conversions may be done using splitters, we use
17047 ;; peepholes in order to allow combine_stack_adjustments pass to see
17048 ;; nonobfuscated RTL.
17049
17050 ;; Convert prologue esp subtractions to push.
17051 ;; We need register to push.  In order to keep verify_flow_info happy we have
17052 ;; two choices
17053 ;; - use scratch and clobber it in order to avoid dependencies
17054 ;; - use already live register
17055 ;; We can't use the second way right now, since there is no reliable way how to
17056 ;; verify that given register is live.  First choice will also most likely in
17057 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17058 ;; call clobbered registers are dead.  We may want to use base pointer as an
17059 ;; alternative when no register is available later.
17060
17061 (define_peephole2
17062   [(match_scratch:P 1 "r")
17063    (parallel [(set (reg:P SP_REG)
17064                    (plus:P (reg:P SP_REG)
17065                            (match_operand:P 0 "const_int_operand" "")))
17066               (clobber (reg:CC FLAGS_REG))
17067               (clobber (mem:BLK (scratch)))])]
17068   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17069    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17070   [(clobber (match_dup 1))
17071    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17072               (clobber (mem:BLK (scratch)))])])
17073
17074 (define_peephole2
17075   [(match_scratch:P 1 "r")
17076    (parallel [(set (reg:P SP_REG)
17077                    (plus:P (reg:P SP_REG)
17078                            (match_operand:P 0 "const_int_operand" "")))
17079               (clobber (reg:CC FLAGS_REG))
17080               (clobber (mem:BLK (scratch)))])]
17081   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17082    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17083   [(clobber (match_dup 1))
17084    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17085    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17086               (clobber (mem:BLK (scratch)))])])
17087
17088 ;; Convert esp subtractions to push.
17089 (define_peephole2
17090   [(match_scratch:P 1 "r")
17091    (parallel [(set (reg:P SP_REG)
17092                    (plus:P (reg:P SP_REG)
17093                            (match_operand:P 0 "const_int_operand" "")))
17094               (clobber (reg:CC FLAGS_REG))])]
17095   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17096    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17097   [(clobber (match_dup 1))
17098    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17099
17100 (define_peephole2
17101   [(match_scratch:P 1 "r")
17102    (parallel [(set (reg:P SP_REG)
17103                    (plus:P (reg:P SP_REG)
17104                            (match_operand:P 0 "const_int_operand" "")))
17105               (clobber (reg:CC FLAGS_REG))])]
17106   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17107    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17108   [(clobber (match_dup 1))
17109    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17110    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17111
17112 ;; Convert epilogue deallocator to pop.
17113 (define_peephole2
17114   [(match_scratch:P 1 "r")
17115    (parallel [(set (reg:P SP_REG)
17116                    (plus:P (reg:P SP_REG)
17117                            (match_operand:P 0 "const_int_operand" "")))
17118               (clobber (reg:CC FLAGS_REG))
17119               (clobber (mem:BLK (scratch)))])]
17120   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17121    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17122   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17123               (clobber (mem:BLK (scratch)))])])
17124
17125 ;; Two pops case is tricky, since pop causes dependency
17126 ;; on destination register.  We use two registers if available.
17127 (define_peephole2
17128   [(match_scratch:P 1 "r")
17129    (match_scratch:P 2 "r")
17130    (parallel [(set (reg:P SP_REG)
17131                    (plus:P (reg:P SP_REG)
17132                            (match_operand:P 0 "const_int_operand" "")))
17133               (clobber (reg:CC FLAGS_REG))
17134               (clobber (mem:BLK (scratch)))])]
17135   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17136    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17137   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17138               (clobber (mem:BLK (scratch)))])
17139    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17140
17141 (define_peephole2
17142   [(match_scratch:P 1 "r")
17143    (parallel [(set (reg:P SP_REG)
17144                    (plus:P (reg:P SP_REG)
17145                            (match_operand:P 0 "const_int_operand" "")))
17146               (clobber (reg:CC FLAGS_REG))
17147               (clobber (mem:BLK (scratch)))])]
17148   "optimize_insn_for_size_p ()
17149    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17150   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17151               (clobber (mem:BLK (scratch)))])
17152    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17153
17154 ;; Convert esp additions to pop.
17155 (define_peephole2
17156   [(match_scratch:P 1 "r")
17157    (parallel [(set (reg:P SP_REG)
17158                    (plus:P (reg:P SP_REG)
17159                            (match_operand:P 0 "const_int_operand" "")))
17160               (clobber (reg:CC FLAGS_REG))])]
17161   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17162   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17163
17164 ;; Two pops case is tricky, since pop causes dependency
17165 ;; on destination register.  We use two registers if available.
17166 (define_peephole2
17167   [(match_scratch:P 1 "r")
17168    (match_scratch:P 2 "r")
17169    (parallel [(set (reg:P SP_REG)
17170                    (plus:P (reg:P SP_REG)
17171                            (match_operand:P 0 "const_int_operand" "")))
17172               (clobber (reg:CC FLAGS_REG))])]
17173   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17174   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17175    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17176
17177 (define_peephole2
17178   [(match_scratch:P 1 "r")
17179    (parallel [(set (reg:P SP_REG)
17180                    (plus:P (reg:P SP_REG)
17181                            (match_operand:P 0 "const_int_operand" "")))
17182               (clobber (reg:CC FLAGS_REG))])]
17183   "optimize_insn_for_size_p ()
17184    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17185   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17186    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17187 \f
17188 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17189 ;; required and register dies.  Similarly for 128 to -128.
17190 (define_peephole2
17191   [(set (match_operand 0 "flags_reg_operand" "")
17192         (match_operator 1 "compare_operator"
17193           [(match_operand 2 "register_operand" "")
17194            (match_operand 3 "const_int_operand" "")]))]
17195   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17196      && incdec_operand (operands[3], GET_MODE (operands[3])))
17197     || (!TARGET_FUSE_CMP_AND_BRANCH
17198         && INTVAL (operands[3]) == 128))
17199    && ix86_match_ccmode (insn, CCGCmode)
17200    && peep2_reg_dead_p (1, operands[2])"
17201   [(parallel [(set (match_dup 0)
17202                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17203               (clobber (match_dup 2))])])
17204 \f
17205 ;; Convert imul by three, five and nine into lea
17206 (define_peephole2
17207   [(parallel
17208     [(set (match_operand:SWI48 0 "register_operand" "")
17209           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17210                       (match_operand:SWI48 2 "const359_operand" "")))
17211      (clobber (reg:CC FLAGS_REG))])]
17212   "!TARGET_PARTIAL_REG_STALL
17213    || <MODE>mode == SImode
17214    || optimize_function_for_size_p (cfun)"
17215   [(set (match_dup 0)
17216         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17217                     (match_dup 1)))]
17218   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17219
17220 (define_peephole2
17221   [(parallel
17222     [(set (match_operand:SWI48 0 "register_operand" "")
17223           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17224                       (match_operand:SWI48 2 "const359_operand" "")))
17225      (clobber (reg:CC FLAGS_REG))])]
17226   "optimize_insn_for_speed_p ()
17227    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17228   [(set (match_dup 0) (match_dup 1))
17229    (set (match_dup 0)
17230         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17231                     (match_dup 0)))]
17232   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17233
17234 ;; imul $32bit_imm, mem, reg is vector decoded, while
17235 ;; imul $32bit_imm, reg, reg is direct decoded.
17236 (define_peephole2
17237   [(match_scratch:SWI48 3 "r")
17238    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17239                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17240                                (match_operand:SWI48 2 "immediate_operand" "")))
17241               (clobber (reg:CC FLAGS_REG))])]
17242   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17243    && !satisfies_constraint_K (operands[2])"
17244   [(set (match_dup 3) (match_dup 1))
17245    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17246               (clobber (reg:CC FLAGS_REG))])])
17247
17248 (define_peephole2
17249   [(match_scratch:SI 3 "r")
17250    (parallel [(set (match_operand:DI 0 "register_operand" "")
17251                    (zero_extend:DI
17252                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17253                               (match_operand:SI 2 "immediate_operand" ""))))
17254               (clobber (reg:CC FLAGS_REG))])]
17255   "TARGET_64BIT
17256    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17257    && !satisfies_constraint_K (operands[2])"
17258   [(set (match_dup 3) (match_dup 1))
17259    (parallel [(set (match_dup 0)
17260                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17261               (clobber (reg:CC FLAGS_REG))])])
17262
17263 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17264 ;; Convert it into imul reg, reg
17265 ;; It would be better to force assembler to encode instruction using long
17266 ;; immediate, but there is apparently no way to do so.
17267 (define_peephole2
17268   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17269                    (mult:SWI248
17270                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17271                     (match_operand:SWI248 2 "const_int_operand" "")))
17272               (clobber (reg:CC FLAGS_REG))])
17273    (match_scratch:SWI248 3 "r")]
17274   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17275    && satisfies_constraint_K (operands[2])"
17276   [(set (match_dup 3) (match_dup 2))
17277    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17278               (clobber (reg:CC FLAGS_REG))])]
17279 {
17280   if (!rtx_equal_p (operands[0], operands[1]))
17281     emit_move_insn (operands[0], operands[1]);
17282 })
17283
17284 ;; After splitting up read-modify operations, array accesses with memory
17285 ;; operands might end up in form:
17286 ;;  sall    $2, %eax
17287 ;;  movl    4(%esp), %edx
17288 ;;  addl    %edx, %eax
17289 ;; instead of pre-splitting:
17290 ;;  sall    $2, %eax
17291 ;;  addl    4(%esp), %eax
17292 ;; Turn it into:
17293 ;;  movl    4(%esp), %edx
17294 ;;  leal    (%edx,%eax,4), %eax
17295
17296 (define_peephole2
17297   [(match_scratch:P 5 "r")
17298    (parallel [(set (match_operand 0 "register_operand" "")
17299                    (ashift (match_operand 1 "register_operand" "")
17300                            (match_operand 2 "const_int_operand" "")))
17301                (clobber (reg:CC FLAGS_REG))])
17302    (parallel [(set (match_operand 3 "register_operand" "")
17303                    (plus (match_dup 0)
17304                          (match_operand 4 "x86_64_general_operand" "")))
17305                    (clobber (reg:CC FLAGS_REG))])]
17306   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17307    /* Validate MODE for lea.  */
17308    && ((!TARGET_PARTIAL_REG_STALL
17309         && (GET_MODE (operands[0]) == QImode
17310             || GET_MODE (operands[0]) == HImode))
17311        || GET_MODE (operands[0]) == SImode
17312        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17313    && (rtx_equal_p (operands[0], operands[3])
17314        || peep2_reg_dead_p (2, operands[0]))
17315    /* We reorder load and the shift.  */
17316    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17317   [(set (match_dup 5) (match_dup 4))
17318    (set (match_dup 0) (match_dup 1))]
17319 {
17320   enum machine_mode op1mode = GET_MODE (operands[1]);
17321   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17322   int scale = 1 << INTVAL (operands[2]);
17323   rtx index = gen_lowpart (Pmode, operands[1]);
17324   rtx base = gen_lowpart (Pmode, operands[5]);
17325   rtx dest = gen_lowpart (mode, operands[3]);
17326
17327   operands[1] = gen_rtx_PLUS (Pmode, base,
17328                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17329   operands[5] = base;
17330   if (mode != Pmode)
17331     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17332   if (op1mode != Pmode)
17333     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17334   operands[0] = dest;
17335 })
17336 \f
17337 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17338 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17339 ;; caught for use by garbage collectors and the like.  Using an insn that
17340 ;; maps to SIGILL makes it more likely the program will rightfully die.
17341 ;; Keeping with tradition, "6" is in honor of #UD.
17342 (define_insn "trap"
17343   [(trap_if (const_int 1) (const_int 6))]
17344   ""
17345   { return ASM_SHORT "0x0b0f"; }
17346   [(set_attr "length" "2")])
17347
17348 (define_expand "prefetch"
17349   [(prefetch (match_operand 0 "address_operand" "")
17350              (match_operand:SI 1 "const_int_operand" "")
17351              (match_operand:SI 2 "const_int_operand" ""))]
17352   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17353 {
17354   int rw = INTVAL (operands[1]);
17355   int locality = INTVAL (operands[2]);
17356
17357   gcc_assert (rw == 0 || rw == 1);
17358   gcc_assert (locality >= 0 && locality <= 3);
17359   gcc_assert (GET_MODE (operands[0]) == Pmode
17360               || GET_MODE (operands[0]) == VOIDmode);
17361
17362   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17363      supported by SSE counterpart or the SSE prefetch is not available
17364      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17365      of locality.  */
17366   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17367     operands[2] = GEN_INT (3);
17368   else
17369     operands[1] = const0_rtx;
17370 })
17371
17372 (define_insn "*prefetch_sse_<mode>"
17373   [(prefetch (match_operand:P 0 "address_operand" "p")
17374              (const_int 0)
17375              (match_operand:SI 1 "const_int_operand" ""))]
17376   "TARGET_PREFETCH_SSE"
17377 {
17378   static const char * const patterns[4] = {
17379    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17380   };
17381
17382   int locality = INTVAL (operands[1]);
17383   gcc_assert (locality >= 0 && locality <= 3);
17384
17385   return patterns[locality];
17386 }
17387   [(set_attr "type" "sse")
17388    (set_attr "atom_sse_attr" "prefetch")
17389    (set (attr "length_address")
17390         (symbol_ref "memory_address_length (operands[0])"))
17391    (set_attr "memory" "none")])
17392
17393 (define_insn "*prefetch_3dnow_<mode>"
17394   [(prefetch (match_operand:P 0 "address_operand" "p")
17395              (match_operand:SI 1 "const_int_operand" "n")
17396              (const_int 3))]
17397   "TARGET_3DNOW"
17398 {
17399   if (INTVAL (operands[1]) == 0)
17400     return "prefetch\t%a0";
17401   else
17402     return "prefetchw\t%a0";
17403 }
17404   [(set_attr "type" "mmx")
17405    (set (attr "length_address")
17406         (symbol_ref "memory_address_length (operands[0])"))
17407    (set_attr "memory" "none")])
17408
17409 (define_expand "stack_protect_set"
17410   [(match_operand 0 "memory_operand" "")
17411    (match_operand 1 "memory_operand" "")]
17412   ""
17413 {
17414   rtx (*insn)(rtx, rtx);
17415
17416 #ifdef TARGET_THREAD_SSP_OFFSET
17417   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17418   insn = (TARGET_LP64
17419           ? gen_stack_tls_protect_set_di
17420           : gen_stack_tls_protect_set_si);
17421 #else
17422   insn = (TARGET_LP64
17423           ? gen_stack_protect_set_di
17424           : gen_stack_protect_set_si);
17425 #endif
17426
17427   emit_insn (insn (operands[0], operands[1]));
17428   DONE;
17429 })
17430
17431 (define_insn "stack_protect_set_<mode>"
17432   [(set (match_operand:PTR 0 "memory_operand" "=m")
17433         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17434                     UNSPEC_SP_SET))
17435    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17436    (clobber (reg:CC FLAGS_REG))]
17437   ""
17438   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17439   [(set_attr "type" "multi")])
17440
17441 (define_insn "stack_tls_protect_set_<mode>"
17442   [(set (match_operand:PTR 0 "memory_operand" "=m")
17443         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17444                     UNSPEC_SP_TLS_SET))
17445    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17446    (clobber (reg:CC FLAGS_REG))]
17447   ""
17448   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17449   [(set_attr "type" "multi")])
17450
17451 (define_expand "stack_protect_test"
17452   [(match_operand 0 "memory_operand" "")
17453    (match_operand 1 "memory_operand" "")
17454    (match_operand 2 "" "")]
17455   ""
17456 {
17457   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17458
17459   rtx (*insn)(rtx, rtx, rtx);
17460
17461 #ifdef TARGET_THREAD_SSP_OFFSET
17462   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17463   insn = (TARGET_LP64
17464           ? gen_stack_tls_protect_test_di
17465           : gen_stack_tls_protect_test_si);
17466 #else
17467   insn = (TARGET_LP64
17468           ? gen_stack_protect_test_di
17469           : gen_stack_protect_test_si);
17470 #endif
17471
17472   emit_insn (insn (flags, operands[0], operands[1]));
17473
17474   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17475                                   flags, const0_rtx, operands[2]));
17476   DONE;
17477 })
17478
17479 (define_insn "stack_protect_test_<mode>"
17480   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17481         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17482                      (match_operand:PTR 2 "memory_operand" "m")]
17483                     UNSPEC_SP_TEST))
17484    (clobber (match_scratch:PTR 3 "=&r"))]
17485   ""
17486   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17487   [(set_attr "type" "multi")])
17488
17489 (define_insn "stack_tls_protect_test_<mode>"
17490   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17491         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17492                      (match_operand:PTR 2 "const_int_operand" "i")]
17493                     UNSPEC_SP_TLS_TEST))
17494    (clobber (match_scratch:PTR 3 "=r"))]
17495   ""
17496   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17497   [(set_attr "type" "multi")])
17498
17499 (define_insn "sse4_2_crc32<mode>"
17500   [(set (match_operand:SI 0 "register_operand" "=r")
17501         (unspec:SI
17502           [(match_operand:SI 1 "register_operand" "0")
17503            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17504           UNSPEC_CRC32))]
17505   "TARGET_SSE4_2 || TARGET_CRC32"
17506   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17507   [(set_attr "type" "sselog1")
17508    (set_attr "prefix_rep" "1")
17509    (set_attr "prefix_extra" "1")
17510    (set (attr "prefix_data16")
17511      (if_then_else (match_operand:HI 2 "" "")
17512        (const_string "1")
17513        (const_string "*")))
17514    (set (attr "prefix_rex")
17515      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17516        (const_string "1")
17517        (const_string "*")))
17518    (set_attr "mode" "SI")])
17519
17520 (define_insn "sse4_2_crc32di"
17521   [(set (match_operand:DI 0 "register_operand" "=r")
17522         (unspec:DI
17523           [(match_operand:DI 1 "register_operand" "0")
17524            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17525           UNSPEC_CRC32))]
17526   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17527   "crc32{q}\t{%2, %0|%0, %2}"
17528   [(set_attr "type" "sselog1")
17529    (set_attr "prefix_rep" "1")
17530    (set_attr "prefix_extra" "1")
17531    (set_attr "mode" "DI")])
17532
17533 (define_expand "rdpmc"
17534   [(match_operand:DI 0 "register_operand" "")
17535    (match_operand:SI 1 "register_operand" "")]
17536   ""
17537 {
17538   rtx reg = gen_reg_rtx (DImode);
17539   rtx si;
17540
17541   /* Force operand 1 into ECX.  */
17542   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17543   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17544   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17545                                 UNSPECV_RDPMC);
17546
17547   if (TARGET_64BIT)
17548     {
17549       rtvec vec = rtvec_alloc (2);
17550       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17551       rtx upper = gen_reg_rtx (DImode);
17552       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17553                                         gen_rtvec (1, const0_rtx),
17554                                         UNSPECV_RDPMC);
17555       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17556       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17557       emit_insn (load);
17558       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17559                                    NULL, 1, OPTAB_DIRECT);
17560       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17561                                  OPTAB_DIRECT);
17562     }
17563   else
17564     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17565   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17566   DONE;
17567 })
17568
17569 (define_insn "*rdpmc"
17570   [(set (match_operand:DI 0 "register_operand" "=A")
17571         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17572                             UNSPECV_RDPMC))]
17573   "!TARGET_64BIT"
17574   "rdpmc"
17575   [(set_attr "type" "other")
17576    (set_attr "length" "2")])
17577
17578 (define_insn "*rdpmc_rex64"
17579   [(set (match_operand:DI 0 "register_operand" "=a")
17580         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17581                             UNSPECV_RDPMC))
17582   (set (match_operand:DI 1 "register_operand" "=d")
17583        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17584   "TARGET_64BIT"
17585   "rdpmc"
17586   [(set_attr "type" "other")
17587    (set_attr "length" "2")])
17588
17589 (define_expand "rdtsc"
17590   [(set (match_operand:DI 0 "register_operand" "")
17591         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17592   ""
17593 {
17594   if (TARGET_64BIT)
17595     {
17596       rtvec vec = rtvec_alloc (2);
17597       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17598       rtx upper = gen_reg_rtx (DImode);
17599       rtx lower = gen_reg_rtx (DImode);
17600       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17601                                          gen_rtvec (1, const0_rtx),
17602                                          UNSPECV_RDTSC);
17603       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17604       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17605       emit_insn (load);
17606       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17607                                    NULL, 1, OPTAB_DIRECT);
17608       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17609                                    OPTAB_DIRECT);
17610       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17611       DONE;
17612     }
17613 })
17614
17615 (define_insn "*rdtsc"
17616   [(set (match_operand:DI 0 "register_operand" "=A")
17617         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17618   "!TARGET_64BIT"
17619   "rdtsc"
17620   [(set_attr "type" "other")
17621    (set_attr "length" "2")])
17622
17623 (define_insn "*rdtsc_rex64"
17624   [(set (match_operand:DI 0 "register_operand" "=a")
17625         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17626    (set (match_operand:DI 1 "register_operand" "=d")
17627         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17628   "TARGET_64BIT"
17629   "rdtsc"
17630   [(set_attr "type" "other")
17631    (set_attr "length" "2")])
17632
17633 (define_expand "rdtscp"
17634   [(match_operand:DI 0 "register_operand" "")
17635    (match_operand:SI 1 "memory_operand" "")]
17636   ""
17637 {
17638   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17639                                     gen_rtvec (1, const0_rtx),
17640                                     UNSPECV_RDTSCP);
17641   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17642                                     gen_rtvec (1, const0_rtx),
17643                                     UNSPECV_RDTSCP);
17644   rtx reg = gen_reg_rtx (DImode);
17645   rtx tmp = gen_reg_rtx (SImode);
17646
17647   if (TARGET_64BIT)
17648     {
17649       rtvec vec = rtvec_alloc (3);
17650       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17651       rtx upper = gen_reg_rtx (DImode);
17652       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17653       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17654       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17655       emit_insn (load);
17656       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17657                                    NULL, 1, OPTAB_DIRECT);
17658       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17659                                  OPTAB_DIRECT);
17660     }
17661   else
17662     {
17663       rtvec vec = rtvec_alloc (2);
17664       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17665       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17666       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17667       emit_insn (load);
17668     }
17669   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17670   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17671   DONE;
17672 })
17673
17674 (define_insn "*rdtscp"
17675   [(set (match_operand:DI 0 "register_operand" "=A")
17676         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17677    (set (match_operand:SI 1 "register_operand" "=c")
17678         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17679   "!TARGET_64BIT"
17680   "rdtscp"
17681   [(set_attr "type" "other")
17682    (set_attr "length" "3")])
17683
17684 (define_insn "*rdtscp_rex64"
17685   [(set (match_operand:DI 0 "register_operand" "=a")
17686         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17687    (set (match_operand:DI 1 "register_operand" "=d")
17688         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17689    (set (match_operand:SI 2 "register_operand" "=c")
17690         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17691   "TARGET_64BIT"
17692   "rdtscp"
17693   [(set_attr "type" "other")
17694    (set_attr "length" "3")])
17695
17696 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17697 ;;
17698 ;; LWP instructions
17699 ;;
17700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17701
17702 (define_expand "lwp_llwpcb"
17703   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17704                     UNSPECV_LLWP_INTRINSIC)]
17705   "TARGET_LWP")
17706
17707 (define_insn "*lwp_llwpcb<mode>1"
17708   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17709                     UNSPECV_LLWP_INTRINSIC)]
17710   "TARGET_LWP"
17711   "llwpcb\t%0"
17712   [(set_attr "type" "lwp")
17713    (set_attr "mode" "<MODE>")
17714    (set_attr "length" "5")])
17715
17716 (define_expand "lwp_slwpcb"
17717   [(set (match_operand 0 "register_operand" "=r")
17718         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17719   "TARGET_LWP"
17720 {
17721   rtx (*insn)(rtx);
17722
17723   insn = (TARGET_64BIT
17724           ? gen_lwp_slwpcbdi
17725           : gen_lwp_slwpcbsi);
17726
17727   emit_insn (insn (operands[0]));
17728   DONE;
17729 })
17730
17731 (define_insn "lwp_slwpcb<mode>"
17732   [(set (match_operand:P 0 "register_operand" "=r")
17733         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17734   "TARGET_LWP"
17735   "slwpcb\t%0"
17736   [(set_attr "type" "lwp")
17737    (set_attr "mode" "<MODE>")
17738    (set_attr "length" "5")])
17739
17740 (define_expand "lwp_lwpval<mode>3"
17741   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17742                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17743                      (match_operand:SI 3 "const_int_operand" "i")]
17744                     UNSPECV_LWPVAL_INTRINSIC)]
17745   "TARGET_LWP"
17746   "/* Avoid unused variable warning.  */
17747    (void) operand0;")
17748
17749 (define_insn "*lwp_lwpval<mode>3_1"
17750   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17751                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17752                      (match_operand:SI 2 "const_int_operand" "i")]
17753                     UNSPECV_LWPVAL_INTRINSIC)]
17754   "TARGET_LWP"
17755   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17756   [(set_attr "type" "lwp")
17757    (set_attr "mode" "<MODE>")
17758    (set (attr "length")
17759         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17760
17761 (define_expand "lwp_lwpins<mode>3"
17762   [(set (reg:CCC FLAGS_REG)
17763         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17764                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17765                               (match_operand:SI 3 "const_int_operand" "i")]
17766                              UNSPECV_LWPINS_INTRINSIC))
17767    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17768         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17769   "TARGET_LWP")
17770
17771 (define_insn "*lwp_lwpins<mode>3_1"
17772   [(set (reg:CCC FLAGS_REG)
17773         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17774                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17775                               (match_operand:SI 2 "const_int_operand" "i")]
17776                              UNSPECV_LWPINS_INTRINSIC))]
17777   "TARGET_LWP"
17778   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17779   [(set_attr "type" "lwp")
17780    (set_attr "mode" "<MODE>")
17781    (set (attr "length")
17782         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17783
17784 (define_insn "rdfsbase<mode>"
17785   [(set (match_operand:SWI48 0 "register_operand" "=r")
17786         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17787   "TARGET_64BIT && TARGET_FSGSBASE"
17788   "rdfsbase %0"
17789   [(set_attr "type" "other")
17790    (set_attr "prefix_extra" "2")])
17791
17792 (define_insn "rdgsbase<mode>"
17793   [(set (match_operand:SWI48 0 "register_operand" "=r")
17794         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17795   "TARGET_64BIT && TARGET_FSGSBASE"
17796   "rdgsbase %0"
17797   [(set_attr "type" "other")
17798    (set_attr "prefix_extra" "2")])
17799
17800 (define_insn "wrfsbase<mode>"
17801   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17802                     UNSPECV_WRFSBASE)]
17803   "TARGET_64BIT && TARGET_FSGSBASE"
17804   "wrfsbase %0"
17805   [(set_attr "type" "other")
17806    (set_attr "prefix_extra" "2")])
17807
17808 (define_insn "wrgsbase<mode>"
17809   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17810                     UNSPECV_WRGSBASE)]
17811   "TARGET_64BIT && TARGET_FSGSBASE"
17812   "wrgsbase %0"
17813   [(set_attr "type" "other")
17814    (set_attr "prefix_extra" "2")])
17815
17816 (define_insn "rdrand<mode>_1"
17817   [(set (match_operand:SWI248 0 "register_operand" "=r")
17818         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17819    (set (reg:CCC FLAGS_REG)
17820         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17821   "TARGET_RDRND"
17822   "rdrand\t%0"
17823   [(set_attr "type" "other")
17824    (set_attr "prefix_extra" "1")])
17825
17826 (define_expand "pause"
17827   [(set (match_dup 0)
17828         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17829   ""
17830 {
17831   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17832   MEM_VOLATILE_P (operands[0]) = 1;
17833 })
17834
17835 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17836 ;; They have the same encoding.
17837 (define_insn "*pause"
17838   [(set (match_operand:BLK 0 "" "")
17839         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17840   ""
17841   "rep; nop"
17842   [(set_attr "length" "2")
17843    (set_attr "memory" "unknown")])
17844
17845 (include "mmx.md")
17846 (include "sse.md")
17847 (include "sync.md")