OSDN Git Service

* config/i386/i386.md (*movdi_internal_rex64): Merge
[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,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 "i") (DI "e")])
865
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
868
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "iF") (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 "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 "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 "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 "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 \f
955 ;; Scheduling descriptions
956
957 (include "pentium.md")
958 (include "ppro.md")
959 (include "k6.md")
960 (include "athlon.md")
961 (include "bdver1.md")
962 (include "geode.md")
963 (include "atom.md")
964 (include "core2.md")
965
966 \f
967 ;; Operand and operator predicates and constraints
968
969 (include "predicates.md")
970 (include "constraints.md")
971
972 \f
973 ;; Compare and branch/compare and store instructions.
974
975 (define_expand "cbranch<mode>4"
976   [(set (reg:CC FLAGS_REG)
977         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978                     (match_operand:SDWIM 2 "<general_operand>" "")))
979    (set (pc) (if_then_else
980                (match_operator 0 "ordered_comparison_operator"
981                 [(reg:CC FLAGS_REG) (const_int 0)])
982                (label_ref (match_operand 3 "" ""))
983                (pc)))]
984   ""
985 {
986   if (MEM_P (operands[1]) && MEM_P (operands[2]))
987     operands[1] = force_reg (<MODE>mode, operands[1]);
988   ix86_expand_branch (GET_CODE (operands[0]),
989                       operands[1], operands[2], operands[3]);
990   DONE;
991 })
992
993 (define_expand "cstore<mode>4"
994   [(set (reg:CC FLAGS_REG)
995         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996                     (match_operand:SWIM 3 "<general_operand>" "")))
997    (set (match_operand:QI 0 "register_operand" "")
998         (match_operator 1 "ordered_comparison_operator"
999           [(reg:CC FLAGS_REG) (const_int 0)]))]
1000   ""
1001 {
1002   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003     operands[2] = force_reg (<MODE>mode, operands[2]);
1004   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005                      operands[2], operands[3]);
1006   DONE;
1007 })
1008
1009 (define_expand "cmp<mode>_1"
1010   [(set (reg:CC FLAGS_REG)
1011         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012                     (match_operand:SWI48 1 "<general_operand>" "")))])
1013
1014 (define_insn "*cmp<mode>_ccno_1"
1015   [(set (reg FLAGS_REG)
1016         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017                  (match_operand:SWI 1 "const0_operand" "")))]
1018   "ix86_match_ccmode (insn, CCNOmode)"
1019   "@
1020    test{<imodesuffix>}\t%0, %0
1021    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022   [(set_attr "type" "test,icmp")
1023    (set_attr "length_immediate" "0,1")
1024    (set_attr "mode" "<MODE>")])
1025
1026 (define_insn "*cmp<mode>_1"
1027   [(set (reg FLAGS_REG)
1028         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030   "ix86_match_ccmode (insn, CCmode)"
1031   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032   [(set_attr "type" "icmp")
1033    (set_attr "mode" "<MODE>")])
1034
1035 (define_insn "*cmp<mode>_minus_1"
1036   [(set (reg FLAGS_REG)
1037         (compare
1038           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1040           (const_int 0)))]
1041   "ix86_match_ccmode (insn, CCGOCmode)"
1042   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043   [(set_attr "type" "icmp")
1044    (set_attr "mode" "<MODE>")])
1045
1046 (define_insn "*cmpqi_ext_1"
1047   [(set (reg FLAGS_REG)
1048         (compare
1049           (match_operand:QI 0 "general_operand" "Qm")
1050           (subreg:QI
1051             (zero_extract:SI
1052               (match_operand 1 "ext_register_operand" "Q")
1053               (const_int 8)
1054               (const_int 8)) 0)))]
1055   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056   "cmp{b}\t{%h1, %0|%0, %h1}"
1057   [(set_attr "type" "icmp")
1058    (set_attr "mode" "QI")])
1059
1060 (define_insn "*cmpqi_ext_1_rex64"
1061   [(set (reg FLAGS_REG)
1062         (compare
1063           (match_operand:QI 0 "register_operand" "Q")
1064           (subreg:QI
1065             (zero_extract:SI
1066               (match_operand 1 "ext_register_operand" "Q")
1067               (const_int 8)
1068               (const_int 8)) 0)))]
1069   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070   "cmp{b}\t{%h1, %0|%0, %h1}"
1071   [(set_attr "type" "icmp")
1072    (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_2"
1075   [(set (reg FLAGS_REG)
1076         (compare
1077           (subreg:QI
1078             (zero_extract:SI
1079               (match_operand 0 "ext_register_operand" "Q")
1080               (const_int 8)
1081               (const_int 8)) 0)
1082           (match_operand:QI 1 "const0_operand" "")))]
1083   "ix86_match_ccmode (insn, CCNOmode)"
1084   "test{b}\t%h0, %h0"
1085   [(set_attr "type" "test")
1086    (set_attr "length_immediate" "0")
1087    (set_attr "mode" "QI")])
1088
1089 (define_expand "cmpqi_ext_3"
1090   [(set (reg:CC FLAGS_REG)
1091         (compare:CC
1092           (subreg:QI
1093             (zero_extract:SI
1094               (match_operand 0 "ext_register_operand" "")
1095               (const_int 8)
1096               (const_int 8)) 0)
1097           (match_operand:QI 1 "immediate_operand" "")))])
1098
1099 (define_insn "*cmpqi_ext_3_insn"
1100   [(set (reg FLAGS_REG)
1101         (compare
1102           (subreg:QI
1103             (zero_extract:SI
1104               (match_operand 0 "ext_register_operand" "Q")
1105               (const_int 8)
1106               (const_int 8)) 0)
1107           (match_operand:QI 1 "general_operand" "Qmn")))]
1108   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109   "cmp{b}\t{%1, %h0|%h0, %1}"
1110   [(set_attr "type" "icmp")
1111    (set_attr "modrm" "1")
1112    (set_attr "mode" "QI")])
1113
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115   [(set (reg FLAGS_REG)
1116         (compare
1117           (subreg:QI
1118             (zero_extract:SI
1119               (match_operand 0 "ext_register_operand" "Q")
1120               (const_int 8)
1121               (const_int 8)) 0)
1122           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124   "cmp{b}\t{%1, %h0|%h0, %1}"
1125   [(set_attr "type" "icmp")
1126    (set_attr "modrm" "1")
1127    (set_attr "mode" "QI")])
1128
1129 (define_insn "*cmpqi_ext_4"
1130   [(set (reg FLAGS_REG)
1131         (compare
1132           (subreg:QI
1133             (zero_extract:SI
1134               (match_operand 0 "ext_register_operand" "Q")
1135               (const_int 8)
1136               (const_int 8)) 0)
1137           (subreg:QI
1138             (zero_extract:SI
1139               (match_operand 1 "ext_register_operand" "Q")
1140               (const_int 8)
1141               (const_int 8)) 0)))]
1142   "ix86_match_ccmode (insn, CCmode)"
1143   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144   [(set_attr "type" "icmp")
1145    (set_attr "mode" "QI")])
1146
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares.  Which is what
1150 ;; the old patterns did, but with many more of them.
1151
1152 (define_expand "cbranchxf4"
1153   [(set (reg:CC FLAGS_REG)
1154         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155                     (match_operand:XF 2 "nonmemory_operand" "")))
1156    (set (pc) (if_then_else
1157               (match_operator 0 "ix86_fp_comparison_operator"
1158                [(reg:CC FLAGS_REG)
1159                 (const_int 0)])
1160               (label_ref (match_operand 3 "" ""))
1161               (pc)))]
1162   "TARGET_80387"
1163 {
1164   ix86_expand_branch (GET_CODE (operands[0]),
1165                       operands[1], operands[2], operands[3]);
1166   DONE;
1167 })
1168
1169 (define_expand "cstorexf4"
1170   [(set (reg:CC FLAGS_REG)
1171         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172                     (match_operand:XF 3 "nonmemory_operand" "")))
1173    (set (match_operand:QI 0 "register_operand" "")
1174               (match_operator 1 "ix86_fp_comparison_operator"
1175                [(reg:CC FLAGS_REG)
1176                 (const_int 0)]))]
1177   "TARGET_80387"
1178 {
1179   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180                      operands[2], operands[3]);
1181   DONE;
1182 })
1183
1184 (define_expand "cbranch<mode>4"
1185   [(set (reg:CC FLAGS_REG)
1186         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188    (set (pc) (if_then_else
1189               (match_operator 0 "ix86_fp_comparison_operator"
1190                [(reg:CC FLAGS_REG)
1191                 (const_int 0)])
1192               (label_ref (match_operand 3 "" ""))
1193               (pc)))]
1194   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1195 {
1196   ix86_expand_branch (GET_CODE (operands[0]),
1197                       operands[1], operands[2], operands[3]);
1198   DONE;
1199 })
1200
1201 (define_expand "cstore<mode>4"
1202   [(set (reg:CC FLAGS_REG)
1203         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205    (set (match_operand:QI 0 "register_operand" "")
1206               (match_operator 1 "ix86_fp_comparison_operator"
1207                [(reg:CC FLAGS_REG)
1208                 (const_int 0)]))]
1209   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1210 {
1211   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212                      operands[2], operands[3]);
1213   DONE;
1214 })
1215
1216 (define_expand "cbranchcc4"
1217   [(set (pc) (if_then_else
1218               (match_operator 0 "comparison_operator"
1219                [(match_operand 1 "flags_reg_operand" "")
1220                 (match_operand 2 "const0_operand" "")])
1221               (label_ref (match_operand 3 "" ""))
1222               (pc)))]
1223   ""
1224 {
1225   ix86_expand_branch (GET_CODE (operands[0]),
1226                       operands[1], operands[2], operands[3]);
1227   DONE;
1228 })
1229
1230 (define_expand "cstorecc4"
1231   [(set (match_operand:QI 0 "register_operand" "")
1232               (match_operator 1 "comparison_operator"
1233                [(match_operand 2 "flags_reg_operand" "")
1234                 (match_operand 3 "const0_operand" "")]))]
1235   ""
1236 {
1237   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238                      operands[2], operands[3]);
1239   DONE;
1240 })
1241
1242
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1245 ;;
1246 ;; CCFPmode     compare with exceptions
1247 ;; CCFPUmode    compare with no exceptions
1248
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1251
1252 (define_insn "*cmpfp_0"
1253   [(set (match_operand:HI 0 "register_operand" "=a")
1254         (unspec:HI
1255           [(compare:CCFP
1256              (match_operand 1 "register_operand" "f")
1257              (match_operand 2 "const0_operand" ""))]
1258         UNSPEC_FNSTSW))]
1259   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261   "* return output_fp_compare (insn, operands, false, false);"
1262   [(set_attr "type" "multi")
1263    (set_attr "unit" "i387")
1264    (set (attr "mode")
1265      (cond [(match_operand:SF 1 "" "")
1266               (const_string "SF")
1267             (match_operand:DF 1 "" "")
1268               (const_string "DF")
1269            ]
1270            (const_string "XF")))])
1271
1272 (define_insn_and_split "*cmpfp_0_cc"
1273   [(set (reg:CCFP FLAGS_REG)
1274         (compare:CCFP
1275           (match_operand 1 "register_operand" "f")
1276           (match_operand 2 "const0_operand" "")))
1277    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279    && TARGET_SAHF && !TARGET_CMOVE
1280    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1281   "#"
1282   "&& reload_completed"
1283   [(set (match_dup 0)
1284         (unspec:HI
1285           [(compare:CCFP (match_dup 1)(match_dup 2))]
1286         UNSPEC_FNSTSW))
1287    (set (reg:CC FLAGS_REG)
1288         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289   ""
1290   [(set_attr "type" "multi")
1291    (set_attr "unit" "i387")
1292    (set (attr "mode")
1293      (cond [(match_operand:SF 1 "" "")
1294               (const_string "SF")
1295             (match_operand:DF 1 "" "")
1296               (const_string "DF")
1297            ]
1298            (const_string "XF")))])
1299
1300 (define_insn "*cmpfp_xf"
1301   [(set (match_operand:HI 0 "register_operand" "=a")
1302         (unspec:HI
1303           [(compare:CCFP
1304              (match_operand:XF 1 "register_operand" "f")
1305              (match_operand:XF 2 "register_operand" "f"))]
1306           UNSPEC_FNSTSW))]
1307   "TARGET_80387"
1308   "* return output_fp_compare (insn, operands, false, false);"
1309   [(set_attr "type" "multi")
1310    (set_attr "unit" "i387")
1311    (set_attr "mode" "XF")])
1312
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314   [(set (reg:CCFP FLAGS_REG)
1315         (compare:CCFP
1316           (match_operand:XF 1 "register_operand" "f")
1317           (match_operand:XF 2 "register_operand" "f")))
1318    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319   "TARGET_80387
1320    && TARGET_SAHF && !TARGET_CMOVE"
1321   "#"
1322   "&& reload_completed"
1323   [(set (match_dup 0)
1324         (unspec:HI
1325           [(compare:CCFP (match_dup 1)(match_dup 2))]
1326         UNSPEC_FNSTSW))
1327    (set (reg:CC FLAGS_REG)
1328         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329   ""
1330   [(set_attr "type" "multi")
1331    (set_attr "unit" "i387")
1332    (set_attr "mode" "XF")])
1333
1334 (define_insn "*cmpfp_<mode>"
1335   [(set (match_operand:HI 0 "register_operand" "=a")
1336         (unspec:HI
1337           [(compare:CCFP
1338              (match_operand:MODEF 1 "register_operand" "f")
1339              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1340           UNSPEC_FNSTSW))]
1341   "TARGET_80387"
1342   "* return output_fp_compare (insn, operands, false, false);"
1343   [(set_attr "type" "multi")
1344    (set_attr "unit" "i387")
1345    (set_attr "mode" "<MODE>")])
1346
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348   [(set (reg:CCFP FLAGS_REG)
1349         (compare:CCFP
1350           (match_operand:MODEF 1 "register_operand" "f")
1351           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1353   "TARGET_80387
1354    && TARGET_SAHF && !TARGET_CMOVE"
1355   "#"
1356   "&& reload_completed"
1357   [(set (match_dup 0)
1358         (unspec:HI
1359           [(compare:CCFP (match_dup 1)(match_dup 2))]
1360         UNSPEC_FNSTSW))
1361    (set (reg:CC FLAGS_REG)
1362         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1363   ""
1364   [(set_attr "type" "multi")
1365    (set_attr "unit" "i387")
1366    (set_attr "mode" "<MODE>")])
1367
1368 (define_insn "*cmpfp_u"
1369   [(set (match_operand:HI 0 "register_operand" "=a")
1370         (unspec:HI
1371           [(compare:CCFPU
1372              (match_operand 1 "register_operand" "f")
1373              (match_operand 2 "register_operand" "f"))]
1374           UNSPEC_FNSTSW))]
1375   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377   "* return output_fp_compare (insn, operands, false, true);"
1378   [(set_attr "type" "multi")
1379    (set_attr "unit" "i387")
1380    (set (attr "mode")
1381      (cond [(match_operand:SF 1 "" "")
1382               (const_string "SF")
1383             (match_operand:DF 1 "" "")
1384               (const_string "DF")
1385            ]
1386            (const_string "XF")))])
1387
1388 (define_insn_and_split "*cmpfp_u_cc"
1389   [(set (reg:CCFPU FLAGS_REG)
1390         (compare:CCFPU
1391           (match_operand 1 "register_operand" "f")
1392           (match_operand 2 "register_operand" "f")))
1393    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395    && TARGET_SAHF && !TARGET_CMOVE
1396    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1397   "#"
1398   "&& reload_completed"
1399   [(set (match_dup 0)
1400         (unspec:HI
1401           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1402         UNSPEC_FNSTSW))
1403    (set (reg:CC FLAGS_REG)
1404         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1405   ""
1406   [(set_attr "type" "multi")
1407    (set_attr "unit" "i387")
1408    (set (attr "mode")
1409      (cond [(match_operand:SF 1 "" "")
1410               (const_string "SF")
1411             (match_operand:DF 1 "" "")
1412               (const_string "DF")
1413            ]
1414            (const_string "XF")))])
1415
1416 (define_insn "*cmpfp_<mode>"
1417   [(set (match_operand:HI 0 "register_operand" "=a")
1418         (unspec:HI
1419           [(compare:CCFP
1420              (match_operand 1 "register_operand" "f")
1421              (match_operator 3 "float_operator"
1422                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1423           UNSPEC_FNSTSW))]
1424   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427   "* return output_fp_compare (insn, operands, false, false);"
1428   [(set_attr "type" "multi")
1429    (set_attr "unit" "i387")
1430    (set_attr "fp_int_src" "true")
1431    (set_attr "mode" "<MODE>")])
1432
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434   [(set (reg:CCFP FLAGS_REG)
1435         (compare:CCFP
1436           (match_operand 1 "register_operand" "f")
1437           (match_operator 3 "float_operator"
1438             [(match_operand:SWI24 2 "memory_operand" "m")])))
1439    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441    && TARGET_SAHF && !TARGET_CMOVE
1442    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1444   "#"
1445   "&& reload_completed"
1446   [(set (match_dup 0)
1447         (unspec:HI
1448           [(compare:CCFP
1449              (match_dup 1)
1450              (match_op_dup 3 [(match_dup 2)]))]
1451         UNSPEC_FNSTSW))
1452    (set (reg:CC FLAGS_REG)
1453         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1454   ""
1455   [(set_attr "type" "multi")
1456    (set_attr "unit" "i387")
1457    (set_attr "fp_int_src" "true")
1458    (set_attr "mode" "<MODE>")])
1459
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1462
1463 (define_insn "x86_fnstsw_1"
1464   [(set (match_operand:HI 0 "register_operand" "=a")
1465         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1466   "TARGET_80387"
1467   "fnstsw\t%0"
1468   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469    (set_attr "mode" "SI")
1470    (set_attr "unit" "i387")])
1471
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1474
1475 (define_insn "x86_sahf_1"
1476   [(set (reg:CC FLAGS_REG)
1477         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1478                    UNSPEC_SAHF))]
1479   "TARGET_SAHF"
1480 {
1481 #ifndef HAVE_AS_IX86_SAHF
1482   if (TARGET_64BIT)
1483     return ASM_BYTE "0x9e";
1484   else
1485 #endif
1486   return "sahf";
1487 }
1488   [(set_attr "length" "1")
1489    (set_attr "athlon_decode" "vector")
1490    (set_attr "amdfam10_decode" "direct")
1491    (set_attr "bdver1_decode" "direct")
1492    (set_attr "mode" "SI")])
1493
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497   [(set (reg:CCFP FLAGS_REG)
1498         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500   "TARGET_MIX_SSE_I387
1501    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503   "* return output_fp_compare (insn, operands, true, false);"
1504   [(set_attr "type" "fcmp,ssecomi")
1505    (set_attr "prefix" "orig,maybe_vex")
1506    (set (attr "mode")
1507      (if_then_else (match_operand:SF 1 "" "")
1508         (const_string "SF")
1509         (const_string "DF")))
1510    (set (attr "prefix_rep")
1511         (if_then_else (eq_attr "type" "ssecomi")
1512                       (const_string "0")
1513                       (const_string "*")))
1514    (set (attr "prefix_data16")
1515         (cond [(eq_attr "type" "fcmp")
1516                  (const_string "*")
1517                (eq_attr "mode" "DF")
1518                  (const_string "1")
1519               ]
1520               (const_string "0")))
1521    (set_attr "athlon_decode" "vector")
1522    (set_attr "amdfam10_decode" "direct")
1523    (set_attr "bdver1_decode" "double")])
1524
1525 (define_insn "*cmpfp_i_sse"
1526   [(set (reg:CCFP FLAGS_REG)
1527         (compare:CCFP (match_operand 0 "register_operand" "x")
1528                       (match_operand 1 "nonimmediate_operand" "xm")))]
1529   "TARGET_SSE_MATH
1530    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532   "* return output_fp_compare (insn, operands, true, false);"
1533   [(set_attr "type" "ssecomi")
1534    (set_attr "prefix" "maybe_vex")
1535    (set (attr "mode")
1536      (if_then_else (match_operand:SF 1 "" "")
1537         (const_string "SF")
1538         (const_string "DF")))
1539    (set_attr "prefix_rep" "0")
1540    (set (attr "prefix_data16")
1541         (if_then_else (eq_attr "mode" "DF")
1542                       (const_string "1")
1543                       (const_string "0")))
1544    (set_attr "athlon_decode" "vector")
1545    (set_attr "amdfam10_decode" "direct")
1546    (set_attr "bdver1_decode" "double")])
1547
1548 (define_insn "*cmpfp_i_i387"
1549   [(set (reg:CCFP FLAGS_REG)
1550         (compare:CCFP (match_operand 0 "register_operand" "f")
1551                       (match_operand 1 "register_operand" "f")))]
1552   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1553    && TARGET_CMOVE
1554    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556   "* return output_fp_compare (insn, operands, true, false);"
1557   [(set_attr "type" "fcmp")
1558    (set (attr "mode")
1559      (cond [(match_operand:SF 1 "" "")
1560               (const_string "SF")
1561             (match_operand:DF 1 "" "")
1562               (const_string "DF")
1563            ]
1564            (const_string "XF")))
1565    (set_attr "athlon_decode" "vector")
1566    (set_attr "amdfam10_decode" "direct")
1567    (set_attr "bdver1_decode" "double")])
1568
1569 (define_insn "*cmpfp_iu_mixed"
1570   [(set (reg:CCFPU FLAGS_REG)
1571         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573   "TARGET_MIX_SSE_I387
1574    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576   "* return output_fp_compare (insn, operands, true, true);"
1577   [(set_attr "type" "fcmp,ssecomi")
1578    (set_attr "prefix" "orig,maybe_vex")
1579    (set (attr "mode")
1580      (if_then_else (match_operand:SF 1 "" "")
1581         (const_string "SF")
1582         (const_string "DF")))
1583    (set (attr "prefix_rep")
1584         (if_then_else (eq_attr "type" "ssecomi")
1585                       (const_string "0")
1586                       (const_string "*")))
1587    (set (attr "prefix_data16")
1588         (cond [(eq_attr "type" "fcmp")
1589                  (const_string "*")
1590                (eq_attr "mode" "DF")
1591                  (const_string "1")
1592               ]
1593               (const_string "0")))
1594    (set_attr "athlon_decode" "vector")
1595    (set_attr "amdfam10_decode" "direct")
1596    (set_attr "bdver1_decode" "double")])
1597
1598 (define_insn "*cmpfp_iu_sse"
1599   [(set (reg:CCFPU FLAGS_REG)
1600         (compare:CCFPU (match_operand 0 "register_operand" "x")
1601                        (match_operand 1 "nonimmediate_operand" "xm")))]
1602   "TARGET_SSE_MATH
1603    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605   "* return output_fp_compare (insn, operands, true, true);"
1606   [(set_attr "type" "ssecomi")
1607    (set_attr "prefix" "maybe_vex")
1608    (set (attr "mode")
1609      (if_then_else (match_operand:SF 1 "" "")
1610         (const_string "SF")
1611         (const_string "DF")))
1612    (set_attr "prefix_rep" "0")
1613    (set (attr "prefix_data16")
1614         (if_then_else (eq_attr "mode" "DF")
1615                       (const_string "1")
1616                       (const_string "0")))
1617    (set_attr "athlon_decode" "vector")
1618    (set_attr "amdfam10_decode" "direct")
1619    (set_attr "bdver1_decode" "double")])
1620
1621 (define_insn "*cmpfp_iu_387"
1622   [(set (reg:CCFPU FLAGS_REG)
1623         (compare:CCFPU (match_operand 0 "register_operand" "f")
1624                        (match_operand 1 "register_operand" "f")))]
1625   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1626    && TARGET_CMOVE
1627    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629   "* return output_fp_compare (insn, operands, true, true);"
1630   [(set_attr "type" "fcmp")
1631    (set (attr "mode")
1632      (cond [(match_operand:SF 1 "" "")
1633               (const_string "SF")
1634             (match_operand:DF 1 "" "")
1635               (const_string "DF")
1636            ]
1637            (const_string "XF")))
1638    (set_attr "athlon_decode" "vector")
1639    (set_attr "amdfam10_decode" "direct")
1640    (set_attr "bdver1_decode" "direct")])
1641 \f
1642 ;; Push/pop instructions.
1643
1644 (define_insn "*push<mode>2"
1645   [(set (match_operand:DWI 0 "push_operand" "=<")
1646         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1647   ""
1648   "#")
1649
1650 (define_split
1651   [(set (match_operand:TI 0 "push_operand" "")
1652         (match_operand:TI 1 "general_operand" ""))]
1653   "TARGET_64BIT && reload_completed
1654    && !SSE_REG_P (operands[1])"
1655   [(const_int 0)]
1656   "ix86_split_long_move (operands); DONE;")
1657
1658 (define_insn "*pushdi2_rex64"
1659   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1661   "TARGET_64BIT"
1662   "@
1663    push{q}\t%1
1664    #"
1665   [(set_attr "type" "push,multi")
1666    (set_attr "mode" "DI")])
1667
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it.  In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1672 (define_peephole2
1673   [(match_scratch:DI 2 "r")
1674    (set (match_operand:DI 0 "push_operand" "")
1675         (match_operand:DI 1 "immediate_operand" ""))]
1676   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677    && !x86_64_immediate_operand (operands[1], DImode)"
1678   [(set (match_dup 2) (match_dup 1))
1679    (set (match_dup 0) (match_dup 2))])
1680
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1684 (define_peephole2
1685   [(set (match_operand:DI 0 "push_operand" "")
1686         (match_operand:DI 1 "immediate_operand" ""))]
1687   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689   [(set (match_dup 0) (match_dup 1))
1690    (set (match_dup 2) (match_dup 3))]
1691 {
1692   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1693
1694   operands[1] = gen_lowpart (DImode, operands[2]);
1695   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1696                                                    GEN_INT (4)));
1697 })
1698
1699 (define_split
1700   [(set (match_operand:DI 0 "push_operand" "")
1701         (match_operand:DI 1 "immediate_operand" ""))]
1702   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703                     ? epilogue_completed : reload_completed)
1704    && !symbolic_operand (operands[1], DImode)
1705    && !x86_64_immediate_operand (operands[1], DImode)"
1706   [(set (match_dup 0) (match_dup 1))
1707    (set (match_dup 2) (match_dup 3))]
1708 {
1709   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1710
1711   operands[1] = gen_lowpart (DImode, operands[2]);
1712   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1713                                                    GEN_INT (4)));
1714 })
1715
1716 (define_split
1717   [(set (match_operand:DI 0 "push_operand" "")
1718         (match_operand:DI 1 "general_operand" ""))]
1719   "!TARGET_64BIT && reload_completed
1720    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1721   [(const_int 0)]
1722   "ix86_split_long_move (operands); DONE;")
1723
1724 (define_insn "*pushsi2"
1725   [(set (match_operand:SI 0 "push_operand" "=<")
1726         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1727   "!TARGET_64BIT"
1728   "push{l}\t%1"
1729   [(set_attr "type" "push")
1730    (set_attr "mode" "SI")])
1731
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word".  But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1735
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738   [(set (match_operand:SWI124 0 "push_operand" "=X")
1739         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1740   "TARGET_64BIT"
1741   "push{q}\t%q1"
1742   [(set_attr "type" "push")
1743    (set_attr "mode" "DI")])
1744
1745 (define_insn "*push<mode>2"
1746   [(set (match_operand:SWI12 0 "push_operand" "=X")
1747         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1748   "!TARGET_64BIT"
1749   "push{l}\t%k1"
1750   [(set_attr "type" "push")
1751    (set_attr "mode" "SI")])
1752
1753 (define_insn "*push<mode>2_prologue"
1754   [(set (match_operand:P 0 "push_operand" "=<")
1755         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756    (clobber (mem:BLK (scratch)))]
1757   ""
1758   "push{<imodesuffix>}\t%1"
1759   [(set_attr "type" "push")
1760    (set_attr "mode" "<MODE>")])
1761
1762 (define_insn "*pop<mode>1"
1763   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764         (match_operand:P 1 "pop_operand" ">"))]
1765   ""
1766   "pop{<imodesuffix>}\t%0"
1767   [(set_attr "type" "pop")
1768    (set_attr "mode" "<MODE>")])
1769
1770 (define_insn "*pop<mode>1_epilogue"
1771   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772         (match_operand:P 1 "pop_operand" ">"))
1773    (clobber (mem:BLK (scratch)))]
1774   ""
1775   "pop{<imodesuffix>}\t%0"
1776   [(set_attr "type" "pop")
1777    (set_attr "mode" "<MODE>")])
1778 \f
1779 ;; Move instructions.
1780
1781 (define_expand "movoi"
1782   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783         (match_operand:OI 1 "general_operand" ""))]
1784   "TARGET_AVX"
1785   "ix86_expand_move (OImode, operands); DONE;")
1786
1787 (define_expand "movti"
1788   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789         (match_operand:TI 1 "nonimmediate_operand" ""))]
1790   "TARGET_64BIT || TARGET_SSE"
1791 {
1792   if (TARGET_64BIT)
1793     ix86_expand_move (TImode, operands);
1794   else if (push_operand (operands[0], TImode))
1795     ix86_expand_push (TImode, operands[1]);
1796   else
1797     ix86_expand_vector_move (TImode, operands);
1798   DONE;
1799 })
1800
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern.  Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807         (match_operand:CDI 1 "general_operand" ""))]
1808   ""
1809 {
1810   if (push_operand (operands[0], CDImode))
1811     emit_move_complex_push (CDImode, operands[0], operands[1]);
1812   else
1813     emit_move_complex_parts (operands[0], operands[1]);
1814   DONE;
1815 })
1816
1817 (define_expand "mov<mode>"
1818   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819         (match_operand:SWI1248x 1 "general_operand" ""))]
1820   ""
1821   "ix86_expand_move (<MODE>mode, operands); DONE;")
1822
1823 (define_insn "*mov<mode>_xor"
1824   [(set (match_operand:SWI48 0 "register_operand" "=r")
1825         (match_operand:SWI48 1 "const0_operand" ""))
1826    (clobber (reg:CC FLAGS_REG))]
1827   "reload_completed"
1828   "xor{l}\t%k0, %k0"
1829   [(set_attr "type" "alu1")
1830    (set_attr "mode" "SI")
1831    (set_attr "length_immediate" "0")])
1832
1833 (define_insn "*mov<mode>_or"
1834   [(set (match_operand:SWI48 0 "register_operand" "=r")
1835         (match_operand:SWI48 1 "const_int_operand" ""))
1836    (clobber (reg:CC FLAGS_REG))]
1837   "reload_completed
1838    && operands[1] == constm1_rtx"
1839   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840   [(set_attr "type" "alu1")
1841    (set_attr "mode" "<MODE>")
1842    (set_attr "length_immediate" "1")])
1843
1844 (define_insn "*movoi_internal_avx"
1845   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1848 {
1849   switch (which_alternative)
1850     {
1851     case 0:
1852       return standard_sse_constant_opcode (insn, operands[1]);
1853     case 1:
1854     case 2:
1855       if (misaligned_operand (operands[0], OImode)
1856           || misaligned_operand (operands[1], OImode))
1857         return "vmovdqu\t{%1, %0|%0, %1}";
1858       else
1859         return "vmovdqa\t{%1, %0|%0, %1}";
1860     default:
1861       gcc_unreachable ();
1862     }
1863 }
1864   [(set_attr "type" "sselog1,ssemov,ssemov")
1865    (set_attr "prefix" "vex")
1866    (set_attr "mode" "OI")])
1867
1868 (define_insn "*movti_internal_rex64"
1869   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1872 {
1873   switch (which_alternative)
1874     {
1875     case 0:
1876     case 1:
1877       return "#";
1878     case 2:
1879       return standard_sse_constant_opcode (insn, operands[1]);
1880     case 3:
1881     case 4:
1882       /* TDmode values are passed as TImode on the stack.  Moving them
1883          to stack may result in unaligned memory access.  */
1884       if (misaligned_operand (operands[0], TImode)
1885           || misaligned_operand (operands[1], TImode))
1886         {
1887           if (get_attr_mode (insn) == MODE_V4SF)
1888             return "%vmovups\t{%1, %0|%0, %1}";
1889           else
1890             return "%vmovdqu\t{%1, %0|%0, %1}";
1891         }
1892       else
1893         {
1894           if (get_attr_mode (insn) == MODE_V4SF)
1895             return "%vmovaps\t{%1, %0|%0, %1}";
1896           else
1897             return "%vmovdqa\t{%1, %0|%0, %1}";
1898         }
1899     default:
1900       gcc_unreachable ();
1901     }
1902 }
1903   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1905    (set (attr "mode")
1906         (cond [(eq_attr "alternative" "2,3")
1907                  (if_then_else
1908                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1909                        (const_int 0))
1910                    (const_string "V4SF")
1911                    (const_string "TI"))
1912                (eq_attr "alternative" "4")
1913                  (if_then_else
1914                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1915                             (const_int 0))
1916                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917                             (const_int 0)))
1918                    (const_string "V4SF")
1919                    (const_string "TI"))]
1920                (const_string "DI")))])
1921
1922 (define_split
1923   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924         (match_operand:TI 1 "general_operand" ""))]
1925   "reload_completed
1926    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1927   [(const_int 0)]
1928   "ix86_split_long_move (operands); DONE;")
1929
1930 (define_insn "*movti_internal_sse"
1931   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933   "TARGET_SSE && !TARGET_64BIT
1934    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 {
1936   switch (which_alternative)
1937     {
1938     case 0:
1939       return standard_sse_constant_opcode (insn, operands[1]);
1940     case 1:
1941     case 2:
1942       /* TDmode values are passed as TImode on the stack.  Moving them
1943          to stack may result in unaligned memory access.  */
1944       if (misaligned_operand (operands[0], TImode)
1945           || misaligned_operand (operands[1], TImode))
1946         {
1947           if (get_attr_mode (insn) == MODE_V4SF)
1948             return "%vmovups\t{%1, %0|%0, %1}";
1949           else
1950             return "%vmovdqu\t{%1, %0|%0, %1}";
1951         }
1952       else
1953         {
1954           if (get_attr_mode (insn) == MODE_V4SF)
1955             return "%vmovaps\t{%1, %0|%0, %1}";
1956           else
1957             return "%vmovdqa\t{%1, %0|%0, %1}";
1958         }
1959     default:
1960       gcc_unreachable ();
1961     }
1962 }
1963   [(set_attr "type" "sselog1,ssemov,ssemov")
1964    (set_attr "prefix" "maybe_vex")
1965    (set (attr "mode")
1966         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1968                         (const_int 0)))
1969                  (const_string "V4SF")
1970                (and (eq_attr "alternative" "2")
1971                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1972                         (const_int 0)))
1973                  (const_string "V4SF")]
1974               (const_string "TI")))])
1975
1976 (define_insn "*movdi_internal_rex64"
1977   [(set (match_operand:DI 0 "nonimmediate_operand"
1978           "=r,r  ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1979         (match_operand:DI 1 "general_operand"
1980           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1981   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 {
1983   switch (get_attr_type (insn))
1984     {
1985     case TYPE_SSECVT:
1986       if (SSE_REG_P (operands[0]))
1987         return "movq2dq\t{%1, %0|%0, %1}";
1988       else
1989         return "movdq2q\t{%1, %0|%0, %1}";
1990
1991     case TYPE_SSEMOV:
1992       if (get_attr_mode (insn) == MODE_TI)
1993         return "%vmovdqa\t{%1, %0|%0, %1}";
1994       /* Handle broken assemblers that require movd instead of movq.  */
1995       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996         return "%vmovd\t{%1, %0|%0, %1}";
1997       else
1998         return "%vmovq\t{%1, %0|%0, %1}";
1999
2000     case TYPE_MMXMOV:
2001       /* Handle broken assemblers that require movd instead of movq.  */
2002       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003         return "movd\t{%1, %0|%0, %1}";
2004       else
2005         return "movq\t{%1, %0|%0, %1}";
2006
2007     case TYPE_SSELOG1:
2008       return standard_sse_constant_opcode (insn, operands[1]);
2009
2010     case TYPE_MMX:
2011       return "pxor\t%0, %0";
2012
2013     case TYPE_MULTI:
2014       return "#";
2015
2016     case TYPE_LEA:
2017       return "lea{q}\t{%a1, %0|%0, %a1}";
2018
2019     default:
2020       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021       if (get_attr_mode (insn) == MODE_SI)
2022         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023       else if (which_alternative == 2)
2024         return "movabs{q}\t{%1, %0|%0, %1}";
2025       else
2026         return "mov{q}\t{%1, %0|%0, %1}";
2027     }
2028 }
2029   [(set (attr "type")
2030      (cond [(eq_attr "alternative" "4")
2031               (const_string "multi")
2032             (eq_attr "alternative" "5")
2033               (const_string "mmx")
2034             (eq_attr "alternative" "6,7,8,9")
2035               (const_string "mmxmov")
2036             (eq_attr "alternative" "10")
2037               (const_string "sselog1")
2038             (eq_attr "alternative" "11,12,13,14,15")
2039               (const_string "ssemov")
2040             (eq_attr "alternative" "16,17")
2041               (const_string "ssecvt")
2042             (match_operand:DI 1 "pic_32bit_operand" "")
2043               (const_string "lea")
2044            ]
2045            (const_string "imov")))
2046    (set (attr "modrm")
2047      (if_then_else
2048        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2049          (const_string "0")
2050          (const_string "*")))
2051    (set (attr "length_immediate")
2052      (if_then_else
2053        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2054          (const_string "8")
2055          (const_string "*")))
2056    (set (attr "prefix_rex")
2057      (if_then_else (eq_attr "alternative" "8,9")
2058        (const_string "1")
2059        (const_string "*")))
2060    (set (attr "prefix_data16")
2061      (if_then_else (eq_attr "alternative" "11")
2062        (const_string "1")
2063        (const_string "*")))
2064    (set (attr "prefix")
2065      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2066        (const_string "maybe_vex")
2067        (const_string "orig")))
2068    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it.  In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))])
2081
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 (define_peephole2
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090   [(set (match_dup 2) (match_dup 3))
2091    (set (match_dup 4) (match_dup 5))]
2092   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2093
2094 (define_split
2095   [(set (match_operand:DI 0 "memory_operand" "")
2096         (match_operand:DI 1 "immediate_operand" ""))]
2097   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098                     ? epilogue_completed : reload_completed)
2099    && !symbolic_operand (operands[1], DImode)
2100    && !x86_64_immediate_operand (operands[1], DImode)"
2101   [(set (match_dup 2) (match_dup 3))
2102    (set (match_dup 4) (match_dup 5))]
2103   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2104
2105 (define_insn "*movdi_internal"
2106   [(set (match_operand:DI 0 "nonimmediate_operand"
2107           "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108         (match_operand:DI 1 "general_operand"
2109           "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2111 {
2112   switch (get_attr_type (insn))
2113     {
2114     case TYPE_SSECVT:
2115       if (SSE_REG_P (operands[0]))
2116         return "movq2dq\t{%1, %0|%0, %1}";
2117       else
2118         return "movdq2q\t{%1, %0|%0, %1}";
2119
2120     case TYPE_SSEMOV:
2121       switch (get_attr_mode (insn))
2122         {
2123         case MODE_TI:
2124           return "%vmovdqa\t{%1, %0|%0, %1}";
2125         case MODE_DI:
2126            return "%vmovq\t{%1, %0|%0, %1}";
2127         case MODE_V4SF:
2128           return "movaps\t{%1, %0|%0, %1}";
2129         case MODE_V2SF:
2130           return "movlps\t{%1, %0|%0, %1}";
2131         default:
2132           gcc_unreachable ();
2133         }
2134
2135     case TYPE_MMXMOV:
2136       return "movq\t{%1, %0|%0, %1}";
2137
2138     case TYPE_SSELOG1:
2139       return standard_sse_constant_opcode (insn, operands[1]);
2140
2141     case TYPE_MMX:
2142       return "pxor\t%0, %0";
2143
2144     case TYPE_MULTI:
2145       return "#";
2146
2147     default:
2148       gcc_unreachable ();
2149     }
2150 }
2151   [(set (attr "isa")
2152      (if_then_else (eq_attr "alternative" "9,10,11,12")
2153        (const_string "noavx")
2154        (const_string "base")))
2155    (set (attr "type")
2156      (cond [(eq_attr "alternative" "0,1")
2157               (const_string "multi")
2158             (eq_attr "alternative" "2")
2159               (const_string "mmx")
2160             (eq_attr "alternative" "3,4")
2161               (const_string "mmxmov")
2162             (eq_attr "alternative" "5,9")
2163               (const_string "sselog1")
2164             (eq_attr "alternative" "13,14")
2165               (const_string "ssecvt")
2166            ]
2167            (const_string "ssemov")))
2168    (set (attr "prefix")
2169      (if_then_else (eq_attr "alternative" "5,6,7,8")
2170        (const_string "maybe_vex")
2171        (const_string "orig")))
2172    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2173
2174 (define_split
2175   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176         (match_operand:DI 1 "general_operand" ""))]
2177   "!TARGET_64BIT && reload_completed
2178    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2180   [(const_int 0)]
2181   "ix86_split_long_move (operands); DONE;")
2182
2183 (define_insn "*movsi_internal"
2184   [(set (match_operand:SI 0 "nonimmediate_operand"
2185                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186         (match_operand:SI 1 "general_operand"
2187                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2188   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 {
2190   switch (get_attr_type (insn))
2191     {
2192     case TYPE_SSELOG1:
2193       return standard_sse_constant_opcode (insn, operands[1]);
2194
2195     case TYPE_SSEMOV:
2196       switch (get_attr_mode (insn))
2197         {
2198         case MODE_TI:
2199           return "%vmovdqa\t{%1, %0|%0, %1}";
2200         case MODE_V4SF:
2201           return "%vmovaps\t{%1, %0|%0, %1}";
2202         case MODE_SI:
2203           return "%vmovd\t{%1, %0|%0, %1}";
2204         case MODE_SF:
2205           return "%vmovss\t{%1, %0|%0, %1}";
2206         default:
2207           gcc_unreachable ();
2208         }
2209
2210     case TYPE_MMX:
2211       return "pxor\t%0, %0";
2212
2213     case TYPE_MMXMOV:
2214       if (get_attr_mode (insn) == MODE_DI)
2215         return "movq\t{%1, %0|%0, %1}";
2216       return "movd\t{%1, %0|%0, %1}";
2217
2218     case TYPE_LEA:
2219       return "lea{l}\t{%a1, %0|%0, %a1}";
2220
2221     default:
2222       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2223       return "mov{l}\t{%1, %0|%0, %1}";
2224     }
2225 }
2226   [(set (attr "type")
2227      (cond [(eq_attr "alternative" "2")
2228               (const_string "mmx")
2229             (eq_attr "alternative" "3,4,5")
2230               (const_string "mmxmov")
2231             (eq_attr "alternative" "6")
2232               (const_string "sselog1")
2233             (eq_attr "alternative" "7,8,9,10,11")
2234               (const_string "ssemov")
2235             (match_operand:DI 1 "pic_32bit_operand" "")
2236               (const_string "lea")
2237            ]
2238            (const_string "imov")))
2239    (set (attr "prefix")
2240      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241        (const_string "orig")
2242        (const_string "maybe_vex")))
2243    (set (attr "prefix_data16")
2244      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2245        (const_string "1")
2246        (const_string "*")))
2247    (set (attr "mode")
2248      (cond [(eq_attr "alternative" "2,3")
2249               (const_string "DI")
2250             (eq_attr "alternative" "6,7")
2251               (if_then_else
2252                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253                 (const_string "V4SF")
2254                 (const_string "TI"))
2255             (and (eq_attr "alternative" "8,9,10,11")
2256                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2257               (const_string "SF")
2258            ]
2259            (const_string "SI")))])
2260
2261 (define_insn "*movhi_internal"
2262   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2265 {
2266   switch (get_attr_type (insn))
2267     {
2268     case TYPE_IMOVX:
2269       /* movzwl is faster than movw on p2 due to partial word stalls,
2270          though not as fast as an aligned movl.  */
2271       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2272     default:
2273       if (get_attr_mode (insn) == MODE_SI)
2274         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2275       else
2276         return "mov{w}\t{%1, %0|%0, %1}";
2277     }
2278 }
2279   [(set (attr "type")
2280      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2281                 (const_int 0))
2282               (const_string "imov")
2283             (and (eq_attr "alternative" "0")
2284                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2285                           (const_int 0))
2286                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2287                           (const_int 0))))
2288               (const_string "imov")
2289             (and (eq_attr "alternative" "1,2")
2290                  (match_operand:HI 1 "aligned_operand" ""))
2291               (const_string "imov")
2292             (and (ne (symbol_ref "TARGET_MOVX")
2293                      (const_int 0))
2294                  (eq_attr "alternative" "0,2"))
2295               (const_string "imovx")
2296            ]
2297            (const_string "imov")))
2298     (set (attr "mode")
2299       (cond [(eq_attr "type" "imovx")
2300                (const_string "SI")
2301              (and (eq_attr "alternative" "1,2")
2302                   (match_operand:HI 1 "aligned_operand" ""))
2303                (const_string "SI")
2304              (and (eq_attr "alternative" "0")
2305                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2306                            (const_int 0))
2307                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2308                            (const_int 0))))
2309                (const_string "SI")
2310             ]
2311             (const_string "HI")))])
2312
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2318 ;; instruction).
2319 ;;
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there.  Then we use movzx.
2323 (define_insn "*movqi_internal"
2324   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2326   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2327 {
2328   switch (get_attr_type (insn))
2329     {
2330     case TYPE_IMOVX:
2331       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2333     default:
2334       if (get_attr_mode (insn) == MODE_SI)
2335         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2336       else
2337         return "mov{b}\t{%1, %0|%0, %1}";
2338     }
2339 }
2340   [(set (attr "type")
2341      (cond [(and (eq_attr "alternative" "5")
2342                  (not (match_operand:QI 1 "aligned_operand" "")))
2343               (const_string "imovx")
2344             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2345                 (const_int 0))
2346               (const_string "imov")
2347             (and (eq_attr "alternative" "3")
2348                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2349                           (const_int 0))
2350                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2351                           (const_int 0))))
2352               (const_string "imov")
2353             (eq_attr "alternative" "3,5")
2354               (const_string "imovx")
2355             (and (ne (symbol_ref "TARGET_MOVX")
2356                      (const_int 0))
2357                  (eq_attr "alternative" "2"))
2358               (const_string "imovx")
2359            ]
2360            (const_string "imov")))
2361    (set (attr "mode")
2362       (cond [(eq_attr "alternative" "3,4,5")
2363                (const_string "SI")
2364              (eq_attr "alternative" "6")
2365                (const_string "QI")
2366              (eq_attr "type" "imovx")
2367                (const_string "SI")
2368              (and (eq_attr "type" "imov")
2369                   (and (eq_attr "alternative" "0,1")
2370                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2371                                 (const_int 0))
2372                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2373                                      (const_int 0))
2374                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2375                                      (const_int 0))))))
2376                (const_string "SI")
2377              ;; Avoid partial register stalls when not using QImode arithmetic
2378              (and (eq_attr "type" "imov")
2379                   (and (eq_attr "alternative" "0,1")
2380                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2381                                 (const_int 0))
2382                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2383                                 (const_int 0)))))
2384                (const_string "SI")
2385            ]
2386            (const_string "QI")))])
2387
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2395   "@
2396    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398   [(set_attr "type" "imov")
2399    (set_attr "modrm" "0,*")
2400    (set_attr "length_address" "8,0")
2401    (set_attr "length_immediate" "0,*")
2402    (set_attr "memory" "store")
2403    (set_attr "mode" "<MODE>")])
2404
2405 (define_insn "*movabs<mode>_2"
2406   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2409   "@
2410    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412   [(set_attr "type" "imov")
2413    (set_attr "modrm" "0,*")
2414    (set_attr "length_address" "8,0")
2415    (set_attr "length_immediate" "0")
2416    (set_attr "memory" "load")
2417    (set_attr "mode" "<MODE>")])
2418
2419 (define_insn "*swap<mode>"
2420   [(set (match_operand:SWI48 0 "register_operand" "+r")
2421         (match_operand:SWI48 1 "register_operand" "+r"))
2422    (set (match_dup 1)
2423         (match_dup 0))]
2424   ""
2425   "xchg{<imodesuffix>}\t%1, %0"
2426   [(set_attr "type" "imov")
2427    (set_attr "mode" "<MODE>")
2428    (set_attr "pent_pair" "np")
2429    (set_attr "athlon_decode" "vector")
2430    (set_attr "amdfam10_decode" "double")
2431    (set_attr "bdver1_decode" "double")])
2432
2433 (define_insn "*swap<mode>_1"
2434   [(set (match_operand:SWI12 0 "register_operand" "+r")
2435         (match_operand:SWI12 1 "register_operand" "+r"))
2436    (set (match_dup 1)
2437         (match_dup 0))]
2438   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2439   "xchg{l}\t%k1, %k0"
2440   [(set_attr "type" "imov")
2441    (set_attr "mode" "SI")
2442    (set_attr "pent_pair" "np")
2443    (set_attr "athlon_decode" "vector")
2444    (set_attr "amdfam10_decode" "double")
2445    (set_attr "bdver1_decode" "double")])
2446
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451         (match_operand:SWI12 1 "register_operand" "+<r>"))
2452    (set (match_dup 1)
2453         (match_dup 0))]
2454   "TARGET_PARTIAL_REG_STALL"
2455   "xchg{<imodesuffix>}\t%1, %0"
2456   [(set_attr "type" "imov")
2457    (set_attr "mode" "<MODE>")
2458    (set_attr "pent_pair" "np")
2459    (set_attr "athlon_decode" "vector")])
2460
2461 (define_expand "movstrict<mode>"
2462   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463         (match_operand:SWI12 1 "general_operand" ""))]
2464   ""
2465 {
2466   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2467     FAIL;
2468   if (GET_CODE (operands[0]) == SUBREG
2469       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2470     FAIL;
2471   /* Don't generate memory->memory moves, go through a register */
2472   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473     operands[1] = force_reg (<MODE>mode, operands[1]);
2474 })
2475
2476 (define_insn "*movstrict<mode>_1"
2477   [(set (strict_low_part
2478           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483   [(set_attr "type" "imov")
2484    (set_attr "mode" "<MODE>")])
2485
2486 (define_insn "*movstrict<mode>_xor"
2487   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488         (match_operand:SWI12 1 "const0_operand" ""))
2489    (clobber (reg:CC FLAGS_REG))]
2490   "reload_completed"
2491   "xor{<imodesuffix>}\t%0, %0"
2492   [(set_attr "type" "alu1")
2493    (set_attr "mode" "<MODE>")
2494    (set_attr "length_immediate" "0")])
2495
2496 (define_insn "*mov<mode>_extv_1"
2497   [(set (match_operand:SWI24 0 "register_operand" "=R")
2498         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2499                             (const_int 8)
2500                             (const_int 8)))]
2501   ""
2502   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503   [(set_attr "type" "imovx")
2504    (set_attr "mode" "SI")])
2505
2506 (define_insn "*movqi_extv_1_rex64"
2507   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2509                          (const_int 8)
2510                          (const_int 8)))]
2511   "TARGET_64BIT"
2512 {
2513   switch (get_attr_type (insn))
2514     {
2515     case TYPE_IMOVX:
2516       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2517     default:
2518       return "mov{b}\t{%h1, %0|%0, %h1}";
2519     }
2520 }
2521   [(set (attr "type")
2522      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523                         (ne (symbol_ref "TARGET_MOVX")
2524                             (const_int 0)))
2525         (const_string "imovx")
2526         (const_string "imov")))
2527    (set (attr "mode")
2528      (if_then_else (eq_attr "type" "imovx")
2529         (const_string "SI")
2530         (const_string "QI")))])
2531
2532 (define_insn "*movqi_extv_1"
2533   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2535                          (const_int 8)
2536                          (const_int 8)))]
2537   "!TARGET_64BIT"
2538 {
2539   switch (get_attr_type (insn))
2540     {
2541     case TYPE_IMOVX:
2542       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2543     default:
2544       return "mov{b}\t{%h1, %0|%0, %h1}";
2545     }
2546 }
2547   [(set (attr "type")
2548      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550                              (ne (symbol_ref "TARGET_MOVX")
2551                                  (const_int 0))))
2552         (const_string "imovx")
2553         (const_string "imov")))
2554    (set (attr "mode")
2555      (if_then_else (eq_attr "type" "imovx")
2556         (const_string "SI")
2557         (const_string "QI")))])
2558
2559 (define_insn "*mov<mode>_extzv_1"
2560   [(set (match_operand:SWI48 0 "register_operand" "=R")
2561         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2562                             (const_int 8)
2563                             (const_int 8)))]
2564   ""
2565   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566   [(set_attr "type" "imovx")
2567    (set_attr "mode" "SI")])
2568
2569 (define_insn "*movqi_extzv_2_rex64"
2570   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2571         (subreg:QI
2572           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2573                            (const_int 8)
2574                            (const_int 8)) 0))]
2575   "TARGET_64BIT"
2576 {
2577   switch (get_attr_type (insn))
2578     {
2579     case TYPE_IMOVX:
2580       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2581     default:
2582       return "mov{b}\t{%h1, %0|%0, %h1}";
2583     }
2584 }
2585   [(set (attr "type")
2586      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587                         (ne (symbol_ref "TARGET_MOVX")
2588                             (const_int 0)))
2589         (const_string "imovx")
2590         (const_string "imov")))
2591    (set (attr "mode")
2592      (if_then_else (eq_attr "type" "imovx")
2593         (const_string "SI")
2594         (const_string "QI")))])
2595
2596 (define_insn "*movqi_extzv_2"
2597   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2598         (subreg:QI
2599           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2600                            (const_int 8)
2601                            (const_int 8)) 0))]
2602   "!TARGET_64BIT"
2603 {
2604   switch (get_attr_type (insn))
2605     {
2606     case TYPE_IMOVX:
2607       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2608     default:
2609       return "mov{b}\t{%h1, %0|%0, %h1}";
2610     }
2611 }
2612   [(set (attr "type")
2613      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615                              (ne (symbol_ref "TARGET_MOVX")
2616                                  (const_int 0))))
2617         (const_string "imovx")
2618         (const_string "imov")))
2619    (set (attr "mode")
2620      (if_then_else (eq_attr "type" "imovx")
2621         (const_string "SI")
2622         (const_string "QI")))])
2623
2624 (define_expand "mov<mode>_insv_1"
2625   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2626                             (const_int 8)
2627                             (const_int 8))
2628         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2629
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2632                              (const_int 8)
2633                              (const_int 8))
2634         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2635   "TARGET_64BIT"
2636   "mov{b}\t{%b1, %h0|%h0, %b1}"
2637   [(set_attr "type" "imov")
2638    (set_attr "mode" "QI")])
2639
2640 (define_insn "*movsi_insv_1"
2641   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2642                          (const_int 8)
2643                          (const_int 8))
2644         (match_operand:SI 1 "general_operand" "Qmn"))]
2645   "!TARGET_64BIT"
2646   "mov{b}\t{%b1, %h0|%h0, %b1}"
2647   [(set_attr "type" "imov")
2648    (set_attr "mode" "QI")])
2649
2650 (define_insn "*movqi_insv_2"
2651   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2652                          (const_int 8)
2653                          (const_int 8))
2654         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2655                      (const_int 8)))]
2656   ""
2657   "mov{b}\t{%h1, %h0|%h0, %h1}"
2658   [(set_attr "type" "imov")
2659    (set_attr "mode" "QI")])
2660 \f
2661 ;; Floating point push instructions.
2662
2663 (define_insn "*pushtf"
2664   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2666   "TARGET_SSE2"
2667 {
2668   /* This insn should be already split before reg-stack.  */
2669   gcc_unreachable ();
2670 }
2671   [(set_attr "type" "multi")
2672    (set_attr "unit" "sse,*,*")
2673    (set_attr "mode" "TF,SI,SI")])
2674
2675 ;; %%% Kill this when call knows how to work this out.
2676 (define_split
2677   [(set (match_operand:TF 0 "push_operand" "")
2678         (match_operand:TF 1 "sse_reg_operand" ""))]
2679   "TARGET_SSE2 && reload_completed"
2680   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2682
2683 (define_insn "*pushxf"
2684   [(set (match_operand:XF 0 "push_operand" "=<,<")
2685         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686   "optimize_function_for_speed_p (cfun)"
2687 {
2688   /* This insn should be already split before reg-stack.  */
2689   gcc_unreachable ();
2690 }
2691   [(set_attr "type" "multi")
2692    (set_attr "unit" "i387,*")
2693    (set_attr "mode" "XF,SI")])
2694
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2700
2701 (define_insn "*pushxf_nointeger"
2702   [(set (match_operand:XF 0 "push_operand" "=X,X")
2703         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704   "optimize_function_for_size_p (cfun)"
2705 {
2706   /* This insn should be already split before reg-stack.  */
2707   gcc_unreachable ();
2708 }
2709   [(set_attr "type" "multi")
2710    (set_attr "unit" "i387,*")
2711    (set_attr "mode" "XF,SI")])
2712
2713 ;; %%% Kill this when call knows how to work this out.
2714 (define_split
2715   [(set (match_operand:XF 0 "push_operand" "")
2716         (match_operand:XF 1 "fp_register_operand" ""))]
2717   "reload_completed"
2718   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2721
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2725
2726 (define_insn "*pushdf"
2727   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2729   ""
2730 {
2731   /* This insn should be already split before reg-stack.  */
2732   gcc_unreachable ();
2733 }
2734   [(set_attr "type" "multi")
2735    (set_attr "unit" "i387,*,*")
2736    (set_attr "mode" "DF,SI,DF")])
2737
2738 ;; %%% Kill this when call knows how to work this out.
2739 (define_split
2740   [(set (match_operand:DF 0 "push_operand" "")
2741         (match_operand:DF 1 "any_fp_register_operand" ""))]
2742   "reload_completed"
2743   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2745
2746 (define_insn "*pushsf_rex64"
2747   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2749   "TARGET_64BIT"
2750 {
2751   /* Anything else should be already split before reg-stack.  */
2752   gcc_assert (which_alternative == 1);
2753   return "push{q}\t%q1";
2754 }
2755   [(set_attr "type" "multi,push,multi")
2756    (set_attr "unit" "i387,*,*")
2757    (set_attr "mode" "SF,DI,SF")])
2758
2759 (define_insn "*pushsf"
2760   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2762   "!TARGET_64BIT"
2763 {
2764   /* Anything else should be already split before reg-stack.  */
2765   gcc_assert (which_alternative == 1);
2766   return "push{l}\t%1";
2767 }
2768   [(set_attr "type" "multi,push,multi")
2769    (set_attr "unit" "i387,*,*")
2770    (set_attr "mode" "SF,SI,SF")])
2771
2772 ;; %%% Kill this when call knows how to work this out.
2773 (define_split
2774   [(set (match_operand:SF 0 "push_operand" "")
2775         (match_operand:SF 1 "any_fp_register_operand" ""))]
2776   "reload_completed"
2777   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2780
2781 (define_split
2782   [(set (match_operand:SF 0 "push_operand" "")
2783         (match_operand:SF 1 "memory_operand" ""))]
2784   "reload_completed
2785    && (operands[2] = find_constant_src (insn))"
2786   [(set (match_dup 0) (match_dup 2))])
2787
2788 (define_split
2789   [(set (match_operand 0 "push_operand" "")
2790         (match_operand 1 "general_operand" ""))]
2791   "reload_completed
2792    && (GET_MODE (operands[0]) == TFmode
2793        || GET_MODE (operands[0]) == XFmode
2794        || GET_MODE (operands[0]) == DFmode)
2795    && !ANY_FP_REG_P (operands[1])"
2796   [(const_int 0)]
2797   "ix86_split_long_move (operands); DONE;")
2798 \f
2799 ;; Floating point move instructions.
2800
2801 (define_expand "movtf"
2802   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803         (match_operand:TF 1 "nonimmediate_operand" ""))]
2804   "TARGET_SSE2"
2805 {
2806   ix86_expand_move (TFmode, operands);
2807   DONE;
2808 })
2809
2810 (define_expand "mov<mode>"
2811   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812         (match_operand:X87MODEF 1 "general_operand" ""))]
2813   ""
2814   "ix86_expand_move (<MODE>mode, operands); DONE;")
2815
2816 (define_insn "*movtf_internal"
2817   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2819   "TARGET_SSE2
2820    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821    && (!can_create_pseudo_p ()
2822        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823        || GET_CODE (operands[1]) != CONST_DOUBLE
2824        || (optimize_function_for_size_p (cfun)
2825            && standard_sse_constant_p (operands[1])
2826            && !memory_operand (operands[0], TFmode))
2827        || (!TARGET_MEMORY_MISMATCH_STALL
2828            && memory_operand (operands[0], TFmode)))"
2829 {
2830   switch (which_alternative)
2831     {
2832     case 0:
2833     case 1:
2834       /* Handle misaligned load/store since we
2835          don't have movmisaligntf pattern. */
2836       if (misaligned_operand (operands[0], TFmode)
2837           || misaligned_operand (operands[1], TFmode))
2838         {
2839           if (get_attr_mode (insn) == MODE_V4SF)
2840             return "%vmovups\t{%1, %0|%0, %1}";
2841           else
2842             return "%vmovdqu\t{%1, %0|%0, %1}";
2843         }
2844       else
2845         {
2846           if (get_attr_mode (insn) == MODE_V4SF)
2847             return "%vmovaps\t{%1, %0|%0, %1}";
2848           else
2849             return "%vmovdqa\t{%1, %0|%0, %1}";
2850         }
2851
2852     case 2:
2853       return standard_sse_constant_opcode (insn, operands[1]);
2854
2855     case 3:
2856     case 4:
2857         return "#";
2858
2859     default:
2860       gcc_unreachable ();
2861     }
2862 }
2863   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2865    (set (attr "mode")
2866         (cond [(eq_attr "alternative" "0,2")
2867                  (if_then_else
2868                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2869                        (const_int 0))
2870                    (const_string "V4SF")
2871                    (const_string "TI"))
2872                (eq_attr "alternative" "1")
2873                  (if_then_else
2874                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2875                             (const_int 0))
2876                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2877                             (const_int 0)))
2878                    (const_string "V4SF")
2879                    (const_string "TI"))]
2880                (const_string "DI")))])
2881
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2886   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887    && (!can_create_pseudo_p ()
2888        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889        || GET_CODE (operands[1]) != CONST_DOUBLE
2890        || (optimize_function_for_size_p (cfun)
2891            && standard_80387_constant_p (operands[1]) > 0
2892            && !memory_operand (operands[0], XFmode))
2893        || (!TARGET_MEMORY_MISMATCH_STALL
2894            && memory_operand (operands[0], XFmode)))"
2895 {
2896   switch (which_alternative)
2897     {
2898     case 0:
2899     case 1:
2900       return output_387_reg_move (insn, operands);
2901
2902     case 2:
2903       return standard_80387_constant_opcode (operands[1]);
2904
2905     case 3:
2906     case 4:
2907       return "#";
2908
2909     default:
2910       gcc_unreachable ();
2911     }
2912 }
2913   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914    (set_attr "mode" "XF,XF,XF,SI,SI")])
2915
2916 (define_insn "*movdf_internal_rex64"
2917   [(set (match_operand:DF 0 "nonimmediate_operand"
2918                 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2919         (match_operand:DF 1 "general_operand"
2920                 "fm,f,G,rm,r ,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2921   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922    && (!can_create_pseudo_p ()
2923        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924        || GET_CODE (operands[1]) != CONST_DOUBLE
2925        || (optimize_function_for_size_p (cfun)
2926            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927                 && standard_80387_constant_p (operands[1]) > 0)
2928                || (TARGET_SSE2 && TARGET_SSE_MATH
2929                    && standard_sse_constant_p (operands[1]))))
2930        || memory_operand (operands[0], DFmode))"
2931 {
2932   switch (which_alternative)
2933     {
2934     case 0:
2935     case 1:
2936       return output_387_reg_move (insn, operands);
2937
2938     case 2:
2939       return standard_80387_constant_opcode (operands[1]);
2940
2941     case 3:
2942     case 4:
2943       return "mov{q}\t{%1, %0|%0, %1}";
2944
2945     case 5:
2946       return "movabs{q}\t{%1, %0|%0, %1}";
2947
2948     case 6:
2949       return "#";
2950
2951     case 7:
2952       return standard_sse_constant_opcode (insn, operands[1]);
2953
2954     case 8:
2955     case 9:
2956     case 10:
2957       switch (get_attr_mode (insn))
2958         {
2959         case MODE_V2DF:
2960           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961             return "%vmovapd\t{%1, %0|%0, %1}";
2962         case MODE_V4SF:
2963           return "%vmovaps\t{%1, %0|%0, %1}";
2964
2965         case MODE_DI:
2966           return "%vmovq\t{%1, %0|%0, %1}";
2967         case MODE_DF:
2968           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2969             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2970           return "%vmovsd\t{%1, %0|%0, %1}";
2971         case MODE_V1DF:
2972           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2973         case MODE_V2SF:
2974           return "%vmovlps\t{%1, %d0|%d0, %1}";
2975         default:
2976           gcc_unreachable ();
2977         }
2978
2979     case 11:
2980     case 12:
2981       /* Handle broken assemblers that require movd instead of movq.  */
2982       return "%vmovd\t{%1, %0|%0, %1}";
2983
2984     default:
2985       gcc_unreachable();
2986     }
2987 }
2988   [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2989    (set (attr "modrm")
2990      (if_then_else
2991        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2992          (const_string "0")
2993          (const_string "*")))
2994    (set (attr "length_immediate")
2995      (if_then_else
2996        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2997          (const_string "8")
2998          (const_string "*")))
2999    (set (attr "prefix")
3000      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3001        (const_string "orig")
3002        (const_string "maybe_vex")))
3003    (set (attr "prefix_data16")
3004      (if_then_else (eq_attr "mode" "V1DF")
3005        (const_string "1")
3006        (const_string "*")))
3007    (set (attr "mode")
3008         (cond [(eq_attr "alternative" "0,1,2")
3009                  (const_string "DF")
3010                (eq_attr "alternative" "3,4,5,6,11,12")
3011                  (const_string "DI")
3012
3013                /* xorps is one byte shorter.  */
3014                (eq_attr "alternative" "7")
3015                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3016                             (const_int 0))
3017                           (const_string "V4SF")
3018                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3019                             (const_int 0))
3020                           (const_string "TI")
3021                        ]
3022                        (const_string "V2DF"))
3023
3024                /* For architectures resolving dependencies on
3025                   whole SSE registers use APD move to break dependency
3026                   chains, otherwise use short move to avoid extra work.
3027
3028                   movaps encodes one byte shorter.  */
3029                (eq_attr "alternative" "8")
3030                  (cond
3031                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3032                         (const_int 0))
3033                       (const_string "V4SF")
3034                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3035                         (const_int 0))
3036                       (const_string "V2DF")
3037                    ]
3038                    (const_string "DF"))
3039                /* For architectures resolving dependencies on register
3040                   parts we may avoid extra work to zero out upper part
3041                   of register.  */
3042                (eq_attr "alternative" "9")
3043                  (if_then_else
3044                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3045                        (const_int 0))
3046                    (const_string "V1DF")
3047                    (const_string "DF"))
3048               ]
3049               (const_string "DF")))])
3050
3051 ;; Possible store forwarding (partial memory) stall in alternative 4.
3052 (define_insn "*movdf_internal"
3053   [(set (match_operand:DF 0 "nonimmediate_operand"
3054                 "=f,m,f,?Yd*r ,!o   ,Y2*x,Y2*x,Y2*x,m  ")
3055         (match_operand:DF 1 "general_operand"
3056                 "fm,f,G,Yd*roF,FYd*r,C   ,Y2*x,m   ,Y2*x"))]
3057   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3058    && (!can_create_pseudo_p ()
3059        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060        || GET_CODE (operands[1]) != CONST_DOUBLE
3061        || (optimize_function_for_size_p (cfun)
3062            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3063                 && standard_80387_constant_p (operands[1]) > 0)
3064                || (TARGET_SSE2 && TARGET_SSE_MATH
3065                    && standard_sse_constant_p (operands[1])))
3066            && !memory_operand (operands[0], DFmode))
3067        || (!TARGET_MEMORY_MISMATCH_STALL
3068            && memory_operand (operands[0], DFmode)))"
3069 {
3070   switch (which_alternative)
3071     {
3072     case 0:
3073     case 1:
3074       return output_387_reg_move (insn, operands);
3075
3076     case 2:
3077       return standard_80387_constant_opcode (operands[1]);
3078
3079     case 3:
3080     case 4:
3081       return "#";
3082
3083     case 5:
3084       return standard_sse_constant_opcode (insn, operands[1]);
3085
3086     case 6:
3087     case 7:
3088     case 8:
3089       switch (get_attr_mode (insn))
3090         {
3091         case MODE_V2DF:
3092           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093             return "%vmovapd\t{%1, %0|%0, %1}";
3094         case MODE_V4SF:
3095           return "%vmovaps\t{%1, %0|%0, %1}";
3096
3097         case MODE_DI:
3098           return "%vmovq\t{%1, %0|%0, %1}";
3099         case MODE_DF:
3100           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3101             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102           return "%vmovsd\t{%1, %0|%0, %1}";
3103         case MODE_V1DF:
3104           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3105         case MODE_V2SF:
3106           return "%vmovlps\t{%1, %d0|%d0, %1}";
3107         default:
3108           gcc_unreachable ();
3109         }
3110
3111     default:
3112       gcc_unreachable ();
3113     }
3114 }
3115   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116    (set (attr "prefix")
3117      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118        (const_string "orig")
3119        (const_string "maybe_vex")))
3120    (set (attr "prefix_data16")
3121      (if_then_else (eq_attr "mode" "V1DF")
3122        (const_string "1")
3123        (const_string "*")))
3124    (set (attr "mode")
3125         (cond [(eq_attr "alternative" "0,1,2")
3126                  (const_string "DF")
3127                (eq_attr "alternative" "3,4")
3128                  (const_string "SI")
3129
3130                /* For SSE1, we have many fewer alternatives.  */
3131                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3132                  (if_then_else
3133                    (eq_attr "alternative" "5,6")
3134                    (const_string "V4SF")
3135                    (const_string "V2SF"))
3136
3137                /* xorps is one byte shorter.  */
3138                (eq_attr "alternative" "5")
3139                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3140                             (const_int 0))
3141                           (const_string "V4SF")
3142                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3143                             (const_int 0))
3144                           (const_string "TI")
3145                        ]
3146                        (const_string "V2DF"))
3147
3148                /* For architectures resolving dependencies on
3149                   whole SSE registers use APD move to break dependency
3150                   chains, otherwise use short move to avoid extra work.
3151
3152                   movaps encodes one byte shorter.  */
3153                (eq_attr "alternative" "6")
3154                  (cond
3155                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3156                         (const_int 0))
3157                       (const_string "V4SF")
3158                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3159                         (const_int 0))
3160                       (const_string "V2DF")
3161                    ]
3162                    (const_string "DF"))
3163                /* For architectures resolving dependencies on register
3164                   parts we may avoid extra work to zero out upper part
3165                   of register.  */
3166                (eq_attr "alternative" "7")
3167                  (if_then_else
3168                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3169                        (const_int 0))
3170                    (const_string "V1DF")
3171                    (const_string "DF"))
3172               ]
3173               (const_string "DF")))])
3174
3175 (define_insn "*movsf_internal"
3176   [(set (match_operand:SF 0 "nonimmediate_operand"
3177           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178         (match_operand:SF 1 "general_operand"
3179           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3180   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181    && (!can_create_pseudo_p ()
3182        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183        || GET_CODE (operands[1]) != CONST_DOUBLE
3184        || (optimize_function_for_size_p (cfun)
3185            && ((!TARGET_SSE_MATH
3186                 && standard_80387_constant_p (operands[1]) > 0)
3187                || (TARGET_SSE_MATH
3188                    && standard_sse_constant_p (operands[1]))))
3189        || memory_operand (operands[0], SFmode))"
3190 {
3191   switch (which_alternative)
3192     {
3193     case 0:
3194     case 1:
3195       return output_387_reg_move (insn, operands);
3196
3197     case 2:
3198       return standard_80387_constant_opcode (operands[1]);
3199
3200     case 3:
3201     case 4:
3202       return "mov{l}\t{%1, %0|%0, %1}";
3203
3204     case 5:
3205       return standard_sse_constant_opcode (insn, operands[1]);
3206
3207     case 6:
3208       if (get_attr_mode (insn) == MODE_V4SF)
3209         return "%vmovaps\t{%1, %0|%0, %1}";
3210       if (TARGET_AVX)
3211         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3212
3213     case 7:
3214     case 8:
3215       return "%vmovss\t{%1, %0|%0, %1}";
3216
3217     case 9:
3218     case 10:
3219     case 14:
3220     case 15:
3221       return "movd\t{%1, %0|%0, %1}";
3222
3223     case 11:
3224       return "movq\t{%1, %0|%0, %1}";
3225
3226     case 12:
3227     case 13:
3228       return "%vmovd\t{%1, %0|%0, %1}";
3229
3230     default:
3231       gcc_unreachable ();
3232     }
3233 }
3234   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3235    (set (attr "prefix")
3236      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3237        (const_string "maybe_vex")
3238        (const_string "orig")))
3239    (set (attr "mode")
3240         (cond [(eq_attr "alternative" "3,4,9,10")
3241                  (const_string "SI")
3242                (eq_attr "alternative" "5")
3243                  (if_then_else
3244                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3245                                  (const_int 0))
3246                              (ne (symbol_ref "TARGET_SSE2")
3247                                  (const_int 0)))
3248                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3249                             (const_int 0)))
3250                    (const_string "TI")
3251                    (const_string "V4SF"))
3252                /* For architectures resolving dependencies on
3253                   whole SSE registers use APS move to break dependency
3254                   chains, otherwise use short move to avoid extra work.
3255
3256                   Do the same for architectures resolving dependencies on
3257                   the parts.  While in DF mode it is better to always handle
3258                   just register parts, the SF mode is different due to lack
3259                   of instructions to load just part of the register.  It is
3260                   better to maintain the whole registers in single format
3261                   to avoid problems on using packed logical operations.  */
3262                (eq_attr "alternative" "6")
3263                  (if_then_else
3264                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265                             (const_int 0))
3266                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3267                             (const_int 0)))
3268                    (const_string "V4SF")
3269                    (const_string "SF"))
3270                (eq_attr "alternative" "11")
3271                  (const_string "DI")]
3272                (const_string "SF")))])
3273
3274 (define_split
3275   [(set (match_operand 0 "any_fp_register_operand" "")
3276         (match_operand 1 "memory_operand" ""))]
3277   "reload_completed
3278    && (GET_MODE (operands[0]) == TFmode
3279        || GET_MODE (operands[0]) == XFmode
3280        || GET_MODE (operands[0]) == DFmode
3281        || GET_MODE (operands[0]) == SFmode)
3282    && (operands[2] = find_constant_src (insn))"
3283   [(set (match_dup 0) (match_dup 2))]
3284 {
3285   rtx c = operands[2];
3286   int r = REGNO (operands[0]);
3287
3288   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3290     FAIL;
3291 })
3292
3293 (define_split
3294   [(set (match_operand 0 "any_fp_register_operand" "")
3295         (float_extend (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    && (operands[2] = find_constant_src (insn))"
3301   [(set (match_dup 0) (match_dup 2))]
3302 {
3303   rtx c = operands[2];
3304   int r = REGNO (operands[0]);
3305
3306   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3308     FAIL;
3309 })
3310
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3312 (define_split
3313   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3315   "reload_completed
3316    && (standard_80387_constant_p (operands[1]) == 8
3317        || standard_80387_constant_p (operands[1]) == 9)"
3318   [(set (match_dup 0)(match_dup 1))
3319    (set (match_dup 0)
3320         (neg:X87MODEF (match_dup 0)))]
3321 {
3322   REAL_VALUE_TYPE r;
3323
3324   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325   if (real_isnegzero (&r))
3326     operands[1] = CONST0_RTX (<MODE>mode);
3327   else
3328     operands[1] = CONST1_RTX (<MODE>mode);
3329 })
3330
3331 (define_split
3332   [(set (match_operand 0 "nonimmediate_operand" "")
3333         (match_operand 1 "general_operand" ""))]
3334   "reload_completed
3335    && (GET_MODE (operands[0]) == TFmode
3336        || GET_MODE (operands[0]) == XFmode
3337        || GET_MODE (operands[0]) == DFmode)
3338    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3339   [(const_int 0)]
3340   "ix86_split_long_move (operands); DONE;")
3341
3342 (define_insn "swapxf"
3343   [(set (match_operand:XF 0 "register_operand" "+f")
3344         (match_operand:XF 1 "register_operand" "+f"))
3345    (set (match_dup 1)
3346         (match_dup 0))]
3347   "TARGET_80387"
3348 {
3349   if (STACK_TOP_P (operands[0]))
3350     return "fxch\t%1";
3351   else
3352     return "fxch\t%0";
3353 }
3354   [(set_attr "type" "fxch")
3355    (set_attr "mode" "XF")])
3356
3357 (define_insn "*swap<mode>"
3358   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3360    (set (match_dup 1)
3361         (match_dup 0))]
3362   "TARGET_80387 || reload_completed"
3363 {
3364   if (STACK_TOP_P (operands[0]))
3365     return "fxch\t%1";
3366   else
3367     return "fxch\t%0";
3368 }
3369   [(set_attr "type" "fxch")
3370    (set_attr "mode" "<MODE>")])
3371 \f
3372 ;; Zero extension instructions
3373
3374 (define_expand "zero_extendsidi2"
3375   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3377   ""
3378 {
3379   if (!TARGET_64BIT)
3380     {
3381       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3382       DONE;
3383     }
3384 })
3385
3386 (define_insn "*zero_extendsidi2_rex64"
3387   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3388         (zero_extend:DI
3389          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3390   "TARGET_64BIT"
3391   "@
3392    mov\t{%k1, %k0|%k0, %k1}
3393    #
3394    movd\t{%1, %0|%0, %1}
3395    movd\t{%1, %0|%0, %1}
3396    %vmovd\t{%1, %0|%0, %1}
3397    %vmovd\t{%1, %0|%0, %1}"
3398   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3399    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400    (set_attr "prefix_0f" "0,*,*,*,*,*")
3401    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3402
3403 (define_split
3404   [(set (match_operand:DI 0 "memory_operand" "")
3405         (zero_extend:DI (match_dup 0)))]
3406   "TARGET_64BIT"
3407   [(set (match_dup 4) (const_int 0))]
3408   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3409
3410 ;; %%% Kill me once multi-word ops are sane.
3411 (define_insn "zero_extendsidi2_1"
3412   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3413         (zero_extend:DI
3414          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3415    (clobber (reg:CC FLAGS_REG))]
3416   "!TARGET_64BIT"
3417   "@
3418    #
3419    #
3420    #
3421    movd\t{%1, %0|%0, %1}
3422    movd\t{%1, %0|%0, %1}
3423    %vmovd\t{%1, %0|%0, %1}
3424    %vmovd\t{%1, %0|%0, %1}"
3425   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3426    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3427    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3428
3429 (define_split
3430   [(set (match_operand:DI 0 "register_operand" "")
3431         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3432    (clobber (reg:CC FLAGS_REG))]
3433   "!TARGET_64BIT && reload_completed
3434    && true_regnum (operands[0]) == true_regnum (operands[1])"
3435   [(set (match_dup 4) (const_int 0))]
3436   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3437
3438 (define_split
3439   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3441    (clobber (reg:CC FLAGS_REG))]
3442   "!TARGET_64BIT && reload_completed
3443    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444   [(set (match_dup 3) (match_dup 1))
3445    (set (match_dup 4) (const_int 0))]
3446   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447
3448 (define_insn "zero_extend<mode>di2"
3449   [(set (match_operand:DI 0 "register_operand" "=r")
3450         (zero_extend:DI
3451          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3452   "TARGET_64BIT"
3453   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454   [(set_attr "type" "imovx")
3455    (set_attr "mode" "SI")])
3456
3457 (define_expand "zero_extendhisi2"
3458   [(set (match_operand:SI 0 "register_operand" "")
3459         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3460   ""
3461 {
3462   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3463     {
3464       operands[1] = force_reg (HImode, operands[1]);
3465       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3466       DONE;
3467     }
3468 })
3469
3470 (define_insn_and_split "zero_extendhisi2_and"
3471   [(set (match_operand:SI 0 "register_operand" "=r")
3472         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3473    (clobber (reg:CC FLAGS_REG))]
3474   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3475   "#"
3476   "&& reload_completed"
3477   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3478               (clobber (reg:CC FLAGS_REG))])]
3479   ""
3480   [(set_attr "type" "alu1")
3481    (set_attr "mode" "SI")])
3482
3483 (define_insn "*zero_extendhisi2_movzwl"
3484   [(set (match_operand:SI 0 "register_operand" "=r")
3485         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3486   "!TARGET_ZERO_EXTEND_WITH_AND
3487    || optimize_function_for_size_p (cfun)"
3488   "movz{wl|x}\t{%1, %0|%0, %1}"
3489   [(set_attr "type" "imovx")
3490    (set_attr "mode" "SI")])
3491
3492 (define_expand "zero_extendqi<mode>2"
3493   [(parallel
3494     [(set (match_operand:SWI24 0 "register_operand" "")
3495           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3496      (clobber (reg:CC FLAGS_REG))])])
3497
3498 (define_insn "*zero_extendqi<mode>2_and"
3499   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3500         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3501    (clobber (reg:CC FLAGS_REG))]
3502   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3503   "#"
3504   [(set_attr "type" "alu1")
3505    (set_attr "mode" "<MODE>")])
3506
3507 ;; When source and destination does not overlap, clear destination
3508 ;; first and then do the movb
3509 (define_split
3510   [(set (match_operand:SWI24 0 "register_operand" "")
3511         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512    (clobber (reg:CC FLAGS_REG))]
3513   "reload_completed
3514    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3515    && ANY_QI_REG_P (operands[0])
3516    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3517    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3518   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3519 {
3520   operands[2] = gen_lowpart (QImode, operands[0]);
3521   ix86_expand_clear (operands[0]);
3522 })
3523
3524 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3525   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3526         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527    (clobber (reg:CC FLAGS_REG))]
3528   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3529   "#"
3530   [(set_attr "type" "imovx,alu1")
3531    (set_attr "mode" "<MODE>")])
3532
3533 ;; For the movzbl case strip only the clobber
3534 (define_split
3535   [(set (match_operand:SWI24 0 "register_operand" "")
3536         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3537    (clobber (reg:CC FLAGS_REG))]
3538   "reload_completed
3539    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3540    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3541   [(set (match_dup 0)
3542         (zero_extend:SWI24 (match_dup 1)))])
3543
3544 ; zero extend to SImode to avoid partial register stalls
3545 (define_insn "*zero_extendqi<mode>2_movzbl"
3546   [(set (match_operand:SWI24 0 "register_operand" "=r")
3547         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3548   "reload_completed
3549    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3550   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3551   [(set_attr "type" "imovx")
3552    (set_attr "mode" "SI")])
3553
3554 ;; Rest is handled by single and.
3555 (define_split
3556   [(set (match_operand:SWI24 0 "register_operand" "")
3557         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3558    (clobber (reg:CC FLAGS_REG))]
3559   "reload_completed
3560    && true_regnum (operands[0]) == true_regnum (operands[1])"
3561   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3562               (clobber (reg:CC FLAGS_REG))])])
3563 \f
3564 ;; Sign extension instructions
3565
3566 (define_expand "extendsidi2"
3567   [(set (match_operand:DI 0 "register_operand" "")
3568         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3569   ""
3570 {
3571   if (!TARGET_64BIT)
3572     {
3573       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3574       DONE;
3575     }
3576 })
3577
3578 (define_insn "*extendsidi2_rex64"
3579   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3580         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3581   "TARGET_64BIT"
3582   "@
3583    {cltq|cdqe}
3584    movs{lq|x}\t{%1, %0|%0, %1}"
3585   [(set_attr "type" "imovx")
3586    (set_attr "mode" "DI")
3587    (set_attr "prefix_0f" "0")
3588    (set_attr "modrm" "0,1")])
3589
3590 (define_insn "extendsidi2_1"
3591   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3592         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3593    (clobber (reg:CC FLAGS_REG))
3594    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3595   "!TARGET_64BIT"
3596   "#")
3597
3598 ;; Extend to memory case when source register does die.
3599 (define_split
3600   [(set (match_operand:DI 0 "memory_operand" "")
3601         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3602    (clobber (reg:CC FLAGS_REG))
3603    (clobber (match_operand:SI 2 "register_operand" ""))]
3604   "(reload_completed
3605     && dead_or_set_p (insn, operands[1])
3606     && !reg_mentioned_p (operands[1], operands[0]))"
3607   [(set (match_dup 3) (match_dup 1))
3608    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3609               (clobber (reg:CC FLAGS_REG))])
3610    (set (match_dup 4) (match_dup 1))]
3611   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3612
3613 ;; Extend to memory case when source register does not die.
3614 (define_split
3615   [(set (match_operand:DI 0 "memory_operand" "")
3616         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617    (clobber (reg:CC FLAGS_REG))
3618    (clobber (match_operand:SI 2 "register_operand" ""))]
3619   "reload_completed"
3620   [(const_int 0)]
3621 {
3622   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3623
3624   emit_move_insn (operands[3], operands[1]);
3625
3626   /* Generate a cltd if possible and doing so it profitable.  */
3627   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3628       && true_regnum (operands[1]) == AX_REG
3629       && true_regnum (operands[2]) == DX_REG)
3630     {
3631       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3632     }
3633   else
3634     {
3635       emit_move_insn (operands[2], operands[1]);
3636       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3637     }
3638   emit_move_insn (operands[4], operands[2]);
3639   DONE;
3640 })
3641
3642 ;; Extend to register case.  Optimize case where source and destination
3643 ;; registers match and cases where we can use cltd.
3644 (define_split
3645   [(set (match_operand:DI 0 "register_operand" "")
3646         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3647    (clobber (reg:CC FLAGS_REG))
3648    (clobber (match_scratch:SI 2 ""))]
3649   "reload_completed"
3650   [(const_int 0)]
3651 {
3652   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3653
3654   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3655     emit_move_insn (operands[3], operands[1]);
3656
3657   /* Generate a cltd if possible and doing so it profitable.  */
3658   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3659       && true_regnum (operands[3]) == AX_REG
3660       && true_regnum (operands[4]) == DX_REG)
3661     {
3662       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3663       DONE;
3664     }
3665
3666   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3667     emit_move_insn (operands[4], operands[1]);
3668
3669   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3670   DONE;
3671 })
3672
3673 (define_insn "extend<mode>di2"
3674   [(set (match_operand:DI 0 "register_operand" "=r")
3675         (sign_extend:DI
3676          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3677   "TARGET_64BIT"
3678   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3679   [(set_attr "type" "imovx")
3680    (set_attr "mode" "DI")])
3681
3682 (define_insn "extendhisi2"
3683   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3684         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3685   ""
3686 {
3687   switch (get_attr_prefix_0f (insn))
3688     {
3689     case 0:
3690       return "{cwtl|cwde}";
3691     default:
3692       return "movs{wl|x}\t{%1, %0|%0, %1}";
3693     }
3694 }
3695   [(set_attr "type" "imovx")
3696    (set_attr "mode" "SI")
3697    (set (attr "prefix_0f")
3698      ;; movsx is short decodable while cwtl is vector decoded.
3699      (if_then_else (and (eq_attr "cpu" "!k6")
3700                         (eq_attr "alternative" "0"))
3701         (const_string "0")
3702         (const_string "1")))
3703    (set (attr "modrm")
3704      (if_then_else (eq_attr "prefix_0f" "0")
3705         (const_string "0")
3706         (const_string "1")))])
3707
3708 (define_insn "*extendhisi2_zext"
3709   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3710         (zero_extend:DI
3711          (sign_extend:SI
3712           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3713   "TARGET_64BIT"
3714 {
3715   switch (get_attr_prefix_0f (insn))
3716     {
3717     case 0:
3718       return "{cwtl|cwde}";
3719     default:
3720       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3721     }
3722 }
3723   [(set_attr "type" "imovx")
3724    (set_attr "mode" "SI")
3725    (set (attr "prefix_0f")
3726      ;; movsx is short decodable while cwtl is vector decoded.
3727      (if_then_else (and (eq_attr "cpu" "!k6")
3728                         (eq_attr "alternative" "0"))
3729         (const_string "0")
3730         (const_string "1")))
3731    (set (attr "modrm")
3732      (if_then_else (eq_attr "prefix_0f" "0")
3733         (const_string "0")
3734         (const_string "1")))])
3735
3736 (define_insn "extendqisi2"
3737   [(set (match_operand:SI 0 "register_operand" "=r")
3738         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739   ""
3740   "movs{bl|x}\t{%1, %0|%0, %1}"
3741    [(set_attr "type" "imovx")
3742     (set_attr "mode" "SI")])
3743
3744 (define_insn "*extendqisi2_zext"
3745   [(set (match_operand:DI 0 "register_operand" "=r")
3746         (zero_extend:DI
3747           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3748   "TARGET_64BIT"
3749   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3750    [(set_attr "type" "imovx")
3751     (set_attr "mode" "SI")])
3752
3753 (define_insn "extendqihi2"
3754   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3755         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3756   ""
3757 {
3758   switch (get_attr_prefix_0f (insn))
3759     {
3760     case 0:
3761       return "{cbtw|cbw}";
3762     default:
3763       return "movs{bw|x}\t{%1, %0|%0, %1}";
3764     }
3765 }
3766   [(set_attr "type" "imovx")
3767    (set_attr "mode" "HI")
3768    (set (attr "prefix_0f")
3769      ;; movsx is short decodable while cwtl is vector decoded.
3770      (if_then_else (and (eq_attr "cpu" "!k6")
3771                         (eq_attr "alternative" "0"))
3772         (const_string "0")
3773         (const_string "1")))
3774    (set (attr "modrm")
3775      (if_then_else (eq_attr "prefix_0f" "0")
3776         (const_string "0")
3777         (const_string "1")))])
3778 \f
3779 ;; Conversions between float and double.
3780
3781 ;; These are all no-ops in the model used for the 80387.
3782 ;; So just emit moves.
3783
3784 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3785 (define_split
3786   [(set (match_operand:DF 0 "push_operand" "")
3787         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3788   "reload_completed"
3789   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3790    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3791
3792 (define_split
3793   [(set (match_operand:XF 0 "push_operand" "")
3794         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3795   "reload_completed"
3796   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3797    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3798   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3799
3800 (define_expand "extendsfdf2"
3801   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3802         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3803   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3804 {
3805   /* ??? Needed for compress_float_constant since all fp constants
3806      are TARGET_LEGITIMATE_CONSTANT_P.  */
3807   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3808     {
3809       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3810           && standard_80387_constant_p (operands[1]) > 0)
3811         {
3812           operands[1] = simplify_const_unary_operation
3813             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3814           emit_move_insn_1 (operands[0], operands[1]);
3815           DONE;
3816         }
3817       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3818     }
3819 })
3820
3821 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3822    cvtss2sd:
3823       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3824       cvtps2pd xmm2,xmm1
3825    We do the conversion post reload to avoid producing of 128bit spills
3826    that might lead to ICE on 32bit target.  The sequence unlikely combine
3827    anyway.  */
3828 (define_split
3829   [(set (match_operand:DF 0 "register_operand" "")
3830         (float_extend:DF
3831           (match_operand:SF 1 "nonimmediate_operand" "")))]
3832   "TARGET_USE_VECTOR_FP_CONVERTS
3833    && optimize_insn_for_speed_p ()
3834    && reload_completed && SSE_REG_P (operands[0])"
3835    [(set (match_dup 2)
3836          (float_extend:V2DF
3837            (vec_select:V2SF
3838              (match_dup 3)
3839              (parallel [(const_int 0) (const_int 1)]))))]
3840 {
3841   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3842   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3843   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3844      Try to avoid move when unpacking can be done in source.  */
3845   if (REG_P (operands[1]))
3846     {
3847       /* If it is unsafe to overwrite upper half of source, we need
3848          to move to destination and unpack there.  */
3849       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3850            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3851           && true_regnum (operands[0]) != true_regnum (operands[1]))
3852         {
3853           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3854           emit_move_insn (tmp, operands[1]);
3855         }
3856       else
3857         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3858       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3859                                              operands[3]));
3860     }
3861   else
3862     emit_insn (gen_vec_setv4sf_0 (operands[3],
3863                                   CONST0_RTX (V4SFmode), operands[1]));
3864 })
3865
3866 (define_insn "*extendsfdf2_mixed"
3867   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3868         (float_extend:DF
3869           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3870   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3871 {
3872   switch (which_alternative)
3873     {
3874     case 0:
3875     case 1:
3876       return output_387_reg_move (insn, operands);
3877
3878     case 2:
3879       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3880
3881     default:
3882       gcc_unreachable ();
3883     }
3884 }
3885   [(set_attr "type" "fmov,fmov,ssecvt")
3886    (set_attr "prefix" "orig,orig,maybe_vex")
3887    (set_attr "mode" "SF,XF,DF")])
3888
3889 (define_insn "*extendsfdf2_sse"
3890   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3891         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3892   "TARGET_SSE2 && TARGET_SSE_MATH"
3893   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3894   [(set_attr "type" "ssecvt")
3895    (set_attr "prefix" "maybe_vex")
3896    (set_attr "mode" "DF")])
3897
3898 (define_insn "*extendsfdf2_i387"
3899   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3900         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3901   "TARGET_80387"
3902   "* return output_387_reg_move (insn, operands);"
3903   [(set_attr "type" "fmov")
3904    (set_attr "mode" "SF,XF")])
3905
3906 (define_expand "extend<mode>xf2"
3907   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3908         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3909   "TARGET_80387"
3910 {
3911   /* ??? Needed for compress_float_constant since all fp constants
3912      are TARGET_LEGITIMATE_CONSTANT_P.  */
3913   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3914     {
3915       if (standard_80387_constant_p (operands[1]) > 0)
3916         {
3917           operands[1] = simplify_const_unary_operation
3918             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3919           emit_move_insn_1 (operands[0], operands[1]);
3920           DONE;
3921         }
3922       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3923     }
3924 })
3925
3926 (define_insn "*extend<mode>xf2_i387"
3927   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3928         (float_extend:XF
3929           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3930   "TARGET_80387"
3931   "* return output_387_reg_move (insn, operands);"
3932   [(set_attr "type" "fmov")
3933    (set_attr "mode" "<MODE>,XF")])
3934
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case.  Otherwise this is just like a simple move
3938 ;; insn.  So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3940
3941 ;; Conversion from DFmode to SFmode.
3942
3943 (define_expand "truncdfsf2"
3944   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3945         (float_truncate:SF
3946           (match_operand:DF 1 "nonimmediate_operand" "")))]
3947   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 {
3949   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950     ;
3951   else if (flag_unsafe_math_optimizations)
3952     ;
3953   else
3954     {
3955       enum ix86_stack_slot slot = (virtuals_instantiated
3956                                    ? SLOT_TEMP
3957                                    : SLOT_VIRTUAL);
3958       rtx temp = assign_386_stack_local (SFmode, slot);
3959       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3960       DONE;
3961     }
3962 })
3963
3964 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3965    cvtsd2ss:
3966       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3967       cvtpd2ps xmm2,xmm1
3968    We do the conversion post reload to avoid producing of 128bit spills
3969    that might lead to ICE on 32bit target.  The sequence unlikely combine
3970    anyway.  */
3971 (define_split
3972   [(set (match_operand:SF 0 "register_operand" "")
3973         (float_truncate:SF
3974           (match_operand:DF 1 "nonimmediate_operand" "")))]
3975   "TARGET_USE_VECTOR_FP_CONVERTS
3976    && optimize_insn_for_speed_p ()
3977    && reload_completed && SSE_REG_P (operands[0])"
3978    [(set (match_dup 2)
3979          (vec_concat:V4SF
3980            (float_truncate:V2SF
3981              (match_dup 4))
3982            (match_dup 3)))]
3983 {
3984   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3985   operands[3] = CONST0_RTX (V2SFmode);
3986   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3987   /* Use movsd for loading from memory, unpcklpd for registers.
3988      Try to avoid move when unpacking can be done in source, or SSE3
3989      movddup is available.  */
3990   if (REG_P (operands[1]))
3991     {
3992       if (!TARGET_SSE3
3993           && true_regnum (operands[0]) != true_regnum (operands[1])
3994           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3995               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3996         {
3997           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3998           emit_move_insn (tmp, operands[1]);
3999           operands[1] = tmp;
4000         }
4001       else if (!TARGET_SSE3)
4002         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4003       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4004     }
4005   else
4006     emit_insn (gen_sse2_loadlpd (operands[4],
4007                                  CONST0_RTX (V2DFmode), operands[1]));
4008 })
4009
4010 (define_expand "truncdfsf2_with_temp"
4011   [(parallel [(set (match_operand:SF 0 "" "")
4012                    (float_truncate:SF (match_operand:DF 1 "" "")))
4013               (clobber (match_operand:SF 2 "" ""))])])
4014
4015 (define_insn "*truncdfsf_fast_mixed"
4016   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4017         (float_truncate:SF
4018           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4019   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4020 {
4021   switch (which_alternative)
4022     {
4023     case 0:
4024       return output_387_reg_move (insn, operands);
4025     case 1:
4026       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4027     default:
4028       gcc_unreachable ();
4029     }
4030 }
4031   [(set_attr "type" "fmov,ssecvt")
4032    (set_attr "prefix" "orig,maybe_vex")
4033    (set_attr "mode" "SF")])
4034
4035 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4036 ;; because nothing we do here is unsafe.
4037 (define_insn "*truncdfsf_fast_sse"
4038   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4039         (float_truncate:SF
4040           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4041   "TARGET_SSE2 && TARGET_SSE_MATH"
4042   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4043   [(set_attr "type" "ssecvt")
4044    (set_attr "prefix" "maybe_vex")
4045    (set_attr "mode" "SF")])
4046
4047 (define_insn "*truncdfsf_fast_i387"
4048   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4049         (float_truncate:SF
4050           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4051   "TARGET_80387 && flag_unsafe_math_optimizations"
4052   "* return output_387_reg_move (insn, operands);"
4053   [(set_attr "type" "fmov")
4054    (set_attr "mode" "SF")])
4055
4056 (define_insn "*truncdfsf_mixed"
4057   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4058         (float_truncate:SF
4059           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4060    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4061   "TARGET_MIX_SSE_I387"
4062 {
4063   switch (which_alternative)
4064     {
4065     case 0:
4066       return output_387_reg_move (insn, operands);
4067     case 1:
4068       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4069
4070     default:
4071       return "#";
4072     }
4073 }
4074   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075    (set_attr "unit" "*,*,i387,i387,i387")
4076    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077    (set_attr "mode" "SF")])
4078
4079 (define_insn "*truncdfsf_i387"
4080   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4081         (float_truncate:SF
4082           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4084   "TARGET_80387"
4085 {
4086   switch (which_alternative)
4087     {
4088     case 0:
4089       return output_387_reg_move (insn, operands);
4090
4091     default:
4092       return "#";
4093     }
4094 }
4095   [(set_attr "type" "fmov,multi,multi,multi")
4096    (set_attr "unit" "*,i387,i387,i387")
4097    (set_attr "mode" "SF")])
4098
4099 (define_insn "*truncdfsf2_i387_1"
4100   [(set (match_operand:SF 0 "memory_operand" "=m")
4101         (float_truncate:SF
4102           (match_operand:DF 1 "register_operand" "f")))]
4103   "TARGET_80387
4104    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105    && !TARGET_MIX_SSE_I387"
4106   "* return output_387_reg_move (insn, operands);"
4107   [(set_attr "type" "fmov")
4108    (set_attr "mode" "SF")])
4109
4110 (define_split
4111   [(set (match_operand:SF 0 "register_operand" "")
4112         (float_truncate:SF
4113          (match_operand:DF 1 "fp_register_operand" "")))
4114    (clobber (match_operand 2 "" ""))]
4115   "reload_completed"
4116   [(set (match_dup 2) (match_dup 1))
4117    (set (match_dup 0) (match_dup 2))]
4118   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4119
4120 ;; Conversion from XFmode to {SF,DF}mode
4121
4122 (define_expand "truncxf<mode>2"
4123   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124                    (float_truncate:MODEF
4125                      (match_operand:XF 1 "register_operand" "")))
4126               (clobber (match_dup 2))])]
4127   "TARGET_80387"
4128 {
4129   if (flag_unsafe_math_optimizations)
4130     {
4131       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133       if (reg != operands[0])
4134         emit_move_insn (operands[0], reg);
4135       DONE;
4136     }
4137   else
4138     {
4139       enum ix86_stack_slot slot = (virtuals_instantiated
4140                                    ? SLOT_TEMP
4141                                    : SLOT_VIRTUAL);
4142       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4143     }
4144 })
4145
4146 (define_insn "*truncxfsf2_mixed"
4147   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4148         (float_truncate:SF
4149           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4150    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4151   "TARGET_80387"
4152 {
4153   gcc_assert (!which_alternative);
4154   return output_387_reg_move (insn, operands);
4155 }
4156   [(set_attr "type" "fmov,multi,multi,multi")
4157    (set_attr "unit" "*,i387,i387,i387")
4158    (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncxfdf2_mixed"
4161   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4162         (float_truncate:DF
4163           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4164    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4165   "TARGET_80387"
4166 {
4167   gcc_assert (!which_alternative);
4168   return output_387_reg_move (insn, operands);
4169 }
4170   [(set_attr "type" "fmov,multi,multi,multi")
4171    (set_attr "unit" "*,i387,i387,i387")
4172    (set_attr "mode" "DF")])
4173
4174 (define_insn "truncxf<mode>2_i387_noop"
4175   [(set (match_operand:MODEF 0 "register_operand" "=f")
4176         (float_truncate:MODEF
4177           (match_operand:XF 1 "register_operand" "f")))]
4178   "TARGET_80387 && flag_unsafe_math_optimizations"
4179   "* return output_387_reg_move (insn, operands);"
4180   [(set_attr "type" "fmov")
4181    (set_attr "mode" "<MODE>")])
4182
4183 (define_insn "*truncxf<mode>2_i387"
4184   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4185         (float_truncate:MODEF
4186           (match_operand:XF 1 "register_operand" "f")))]
4187   "TARGET_80387"
4188   "* return output_387_reg_move (insn, operands);"
4189   [(set_attr "type" "fmov")
4190    (set_attr "mode" "<MODE>")])
4191
4192 (define_split
4193   [(set (match_operand:MODEF 0 "register_operand" "")
4194         (float_truncate:MODEF
4195           (match_operand:XF 1 "register_operand" "")))
4196    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4197   "TARGET_80387 && reload_completed"
4198   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4199    (set (match_dup 0) (match_dup 2))])
4200
4201 (define_split
4202   [(set (match_operand:MODEF 0 "memory_operand" "")
4203         (float_truncate:MODEF
4204           (match_operand:XF 1 "register_operand" "")))
4205    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4206   "TARGET_80387"
4207   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4208 \f
4209 ;; Signed conversion to DImode.
4210
4211 (define_expand "fix_truncxfdi2"
4212   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4214               (clobber (reg:CC FLAGS_REG))])]
4215   "TARGET_80387"
4216 {
4217   if (TARGET_FISTTP)
4218    {
4219      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4220      DONE;
4221    }
4222 })
4223
4224 (define_expand "fix_trunc<mode>di2"
4225   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4227               (clobber (reg:CC FLAGS_REG))])]
4228   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4229 {
4230   if (TARGET_FISTTP
4231       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4232    {
4233      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4234      DONE;
4235    }
4236   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4237    {
4238      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4239      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4240      if (out != operands[0])
4241         emit_move_insn (operands[0], out);
4242      DONE;
4243    }
4244 })
4245
4246 ;; Signed conversion to SImode.
4247
4248 (define_expand "fix_truncxfsi2"
4249   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4250                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4251               (clobber (reg:CC FLAGS_REG))])]
4252   "TARGET_80387"
4253 {
4254   if (TARGET_FISTTP)
4255    {
4256      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4257      DONE;
4258    }
4259 })
4260
4261 (define_expand "fix_trunc<mode>si2"
4262   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4263                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4264               (clobber (reg:CC FLAGS_REG))])]
4265   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4266 {
4267   if (TARGET_FISTTP
4268       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4269    {
4270      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4271      DONE;
4272    }
4273   if (SSE_FLOAT_MODE_P (<MODE>mode))
4274    {
4275      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4276      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4277      if (out != operands[0])
4278         emit_move_insn (operands[0], out);
4279      DONE;
4280    }
4281 })
4282
4283 ;; Signed conversion to HImode.
4284
4285 (define_expand "fix_trunc<mode>hi2"
4286   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4287                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4288               (clobber (reg:CC FLAGS_REG))])]
4289   "TARGET_80387
4290    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4291 {
4292   if (TARGET_FISTTP)
4293    {
4294      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4295      DONE;
4296    }
4297 })
4298
4299 ;; Unsigned conversion to SImode.
4300
4301 (define_expand "fixuns_trunc<mode>si2"
4302   [(parallel
4303     [(set (match_operand:SI 0 "register_operand" "")
4304           (unsigned_fix:SI
4305             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4306      (use (match_dup 2))
4307      (clobber (match_scratch:<ssevecmode> 3 ""))
4308      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4309   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4310 {
4311   enum machine_mode mode = <MODE>mode;
4312   enum machine_mode vecmode = <ssevecmode>mode;
4313   REAL_VALUE_TYPE TWO31r;
4314   rtx two31;
4315
4316   if (optimize_insn_for_size_p ())
4317     FAIL;
4318
4319   real_ldexp (&TWO31r, &dconst1, 31);
4320   two31 = const_double_from_real_value (TWO31r, mode);
4321   two31 = ix86_build_const_vector (vecmode, true, two31);
4322   operands[2] = force_reg (vecmode, two31);
4323 })
4324
4325 (define_insn_and_split "*fixuns_trunc<mode>_1"
4326   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4327         (unsigned_fix:SI
4328           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4329    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4330    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4331    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4332   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4333    && optimize_function_for_speed_p (cfun)"
4334   "#"
4335   "&& reload_completed"
4336   [(const_int 0)]
4337 {
4338   ix86_split_convert_uns_si_sse (operands);
4339   DONE;
4340 })
4341
4342 ;; Unsigned conversion to HImode.
4343 ;; Without these patterns, we'll try the unsigned SI conversion which
4344 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4345
4346 (define_expand "fixuns_trunc<mode>hi2"
4347   [(set (match_dup 2)
4348         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4349    (set (match_operand:HI 0 "nonimmediate_operand" "")
4350         (subreg:HI (match_dup 2) 0))]
4351   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4352   "operands[2] = gen_reg_rtx (SImode);")
4353
4354 ;; When SSE is available, it is always faster to use it!
4355 (define_insn "fix_trunc<mode>di_sse"
4356   [(set (match_operand:DI 0 "register_operand" "=r,r")
4357         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4358   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4359    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4360   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4361   [(set_attr "type" "sseicvt")
4362    (set_attr "prefix" "maybe_vex")
4363    (set_attr "prefix_rex" "1")
4364    (set_attr "mode" "<MODE>")
4365    (set_attr "athlon_decode" "double,vector")
4366    (set_attr "amdfam10_decode" "double,double")
4367    (set_attr "bdver1_decode" "double,double")])
4368
4369 (define_insn "fix_trunc<mode>si_sse"
4370   [(set (match_operand:SI 0 "register_operand" "=r,r")
4371         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4372   "SSE_FLOAT_MODE_P (<MODE>mode)
4373    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4375   [(set_attr "type" "sseicvt")
4376    (set_attr "prefix" "maybe_vex")
4377    (set_attr "mode" "<MODE>")
4378    (set_attr "athlon_decode" "double,vector")
4379    (set_attr "amdfam10_decode" "double,double")
4380    (set_attr "bdver1_decode" "double,double")])
4381
4382 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4383 (define_peephole2
4384   [(set (match_operand:MODEF 0 "register_operand" "")
4385         (match_operand:MODEF 1 "memory_operand" ""))
4386    (set (match_operand:SWI48x 2 "register_operand" "")
4387         (fix:SWI48x (match_dup 0)))]
4388   "TARGET_SHORTEN_X87_SSE
4389    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4390    && peep2_reg_dead_p (2, operands[0])"
4391   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4392
4393 ;; Avoid vector decoded forms of the instruction.
4394 (define_peephole2
4395   [(match_scratch:DF 2 "Y2")
4396    (set (match_operand:SWI48x 0 "register_operand" "")
4397         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4398   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4399   [(set (match_dup 2) (match_dup 1))
4400    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4401
4402 (define_peephole2
4403   [(match_scratch:SF 2 "x")
4404    (set (match_operand:SWI48x 0 "register_operand" "")
4405         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4406   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4407   [(set (match_dup 2) (match_dup 1))
4408    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4409
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4412         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4413   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4414    && TARGET_FISTTP
4415    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416          && (TARGET_64BIT || <MODE>mode != DImode))
4417         && TARGET_SSE_MATH)
4418    && can_create_pseudo_p ()"
4419   "#"
4420   "&& 1"
4421   [(const_int 0)]
4422 {
4423   if (memory_operand (operands[0], VOIDmode))
4424     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4425   else
4426     {
4427       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4429                                                             operands[1],
4430                                                             operands[2]));
4431     }
4432   DONE;
4433 }
4434   [(set_attr "type" "fisttp")
4435    (set_attr "mode" "<MODE>")])
4436
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4439         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4440    (clobber (match_scratch:XF 2 "=&1f"))]
4441   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4442    && TARGET_FISTTP
4443    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444          && (TARGET_64BIT || <MODE>mode != DImode))
4445         && TARGET_SSE_MATH)"
4446   "* return output_fix_trunc (insn, operands, true);"
4447   [(set_attr "type" "fisttp")
4448    (set_attr "mode" "<MODE>")])
4449
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4452         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4453    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4454    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4456    && TARGET_FISTTP
4457    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458         && (TARGET_64BIT || <MODE>mode != DImode))
4459         && TARGET_SSE_MATH)"
4460   "#"
4461   [(set_attr "type" "fisttp")
4462    (set_attr "mode" "<MODE>")])
4463
4464 (define_split
4465   [(set (match_operand:SWI248x 0 "register_operand" "")
4466         (fix:SWI248x (match_operand 1 "register_operand" "")))
4467    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468    (clobber (match_scratch 3 ""))]
4469   "reload_completed"
4470   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4471               (clobber (match_dup 3))])
4472    (set (match_dup 0) (match_dup 2))])
4473
4474 (define_split
4475   [(set (match_operand:SWI248x 0 "memory_operand" "")
4476         (fix:SWI248x (match_operand 1 "register_operand" "")))
4477    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4478    (clobber (match_scratch 3 ""))]
4479   "reload_completed"
4480   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4481               (clobber (match_dup 3))])])
4482
4483 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4484 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4485 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4486 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4487 ;; function in i386.c.
4488 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4489   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4490         (fix:SWI248x (match_operand 1 "register_operand" "")))
4491    (clobber (reg:CC FLAGS_REG))]
4492   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4493    && !TARGET_FISTTP
4494    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495          && (TARGET_64BIT || <MODE>mode != DImode))
4496    && can_create_pseudo_p ()"
4497   "#"
4498   "&& 1"
4499   [(const_int 0)]
4500 {
4501   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4502
4503   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4504   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4505   if (memory_operand (operands[0], VOIDmode))
4506     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4507                                          operands[2], operands[3]));
4508   else
4509     {
4510       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4511       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4512                                                      operands[2], operands[3],
4513                                                      operands[4]));
4514     }
4515   DONE;
4516 }
4517   [(set_attr "type" "fistp")
4518    (set_attr "i387_cw" "trunc")
4519    (set_attr "mode" "<MODE>")])
4520
4521 (define_insn "fix_truncdi_i387"
4522   [(set (match_operand:DI 0 "memory_operand" "=m")
4523         (fix:DI (match_operand 1 "register_operand" "f")))
4524    (use (match_operand:HI 2 "memory_operand" "m"))
4525    (use (match_operand:HI 3 "memory_operand" "m"))
4526    (clobber (match_scratch:XF 4 "=&1f"))]
4527   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528    && !TARGET_FISTTP
4529    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4530   "* return output_fix_trunc (insn, operands, false);"
4531   [(set_attr "type" "fistp")
4532    (set_attr "i387_cw" "trunc")
4533    (set_attr "mode" "DI")])
4534
4535 (define_insn "fix_truncdi_i387_with_temp"
4536   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4537         (fix:DI (match_operand 1 "register_operand" "f,f")))
4538    (use (match_operand:HI 2 "memory_operand" "m,m"))
4539    (use (match_operand:HI 3 "memory_operand" "m,m"))
4540    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4541    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4542   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543    && !TARGET_FISTTP
4544    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4545   "#"
4546   [(set_attr "type" "fistp")
4547    (set_attr "i387_cw" "trunc")
4548    (set_attr "mode" "DI")])
4549
4550 (define_split
4551   [(set (match_operand:DI 0 "register_operand" "")
4552         (fix:DI (match_operand 1 "register_operand" "")))
4553    (use (match_operand:HI 2 "memory_operand" ""))
4554    (use (match_operand:HI 3 "memory_operand" ""))
4555    (clobber (match_operand:DI 4 "memory_operand" ""))
4556    (clobber (match_scratch 5 ""))]
4557   "reload_completed"
4558   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4559               (use (match_dup 2))
4560               (use (match_dup 3))
4561               (clobber (match_dup 5))])
4562    (set (match_dup 0) (match_dup 4))])
4563
4564 (define_split
4565   [(set (match_operand:DI 0 "memory_operand" "")
4566         (fix:DI (match_operand 1 "register_operand" "")))
4567    (use (match_operand:HI 2 "memory_operand" ""))
4568    (use (match_operand:HI 3 "memory_operand" ""))
4569    (clobber (match_operand:DI 4 "memory_operand" ""))
4570    (clobber (match_scratch 5 ""))]
4571   "reload_completed"
4572   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4573               (use (match_dup 2))
4574               (use (match_dup 3))
4575               (clobber (match_dup 5))])])
4576
4577 (define_insn "fix_trunc<mode>_i387"
4578   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4579         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4580    (use (match_operand:HI 2 "memory_operand" "m"))
4581    (use (match_operand:HI 3 "memory_operand" "m"))]
4582   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583    && !TARGET_FISTTP
4584    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4585   "* return output_fix_trunc (insn, operands, false);"
4586   [(set_attr "type" "fistp")
4587    (set_attr "i387_cw" "trunc")
4588    (set_attr "mode" "<MODE>")])
4589
4590 (define_insn "fix_trunc<mode>_i387_with_temp"
4591   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4592         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4593    (use (match_operand:HI 2 "memory_operand" "m,m"))
4594    (use (match_operand:HI 3 "memory_operand" "m,m"))
4595    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4596   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597    && !TARGET_FISTTP
4598    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4599   "#"
4600   [(set_attr "type" "fistp")
4601    (set_attr "i387_cw" "trunc")
4602    (set_attr "mode" "<MODE>")])
4603
4604 (define_split
4605   [(set (match_operand:SWI24 0 "register_operand" "")
4606         (fix:SWI24 (match_operand 1 "register_operand" "")))
4607    (use (match_operand:HI 2 "memory_operand" ""))
4608    (use (match_operand:HI 3 "memory_operand" ""))
4609    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4610   "reload_completed"
4611   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4612               (use (match_dup 2))
4613               (use (match_dup 3))])
4614    (set (match_dup 0) (match_dup 4))])
4615
4616 (define_split
4617   [(set (match_operand:SWI24 0 "memory_operand" "")
4618         (fix:SWI24 (match_operand 1 "register_operand" "")))
4619    (use (match_operand:HI 2 "memory_operand" ""))
4620    (use (match_operand:HI 3 "memory_operand" ""))
4621    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4622   "reload_completed"
4623   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4624               (use (match_dup 2))
4625               (use (match_dup 3))])])
4626
4627 (define_insn "x86_fnstcw_1"
4628   [(set (match_operand:HI 0 "memory_operand" "=m")
4629         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4630   "TARGET_80387"
4631   "fnstcw\t%0"
4632   [(set (attr "length")
4633         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4634    (set_attr "mode" "HI")
4635    (set_attr "unit" "i387")
4636    (set_attr "bdver1_decode" "vector")])
4637
4638 (define_insn "x86_fldcw_1"
4639   [(set (reg:HI FPCR_REG)
4640         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4641   "TARGET_80387"
4642   "fldcw\t%0"
4643   [(set (attr "length")
4644         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4645    (set_attr "mode" "HI")
4646    (set_attr "unit" "i387")
4647    (set_attr "athlon_decode" "vector")
4648    (set_attr "amdfam10_decode" "vector")
4649    (set_attr "bdver1_decode" "vector")])
4650 \f
4651 ;; Conversion between fixed point and floating point.
4652
4653 ;; Even though we only accept memory inputs, the backend _really_
4654 ;; wants to be able to do this between registers.
4655
4656 (define_expand "floathi<mode>2"
4657   [(set (match_operand:X87MODEF 0 "register_operand" "")
4658         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4659   "TARGET_80387
4660    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661        || TARGET_MIX_SSE_I387)")
4662
4663 ;; Pre-reload splitter to add memory clobber to the pattern.
4664 (define_insn_and_split "*floathi<mode>2_1"
4665   [(set (match_operand:X87MODEF 0 "register_operand" "")
4666         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4667   "TARGET_80387
4668    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669        || TARGET_MIX_SSE_I387)
4670    && can_create_pseudo_p ()"
4671   "#"
4672   "&& 1"
4673   [(parallel [(set (match_dup 0)
4674               (float:X87MODEF (match_dup 1)))
4675    (clobber (match_dup 2))])]
4676   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4677
4678 (define_insn "*floathi<mode>2_i387_with_temp"
4679   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4680         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4681   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4682   "TARGET_80387
4683    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4684        || TARGET_MIX_SSE_I387)"
4685   "#"
4686   [(set_attr "type" "fmov,multi")
4687    (set_attr "mode" "<MODE>")
4688    (set_attr "unit" "*,i387")
4689    (set_attr "fp_int_src" "true")])
4690
4691 (define_insn "*floathi<mode>2_i387"
4692   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4693         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4694   "TARGET_80387
4695    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696        || TARGET_MIX_SSE_I387)"
4697   "fild%Z1\t%1"
4698   [(set_attr "type" "fmov")
4699    (set_attr "mode" "<MODE>")
4700    (set_attr "fp_int_src" "true")])
4701
4702 (define_split
4703   [(set (match_operand:X87MODEF 0 "register_operand" "")
4704         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4705    (clobber (match_operand:HI 2 "memory_operand" ""))]
4706   "TARGET_80387
4707    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4708        || TARGET_MIX_SSE_I387)
4709    && reload_completed"
4710   [(set (match_dup 2) (match_dup 1))
4711    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4712
4713 (define_split
4714   [(set (match_operand:X87MODEF 0 "register_operand" "")
4715         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4716    (clobber (match_operand:HI 2 "memory_operand" ""))]
4717    "TARGET_80387
4718     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719         || TARGET_MIX_SSE_I387)
4720     && reload_completed"
4721   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4722
4723 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4724   [(set (match_operand:X87MODEF 0 "register_operand" "")
4725         (float:X87MODEF
4726           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4727   "TARGET_80387
4728    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4729        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4730 {
4731   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4732         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4733       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4734     {
4735       rtx reg = gen_reg_rtx (XFmode);
4736       rtx (*insn)(rtx, rtx);
4737
4738       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4739
4740       if (<X87MODEF:MODE>mode == SFmode)
4741         insn = gen_truncxfsf2;
4742       else if (<X87MODEF:MODE>mode == DFmode)
4743         insn = gen_truncxfdf2;
4744       else
4745         gcc_unreachable ();
4746
4747       emit_insn (insn (operands[0], reg));
4748       DONE;
4749     }
4750 })
4751
4752 ;; Pre-reload splitter to add memory clobber to the pattern.
4753 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4754   [(set (match_operand:X87MODEF 0 "register_operand" "")
4755         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4756   "((TARGET_80387
4757      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4758      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4759            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4760          || TARGET_MIX_SSE_I387))
4761     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4762         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4763         && ((<SWI48x:MODE>mode == SImode
4764              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4765              && optimize_function_for_speed_p (cfun)
4766              && flag_trapping_math)
4767             || !(TARGET_INTER_UNIT_CONVERSIONS
4768                  || optimize_function_for_size_p (cfun)))))
4769    && can_create_pseudo_p ()"
4770   "#"
4771   "&& 1"
4772   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4773               (clobber (match_dup 2))])]
4774 {
4775   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4776
4777   /* Avoid store forwarding (partial memory) stall penalty
4778      by passing DImode value through XMM registers.  */
4779   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4780       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4781       && optimize_function_for_speed_p (cfun))
4782     {
4783       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4784                                                             operands[1],
4785                                                             operands[2]));
4786       DONE;
4787     }
4788 })
4789
4790 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4791   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4792         (float:MODEF
4793           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4794    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4795   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4796    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4797   "#"
4798   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4799    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4800    (set_attr "unit" "*,i387,*,*,*")
4801    (set_attr "athlon_decode" "*,*,double,direct,double")
4802    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4803    (set_attr "bdver1_decode" "*,*,double,direct,double")
4804    (set_attr "fp_int_src" "true")])
4805
4806 (define_insn "*floatsi<mode>2_vector_mixed"
4807   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4808         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4809   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4810    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4811   "@
4812    fild%Z1\t%1
4813    #"
4814   [(set_attr "type" "fmov,sseicvt")
4815    (set_attr "mode" "<MODE>,<ssevecmode>")
4816    (set_attr "unit" "i387,*")
4817    (set_attr "athlon_decode" "*,direct")
4818    (set_attr "amdfam10_decode" "*,double")
4819    (set_attr "bdver1_decode" "*,direct")
4820    (set_attr "fp_int_src" "true")])
4821
4822 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4823   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4824         (float:MODEF
4825           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4826    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4827   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4829   "#"
4830   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4831    (set_attr "mode" "<MODEF:MODE>")
4832    (set_attr "unit" "*,i387,*,*")
4833    (set_attr "athlon_decode" "*,*,double,direct")
4834    (set_attr "amdfam10_decode" "*,*,vector,double")
4835    (set_attr "bdver1_decode" "*,*,double,direct")
4836    (set_attr "fp_int_src" "true")])
4837
4838 (define_split
4839   [(set (match_operand:MODEF 0 "register_operand" "")
4840         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4841    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4842   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4843    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844    && TARGET_INTER_UNIT_CONVERSIONS
4845    && reload_completed
4846    && (SSE_REG_P (operands[0])
4847        || (GET_CODE (operands[0]) == SUBREG
4848            && SSE_REG_P (operands[0])))"
4849   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4850
4851 (define_split
4852   [(set (match_operand:MODEF 0 "register_operand" "")
4853         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4854    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4855   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4856    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4857    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4858    && reload_completed
4859    && (SSE_REG_P (operands[0])
4860        || (GET_CODE (operands[0]) == SUBREG
4861            && SSE_REG_P (operands[0])))"
4862   [(set (match_dup 2) (match_dup 1))
4863    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4864
4865 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4866   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4867         (float:MODEF
4868           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4869   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4870    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4871    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4872   "@
4873    fild%Z1\t%1
4874    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4875    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4876   [(set_attr "type" "fmov,sseicvt,sseicvt")
4877    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4878    (set_attr "mode" "<MODEF:MODE>")
4879    (set (attr "prefix_rex")
4880      (if_then_else
4881        (and (eq_attr "prefix" "maybe_vex")
4882             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4883        (const_string "1")
4884        (const_string "*")))
4885    (set_attr "unit" "i387,*,*")
4886    (set_attr "athlon_decode" "*,double,direct")
4887    (set_attr "amdfam10_decode" "*,vector,double")
4888    (set_attr "bdver1_decode" "*,double,direct")
4889    (set_attr "fp_int_src" "true")])
4890
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4892   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4893         (float:MODEF
4894           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4895   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4896    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4897    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4898   "@
4899    fild%Z1\t%1
4900    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4901   [(set_attr "type" "fmov,sseicvt")
4902    (set_attr "prefix" "orig,maybe_vex")
4903    (set_attr "mode" "<MODEF:MODE>")
4904    (set (attr "prefix_rex")
4905      (if_then_else
4906        (and (eq_attr "prefix" "maybe_vex")
4907             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4908        (const_string "1")
4909        (const_string "*")))
4910    (set_attr "athlon_decode" "*,direct")
4911    (set_attr "amdfam10_decode" "*,double")
4912    (set_attr "bdver1_decode" "*,direct")
4913    (set_attr "fp_int_src" "true")])
4914
4915 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4916   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4917         (float:MODEF
4918           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4919    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4920   "TARGET_SSE2 && TARGET_SSE_MATH
4921    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4922   "#"
4923   [(set_attr "type" "sseicvt")
4924    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4925    (set_attr "athlon_decode" "double,direct,double")
4926    (set_attr "amdfam10_decode" "vector,double,double")
4927    (set_attr "bdver1_decode" "double,direct,double")
4928    (set_attr "fp_int_src" "true")])
4929
4930 (define_insn "*floatsi<mode>2_vector_sse"
4931   [(set (match_operand:MODEF 0 "register_operand" "=x")
4932         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4933   "TARGET_SSE2 && TARGET_SSE_MATH
4934    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4935   "#"
4936   [(set_attr "type" "sseicvt")
4937    (set_attr "mode" "<MODE>")
4938    (set_attr "athlon_decode" "direct")
4939    (set_attr "amdfam10_decode" "double")
4940    (set_attr "bdver1_decode" "direct")
4941    (set_attr "fp_int_src" "true")])
4942
4943 (define_split
4944   [(set (match_operand:MODEF 0 "register_operand" "")
4945         (float:MODEF (match_operand:SI 1 "register_operand" "")))
4946    (clobber (match_operand:SI 2 "memory_operand" ""))]
4947   "TARGET_SSE2 && TARGET_SSE_MATH
4948    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4949    && reload_completed
4950    && (SSE_REG_P (operands[0])
4951        || (GET_CODE (operands[0]) == SUBREG
4952            && SSE_REG_P (operands[0])))"
4953   [(const_int 0)]
4954 {
4955   rtx op1 = operands[1];
4956
4957   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4958                                      <MODE>mode, 0);
4959   if (GET_CODE (op1) == SUBREG)
4960     op1 = SUBREG_REG (op1);
4961
4962   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4963     {
4964       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965       emit_insn (gen_sse2_loadld (operands[4],
4966                                   CONST0_RTX (V4SImode), operands[1]));
4967     }
4968   /* We can ignore possible trapping value in the
4969      high part of SSE register for non-trapping math. */
4970   else if (SSE_REG_P (op1) && !flag_trapping_math)
4971     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4972   else
4973     {
4974       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4975       emit_move_insn (operands[2], operands[1]);
4976       emit_insn (gen_sse2_loadld (operands[4],
4977                                   CONST0_RTX (V4SImode), operands[2]));
4978     }
4979   emit_insn
4980     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
4981   DONE;
4982 })
4983
4984 (define_split
4985   [(set (match_operand:MODEF 0 "register_operand" "")
4986         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4987    (clobber (match_operand:SI 2 "memory_operand" ""))]
4988   "TARGET_SSE2 && TARGET_SSE_MATH
4989    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4990    && reload_completed
4991    && (SSE_REG_P (operands[0])
4992        || (GET_CODE (operands[0]) == SUBREG
4993            && SSE_REG_P (operands[0])))"
4994   [(const_int 0)]
4995 {
4996   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4997                                      <MODE>mode, 0);
4998   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4999
5000   emit_insn (gen_sse2_loadld (operands[4],
5001                               CONST0_RTX (V4SImode), operands[1]));
5002   emit_insn
5003     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5004   DONE;
5005 })
5006
5007 (define_split
5008   [(set (match_operand:MODEF 0 "register_operand" "")
5009         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5010   "TARGET_SSE2 && TARGET_SSE_MATH
5011    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5012    && reload_completed
5013    && (SSE_REG_P (operands[0])
5014        || (GET_CODE (operands[0]) == SUBREG
5015            && SSE_REG_P (operands[0])))"
5016   [(const_int 0)]
5017 {
5018   rtx op1 = operands[1];
5019
5020   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5021                                      <MODE>mode, 0);
5022   if (GET_CODE (op1) == SUBREG)
5023     op1 = SUBREG_REG (op1);
5024
5025   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5026     {
5027       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5028       emit_insn (gen_sse2_loadld (operands[4],
5029                                   CONST0_RTX (V4SImode), operands[1]));
5030     }
5031   /* We can ignore possible trapping value in the
5032      high part of SSE register for non-trapping math. */
5033   else if (SSE_REG_P (op1) && !flag_trapping_math)
5034     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5035   else
5036     gcc_unreachable ();
5037   emit_insn
5038     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5039   DONE;
5040 })
5041
5042 (define_split
5043   [(set (match_operand:MODEF 0 "register_operand" "")
5044         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5045   "TARGET_SSE2 && TARGET_SSE_MATH
5046    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047    && reload_completed
5048    && (SSE_REG_P (operands[0])
5049        || (GET_CODE (operands[0]) == SUBREG
5050            && SSE_REG_P (operands[0])))"
5051   [(const_int 0)]
5052 {
5053   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5054                                      <MODE>mode, 0);
5055   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5056
5057   emit_insn (gen_sse2_loadld (operands[4],
5058                               CONST0_RTX (V4SImode), operands[1]));
5059   emit_insn
5060     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5061   DONE;
5062 })
5063
5064 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5065   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5066         (float:MODEF
5067           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5068   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5069   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5070    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5071   "#"
5072   [(set_attr "type" "sseicvt")
5073    (set_attr "mode" "<MODEF:MODE>")
5074    (set_attr "athlon_decode" "double,direct")
5075    (set_attr "amdfam10_decode" "vector,double")
5076    (set_attr "bdver1_decode" "double,direct")
5077    (set_attr "fp_int_src" "true")])
5078
5079 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5080   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5081         (float:MODEF
5082           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5083   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5084    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5085    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5086   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5087   [(set_attr "type" "sseicvt")
5088    (set_attr "prefix" "maybe_vex")
5089    (set_attr "mode" "<MODEF:MODE>")
5090    (set (attr "prefix_rex")
5091      (if_then_else
5092        (and (eq_attr "prefix" "maybe_vex")
5093             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5094        (const_string "1")
5095        (const_string "*")))
5096    (set_attr "athlon_decode" "double,direct")
5097    (set_attr "amdfam10_decode" "vector,double")
5098    (set_attr "bdver1_decode" "double,direct")
5099    (set_attr "fp_int_src" "true")])
5100
5101 (define_split
5102   [(set (match_operand:MODEF 0 "register_operand" "")
5103         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5104    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5105   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5106    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5107    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5108    && reload_completed
5109    && (SSE_REG_P (operands[0])
5110        || (GET_CODE (operands[0]) == SUBREG
5111            && SSE_REG_P (operands[0])))"
5112   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5113
5114 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5115   [(set (match_operand:MODEF 0 "register_operand" "=x")
5116         (float:MODEF
5117           (match_operand:SWI48x 1 "memory_operand" "m")))]
5118   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5119    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5122   [(set_attr "type" "sseicvt")
5123    (set_attr "prefix" "maybe_vex")
5124    (set_attr "mode" "<MODEF:MODE>")
5125    (set (attr "prefix_rex")
5126      (if_then_else
5127        (and (eq_attr "prefix" "maybe_vex")
5128             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5129        (const_string "1")
5130        (const_string "*")))
5131    (set_attr "athlon_decode" "direct")
5132    (set_attr "amdfam10_decode" "double")
5133    (set_attr "bdver1_decode" "direct")
5134    (set_attr "fp_int_src" "true")])
5135
5136 (define_split
5137   [(set (match_operand:MODEF 0 "register_operand" "")
5138         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5139    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5140   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5141    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5143    && reload_completed
5144    && (SSE_REG_P (operands[0])
5145        || (GET_CODE (operands[0]) == SUBREG
5146            && SSE_REG_P (operands[0])))"
5147   [(set (match_dup 2) (match_dup 1))
5148    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5149
5150 (define_split
5151   [(set (match_operand:MODEF 0 "register_operand" "")
5152         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5153    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5154   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5155    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5156    && reload_completed
5157    && (SSE_REG_P (operands[0])
5158        || (GET_CODE (operands[0]) == SUBREG
5159            && SSE_REG_P (operands[0])))"
5160   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5161
5162 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5163   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5164         (float:X87MODEF
5165           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5166   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5167   "TARGET_80387
5168    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5169   "@
5170    fild%Z1\t%1
5171    #"
5172   [(set_attr "type" "fmov,multi")
5173    (set_attr "mode" "<X87MODEF:MODE>")
5174    (set_attr "unit" "*,i387")
5175    (set_attr "fp_int_src" "true")])
5176
5177 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5178   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5179         (float:X87MODEF
5180           (match_operand:SWI48x 1 "memory_operand" "m")))]
5181   "TARGET_80387
5182    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5183   "fild%Z1\t%1"
5184   [(set_attr "type" "fmov")
5185    (set_attr "mode" "<X87MODEF:MODE>")
5186    (set_attr "fp_int_src" "true")])
5187
5188 (define_split
5189   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5190         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5191    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5192   "TARGET_80387
5193    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5194    && reload_completed"
5195   [(set (match_dup 2) (match_dup 1))
5196    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5197
5198 (define_split
5199   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5200         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5201    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5202   "TARGET_80387
5203    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5204    && reload_completed"
5205   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5206
5207 ;; Avoid store forwarding (partial memory) stall penalty
5208 ;; by passing DImode value through XMM registers.  */
5209
5210 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5211   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5212         (float:X87MODEF
5213           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5214    (clobber (match_scratch:V4SI 3 "=X,x"))
5215    (clobber (match_scratch:V4SI 4 "=X,x"))
5216    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5217   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5218    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5219    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5220   "#"
5221   [(set_attr "type" "multi")
5222    (set_attr "mode" "<X87MODEF:MODE>")
5223    (set_attr "unit" "i387")
5224    (set_attr "fp_int_src" "true")])
5225
5226 (define_split
5227   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5228         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5229    (clobber (match_scratch:V4SI 3 ""))
5230    (clobber (match_scratch:V4SI 4 ""))
5231    (clobber (match_operand:DI 2 "memory_operand" ""))]
5232   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5233    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5234    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5235    && reload_completed"
5236   [(set (match_dup 2) (match_dup 3))
5237    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5238 {
5239   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5240      Assemble the 64-bit DImode value in an xmm register.  */
5241   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5242                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5243   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5244                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5245   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5246                                          operands[4]));
5247
5248   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5249 })
5250
5251 (define_split
5252   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5253         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5254    (clobber (match_scratch:V4SI 3 ""))
5255    (clobber (match_scratch:V4SI 4 ""))
5256    (clobber (match_operand:DI 2 "memory_operand" ""))]
5257   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5258    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5259    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5260    && reload_completed"
5261   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5262
5263 ;; Avoid store forwarding (partial memory) stall penalty by extending
5264 ;; SImode value to DImode through XMM register instead of pushing two
5265 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5266 ;; targets benefit from this optimization. Also note that fild
5267 ;; loads from memory only.
5268
5269 (define_insn "*floatunssi<mode>2_1"
5270   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5271         (unsigned_float:X87MODEF
5272           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5273    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5274    (clobber (match_scratch:SI 3 "=X,x"))]
5275   "!TARGET_64BIT
5276    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5277    && TARGET_SSE"
5278   "#"
5279   [(set_attr "type" "multi")
5280    (set_attr "mode" "<MODE>")])
5281
5282 (define_split
5283   [(set (match_operand:X87MODEF 0 "register_operand" "")
5284         (unsigned_float:X87MODEF
5285           (match_operand:SI 1 "register_operand" "")))
5286    (clobber (match_operand:DI 2 "memory_operand" ""))
5287    (clobber (match_scratch:SI 3 ""))]
5288   "!TARGET_64BIT
5289    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5290    && TARGET_SSE
5291    && reload_completed"
5292   [(set (match_dup 2) (match_dup 1))
5293    (set (match_dup 0)
5294         (float:X87MODEF (match_dup 2)))]
5295   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5296
5297 (define_split
5298   [(set (match_operand:X87MODEF 0 "register_operand" "")
5299         (unsigned_float:X87MODEF
5300           (match_operand:SI 1 "memory_operand" "")))
5301    (clobber (match_operand:DI 2 "memory_operand" ""))
5302    (clobber (match_scratch:SI 3 ""))]
5303   "!TARGET_64BIT
5304    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305    && TARGET_SSE
5306    && reload_completed"
5307   [(set (match_dup 2) (match_dup 3))
5308    (set (match_dup 0)
5309         (float:X87MODEF (match_dup 2)))]
5310 {
5311   emit_move_insn (operands[3], operands[1]);
5312   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5313 })
5314
5315 (define_expand "floatunssi<mode>2"
5316   [(parallel
5317      [(set (match_operand:X87MODEF 0 "register_operand" "")
5318            (unsigned_float:X87MODEF
5319              (match_operand:SI 1 "nonimmediate_operand" "")))
5320       (clobber (match_dup 2))
5321       (clobber (match_scratch:SI 3 ""))])]
5322   "!TARGET_64BIT
5323    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5324         && TARGET_SSE)
5325        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5326 {
5327   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5328     {
5329       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5330       DONE;
5331     }
5332   else
5333     {
5334       enum ix86_stack_slot slot = (virtuals_instantiated
5335                                    ? SLOT_TEMP
5336                                    : SLOT_VIRTUAL);
5337       operands[2] = assign_386_stack_local (DImode, slot);
5338     }
5339 })
5340
5341 (define_expand "floatunsdisf2"
5342   [(use (match_operand:SF 0 "register_operand" ""))
5343    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5344   "TARGET_64BIT && TARGET_SSE_MATH"
5345   "x86_emit_floatuns (operands); DONE;")
5346
5347 (define_expand "floatunsdidf2"
5348   [(use (match_operand:DF 0 "register_operand" ""))
5349    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5350   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5351    && TARGET_SSE2 && TARGET_SSE_MATH"
5352 {
5353   if (TARGET_64BIT)
5354     x86_emit_floatuns (operands);
5355   else
5356     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5357   DONE;
5358 })
5359 \f
5360 ;; Add instructions
5361
5362 (define_expand "add<mode>3"
5363   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5364         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5365                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5366   ""
5367   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5368
5369 (define_insn_and_split "*add<dwi>3_doubleword"
5370   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5371         (plus:<DWI>
5372           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5373           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5374    (clobber (reg:CC FLAGS_REG))]
5375   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5376   "#"
5377   "reload_completed"
5378   [(parallel [(set (reg:CC FLAGS_REG)
5379                    (unspec:CC [(match_dup 1) (match_dup 2)]
5380                               UNSPEC_ADD_CARRY))
5381               (set (match_dup 0)
5382                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5383    (parallel [(set (match_dup 3)
5384                    (plus:DWIH
5385                      (match_dup 4)
5386                      (plus:DWIH
5387                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5388                        (match_dup 5))))
5389               (clobber (reg:CC FLAGS_REG))])]
5390   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5391
5392 (define_insn "*add<mode>3_cc"
5393   [(set (reg:CC FLAGS_REG)
5394         (unspec:CC
5395           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5396            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5397           UNSPEC_ADD_CARRY))
5398    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5399         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5400   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5401   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5402   [(set_attr "type" "alu")
5403    (set_attr "mode" "<MODE>")])
5404
5405 (define_insn "addqi3_cc"
5406   [(set (reg:CC FLAGS_REG)
5407         (unspec:CC
5408           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5409            (match_operand:QI 2 "general_operand" "qn,qm")]
5410           UNSPEC_ADD_CARRY))
5411    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5412         (plus:QI (match_dup 1) (match_dup 2)))]
5413   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5414   "add{b}\t{%2, %0|%0, %2}"
5415   [(set_attr "type" "alu")
5416    (set_attr "mode" "QI")])
5417
5418 (define_insn "*lea_1"
5419   [(set (match_operand:P 0 "register_operand" "=r")
5420         (match_operand:P 1 "no_seg_address_operand" "p"))]
5421   ""
5422   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5423   [(set_attr "type" "lea")
5424    (set_attr "mode" "<MODE>")])
5425
5426 (define_insn "*lea_2"
5427   [(set (match_operand:SI 0 "register_operand" "=r")
5428         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5429   "TARGET_64BIT"
5430   "lea{l}\t{%a1, %0|%0, %a1}"
5431   [(set_attr "type" "lea")
5432    (set_attr "mode" "SI")])
5433
5434 (define_insn "*lea_2_zext"
5435   [(set (match_operand:DI 0 "register_operand" "=r")
5436         (zero_extend:DI
5437           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5438   "TARGET_64BIT"
5439   "lea{l}\t{%a1, %k0|%k0, %a1}"
5440   [(set_attr "type" "lea")
5441    (set_attr "mode" "SI")])
5442
5443 (define_insn "*add<mode>_1"
5444   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5445         (plus:SWI48
5446           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5447           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5448    (clobber (reg:CC FLAGS_REG))]
5449   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5450 {
5451   switch (get_attr_type (insn))
5452     {
5453     case TYPE_LEA:
5454       return "#";
5455
5456     case TYPE_INCDEC:
5457       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5458       if (operands[2] == const1_rtx)
5459         return "inc{<imodesuffix>}\t%0";
5460       else
5461         {
5462           gcc_assert (operands[2] == constm1_rtx);
5463           return "dec{<imodesuffix>}\t%0";
5464         }
5465
5466     default:
5467       /* For most processors, ADD is faster than LEA.  This alternative
5468          was added to use ADD as much as possible.  */
5469       if (which_alternative == 2)
5470         {
5471           rtx tmp;
5472           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5473         }
5474         
5475       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5477         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5478
5479       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5480     }
5481 }
5482   [(set (attr "type")
5483      (cond [(eq_attr "alternative" "3")
5484               (const_string "lea")
5485             (match_operand:SWI48 2 "incdec_operand" "")
5486               (const_string "incdec")
5487            ]
5488            (const_string "alu")))
5489    (set (attr "length_immediate")
5490       (if_then_else
5491         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5492         (const_string "1")
5493         (const_string "*")))
5494    (set_attr "mode" "<MODE>")])
5495
5496 ;; It may seem that nonimmediate operand is proper one for operand 1.
5497 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5498 ;; we take care in ix86_binary_operator_ok to not allow two memory
5499 ;; operands so proper swapping will be done in reload.  This allow
5500 ;; patterns constructed from addsi_1 to match.
5501
5502 (define_insn "*addsi_1_zext"
5503   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5504         (zero_extend:DI
5505           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5506                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5507    (clobber (reg:CC FLAGS_REG))]
5508   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5509 {
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_LEA:
5513       return "#";
5514
5515     case TYPE_INCDEC:
5516       if (operands[2] == const1_rtx)
5517         return "inc{l}\t%k0";
5518       else
5519         {
5520           gcc_assert (operands[2] == constm1_rtx);
5521           return "dec{l}\t%k0";
5522         }
5523
5524     default:
5525       /* For most processors, ADD is faster than LEA.  This alternative
5526          was added to use ADD as much as possible.  */
5527       if (which_alternative == 1)
5528         {
5529           rtx tmp;
5530           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5531         }
5532
5533       if (x86_maybe_negate_const_int (&operands[2], SImode))
5534         return "sub{l}\t{%2, %k0|%k0, %2}";
5535
5536       return "add{l}\t{%2, %k0|%k0, %2}";
5537     }
5538 }
5539   [(set (attr "type")
5540      (cond [(eq_attr "alternative" "2")
5541               (const_string "lea")
5542             (match_operand:SI 2 "incdec_operand" "")
5543               (const_string "incdec")
5544            ]
5545            (const_string "alu")))
5546    (set (attr "length_immediate")
5547       (if_then_else
5548         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5549         (const_string "1")
5550         (const_string "*")))
5551    (set_attr "mode" "SI")])
5552
5553 (define_insn "*addhi_1"
5554   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5555         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5556                  (match_operand:HI 2 "general_operand" "rn,rm")))
5557    (clobber (reg:CC FLAGS_REG))]
5558   "TARGET_PARTIAL_REG_STALL
5559    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5560 {
5561   switch (get_attr_type (insn))
5562     {
5563     case TYPE_INCDEC:
5564       if (operands[2] == const1_rtx)
5565         return "inc{w}\t%0";
5566       else
5567         {
5568           gcc_assert (operands[2] == constm1_rtx);
5569           return "dec{w}\t%0";
5570         }
5571
5572     default:
5573       if (x86_maybe_negate_const_int (&operands[2], HImode))
5574         return "sub{w}\t{%2, %0|%0, %2}";
5575
5576       return "add{w}\t{%2, %0|%0, %2}";
5577     }
5578 }
5579   [(set (attr "type")
5580      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5581         (const_string "incdec")
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" "HI")])
5589
5590 (define_insn "*addhi_1_lea"
5591   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5592         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5593                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
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_LEA:
5601       return "#";
5602
5603     case TYPE_INCDEC:
5604       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605       if (operands[2] == const1_rtx)
5606         return "inc{w}\t%0";
5607       else
5608         {
5609           gcc_assert (operands[2] == constm1_rtx);
5610           return "dec{w}\t%0";
5611         }
5612
5613     default:
5614       /* For most processors, ADD is faster than LEA.  This alternative
5615          was added to use ADD as much as possible.  */
5616       if (which_alternative == 2)
5617         {
5618           rtx tmp;
5619           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5620         }
5621
5622       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5623       if (x86_maybe_negate_const_int (&operands[2], HImode))
5624         return "sub{w}\t{%2, %0|%0, %2}";
5625
5626       return "add{w}\t{%2, %0|%0, %2}";
5627     }
5628 }
5629   [(set (attr "type")
5630      (cond [(eq_attr "alternative" "3")
5631               (const_string "lea")
5632             (match_operand:HI 2 "incdec_operand" "")
5633               (const_string "incdec")
5634            ]
5635            (const_string "alu")))
5636    (set (attr "length_immediate")
5637       (if_then_else
5638         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5639         (const_string "1")
5640         (const_string "*")))
5641    (set_attr "mode" "HI,HI,HI,SI")])
5642
5643 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5644 (define_insn "*addqi_1"
5645   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5646         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5647                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5648    (clobber (reg:CC FLAGS_REG))]
5649   "TARGET_PARTIAL_REG_STALL
5650    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5651 {
5652   int widen = (which_alternative == 2);
5653   switch (get_attr_type (insn))
5654     {
5655     case TYPE_INCDEC:
5656       if (operands[2] == const1_rtx)
5657         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5658       else
5659         {
5660           gcc_assert (operands[2] == constm1_rtx);
5661           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5662         }
5663
5664     default:
5665       if (x86_maybe_negate_const_int (&operands[2], QImode))
5666         {
5667           if (widen)
5668             return "sub{l}\t{%2, %k0|%k0, %2}";
5669           else
5670             return "sub{b}\t{%2, %0|%0, %2}";
5671         }
5672       if (widen)
5673         return "add{l}\t{%k2, %k0|%k0, %k2}";
5674       else
5675         return "add{b}\t{%2, %0|%0, %2}";
5676     }
5677 }
5678   [(set (attr "type")
5679      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5680         (const_string "incdec")
5681         (const_string "alu")))
5682    (set (attr "length_immediate")
5683       (if_then_else
5684         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5685         (const_string "1")
5686         (const_string "*")))
5687    (set_attr "mode" "QI,QI,SI")])
5688
5689 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5690 (define_insn "*addqi_1_lea"
5691   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5692         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5693                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5694    (clobber (reg:CC FLAGS_REG))]
5695   "!TARGET_PARTIAL_REG_STALL
5696    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5697 {
5698   int widen = (which_alternative == 3 || which_alternative == 4);
5699
5700   switch (get_attr_type (insn))
5701     {
5702     case TYPE_LEA:
5703       return "#";
5704
5705     case TYPE_INCDEC:
5706       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707       if (operands[2] == const1_rtx)
5708         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5709       else
5710         {
5711           gcc_assert (operands[2] == constm1_rtx);
5712           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5713         }
5714
5715     default:
5716       /* For most processors, ADD is faster than LEA.  These alternatives
5717          were added to use ADD as much as possible.  */
5718       if (which_alternative == 2 || which_alternative == 4)
5719         {
5720           rtx tmp;
5721           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5722         }
5723
5724       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5725       if (x86_maybe_negate_const_int (&operands[2], QImode))
5726         {
5727           if (widen)
5728             return "sub{l}\t{%2, %k0|%k0, %2}";
5729           else
5730             return "sub{b}\t{%2, %0|%0, %2}";
5731         }
5732       if (widen)
5733         return "add{l}\t{%k2, %k0|%k0, %k2}";
5734       else
5735         return "add{b}\t{%2, %0|%0, %2}";
5736     }
5737 }
5738   [(set (attr "type")
5739      (cond [(eq_attr "alternative" "5")
5740               (const_string "lea")
5741             (match_operand:QI 2 "incdec_operand" "")
5742               (const_string "incdec")
5743            ]
5744            (const_string "alu")))
5745    (set (attr "length_immediate")
5746       (if_then_else
5747         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5748         (const_string "1")
5749         (const_string "*")))
5750    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5751
5752 (define_insn "*addqi_1_slp"
5753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5754         (plus:QI (match_dup 0)
5755                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5756    (clobber (reg:CC FLAGS_REG))]
5757   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5758    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5759 {
5760   switch (get_attr_type (insn))
5761     {
5762     case TYPE_INCDEC:
5763       if (operands[1] == const1_rtx)
5764         return "inc{b}\t%0";
5765       else
5766         {
5767           gcc_assert (operands[1] == constm1_rtx);
5768           return "dec{b}\t%0";
5769         }
5770
5771     default:
5772       if (x86_maybe_negate_const_int (&operands[1], QImode))
5773         return "sub{b}\t{%1, %0|%0, %1}";
5774
5775       return "add{b}\t{%1, %0|%0, %1}";
5776     }
5777 }
5778   [(set (attr "type")
5779      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5780         (const_string "incdec")
5781         (const_string "alu1")))
5782    (set (attr "memory")
5783      (if_then_else (match_operand 1 "memory_operand" "")
5784         (const_string "load")
5785         (const_string "none")))
5786    (set_attr "mode" "QI")])
5787
5788 ;; Convert lea to the lea pattern to avoid flags dependency.
5789 (define_split
5790   [(set (match_operand 0 "register_operand" "")
5791         (plus (match_operand 1 "register_operand" "")
5792               (match_operand 2 "nonmemory_operand" "")))
5793    (clobber (reg:CC FLAGS_REG))]
5794   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5795   [(const_int 0)]
5796 {
5797   rtx pat;
5798   enum machine_mode mode = GET_MODE (operands[0]);
5799
5800   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5801      may confuse gen_lowpart.  */
5802   if (mode != Pmode)
5803     {
5804       operands[1] = gen_lowpart (Pmode, operands[1]);
5805       operands[2] = gen_lowpart (Pmode, operands[2]);
5806     }
5807
5808   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5809
5810   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5811     operands[0] = gen_lowpart (SImode, operands[0]);
5812
5813   if (TARGET_64BIT && mode != Pmode)
5814     pat = gen_rtx_SUBREG (SImode, pat, 0);
5815
5816   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5817   DONE;
5818 })
5819
5820 ;; Convert lea to the lea pattern to avoid flags dependency.
5821 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5822 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5823 (define_split
5824   [(set (match_operand:DI 0 "register_operand" "")
5825         (plus:DI (match_operand:DI 1 "register_operand" "")
5826                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
5827    (clobber (reg:CC FLAGS_REG))]
5828   "TARGET_64BIT && reload_completed 
5829    && true_regnum (operands[0]) != true_regnum (operands[1])"
5830   [(set (match_dup 0)
5831         (plus:DI (match_dup 1) (match_dup 2)))])
5832
5833 ;; Convert lea to the lea pattern to avoid flags dependency.
5834 (define_split
5835   [(set (match_operand:DI 0 "register_operand" "")
5836         (zero_extend:DI
5837           (plus:SI (match_operand:SI 1 "register_operand" "")
5838                    (match_operand:SI 2 "nonmemory_operand" ""))))
5839    (clobber (reg:CC FLAGS_REG))]
5840   "TARGET_64BIT && reload_completed
5841    && ix86_lea_for_add_ok (insn, operands)"
5842   [(set (match_dup 0)
5843         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5844 {
5845   operands[1] = gen_lowpart (DImode, operands[1]);
5846   operands[2] = gen_lowpart (DImode, operands[2]);
5847 })
5848
5849 (define_insn "*add<mode>_2"
5850   [(set (reg FLAGS_REG)
5851         (compare
5852           (plus:SWI
5853             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5854             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5855           (const_int 0)))
5856    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5857         (plus:SWI (match_dup 1) (match_dup 2)))]
5858   "ix86_match_ccmode (insn, CCGOCmode)
5859    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5860 {
5861   switch (get_attr_type (insn))
5862     {
5863     case TYPE_INCDEC:
5864       if (operands[2] == const1_rtx)
5865         return "inc{<imodesuffix>}\t%0";
5866       else
5867         {
5868           gcc_assert (operands[2] == constm1_rtx);
5869           return "dec{<imodesuffix>}\t%0";
5870         }
5871
5872     default:
5873       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5874         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5875
5876       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5877     }
5878 }
5879   [(set (attr "type")
5880      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5881         (const_string "incdec")
5882         (const_string "alu")))
5883    (set (attr "length_immediate")
5884       (if_then_else
5885         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5886         (const_string "1")
5887         (const_string "*")))
5888    (set_attr "mode" "<MODE>")])
5889
5890 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5891 (define_insn "*addsi_2_zext"
5892   [(set (reg FLAGS_REG)
5893         (compare
5894           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5895                    (match_operand:SI 2 "general_operand" "g"))
5896           (const_int 0)))
5897    (set (match_operand:DI 0 "register_operand" "=r")
5898         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5899   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5900    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5901 {
5902   switch (get_attr_type (insn))
5903     {
5904     case TYPE_INCDEC:
5905       if (operands[2] == const1_rtx)
5906         return "inc{l}\t%k0";
5907       else
5908         {
5909           gcc_assert (operands[2] == constm1_rtx);
5910           return "dec{l}\t%k0";
5911         }
5912
5913     default:
5914       if (x86_maybe_negate_const_int (&operands[2], SImode))
5915         return "sub{l}\t{%2, %k0|%k0, %2}";
5916
5917       return "add{l}\t{%2, %k0|%k0, %2}";
5918     }
5919 }
5920   [(set (attr "type")
5921      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5922         (const_string "incdec")
5923         (const_string "alu")))
5924    (set (attr "length_immediate")
5925       (if_then_else
5926         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5927         (const_string "1")
5928         (const_string "*")))
5929    (set_attr "mode" "SI")])
5930
5931 (define_insn "*add<mode>_3"
5932   [(set (reg FLAGS_REG)
5933         (compare
5934           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5935           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5936    (clobber (match_scratch:SWI 0 "=<r>"))]
5937   "ix86_match_ccmode (insn, CCZmode)
5938    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5939 {
5940   switch (get_attr_type (insn))
5941     {
5942     case TYPE_INCDEC:
5943       if (operands[2] == const1_rtx)
5944         return "inc{<imodesuffix>}\t%0";
5945       else
5946         {
5947           gcc_assert (operands[2] == constm1_rtx);
5948           return "dec{<imodesuffix>}\t%0";
5949         }
5950
5951     default:
5952       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5953         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5954
5955       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5956     }
5957 }
5958   [(set (attr "type")
5959      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5960         (const_string "incdec")
5961         (const_string "alu")))
5962    (set (attr "length_immediate")
5963       (if_then_else
5964         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5965         (const_string "1")
5966         (const_string "*")))
5967    (set_attr "mode" "<MODE>")])
5968
5969 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5970 (define_insn "*addsi_3_zext"
5971   [(set (reg FLAGS_REG)
5972         (compare
5973           (neg:SI (match_operand:SI 2 "general_operand" "g"))
5974           (match_operand:SI 1 "nonimmediate_operand" "%0")))
5975    (set (match_operand:DI 0 "register_operand" "=r")
5976         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5977   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5978    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5979 {
5980   switch (get_attr_type (insn))
5981     {
5982     case TYPE_INCDEC:
5983       if (operands[2] == const1_rtx)
5984         return "inc{l}\t%k0";
5985       else
5986         {
5987           gcc_assert (operands[2] == constm1_rtx);
5988           return "dec{l}\t%k0";
5989         }
5990
5991     default:
5992       if (x86_maybe_negate_const_int (&operands[2], SImode))
5993         return "sub{l}\t{%2, %k0|%k0, %2}";
5994
5995       return "add{l}\t{%2, %k0|%k0, %2}";
5996     }
5997 }
5998   [(set (attr "type")
5999      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6000         (const_string "incdec")
6001         (const_string "alu")))
6002    (set (attr "length_immediate")
6003       (if_then_else
6004         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6005         (const_string "1")
6006         (const_string "*")))
6007    (set_attr "mode" "SI")])
6008
6009 ; For comparisons against 1, -1 and 128, we may generate better code
6010 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6011 ; is matched then.  We can't accept general immediate, because for
6012 ; case of overflows,  the result is messed up.
6013 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6014 ; only for comparisons not depending on it.
6015
6016 (define_insn "*adddi_4"
6017   [(set (reg FLAGS_REG)
6018         (compare
6019           (match_operand:DI 1 "nonimmediate_operand" "0")
6020           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6021    (clobber (match_scratch:DI 0 "=rm"))]
6022   "TARGET_64BIT
6023    && ix86_match_ccmode (insn, CCGCmode)"
6024 {
6025   switch (get_attr_type (insn))
6026     {
6027     case TYPE_INCDEC:
6028       if (operands[2] == constm1_rtx)
6029         return "inc{q}\t%0";
6030       else
6031         {
6032           gcc_assert (operands[2] == const1_rtx);
6033           return "dec{q}\t%0";
6034         }
6035
6036     default:
6037       if (x86_maybe_negate_const_int (&operands[2], DImode))
6038         return "add{q}\t{%2, %0|%0, %2}";
6039
6040       return "sub{q}\t{%2, %0|%0, %2}";
6041     }
6042 }
6043   [(set (attr "type")
6044      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6045         (const_string "incdec")
6046         (const_string "alu")))
6047    (set (attr "length_immediate")
6048       (if_then_else
6049         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6050         (const_string "1")
6051         (const_string "*")))
6052    (set_attr "mode" "DI")])
6053
6054 ; For comparisons against 1, -1 and 128, we may generate better code
6055 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6056 ; is matched then.  We can't accept general immediate, because for
6057 ; case of overflows,  the result is messed up.
6058 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6059 ; only for comparisons not depending on it.
6060
6061 (define_insn "*add<mode>_4"
6062   [(set (reg FLAGS_REG)
6063         (compare
6064           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6065           (match_operand:SWI124 2 "const_int_operand" "n")))
6066    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6067   "ix86_match_ccmode (insn, CCGCmode)"
6068 {
6069   switch (get_attr_type (insn))
6070     {
6071     case TYPE_INCDEC:
6072       if (operands[2] == constm1_rtx)
6073         return "inc{<imodesuffix>}\t%0";
6074       else
6075         {
6076           gcc_assert (operands[2] == const1_rtx);
6077           return "dec{<imodesuffix>}\t%0";
6078         }
6079
6080     default:
6081       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6082         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6083
6084       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6085     }
6086 }
6087   [(set (attr "type")
6088      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6089         (const_string "incdec")
6090         (const_string "alu")))
6091    (set (attr "length_immediate")
6092       (if_then_else
6093         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6094         (const_string "1")
6095         (const_string "*")))
6096    (set_attr "mode" "<MODE>")])
6097
6098 (define_insn "*add<mode>_5"
6099   [(set (reg FLAGS_REG)
6100         (compare
6101           (plus:SWI
6102             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6103             (match_operand:SWI 2 "<general_operand>" "<g>"))
6104           (const_int 0)))
6105    (clobber (match_scratch:SWI 0 "=<r>"))]
6106   "ix86_match_ccmode (insn, CCGOCmode)
6107    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6108 {
6109   switch (get_attr_type (insn))
6110     {
6111     case TYPE_INCDEC:
6112       if (operands[2] == const1_rtx)
6113         return "inc{<imodesuffix>}\t%0";
6114       else
6115         {
6116           gcc_assert (operands[2] == constm1_rtx);
6117           return "dec{<imodesuffix>}\t%0";
6118         }
6119
6120     default:
6121       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6122         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6123
6124       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6125     }
6126 }
6127   [(set (attr "type")
6128      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6129         (const_string "incdec")
6130         (const_string "alu")))
6131    (set (attr "length_immediate")
6132       (if_then_else
6133         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6134         (const_string "1")
6135         (const_string "*")))
6136    (set_attr "mode" "<MODE>")])
6137
6138 (define_insn "*addqi_ext_1_rex64"
6139   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6140                          (const_int 8)
6141                          (const_int 8))
6142         (plus:SI
6143           (zero_extract:SI
6144             (match_operand 1 "ext_register_operand" "0")
6145             (const_int 8)
6146             (const_int 8))
6147           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6148    (clobber (reg:CC FLAGS_REG))]
6149   "TARGET_64BIT"
6150 {
6151   switch (get_attr_type (insn))
6152     {
6153     case TYPE_INCDEC:
6154       if (operands[2] == const1_rtx)
6155         return "inc{b}\t%h0";
6156       else
6157         {
6158           gcc_assert (operands[2] == constm1_rtx);
6159           return "dec{b}\t%h0";
6160         }
6161
6162     default:
6163       return "add{b}\t{%2, %h0|%h0, %2}";
6164     }
6165 }
6166   [(set (attr "type")
6167      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6168         (const_string "incdec")
6169         (const_string "alu")))
6170    (set_attr "modrm" "1")
6171    (set_attr "mode" "QI")])
6172
6173 (define_insn "addqi_ext_1"
6174   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6175                          (const_int 8)
6176                          (const_int 8))
6177         (plus:SI
6178           (zero_extract:SI
6179             (match_operand 1 "ext_register_operand" "0")
6180             (const_int 8)
6181             (const_int 8))
6182           (match_operand:QI 2 "general_operand" "Qmn")))
6183    (clobber (reg:CC FLAGS_REG))]
6184   "!TARGET_64BIT"
6185 {
6186   switch (get_attr_type (insn))
6187     {
6188     case TYPE_INCDEC:
6189       if (operands[2] == const1_rtx)
6190         return "inc{b}\t%h0";
6191       else
6192         {
6193           gcc_assert (operands[2] == constm1_rtx);
6194           return "dec{b}\t%h0";
6195         }
6196
6197     default:
6198       return "add{b}\t{%2, %h0|%h0, %2}";
6199     }
6200 }
6201   [(set (attr "type")
6202      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6203         (const_string "incdec")
6204         (const_string "alu")))
6205    (set_attr "modrm" "1")
6206    (set_attr "mode" "QI")])
6207
6208 (define_insn "*addqi_ext_2"
6209   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6210                          (const_int 8)
6211                          (const_int 8))
6212         (plus:SI
6213           (zero_extract:SI
6214             (match_operand 1 "ext_register_operand" "%0")
6215             (const_int 8)
6216             (const_int 8))
6217           (zero_extract:SI
6218             (match_operand 2 "ext_register_operand" "Q")
6219             (const_int 8)
6220             (const_int 8))))
6221    (clobber (reg:CC FLAGS_REG))]
6222   ""
6223   "add{b}\t{%h2, %h0|%h0, %h2}"
6224   [(set_attr "type" "alu")
6225    (set_attr "mode" "QI")])
6226
6227 ;; The lea patterns for non-Pmodes needs to be matched by
6228 ;; several insns converted to real lea by splitters.
6229
6230 (define_insn_and_split "*lea_general_1"
6231   [(set (match_operand 0 "register_operand" "=r")
6232         (plus (plus (match_operand 1 "index_register_operand" "l")
6233                     (match_operand 2 "register_operand" "r"))
6234               (match_operand 3 "immediate_operand" "i")))]
6235   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6236     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6237    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6238    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6239    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6240    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6241        || GET_MODE (operands[3]) == VOIDmode)"
6242   "#"
6243   "&& reload_completed"
6244   [(const_int 0)]
6245 {
6246   rtx pat;
6247   operands[0] = gen_lowpart (SImode, operands[0]);
6248   operands[1] = gen_lowpart (Pmode, operands[1]);
6249   operands[2] = gen_lowpart (Pmode, operands[2]);
6250   operands[3] = gen_lowpart (Pmode, operands[3]);
6251   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6252                       operands[3]);
6253   if (Pmode != SImode)
6254     pat = gen_rtx_SUBREG (SImode, pat, 0);
6255   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6256   DONE;
6257 }
6258   [(set_attr "type" "lea")
6259    (set_attr "mode" "SI")])
6260
6261 (define_insn_and_split "*lea_general_1_zext"
6262   [(set (match_operand:DI 0 "register_operand" "=r")
6263         (zero_extend:DI
6264           (plus:SI (plus:SI
6265                      (match_operand:SI 1 "index_register_operand" "l")
6266                      (match_operand:SI 2 "register_operand" "r"))
6267                    (match_operand:SI 3 "immediate_operand" "i"))))]
6268   "TARGET_64BIT"
6269   "#"
6270   "&& reload_completed"
6271   [(set (match_dup 0)
6272         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6273                                                      (match_dup 2))
6274                                             (match_dup 3)) 0)))]
6275 {
6276   operands[1] = gen_lowpart (Pmode, operands[1]);
6277   operands[2] = gen_lowpart (Pmode, operands[2]);
6278   operands[3] = gen_lowpart (Pmode, operands[3]);
6279 }
6280   [(set_attr "type" "lea")
6281    (set_attr "mode" "SI")])
6282
6283 (define_insn_and_split "*lea_general_2"
6284   [(set (match_operand 0 "register_operand" "=r")
6285         (plus (mult (match_operand 1 "index_register_operand" "l")
6286                     (match_operand 2 "const248_operand" "i"))
6287               (match_operand 3 "nonmemory_operand" "ri")))]
6288   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6289     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6290    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6291    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6292    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6293        || GET_MODE (operands[3]) == VOIDmode)"
6294   "#"
6295   "&& reload_completed"
6296   [(const_int 0)]
6297 {
6298   rtx pat;
6299   operands[0] = gen_lowpart (SImode, operands[0]);
6300   operands[1] = gen_lowpart (Pmode, operands[1]);
6301   operands[3] = gen_lowpart (Pmode, operands[3]);
6302   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6303                       operands[3]);
6304   if (Pmode != SImode)
6305     pat = gen_rtx_SUBREG (SImode, pat, 0);
6306   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6307   DONE;
6308 }
6309   [(set_attr "type" "lea")
6310    (set_attr "mode" "SI")])
6311
6312 (define_insn_and_split "*lea_general_2_zext"
6313   [(set (match_operand:DI 0 "register_operand" "=r")
6314         (zero_extend:DI
6315           (plus:SI (mult:SI
6316                      (match_operand:SI 1 "index_register_operand" "l")
6317                      (match_operand:SI 2 "const248_operand" "n"))
6318                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6319   "TARGET_64BIT"
6320   "#"
6321   "&& reload_completed"
6322   [(set (match_dup 0)
6323         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6324                                                      (match_dup 2))
6325                                             (match_dup 3)) 0)))]
6326 {
6327   operands[1] = gen_lowpart (Pmode, operands[1]);
6328   operands[3] = gen_lowpart (Pmode, operands[3]);
6329 }
6330   [(set_attr "type" "lea")
6331    (set_attr "mode" "SI")])
6332
6333 (define_insn_and_split "*lea_general_3"
6334   [(set (match_operand 0 "register_operand" "=r")
6335         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6336                           (match_operand 2 "const248_operand" "i"))
6337                     (match_operand 3 "register_operand" "r"))
6338               (match_operand 4 "immediate_operand" "i")))]
6339   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6340     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6341    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6342    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6343    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6344   "#"
6345   "&& reload_completed"
6346   [(const_int 0)]
6347 {
6348   rtx pat;
6349   operands[0] = gen_lowpart (SImode, operands[0]);
6350   operands[1] = gen_lowpart (Pmode, operands[1]);
6351   operands[3] = gen_lowpart (Pmode, operands[3]);
6352   operands[4] = gen_lowpart (Pmode, operands[4]);
6353   pat = gen_rtx_PLUS (Pmode,
6354                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6355                                                          operands[2]),
6356                                     operands[3]),
6357                       operands[4]);
6358   if (Pmode != SImode)
6359     pat = gen_rtx_SUBREG (SImode, pat, 0);
6360   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6361   DONE;
6362 }
6363   [(set_attr "type" "lea")
6364    (set_attr "mode" "SI")])
6365
6366 (define_insn_and_split "*lea_general_3_zext"
6367   [(set (match_operand:DI 0 "register_operand" "=r")
6368         (zero_extend:DI
6369           (plus:SI (plus:SI
6370                      (mult:SI
6371                        (match_operand:SI 1 "index_register_operand" "l")
6372                        (match_operand:SI 2 "const248_operand" "n"))
6373                      (match_operand:SI 3 "register_operand" "r"))
6374                    (match_operand:SI 4 "immediate_operand" "i"))))]
6375   "TARGET_64BIT"
6376   "#"
6377   "&& reload_completed"
6378   [(set (match_dup 0)
6379         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6380                                                               (match_dup 2))
6381                                                      (match_dup 3))
6382                                             (match_dup 4)) 0)))]
6383 {
6384   operands[1] = gen_lowpart (Pmode, operands[1]);
6385   operands[3] = gen_lowpart (Pmode, operands[3]);
6386   operands[4] = gen_lowpart (Pmode, operands[4]);
6387 }
6388   [(set_attr "type" "lea")
6389    (set_attr "mode" "SI")])
6390
6391 (define_insn_and_split "*lea_general_4"
6392   [(set (match_operand:SWI 0 "register_operand" "=r")
6393         (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" "l")
6394                                 (match_operand:SWI 2 "const_int_operand" "n"))
6395                     (match_operand 3 "const_int_operand" "n")))]
6396   "(<MODE>mode == DImode
6397     || <MODE>mode == SImode
6398     || !TARGET_PARTIAL_REG_STALL
6399     || optimize_function_for_size_p (cfun))
6400    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6401    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6402        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6403   "#"
6404   "&& reload_completed"
6405   [(const_int 0)]
6406 {
6407   rtx pat;
6408   if (<MODE>mode != DImode)
6409     operands[0] = gen_lowpart (SImode, operands[0]);
6410   operands[1] = gen_lowpart (Pmode, operands[1]);
6411   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6412   pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]),
6413                        INTVAL (operands[3]));
6414   if (Pmode != SImode && <MODE>mode != DImode)
6415     pat = gen_rtx_SUBREG (SImode, pat, 0);
6416   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6417   DONE;
6418 }
6419   [(set_attr "type" "lea")
6420    (set (attr "mode")
6421       (if_then_else (eq (symbol_ref "<MODE>mode == DImode") (const_int 0))
6422         (const_string "SI")
6423         (const_string "DI")))])
6424 \f
6425 ;; Subtract instructions
6426
6427 (define_expand "sub<mode>3"
6428   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6429         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6430                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6431   ""
6432   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6433
6434 (define_insn_and_split "*sub<dwi>3_doubleword"
6435   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6436         (minus:<DWI>
6437           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6438           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6439    (clobber (reg:CC FLAGS_REG))]
6440   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6441   "#"
6442   "reload_completed"
6443   [(parallel [(set (reg:CC FLAGS_REG)
6444                    (compare:CC (match_dup 1) (match_dup 2)))
6445               (set (match_dup 0)
6446                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6447    (parallel [(set (match_dup 3)
6448                    (minus:DWIH
6449                      (match_dup 4)
6450                      (plus:DWIH
6451                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6452                        (match_dup 5))))
6453               (clobber (reg:CC FLAGS_REG))])]
6454   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6455
6456 (define_insn "*sub<mode>_1"
6457   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6458         (minus:SWI
6459           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6460           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6461    (clobber (reg:CC FLAGS_REG))]
6462   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6463   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6464   [(set_attr "type" "alu")
6465    (set_attr "mode" "<MODE>")])
6466
6467 (define_insn "*subsi_1_zext"
6468   [(set (match_operand:DI 0 "register_operand" "=r")
6469         (zero_extend:DI
6470           (minus:SI (match_operand:SI 1 "register_operand" "0")
6471                     (match_operand:SI 2 "general_operand" "g"))))
6472    (clobber (reg:CC FLAGS_REG))]
6473   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6474   "sub{l}\t{%2, %k0|%k0, %2}"
6475   [(set_attr "type" "alu")
6476    (set_attr "mode" "SI")])
6477
6478 (define_insn "*subqi_1_slp"
6479   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6480         (minus:QI (match_dup 0)
6481                   (match_operand:QI 1 "general_operand" "qn,qm")))
6482    (clobber (reg:CC FLAGS_REG))]
6483   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6484    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6485   "sub{b}\t{%1, %0|%0, %1}"
6486   [(set_attr "type" "alu1")
6487    (set_attr "mode" "QI")])
6488
6489 (define_insn "*sub<mode>_2"
6490   [(set (reg FLAGS_REG)
6491         (compare
6492           (minus:SWI
6493             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6494             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6495           (const_int 0)))
6496    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6497         (minus:SWI (match_dup 1) (match_dup 2)))]
6498   "ix86_match_ccmode (insn, CCGOCmode)
6499    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6500   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6501   [(set_attr "type" "alu")
6502    (set_attr "mode" "<MODE>")])
6503
6504 (define_insn "*subsi_2_zext"
6505   [(set (reg FLAGS_REG)
6506         (compare
6507           (minus:SI (match_operand:SI 1 "register_operand" "0")
6508                     (match_operand:SI 2 "general_operand" "g"))
6509           (const_int 0)))
6510    (set (match_operand:DI 0 "register_operand" "=r")
6511         (zero_extend:DI
6512           (minus:SI (match_dup 1)
6513                     (match_dup 2))))]
6514   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6515    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516   "sub{l}\t{%2, %k0|%k0, %2}"
6517   [(set_attr "type" "alu")
6518    (set_attr "mode" "SI")])
6519
6520 (define_insn "*sub<mode>_3"
6521   [(set (reg FLAGS_REG)
6522         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6523                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6524    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6525         (minus:SWI (match_dup 1) (match_dup 2)))]
6526   "ix86_match_ccmode (insn, CCmode)
6527    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6528   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6529   [(set_attr "type" "alu")
6530    (set_attr "mode" "<MODE>")])
6531
6532 (define_insn "*subsi_3_zext"
6533   [(set (reg FLAGS_REG)
6534         (compare (match_operand:SI 1 "register_operand" "0")
6535                  (match_operand:SI 2 "general_operand" "g")))
6536    (set (match_operand:DI 0 "register_operand" "=r")
6537         (zero_extend:DI
6538           (minus:SI (match_dup 1)
6539                     (match_dup 2))))]
6540   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6541    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6542   "sub{l}\t{%2, %1|%1, %2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "mode" "SI")])
6545 \f
6546 ;; Add with carry and subtract with borrow
6547
6548 (define_expand "<plusminus_insn><mode>3_carry"
6549   [(parallel
6550     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6551           (plusminus:SWI
6552             (match_operand:SWI 1 "nonimmediate_operand" "")
6553             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6554                        [(match_operand 3 "flags_reg_operand" "")
6555                         (const_int 0)])
6556                       (match_operand:SWI 2 "<general_operand>" ""))))
6557      (clobber (reg:CC FLAGS_REG))])]
6558   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6559
6560 (define_insn "*<plusminus_insn><mode>3_carry"
6561   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6562         (plusminus:SWI
6563           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6564           (plus:SWI
6565             (match_operator 3 "ix86_carry_flag_operator"
6566              [(reg FLAGS_REG) (const_int 0)])
6567             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6568    (clobber (reg:CC FLAGS_REG))]
6569   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6570   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6571   [(set_attr "type" "alu")
6572    (set_attr "use_carry" "1")
6573    (set_attr "pent_pair" "pu")
6574    (set_attr "mode" "<MODE>")])
6575
6576 (define_insn "*addsi3_carry_zext"
6577   [(set (match_operand:DI 0 "register_operand" "=r")
6578         (zero_extend:DI
6579           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6580                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6581                              [(reg FLAGS_REG) (const_int 0)])
6582                             (match_operand:SI 2 "general_operand" "g")))))
6583    (clobber (reg:CC FLAGS_REG))]
6584   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6585   "adc{l}\t{%2, %k0|%k0, %2}"
6586   [(set_attr "type" "alu")
6587    (set_attr "use_carry" "1")
6588    (set_attr "pent_pair" "pu")
6589    (set_attr "mode" "SI")])
6590
6591 (define_insn "*subsi3_carry_zext"
6592   [(set (match_operand:DI 0 "register_operand" "=r")
6593         (zero_extend:DI
6594           (minus:SI (match_operand:SI 1 "register_operand" "0")
6595                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6596                               [(reg FLAGS_REG) (const_int 0)])
6597                              (match_operand:SI 2 "general_operand" "g")))))
6598    (clobber (reg:CC FLAGS_REG))]
6599   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6600   "sbb{l}\t{%2, %k0|%k0, %2}"
6601   [(set_attr "type" "alu")
6602    (set_attr "pent_pair" "pu")
6603    (set_attr "mode" "SI")])
6604 \f
6605 ;; Overflow setting add and subtract instructions
6606
6607 (define_insn "*add<mode>3_cconly_overflow"
6608   [(set (reg:CCC FLAGS_REG)
6609         (compare:CCC
6610           (plus:SWI
6611             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6612             (match_operand:SWI 2 "<general_operand>" "<g>"))
6613           (match_dup 1)))
6614    (clobber (match_scratch:SWI 0 "=<r>"))]
6615   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6617   [(set_attr "type" "alu")
6618    (set_attr "mode" "<MODE>")])
6619
6620 (define_insn "*sub<mode>3_cconly_overflow"
6621   [(set (reg:CCC FLAGS_REG)
6622         (compare:CCC
6623           (minus:SWI
6624             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6625             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6626           (match_dup 0)))]
6627   ""
6628   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6629   [(set_attr "type" "icmp")
6630    (set_attr "mode" "<MODE>")])
6631
6632 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6633   [(set (reg:CCC FLAGS_REG)
6634         (compare:CCC
6635             (plusminus:SWI
6636                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6637                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6638             (match_dup 1)))
6639    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6640         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6641   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6642   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "mode" "<MODE>")])
6645
6646 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6647   [(set (reg:CCC FLAGS_REG)
6648         (compare:CCC
6649           (plusminus:SI
6650             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6651             (match_operand:SI 2 "general_operand" "g"))
6652           (match_dup 1)))
6653    (set (match_operand:DI 0 "register_operand" "=r")
6654         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6655   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6656   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6657   [(set_attr "type" "alu")
6658    (set_attr "mode" "SI")])
6659
6660 ;; The patterns that match these are at the end of this file.
6661
6662 (define_expand "<plusminus_insn>xf3"
6663   [(set (match_operand:XF 0 "register_operand" "")
6664         (plusminus:XF
6665           (match_operand:XF 1 "register_operand" "")
6666           (match_operand:XF 2 "register_operand" "")))]
6667   "TARGET_80387")
6668
6669 (define_expand "<plusminus_insn><mode>3"
6670   [(set (match_operand:MODEF 0 "register_operand" "")
6671         (plusminus:MODEF
6672           (match_operand:MODEF 1 "register_operand" "")
6673           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6674   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6675     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6676 \f
6677 ;; Multiply instructions
6678
6679 (define_expand "mul<mode>3"
6680   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6681                    (mult:SWIM248
6682                      (match_operand:SWIM248 1 "register_operand" "")
6683                      (match_operand:SWIM248 2 "<general_operand>" "")))
6684               (clobber (reg:CC FLAGS_REG))])])
6685
6686 (define_expand "mulqi3"
6687   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6688                    (mult:QI
6689                      (match_operand:QI 1 "register_operand" "")
6690                      (match_operand:QI 2 "nonimmediate_operand" "")))
6691               (clobber (reg:CC FLAGS_REG))])]
6692   "TARGET_QIMODE_MATH")
6693
6694 ;; On AMDFAM10
6695 ;; IMUL reg32/64, reg32/64, imm8        Direct
6696 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6697 ;; IMUL reg32/64, reg32/64, imm32       Direct
6698 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6699 ;; IMUL reg32/64, reg32/64              Direct
6700 ;; IMUL reg32/64, mem32/64              Direct
6701 ;;
6702 ;; On BDVER1, all above IMULs use DirectPath
6703
6704 (define_insn "*mul<mode>3_1"
6705   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6706         (mult:SWI48
6707           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6708           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6709    (clobber (reg:CC FLAGS_REG))]
6710   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6711   "@
6712    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6713    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6714    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6715   [(set_attr "type" "imul")
6716    (set_attr "prefix_0f" "0,0,1")
6717    (set (attr "athlon_decode")
6718         (cond [(eq_attr "cpu" "athlon")
6719                   (const_string "vector")
6720                (eq_attr "alternative" "1")
6721                   (const_string "vector")
6722                (and (eq_attr "alternative" "2")
6723                     (match_operand 1 "memory_operand" ""))
6724                   (const_string "vector")]
6725               (const_string "direct")))
6726    (set (attr "amdfam10_decode")
6727         (cond [(and (eq_attr "alternative" "0,1")
6728                     (match_operand 1 "memory_operand" ""))
6729                   (const_string "vector")]
6730               (const_string "direct")))
6731    (set_attr "bdver1_decode" "direct")
6732    (set_attr "mode" "<MODE>")])
6733
6734 (define_insn "*mulsi3_1_zext"
6735   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6736         (zero_extend:DI
6737           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6738                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6739    (clobber (reg:CC FLAGS_REG))]
6740   "TARGET_64BIT
6741    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6742   "@
6743    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6744    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6745    imul{l}\t{%2, %k0|%k0, %2}"
6746   [(set_attr "type" "imul")
6747    (set_attr "prefix_0f" "0,0,1")
6748    (set (attr "athlon_decode")
6749         (cond [(eq_attr "cpu" "athlon")
6750                   (const_string "vector")
6751                (eq_attr "alternative" "1")
6752                   (const_string "vector")
6753                (and (eq_attr "alternative" "2")
6754                     (match_operand 1 "memory_operand" ""))
6755                   (const_string "vector")]
6756               (const_string "direct")))
6757    (set (attr "amdfam10_decode")
6758         (cond [(and (eq_attr "alternative" "0,1")
6759                     (match_operand 1 "memory_operand" ""))
6760                   (const_string "vector")]
6761               (const_string "direct")))
6762    (set_attr "bdver1_decode" "direct")
6763    (set_attr "mode" "SI")])
6764
6765 ;; On AMDFAM10
6766 ;; IMUL reg16, reg16, imm8      VectorPath
6767 ;; IMUL reg16, mem16, imm8      VectorPath
6768 ;; IMUL reg16, reg16, imm16     VectorPath
6769 ;; IMUL reg16, mem16, imm16     VectorPath
6770 ;; IMUL reg16, reg16            Direct
6771 ;; IMUL reg16, mem16            Direct
6772 ;;
6773 ;; On BDVER1, all HI MULs use DoublePath
6774
6775 (define_insn "*mulhi3_1"
6776   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6777         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6778                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6779    (clobber (reg:CC FLAGS_REG))]
6780   "TARGET_HIMODE_MATH
6781    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6782   "@
6783    imul{w}\t{%2, %1, %0|%0, %1, %2}
6784    imul{w}\t{%2, %1, %0|%0, %1, %2}
6785    imul{w}\t{%2, %0|%0, %2}"
6786   [(set_attr "type" "imul")
6787    (set_attr "prefix_0f" "0,0,1")
6788    (set (attr "athlon_decode")
6789         (cond [(eq_attr "cpu" "athlon")
6790                   (const_string "vector")
6791                (eq_attr "alternative" "1,2")
6792                   (const_string "vector")]
6793               (const_string "direct")))
6794    (set (attr "amdfam10_decode")
6795         (cond [(eq_attr "alternative" "0,1")
6796                   (const_string "vector")]
6797               (const_string "direct")))
6798    (set_attr "bdver1_decode" "double")
6799    (set_attr "mode" "HI")])
6800
6801 ;;On AMDFAM10 and BDVER1
6802 ;; MUL reg8     Direct
6803 ;; MUL mem8     Direct
6804
6805 (define_insn "*mulqi3_1"
6806   [(set (match_operand:QI 0 "register_operand" "=a")
6807         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6808                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6809    (clobber (reg:CC FLAGS_REG))]
6810   "TARGET_QIMODE_MATH
6811    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812   "mul{b}\t%2"
6813   [(set_attr "type" "imul")
6814    (set_attr "length_immediate" "0")
6815    (set (attr "athlon_decode")
6816      (if_then_else (eq_attr "cpu" "athlon")
6817         (const_string "vector")
6818         (const_string "direct")))
6819    (set_attr "amdfam10_decode" "direct")
6820    (set_attr "bdver1_decode" "direct")
6821    (set_attr "mode" "QI")])
6822
6823 (define_expand "<u>mul<mode><dwi>3"
6824   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6825                    (mult:<DWI>
6826                      (any_extend:<DWI>
6827                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6828                      (any_extend:<DWI>
6829                        (match_operand:DWIH 2 "register_operand" ""))))
6830               (clobber (reg:CC FLAGS_REG))])])
6831
6832 (define_expand "<u>mulqihi3"
6833   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6834                    (mult:HI
6835                      (any_extend:HI
6836                        (match_operand:QI 1 "nonimmediate_operand" ""))
6837                      (any_extend:HI
6838                        (match_operand:QI 2 "register_operand" ""))))
6839               (clobber (reg:CC FLAGS_REG))])]
6840   "TARGET_QIMODE_MATH")
6841
6842 (define_insn "*<u>mul<mode><dwi>3_1"
6843   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6844         (mult:<DWI>
6845           (any_extend:<DWI>
6846             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6847           (any_extend:<DWI>
6848             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6849    (clobber (reg:CC FLAGS_REG))]
6850   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6851   "<sgnprefix>mul{<imodesuffix>}\t%2"
6852   [(set_attr "type" "imul")
6853    (set_attr "length_immediate" "0")
6854    (set (attr "athlon_decode")
6855      (if_then_else (eq_attr "cpu" "athlon")
6856         (const_string "vector")
6857         (const_string "double")))
6858    (set_attr "amdfam10_decode" "double")
6859    (set_attr "bdver1_decode" "direct")
6860    (set_attr "mode" "<MODE>")])
6861
6862 (define_insn "*<u>mulqihi3_1"
6863   [(set (match_operand:HI 0 "register_operand" "=a")
6864         (mult:HI
6865           (any_extend:HI
6866             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6867           (any_extend:HI
6868             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6869    (clobber (reg:CC FLAGS_REG))]
6870   "TARGET_QIMODE_MATH
6871    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6872   "<sgnprefix>mul{b}\t%2"
6873   [(set_attr "type" "imul")
6874    (set_attr "length_immediate" "0")
6875    (set (attr "athlon_decode")
6876      (if_then_else (eq_attr "cpu" "athlon")
6877         (const_string "vector")
6878         (const_string "direct")))
6879    (set_attr "amdfam10_decode" "direct")
6880    (set_attr "bdver1_decode" "direct")
6881    (set_attr "mode" "QI")])
6882
6883 (define_expand "<s>mul<mode>3_highpart"
6884   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6885                    (truncate:SWI48
6886                      (lshiftrt:<DWI>
6887                        (mult:<DWI>
6888                          (any_extend:<DWI>
6889                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6890                          (any_extend:<DWI>
6891                            (match_operand:SWI48 2 "register_operand" "")))
6892                        (match_dup 4))))
6893               (clobber (match_scratch:SWI48 3 ""))
6894               (clobber (reg:CC FLAGS_REG))])]
6895   ""
6896   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6897
6898 (define_insn "*<s>muldi3_highpart_1"
6899   [(set (match_operand:DI 0 "register_operand" "=d")
6900         (truncate:DI
6901           (lshiftrt:TI
6902             (mult:TI
6903               (any_extend:TI
6904                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6905               (any_extend:TI
6906                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6907             (const_int 64))))
6908    (clobber (match_scratch:DI 3 "=1"))
6909    (clobber (reg:CC FLAGS_REG))]
6910   "TARGET_64BIT
6911    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6912   "<sgnprefix>mul{q}\t%2"
6913   [(set_attr "type" "imul")
6914    (set_attr "length_immediate" "0")
6915    (set (attr "athlon_decode")
6916      (if_then_else (eq_attr "cpu" "athlon")
6917         (const_string "vector")
6918         (const_string "double")))
6919    (set_attr "amdfam10_decode" "double")
6920    (set_attr "bdver1_decode" "direct")
6921    (set_attr "mode" "DI")])
6922
6923 (define_insn "*<s>mulsi3_highpart_1"
6924   [(set (match_operand:SI 0 "register_operand" "=d")
6925         (truncate:SI
6926           (lshiftrt:DI
6927             (mult:DI
6928               (any_extend:DI
6929                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6930               (any_extend:DI
6931                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6932             (const_int 32))))
6933    (clobber (match_scratch:SI 3 "=1"))
6934    (clobber (reg:CC FLAGS_REG))]
6935   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6936   "<sgnprefix>mul{l}\t%2"
6937   [(set_attr "type" "imul")
6938    (set_attr "length_immediate" "0")
6939    (set (attr "athlon_decode")
6940      (if_then_else (eq_attr "cpu" "athlon")
6941         (const_string "vector")
6942         (const_string "double")))
6943    (set_attr "amdfam10_decode" "double")
6944    (set_attr "bdver1_decode" "direct")
6945    (set_attr "mode" "SI")])
6946
6947 (define_insn "*<s>mulsi3_highpart_zext"
6948   [(set (match_operand:DI 0 "register_operand" "=d")
6949         (zero_extend:DI (truncate:SI
6950           (lshiftrt:DI
6951             (mult:DI (any_extend:DI
6952                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6953                      (any_extend:DI
6954                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6955             (const_int 32)))))
6956    (clobber (match_scratch:SI 3 "=1"))
6957    (clobber (reg:CC FLAGS_REG))]
6958   "TARGET_64BIT
6959    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960   "<sgnprefix>mul{l}\t%2"
6961   [(set_attr "type" "imul")
6962    (set_attr "length_immediate" "0")
6963    (set (attr "athlon_decode")
6964      (if_then_else (eq_attr "cpu" "athlon")
6965         (const_string "vector")
6966         (const_string "double")))
6967    (set_attr "amdfam10_decode" "double")
6968    (set_attr "bdver1_decode" "direct")
6969    (set_attr "mode" "SI")])
6970
6971 ;; The patterns that match these are at the end of this file.
6972
6973 (define_expand "mulxf3"
6974   [(set (match_operand:XF 0 "register_operand" "")
6975         (mult:XF (match_operand:XF 1 "register_operand" "")
6976                  (match_operand:XF 2 "register_operand" "")))]
6977   "TARGET_80387")
6978
6979 (define_expand "mul<mode>3"
6980   [(set (match_operand:MODEF 0 "register_operand" "")
6981         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6982                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6983   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6984     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6985 \f
6986 ;; Divide instructions
6987
6988 ;; The patterns that match these are at the end of this file.
6989
6990 (define_expand "divxf3"
6991   [(set (match_operand:XF 0 "register_operand" "")
6992         (div:XF (match_operand:XF 1 "register_operand" "")
6993                 (match_operand:XF 2 "register_operand" "")))]
6994   "TARGET_80387")
6995
6996 (define_expand "divdf3"
6997   [(set (match_operand:DF 0 "register_operand" "")
6998         (div:DF (match_operand:DF 1 "register_operand" "")
6999                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7000    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7001     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7002
7003 (define_expand "divsf3"
7004   [(set (match_operand:SF 0 "register_operand" "")
7005         (div:SF (match_operand:SF 1 "register_operand" "")
7006                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7007   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7008     || TARGET_SSE_MATH"
7009 {
7010   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7011       && flag_finite_math_only && !flag_trapping_math
7012       && flag_unsafe_math_optimizations)
7013     {
7014       ix86_emit_swdivsf (operands[0], operands[1],
7015                          operands[2], SFmode);
7016       DONE;
7017     }
7018 })
7019 \f
7020 ;; Divmod instructions.
7021
7022 (define_expand "divmod<mode>4"
7023   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7024                    (div:SWIM248
7025                      (match_operand:SWIM248 1 "register_operand" "")
7026                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7027               (set (match_operand:SWIM248 3 "register_operand" "")
7028                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7029               (clobber (reg:CC FLAGS_REG))])])
7030
7031 ;; Split with 8bit unsigned divide:
7032 ;;      if (dividend an divisor are in [0-255])
7033 ;;         use 8bit unsigned integer divide
7034 ;;       else
7035 ;;         use original integer divide
7036 (define_split
7037   [(set (match_operand:SWI48 0 "register_operand" "")
7038         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7039                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7040    (set (match_operand:SWI48 1 "register_operand" "")
7041         (mod:SWI48 (match_dup 2) (match_dup 3)))
7042    (clobber (reg:CC FLAGS_REG))]
7043   "TARGET_USE_8BIT_IDIV
7044    && TARGET_QIMODE_MATH
7045    && can_create_pseudo_p ()
7046    && !optimize_insn_for_size_p ()"
7047   [(const_int 0)]
7048   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7049
7050 (define_insn_and_split "divmod<mode>4_1"
7051   [(set (match_operand:SWI48 0 "register_operand" "=a")
7052         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7053                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7054    (set (match_operand:SWI48 1 "register_operand" "=&d")
7055         (mod:SWI48 (match_dup 2) (match_dup 3)))
7056    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7057    (clobber (reg:CC FLAGS_REG))]
7058   ""
7059   "#"
7060   "reload_completed"
7061   [(parallel [(set (match_dup 1)
7062                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7063               (clobber (reg:CC FLAGS_REG))])
7064    (parallel [(set (match_dup 0)
7065                    (div:SWI48 (match_dup 2) (match_dup 3)))
7066               (set (match_dup 1)
7067                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7068               (use (match_dup 1))
7069               (clobber (reg:CC FLAGS_REG))])]
7070 {
7071   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7072
7073   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7074     operands[4] = operands[2];
7075   else
7076     {
7077       /* Avoid use of cltd in favor of a mov+shift.  */
7078       emit_move_insn (operands[1], operands[2]);
7079       operands[4] = operands[1];
7080     }
7081 }
7082   [(set_attr "type" "multi")
7083    (set_attr "mode" "<MODE>")])
7084
7085 (define_insn_and_split "*divmod<mode>4"
7086   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7087         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7088                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7089    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7090         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7091    (clobber (reg:CC FLAGS_REG))]
7092   ""
7093   "#"
7094   "reload_completed"
7095   [(parallel [(set (match_dup 1)
7096                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7097               (clobber (reg:CC FLAGS_REG))])
7098    (parallel [(set (match_dup 0)
7099                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7100               (set (match_dup 1)
7101                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7102               (use (match_dup 1))
7103               (clobber (reg:CC FLAGS_REG))])]
7104 {
7105   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7106
7107   if (<MODE>mode != HImode
7108       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7109     operands[4] = operands[2];
7110   else
7111     {
7112       /* Avoid use of cltd in favor of a mov+shift.  */
7113       emit_move_insn (operands[1], operands[2]);
7114       operands[4] = operands[1];
7115     }
7116 }
7117   [(set_attr "type" "multi")
7118    (set_attr "mode" "<MODE>")])
7119
7120 (define_insn "*divmod<mode>4_noext"
7121   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7122         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7123                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7124    (set (match_operand:SWIM248 1 "register_operand" "=d")
7125         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7126    (use (match_operand:SWIM248 4 "register_operand" "1"))
7127    (clobber (reg:CC FLAGS_REG))]
7128   ""
7129   "idiv{<imodesuffix>}\t%3"
7130   [(set_attr "type" "idiv")
7131    (set_attr "mode" "<MODE>")])
7132
7133 (define_expand "divmodqi4"
7134   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7135                    (div:QI
7136                      (match_operand:QI 1 "register_operand" "")
7137                      (match_operand:QI 2 "nonimmediate_operand" "")))
7138               (set (match_operand:QI 3 "register_operand" "")
7139                    (mod:QI (match_dup 1) (match_dup 2)))
7140               (clobber (reg:CC FLAGS_REG))])]
7141   "TARGET_QIMODE_MATH"
7142 {
7143   rtx div, mod, insn;
7144   rtx tmp0, tmp1;
7145   
7146   tmp0 = gen_reg_rtx (HImode);
7147   tmp1 = gen_reg_rtx (HImode);
7148
7149   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7150      in AX.  */
7151   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7152   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7153
7154   /* Extract remainder from AH.  */
7155   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7156   insn = emit_move_insn (operands[3], tmp1);
7157
7158   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7159   set_unique_reg_note (insn, REG_EQUAL, mod);
7160
7161   /* Extract quotient from AL.  */
7162   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7163
7164   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7165   set_unique_reg_note (insn, REG_EQUAL, div);
7166
7167   DONE;
7168 })
7169
7170 ;; Divide AX by r/m8, with result stored in
7171 ;; AL <- Quotient
7172 ;; AH <- Remainder
7173 ;; Change div/mod to HImode and extend the second argument to HImode
7174 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7175 ;; combine may fail.
7176 (define_insn "divmodhiqi3"
7177   [(set (match_operand:HI 0 "register_operand" "=a")
7178         (ior:HI
7179           (ashift:HI
7180             (zero_extend:HI
7181               (truncate:QI
7182                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7183                         (sign_extend:HI
7184                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7185             (const_int 8))
7186           (zero_extend:HI
7187             (truncate:QI
7188               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7189    (clobber (reg:CC FLAGS_REG))]
7190   "TARGET_QIMODE_MATH"
7191   "idiv{b}\t%2"
7192   [(set_attr "type" "idiv")
7193    (set_attr "mode" "QI")])
7194
7195 (define_expand "udivmod<mode>4"
7196   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7197                    (udiv:SWIM248
7198                      (match_operand:SWIM248 1 "register_operand" "")
7199                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7200               (set (match_operand:SWIM248 3 "register_operand" "")
7201                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7202               (clobber (reg:CC FLAGS_REG))])])
7203
7204 ;; Split with 8bit unsigned divide:
7205 ;;      if (dividend an divisor are in [0-255])
7206 ;;         use 8bit unsigned integer divide
7207 ;;       else
7208 ;;         use original integer divide
7209 (define_split
7210   [(set (match_operand:SWI48 0 "register_operand" "")
7211         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7212                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7213    (set (match_operand:SWI48 1 "register_operand" "")
7214         (umod:SWI48 (match_dup 2) (match_dup 3)))
7215    (clobber (reg:CC FLAGS_REG))]
7216   "TARGET_USE_8BIT_IDIV
7217    && TARGET_QIMODE_MATH
7218    && can_create_pseudo_p ()
7219    && !optimize_insn_for_size_p ()"
7220   [(const_int 0)]
7221   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7222
7223 (define_insn_and_split "udivmod<mode>4_1"
7224   [(set (match_operand:SWI48 0 "register_operand" "=a")
7225         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7226                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7227    (set (match_operand:SWI48 1 "register_operand" "=&d")
7228         (umod:SWI48 (match_dup 2) (match_dup 3)))
7229    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7230    (clobber (reg:CC FLAGS_REG))]
7231   ""
7232   "#"
7233   "reload_completed"
7234   [(set (match_dup 1) (const_int 0))
7235    (parallel [(set (match_dup 0)
7236                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7237               (set (match_dup 1)
7238                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7239               (use (match_dup 1))
7240               (clobber (reg:CC FLAGS_REG))])]
7241   ""
7242   [(set_attr "type" "multi")
7243    (set_attr "mode" "<MODE>")])
7244
7245 (define_insn_and_split "*udivmod<mode>4"
7246   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7247         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7248                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7249    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7250         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7251    (clobber (reg:CC FLAGS_REG))]
7252   ""
7253   "#"
7254   "reload_completed"
7255   [(set (match_dup 1) (const_int 0))
7256    (parallel [(set (match_dup 0)
7257                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7258               (set (match_dup 1)
7259                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7260               (use (match_dup 1))
7261               (clobber (reg:CC FLAGS_REG))])]
7262   ""
7263   [(set_attr "type" "multi")
7264    (set_attr "mode" "<MODE>")])
7265
7266 (define_insn "*udivmod<mode>4_noext"
7267   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7268         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7269                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7270    (set (match_operand:SWIM248 1 "register_operand" "=d")
7271         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7272    (use (match_operand:SWIM248 4 "register_operand" "1"))
7273    (clobber (reg:CC FLAGS_REG))]
7274   ""
7275   "div{<imodesuffix>}\t%3"
7276   [(set_attr "type" "idiv")
7277    (set_attr "mode" "<MODE>")])
7278
7279 (define_expand "udivmodqi4"
7280   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7281                    (udiv:QI
7282                      (match_operand:QI 1 "register_operand" "")
7283                      (match_operand:QI 2 "nonimmediate_operand" "")))
7284               (set (match_operand:QI 3 "register_operand" "")
7285                    (umod:QI (match_dup 1) (match_dup 2)))
7286               (clobber (reg:CC FLAGS_REG))])]
7287   "TARGET_QIMODE_MATH"
7288 {
7289   rtx div, mod, insn;
7290   rtx tmp0, tmp1;
7291   
7292   tmp0 = gen_reg_rtx (HImode);
7293   tmp1 = gen_reg_rtx (HImode);
7294
7295   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7296      in AX.  */
7297   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7298   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7299
7300   /* Extract remainder from AH.  */
7301   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7302   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7303   insn = emit_move_insn (operands[3], tmp1);
7304
7305   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7306   set_unique_reg_note (insn, REG_EQUAL, mod);
7307
7308   /* Extract quotient from AL.  */
7309   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7310
7311   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7312   set_unique_reg_note (insn, REG_EQUAL, div);
7313
7314   DONE;
7315 })
7316
7317 (define_insn "udivmodhiqi3"
7318   [(set (match_operand:HI 0 "register_operand" "=a")
7319         (ior:HI
7320           (ashift:HI
7321             (zero_extend:HI
7322               (truncate:QI
7323                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7324                         (zero_extend:HI
7325                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7326             (const_int 8))
7327           (zero_extend:HI
7328             (truncate:QI
7329               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7330    (clobber (reg:CC FLAGS_REG))]
7331   "TARGET_QIMODE_MATH"
7332   "div{b}\t%2"
7333   [(set_attr "type" "idiv")
7334    (set_attr "mode" "QI")])
7335
7336 ;; We cannot use div/idiv for double division, because it causes
7337 ;; "division by zero" on the overflow and that's not what we expect
7338 ;; from truncate.  Because true (non truncating) double division is
7339 ;; never generated, we can't create this insn anyway.
7340 ;
7341 ;(define_insn ""
7342 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7343 ;       (truncate:SI
7344 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7345 ;                  (zero_extend:DI
7346 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7347 ;   (set (match_operand:SI 3 "register_operand" "=d")
7348 ;       (truncate:SI
7349 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7350 ;   (clobber (reg:CC FLAGS_REG))]
7351 ;  ""
7352 ;  "div{l}\t{%2, %0|%0, %2}"
7353 ;  [(set_attr "type" "idiv")])
7354 \f
7355 ;;- Logical AND instructions
7356
7357 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7358 ;; Note that this excludes ah.
7359
7360 (define_expand "testsi_ccno_1"
7361   [(set (reg:CCNO FLAGS_REG)
7362         (compare:CCNO
7363           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7364                   (match_operand:SI 1 "nonmemory_operand" ""))
7365           (const_int 0)))])
7366
7367 (define_expand "testqi_ccz_1"
7368   [(set (reg:CCZ FLAGS_REG)
7369         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7370                              (match_operand:QI 1 "nonmemory_operand" ""))
7371                  (const_int 0)))])
7372
7373 (define_expand "testdi_ccno_1"
7374   [(set (reg:CCNO FLAGS_REG)
7375         (compare:CCNO
7376           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7377                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7378           (const_int 0)))]
7379   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7380
7381 (define_insn "*testdi_1"
7382   [(set (reg FLAGS_REG)
7383         (compare
7384          (and:DI
7385           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7386           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7387          (const_int 0)))]
7388   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7389    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7390   "@
7391    test{l}\t{%k1, %k0|%k0, %k1}
7392    test{l}\t{%k1, %k0|%k0, %k1}
7393    test{q}\t{%1, %0|%0, %1}
7394    test{q}\t{%1, %0|%0, %1}
7395    test{q}\t{%1, %0|%0, %1}"
7396   [(set_attr "type" "test")
7397    (set_attr "modrm" "0,1,0,1,1")
7398    (set_attr "mode" "SI,SI,DI,DI,DI")])
7399
7400 (define_insn "*testqi_1_maybe_si"
7401   [(set (reg FLAGS_REG)
7402         (compare
7403           (and:QI
7404             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7405             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7406           (const_int 0)))]
7407    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7408     && ix86_match_ccmode (insn,
7409                          CONST_INT_P (operands[1])
7410                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7411 {
7412   if (which_alternative == 3)
7413     {
7414       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7415         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7416       return "test{l}\t{%1, %k0|%k0, %1}";
7417     }
7418   return "test{b}\t{%1, %0|%0, %1}";
7419 }
7420   [(set_attr "type" "test")
7421    (set_attr "modrm" "0,1,1,1")
7422    (set_attr "mode" "QI,QI,QI,SI")
7423    (set_attr "pent_pair" "uv,np,uv,np")])
7424
7425 (define_insn "*test<mode>_1"
7426   [(set (reg FLAGS_REG)
7427         (compare
7428          (and:SWI124
7429           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7430           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7431          (const_int 0)))]
7432   "ix86_match_ccmode (insn, CCNOmode)
7433    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7434   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7435   [(set_attr "type" "test")
7436    (set_attr "modrm" "0,1,1")
7437    (set_attr "mode" "<MODE>")
7438    (set_attr "pent_pair" "uv,np,uv")])
7439
7440 (define_expand "testqi_ext_ccno_0"
7441   [(set (reg:CCNO FLAGS_REG)
7442         (compare:CCNO
7443           (and:SI
7444             (zero_extract:SI
7445               (match_operand 0 "ext_register_operand" "")
7446               (const_int 8)
7447               (const_int 8))
7448             (match_operand 1 "const_int_operand" ""))
7449           (const_int 0)))])
7450
7451 (define_insn "*testqi_ext_0"
7452   [(set (reg FLAGS_REG)
7453         (compare
7454           (and:SI
7455             (zero_extract:SI
7456               (match_operand 0 "ext_register_operand" "Q")
7457               (const_int 8)
7458               (const_int 8))
7459             (match_operand 1 "const_int_operand" "n"))
7460           (const_int 0)))]
7461   "ix86_match_ccmode (insn, CCNOmode)"
7462   "test{b}\t{%1, %h0|%h0, %1}"
7463   [(set_attr "type" "test")
7464    (set_attr "mode" "QI")
7465    (set_attr "length_immediate" "1")
7466    (set_attr "modrm" "1")
7467    (set_attr "pent_pair" "np")])
7468
7469 (define_insn "*testqi_ext_1_rex64"
7470   [(set (reg FLAGS_REG)
7471         (compare
7472           (and:SI
7473             (zero_extract:SI
7474               (match_operand 0 "ext_register_operand" "Q")
7475               (const_int 8)
7476               (const_int 8))
7477             (zero_extend:SI
7478               (match_operand:QI 1 "register_operand" "Q")))
7479           (const_int 0)))]
7480   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7481   "test{b}\t{%1, %h0|%h0, %1}"
7482   [(set_attr "type" "test")
7483    (set_attr "mode" "QI")])
7484
7485 (define_insn "*testqi_ext_1"
7486   [(set (reg FLAGS_REG)
7487         (compare
7488           (and:SI
7489             (zero_extract:SI
7490               (match_operand 0 "ext_register_operand" "Q")
7491               (const_int 8)
7492               (const_int 8))
7493             (zero_extend:SI
7494               (match_operand:QI 1 "general_operand" "Qm")))
7495           (const_int 0)))]
7496   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7497   "test{b}\t{%1, %h0|%h0, %1}"
7498   [(set_attr "type" "test")
7499    (set_attr "mode" "QI")])
7500
7501 (define_insn "*testqi_ext_2"
7502   [(set (reg FLAGS_REG)
7503         (compare
7504           (and:SI
7505             (zero_extract:SI
7506               (match_operand 0 "ext_register_operand" "Q")
7507               (const_int 8)
7508               (const_int 8))
7509             (zero_extract:SI
7510               (match_operand 1 "ext_register_operand" "Q")
7511               (const_int 8)
7512               (const_int 8)))
7513           (const_int 0)))]
7514   "ix86_match_ccmode (insn, CCNOmode)"
7515   "test{b}\t{%h1, %h0|%h0, %h1}"
7516   [(set_attr "type" "test")
7517    (set_attr "mode" "QI")])
7518
7519 (define_insn "*testqi_ext_3_rex64"
7520   [(set (reg FLAGS_REG)
7521         (compare (zero_extract:DI
7522                    (match_operand 0 "nonimmediate_operand" "rm")
7523                    (match_operand:DI 1 "const_int_operand" "")
7524                    (match_operand:DI 2 "const_int_operand" ""))
7525                  (const_int 0)))]
7526   "TARGET_64BIT
7527    && ix86_match_ccmode (insn, CCNOmode)
7528    && INTVAL (operands[1]) > 0
7529    && INTVAL (operands[2]) >= 0
7530    /* Ensure that resulting mask is zero or sign extended operand.  */
7531    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7532        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7533            && INTVAL (operands[1]) > 32))
7534    && (GET_MODE (operands[0]) == SImode
7535        || GET_MODE (operands[0]) == DImode
7536        || GET_MODE (operands[0]) == HImode
7537        || GET_MODE (operands[0]) == QImode)"
7538   "#")
7539
7540 ;; Combine likes to form bit extractions for some tests.  Humor it.
7541 (define_insn "*testqi_ext_3"
7542   [(set (reg FLAGS_REG)
7543         (compare (zero_extract:SI
7544                    (match_operand 0 "nonimmediate_operand" "rm")
7545                    (match_operand:SI 1 "const_int_operand" "")
7546                    (match_operand:SI 2 "const_int_operand" ""))
7547                  (const_int 0)))]
7548   "ix86_match_ccmode (insn, CCNOmode)
7549    && INTVAL (operands[1]) > 0
7550    && INTVAL (operands[2]) >= 0
7551    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7552    && (GET_MODE (operands[0]) == SImode
7553        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7554        || GET_MODE (operands[0]) == HImode
7555        || GET_MODE (operands[0]) == QImode)"
7556   "#")
7557
7558 (define_split
7559   [(set (match_operand 0 "flags_reg_operand" "")
7560         (match_operator 1 "compare_operator"
7561           [(zero_extract
7562              (match_operand 2 "nonimmediate_operand" "")
7563              (match_operand 3 "const_int_operand" "")
7564              (match_operand 4 "const_int_operand" ""))
7565            (const_int 0)]))]
7566   "ix86_match_ccmode (insn, CCNOmode)"
7567   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7568 {
7569   rtx val = operands[2];
7570   HOST_WIDE_INT len = INTVAL (operands[3]);
7571   HOST_WIDE_INT pos = INTVAL (operands[4]);
7572   HOST_WIDE_INT mask;
7573   enum machine_mode mode, submode;
7574
7575   mode = GET_MODE (val);
7576   if (MEM_P (val))
7577     {
7578       /* ??? Combine likes to put non-volatile mem extractions in QImode
7579          no matter the size of the test.  So find a mode that works.  */
7580       if (! MEM_VOLATILE_P (val))
7581         {
7582           mode = smallest_mode_for_size (pos + len, MODE_INT);
7583           val = adjust_address (val, mode, 0);
7584         }
7585     }
7586   else if (GET_CODE (val) == SUBREG
7587            && (submode = GET_MODE (SUBREG_REG (val)),
7588                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7589            && pos + len <= GET_MODE_BITSIZE (submode)
7590            && GET_MODE_CLASS (submode) == MODE_INT)
7591     {
7592       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7593       mode = submode;
7594       val = SUBREG_REG (val);
7595     }
7596   else if (mode == HImode && pos + len <= 8)
7597     {
7598       /* Small HImode tests can be converted to QImode.  */
7599       mode = QImode;
7600       val = gen_lowpart (QImode, val);
7601     }
7602
7603   if (len == HOST_BITS_PER_WIDE_INT)
7604     mask = -1;
7605   else
7606     mask = ((HOST_WIDE_INT)1 << len) - 1;
7607   mask <<= pos;
7608
7609   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7610 })
7611
7612 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7613 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7614 ;; this is relatively important trick.
7615 ;; Do the conversion only post-reload to avoid limiting of the register class
7616 ;; to QI regs.
7617 (define_split
7618   [(set (match_operand 0 "flags_reg_operand" "")
7619         (match_operator 1 "compare_operator"
7620           [(and (match_operand 2 "register_operand" "")
7621                 (match_operand 3 "const_int_operand" ""))
7622            (const_int 0)]))]
7623    "reload_completed
7624     && QI_REG_P (operands[2])
7625     && GET_MODE (operands[2]) != QImode
7626     && ((ix86_match_ccmode (insn, CCZmode)
7627          && !(INTVAL (operands[3]) & ~(255 << 8)))
7628         || (ix86_match_ccmode (insn, CCNOmode)
7629             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7630   [(set (match_dup 0)
7631         (match_op_dup 1
7632           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7633                    (match_dup 3))
7634            (const_int 0)]))]
7635   "operands[2] = gen_lowpart (SImode, operands[2]);
7636    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7637
7638 (define_split
7639   [(set (match_operand 0 "flags_reg_operand" "")
7640         (match_operator 1 "compare_operator"
7641           [(and (match_operand 2 "nonimmediate_operand" "")
7642                 (match_operand 3 "const_int_operand" ""))
7643            (const_int 0)]))]
7644    "reload_completed
7645     && GET_MODE (operands[2]) != QImode
7646     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7647     && ((ix86_match_ccmode (insn, CCZmode)
7648          && !(INTVAL (operands[3]) & ~255))
7649         || (ix86_match_ccmode (insn, CCNOmode)
7650             && !(INTVAL (operands[3]) & ~127)))"
7651   [(set (match_dup 0)
7652         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7653                          (const_int 0)]))]
7654   "operands[2] = gen_lowpart (QImode, operands[2]);
7655    operands[3] = gen_lowpart (QImode, operands[3]);")
7656
7657 ;; %%% This used to optimize known byte-wide and operations to memory,
7658 ;; and sometimes to QImode registers.  If this is considered useful,
7659 ;; it should be done with splitters.
7660
7661 (define_expand "and<mode>3"
7662   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7663         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7664                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7665   ""
7666   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7667
7668 (define_insn "*anddi_1"
7669   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7670         (and:DI
7671          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7672          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7673    (clobber (reg:CC FLAGS_REG))]
7674   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7675 {
7676   switch (get_attr_type (insn))
7677     {
7678     case TYPE_IMOVX:
7679       {
7680         enum machine_mode mode;
7681
7682         gcc_assert (CONST_INT_P (operands[2]));
7683         if (INTVAL (operands[2]) == 0xff)
7684           mode = QImode;
7685         else
7686           {
7687             gcc_assert (INTVAL (operands[2]) == 0xffff);
7688             mode = HImode;
7689           }
7690
7691         operands[1] = gen_lowpart (mode, operands[1]);
7692         if (mode == QImode)
7693           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7694         else
7695           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7696       }
7697
7698     default:
7699       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7700       if (get_attr_mode (insn) == MODE_SI)
7701         return "and{l}\t{%k2, %k0|%k0, %k2}";
7702       else
7703         return "and{q}\t{%2, %0|%0, %2}";
7704     }
7705 }
7706   [(set_attr "type" "alu,alu,alu,imovx")
7707    (set_attr "length_immediate" "*,*,*,0")
7708    (set (attr "prefix_rex")
7709      (if_then_else
7710        (and (eq_attr "type" "imovx")
7711             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7712                  (match_operand 1 "ext_QIreg_operand" "")))
7713        (const_string "1")
7714        (const_string "*")))
7715    (set_attr "mode" "SI,DI,DI,SI")])
7716
7717 (define_insn "*andsi_1"
7718   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7719         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7720                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7721    (clobber (reg:CC FLAGS_REG))]
7722   "ix86_binary_operator_ok (AND, SImode, operands)"
7723 {
7724   switch (get_attr_type (insn))
7725     {
7726     case TYPE_IMOVX:
7727       {
7728         enum machine_mode mode;
7729
7730         gcc_assert (CONST_INT_P (operands[2]));
7731         if (INTVAL (operands[2]) == 0xff)
7732           mode = QImode;
7733         else
7734           {
7735             gcc_assert (INTVAL (operands[2]) == 0xffff);
7736             mode = HImode;
7737           }
7738
7739         operands[1] = gen_lowpart (mode, operands[1]);
7740         if (mode == QImode)
7741           return "movz{bl|x}\t{%1, %0|%0, %1}";
7742         else
7743           return "movz{wl|x}\t{%1, %0|%0, %1}";
7744       }
7745
7746     default:
7747       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7748       return "and{l}\t{%2, %0|%0, %2}";
7749     }
7750 }
7751   [(set_attr "type" "alu,alu,imovx")
7752    (set (attr "prefix_rex")
7753      (if_then_else
7754        (and (eq_attr "type" "imovx")
7755             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7756                  (match_operand 1 "ext_QIreg_operand" "")))
7757        (const_string "1")
7758        (const_string "*")))
7759    (set_attr "length_immediate" "*,*,0")
7760    (set_attr "mode" "SI")])
7761
7762 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7763 (define_insn "*andsi_1_zext"
7764   [(set (match_operand:DI 0 "register_operand" "=r")
7765         (zero_extend:DI
7766           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7767                   (match_operand:SI 2 "general_operand" "g"))))
7768    (clobber (reg:CC FLAGS_REG))]
7769   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7770   "and{l}\t{%2, %k0|%k0, %2}"
7771   [(set_attr "type" "alu")
7772    (set_attr "mode" "SI")])
7773
7774 (define_insn "*andhi_1"
7775   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7776         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7777                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7778    (clobber (reg:CC FLAGS_REG))]
7779   "ix86_binary_operator_ok (AND, HImode, operands)"
7780 {
7781   switch (get_attr_type (insn))
7782     {
7783     case TYPE_IMOVX:
7784       gcc_assert (CONST_INT_P (operands[2]));
7785       gcc_assert (INTVAL (operands[2]) == 0xff);
7786       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7787
7788     default:
7789       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7790
7791       return "and{w}\t{%2, %0|%0, %2}";
7792     }
7793 }
7794   [(set_attr "type" "alu,alu,imovx")
7795    (set_attr "length_immediate" "*,*,0")
7796    (set (attr "prefix_rex")
7797      (if_then_else
7798        (and (eq_attr "type" "imovx")
7799             (match_operand 1 "ext_QIreg_operand" ""))
7800        (const_string "1")
7801        (const_string "*")))
7802    (set_attr "mode" "HI,HI,SI")])
7803
7804 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7805 (define_insn "*andqi_1"
7806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7807         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7808                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7809    (clobber (reg:CC FLAGS_REG))]
7810   "ix86_binary_operator_ok (AND, QImode, operands)"
7811   "@
7812    and{b}\t{%2, %0|%0, %2}
7813    and{b}\t{%2, %0|%0, %2}
7814    and{l}\t{%k2, %k0|%k0, %k2}"
7815   [(set_attr "type" "alu")
7816    (set_attr "mode" "QI,QI,SI")])
7817
7818 (define_insn "*andqi_1_slp"
7819   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7820         (and:QI (match_dup 0)
7821                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7822    (clobber (reg:CC FLAGS_REG))]
7823   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7824    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7825   "and{b}\t{%1, %0|%0, %1}"
7826   [(set_attr "type" "alu1")
7827    (set_attr "mode" "QI")])
7828
7829 (define_split
7830   [(set (match_operand 0 "register_operand" "")
7831         (and (match_dup 0)
7832              (const_int -65536)))
7833    (clobber (reg:CC FLAGS_REG))]
7834   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7835     || optimize_function_for_size_p (cfun)"
7836   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7837   "operands[1] = gen_lowpart (HImode, operands[0]);")
7838
7839 (define_split
7840   [(set (match_operand 0 "ext_register_operand" "")
7841         (and (match_dup 0)
7842              (const_int -256)))
7843    (clobber (reg:CC FLAGS_REG))]
7844   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7845    && reload_completed"
7846   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7847   "operands[1] = gen_lowpart (QImode, operands[0]);")
7848
7849 (define_split
7850   [(set (match_operand 0 "ext_register_operand" "")
7851         (and (match_dup 0)
7852              (const_int -65281)))
7853    (clobber (reg:CC FLAGS_REG))]
7854   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7855    && reload_completed"
7856   [(parallel [(set (zero_extract:SI (match_dup 0)
7857                                     (const_int 8)
7858                                     (const_int 8))
7859                    (xor:SI
7860                      (zero_extract:SI (match_dup 0)
7861                                       (const_int 8)
7862                                       (const_int 8))
7863                      (zero_extract:SI (match_dup 0)
7864                                       (const_int 8)
7865                                       (const_int 8))))
7866               (clobber (reg:CC FLAGS_REG))])]
7867   "operands[0] = gen_lowpart (SImode, operands[0]);")
7868
7869 (define_insn "*anddi_2"
7870   [(set (reg FLAGS_REG)
7871         (compare
7872          (and:DI
7873           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7874           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7875          (const_int 0)))
7876    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7877         (and:DI (match_dup 1) (match_dup 2)))]
7878   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7879    && ix86_binary_operator_ok (AND, DImode, operands)"
7880   "@
7881    and{l}\t{%k2, %k0|%k0, %k2}
7882    and{q}\t{%2, %0|%0, %2}
7883    and{q}\t{%2, %0|%0, %2}"
7884   [(set_attr "type" "alu")
7885    (set_attr "mode" "SI,DI,DI")])
7886
7887 (define_insn "*andqi_2_maybe_si"
7888   [(set (reg FLAGS_REG)
7889         (compare (and:QI
7890                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7891                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7892                  (const_int 0)))
7893    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7894         (and:QI (match_dup 1) (match_dup 2)))]
7895   "ix86_binary_operator_ok (AND, QImode, operands)
7896    && ix86_match_ccmode (insn,
7897                          CONST_INT_P (operands[2])
7898                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7899 {
7900   if (which_alternative == 2)
7901     {
7902       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7903         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7904       return "and{l}\t{%2, %k0|%k0, %2}";
7905     }
7906   return "and{b}\t{%2, %0|%0, %2}";
7907 }
7908   [(set_attr "type" "alu")
7909    (set_attr "mode" "QI,QI,SI")])
7910
7911 (define_insn "*and<mode>_2"
7912   [(set (reg FLAGS_REG)
7913         (compare (and:SWI124
7914                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7915                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7916                  (const_int 0)))
7917    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7918         (and:SWI124 (match_dup 1) (match_dup 2)))]
7919   "ix86_match_ccmode (insn, CCNOmode)
7920    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7921   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7922   [(set_attr "type" "alu")
7923    (set_attr "mode" "<MODE>")])
7924
7925 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7926 (define_insn "*andsi_2_zext"
7927   [(set (reg FLAGS_REG)
7928         (compare (and:SI
7929                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7930                   (match_operand:SI 2 "general_operand" "g"))
7931                  (const_int 0)))
7932    (set (match_operand:DI 0 "register_operand" "=r")
7933         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7934   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7935    && ix86_binary_operator_ok (AND, SImode, operands)"
7936   "and{l}\t{%2, %k0|%k0, %2}"
7937   [(set_attr "type" "alu")
7938    (set_attr "mode" "SI")])
7939
7940 (define_insn "*andqi_2_slp"
7941   [(set (reg FLAGS_REG)
7942         (compare (and:QI
7943                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7944                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7945                  (const_int 0)))
7946    (set (strict_low_part (match_dup 0))
7947         (and:QI (match_dup 0) (match_dup 1)))]
7948   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7949    && ix86_match_ccmode (insn, CCNOmode)
7950    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7951   "and{b}\t{%1, %0|%0, %1}"
7952   [(set_attr "type" "alu1")
7953    (set_attr "mode" "QI")])
7954
7955 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7956 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7957 ;; for a QImode operand, which of course failed.
7958 (define_insn "andqi_ext_0"
7959   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7960                          (const_int 8)
7961                          (const_int 8))
7962         (and:SI
7963           (zero_extract:SI
7964             (match_operand 1 "ext_register_operand" "0")
7965             (const_int 8)
7966             (const_int 8))
7967           (match_operand 2 "const_int_operand" "n")))
7968    (clobber (reg:CC FLAGS_REG))]
7969   ""
7970   "and{b}\t{%2, %h0|%h0, %2}"
7971   [(set_attr "type" "alu")
7972    (set_attr "length_immediate" "1")
7973    (set_attr "modrm" "1")
7974    (set_attr "mode" "QI")])
7975
7976 ;; Generated by peephole translating test to and.  This shows up
7977 ;; often in fp comparisons.
7978 (define_insn "*andqi_ext_0_cc"
7979   [(set (reg FLAGS_REG)
7980         (compare
7981           (and:SI
7982             (zero_extract:SI
7983               (match_operand 1 "ext_register_operand" "0")
7984               (const_int 8)
7985               (const_int 8))
7986             (match_operand 2 "const_int_operand" "n"))
7987           (const_int 0)))
7988    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7989                          (const_int 8)
7990                          (const_int 8))
7991         (and:SI
7992           (zero_extract:SI
7993             (match_dup 1)
7994             (const_int 8)
7995             (const_int 8))
7996           (match_dup 2)))]
7997   "ix86_match_ccmode (insn, CCNOmode)"
7998   "and{b}\t{%2, %h0|%h0, %2}"
7999   [(set_attr "type" "alu")
8000    (set_attr "length_immediate" "1")
8001    (set_attr "modrm" "1")
8002    (set_attr "mode" "QI")])
8003
8004 (define_insn "*andqi_ext_1_rex64"
8005   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8006                          (const_int 8)
8007                          (const_int 8))
8008         (and:SI
8009           (zero_extract:SI
8010             (match_operand 1 "ext_register_operand" "0")
8011             (const_int 8)
8012             (const_int 8))
8013           (zero_extend:SI
8014             (match_operand 2 "ext_register_operand" "Q"))))
8015    (clobber (reg:CC FLAGS_REG))]
8016   "TARGET_64BIT"
8017   "and{b}\t{%2, %h0|%h0, %2}"
8018   [(set_attr "type" "alu")
8019    (set_attr "length_immediate" "0")
8020    (set_attr "mode" "QI")])
8021
8022 (define_insn "*andqi_ext_1"
8023   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8024                          (const_int 8)
8025                          (const_int 8))
8026         (and:SI
8027           (zero_extract:SI
8028             (match_operand 1 "ext_register_operand" "0")
8029             (const_int 8)
8030             (const_int 8))
8031           (zero_extend:SI
8032             (match_operand:QI 2 "general_operand" "Qm"))))
8033    (clobber (reg:CC FLAGS_REG))]
8034   "!TARGET_64BIT"
8035   "and{b}\t{%2, %h0|%h0, %2}"
8036   [(set_attr "type" "alu")
8037    (set_attr "length_immediate" "0")
8038    (set_attr "mode" "QI")])
8039
8040 (define_insn "*andqi_ext_2"
8041   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8042                          (const_int 8)
8043                          (const_int 8))
8044         (and:SI
8045           (zero_extract:SI
8046             (match_operand 1 "ext_register_operand" "%0")
8047             (const_int 8)
8048             (const_int 8))
8049           (zero_extract:SI
8050             (match_operand 2 "ext_register_operand" "Q")
8051             (const_int 8)
8052             (const_int 8))))
8053    (clobber (reg:CC FLAGS_REG))]
8054   ""
8055   "and{b}\t{%h2, %h0|%h0, %h2}"
8056   [(set_attr "type" "alu")
8057    (set_attr "length_immediate" "0")
8058    (set_attr "mode" "QI")])
8059
8060 ;; Convert wide AND instructions with immediate operand to shorter QImode
8061 ;; equivalents when possible.
8062 ;; Don't do the splitting with memory operands, since it introduces risk
8063 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8064 ;; for size, but that can (should?) be handled by generic code instead.
8065 (define_split
8066   [(set (match_operand 0 "register_operand" "")
8067         (and (match_operand 1 "register_operand" "")
8068              (match_operand 2 "const_int_operand" "")))
8069    (clobber (reg:CC FLAGS_REG))]
8070    "reload_completed
8071     && QI_REG_P (operands[0])
8072     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8073     && !(~INTVAL (operands[2]) & ~(255 << 8))
8074     && GET_MODE (operands[0]) != QImode"
8075   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8076                    (and:SI (zero_extract:SI (match_dup 1)
8077                                             (const_int 8) (const_int 8))
8078                            (match_dup 2)))
8079               (clobber (reg:CC FLAGS_REG))])]
8080   "operands[0] = gen_lowpart (SImode, operands[0]);
8081    operands[1] = gen_lowpart (SImode, operands[1]);
8082    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8083
8084 ;; Since AND can be encoded with sign extended immediate, this is only
8085 ;; profitable when 7th bit is not set.
8086 (define_split
8087   [(set (match_operand 0 "register_operand" "")
8088         (and (match_operand 1 "general_operand" "")
8089              (match_operand 2 "const_int_operand" "")))
8090    (clobber (reg:CC FLAGS_REG))]
8091    "reload_completed
8092     && ANY_QI_REG_P (operands[0])
8093     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8094     && !(~INTVAL (operands[2]) & ~255)
8095     && !(INTVAL (operands[2]) & 128)
8096     && GET_MODE (operands[0]) != QImode"
8097   [(parallel [(set (strict_low_part (match_dup 0))
8098                    (and:QI (match_dup 1)
8099                            (match_dup 2)))
8100               (clobber (reg:CC FLAGS_REG))])]
8101   "operands[0] = gen_lowpart (QImode, operands[0]);
8102    operands[1] = gen_lowpart (QImode, operands[1]);
8103    operands[2] = gen_lowpart (QImode, operands[2]);")
8104 \f
8105 ;; Logical inclusive and exclusive OR instructions
8106
8107 ;; %%% This used to optimize known byte-wide and operations to memory.
8108 ;; If this is considered useful, it should be done with splitters.
8109
8110 (define_expand "<code><mode>3"
8111   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8112         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8113                      (match_operand:SWIM 2 "<general_operand>" "")))]
8114   ""
8115   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8116
8117 (define_insn "*<code><mode>_1"
8118   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8119         (any_or:SWI248
8120          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8121          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8122    (clobber (reg:CC FLAGS_REG))]
8123   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8124   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8125   [(set_attr "type" "alu")
8126    (set_attr "mode" "<MODE>")])
8127
8128 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8129 (define_insn "*<code>qi_1"
8130   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8131         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8132                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8133    (clobber (reg:CC FLAGS_REG))]
8134   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8135   "@
8136    <logic>{b}\t{%2, %0|%0, %2}
8137    <logic>{b}\t{%2, %0|%0, %2}
8138    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8139   [(set_attr "type" "alu")
8140    (set_attr "mode" "QI,QI,SI")])
8141
8142 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8143 (define_insn "*<code>si_1_zext"
8144   [(set (match_operand:DI 0 "register_operand" "=r")
8145         (zero_extend:DI
8146          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8147                     (match_operand:SI 2 "general_operand" "g"))))
8148    (clobber (reg:CC FLAGS_REG))]
8149   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8150   "<logic>{l}\t{%2, %k0|%k0, %2}"
8151   [(set_attr "type" "alu")
8152    (set_attr "mode" "SI")])
8153
8154 (define_insn "*<code>si_1_zext_imm"
8155   [(set (match_operand:DI 0 "register_operand" "=r")
8156         (any_or:DI
8157          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8158          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8159    (clobber (reg:CC FLAGS_REG))]
8160   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8161   "<logic>{l}\t{%2, %k0|%k0, %2}"
8162   [(set_attr "type" "alu")
8163    (set_attr "mode" "SI")])
8164
8165 (define_insn "*<code>qi_1_slp"
8166   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8167         (any_or:QI (match_dup 0)
8168                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8171    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8172   "<logic>{b}\t{%1, %0|%0, %1}"
8173   [(set_attr "type" "alu1")
8174    (set_attr "mode" "QI")])
8175
8176 (define_insn "*<code><mode>_2"
8177   [(set (reg FLAGS_REG)
8178         (compare (any_or:SWI
8179                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8180                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8181                  (const_int 0)))
8182    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8183         (any_or:SWI (match_dup 1) (match_dup 2)))]
8184   "ix86_match_ccmode (insn, CCNOmode)
8185    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8186   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8187   [(set_attr "type" "alu")
8188    (set_attr "mode" "<MODE>")])
8189
8190 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8191 ;; ??? Special case for immediate operand is missing - it is tricky.
8192 (define_insn "*<code>si_2_zext"
8193   [(set (reg FLAGS_REG)
8194         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8195                             (match_operand:SI 2 "general_operand" "g"))
8196                  (const_int 0)))
8197    (set (match_operand:DI 0 "register_operand" "=r")
8198         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8199   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8200    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8201   "<logic>{l}\t{%2, %k0|%k0, %2}"
8202   [(set_attr "type" "alu")
8203    (set_attr "mode" "SI")])
8204
8205 (define_insn "*<code>si_2_zext_imm"
8206   [(set (reg FLAGS_REG)
8207         (compare (any_or:SI
8208                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8209                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8210                  (const_int 0)))
8211    (set (match_operand:DI 0 "register_operand" "=r")
8212         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8213   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8214    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8215   "<logic>{l}\t{%2, %k0|%k0, %2}"
8216   [(set_attr "type" "alu")
8217    (set_attr "mode" "SI")])
8218
8219 (define_insn "*<code>qi_2_slp"
8220   [(set (reg FLAGS_REG)
8221         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8222                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8223                  (const_int 0)))
8224    (set (strict_low_part (match_dup 0))
8225         (any_or:QI (match_dup 0) (match_dup 1)))]
8226   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8227    && ix86_match_ccmode (insn, CCNOmode)
8228    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8229   "<logic>{b}\t{%1, %0|%0, %1}"
8230   [(set_attr "type" "alu1")
8231    (set_attr "mode" "QI")])
8232
8233 (define_insn "*<code><mode>_3"
8234   [(set (reg FLAGS_REG)
8235         (compare (any_or:SWI
8236                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8237                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8238                  (const_int 0)))
8239    (clobber (match_scratch:SWI 0 "=<r>"))]
8240   "ix86_match_ccmode (insn, CCNOmode)
8241    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8242   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8243   [(set_attr "type" "alu")
8244    (set_attr "mode" "<MODE>")])
8245
8246 (define_insn "*<code>qi_ext_0"
8247   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8248                          (const_int 8)
8249                          (const_int 8))
8250         (any_or:SI
8251           (zero_extract:SI
8252             (match_operand 1 "ext_register_operand" "0")
8253             (const_int 8)
8254             (const_int 8))
8255           (match_operand 2 "const_int_operand" "n")))
8256    (clobber (reg:CC FLAGS_REG))]
8257   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8258   "<logic>{b}\t{%2, %h0|%h0, %2}"
8259   [(set_attr "type" "alu")
8260    (set_attr "length_immediate" "1")
8261    (set_attr "modrm" "1")
8262    (set_attr "mode" "QI")])
8263
8264 (define_insn "*<code>qi_ext_1_rex64"
8265   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8266                          (const_int 8)
8267                          (const_int 8))
8268         (any_or:SI
8269           (zero_extract:SI
8270             (match_operand 1 "ext_register_operand" "0")
8271             (const_int 8)
8272             (const_int 8))
8273           (zero_extend:SI
8274             (match_operand 2 "ext_register_operand" "Q"))))
8275    (clobber (reg:CC FLAGS_REG))]
8276   "TARGET_64BIT
8277    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8278   "<logic>{b}\t{%2, %h0|%h0, %2}"
8279   [(set_attr "type" "alu")
8280    (set_attr "length_immediate" "0")
8281    (set_attr "mode" "QI")])
8282
8283 (define_insn "*<code>qi_ext_1"
8284   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8285                          (const_int 8)
8286                          (const_int 8))
8287         (any_or:SI
8288           (zero_extract:SI
8289             (match_operand 1 "ext_register_operand" "0")
8290             (const_int 8)
8291             (const_int 8))
8292           (zero_extend:SI
8293             (match_operand:QI 2 "general_operand" "Qm"))))
8294    (clobber (reg:CC FLAGS_REG))]
8295   "!TARGET_64BIT
8296    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8297   "<logic>{b}\t{%2, %h0|%h0, %2}"
8298   [(set_attr "type" "alu")
8299    (set_attr "length_immediate" "0")
8300    (set_attr "mode" "QI")])
8301
8302 (define_insn "*<code>qi_ext_2"
8303   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8304                          (const_int 8)
8305                          (const_int 8))
8306         (any_or:SI
8307           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8308                            (const_int 8)
8309                            (const_int 8))
8310           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8311                            (const_int 8)
8312                            (const_int 8))))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8315   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8316   [(set_attr "type" "alu")
8317    (set_attr "length_immediate" "0")
8318    (set_attr "mode" "QI")])
8319
8320 (define_split
8321   [(set (match_operand 0 "register_operand" "")
8322         (any_or (match_operand 1 "register_operand" "")
8323                 (match_operand 2 "const_int_operand" "")))
8324    (clobber (reg:CC FLAGS_REG))]
8325    "reload_completed
8326     && QI_REG_P (operands[0])
8327     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8328     && !(INTVAL (operands[2]) & ~(255 << 8))
8329     && GET_MODE (operands[0]) != QImode"
8330   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8331                    (any_or:SI (zero_extract:SI (match_dup 1)
8332                                                (const_int 8) (const_int 8))
8333                               (match_dup 2)))
8334               (clobber (reg:CC FLAGS_REG))])]
8335   "operands[0] = gen_lowpart (SImode, operands[0]);
8336    operands[1] = gen_lowpart (SImode, operands[1]);
8337    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8338
8339 ;; Since OR can be encoded with sign extended immediate, this is only
8340 ;; profitable when 7th bit is set.
8341 (define_split
8342   [(set (match_operand 0 "register_operand" "")
8343         (any_or (match_operand 1 "general_operand" "")
8344                 (match_operand 2 "const_int_operand" "")))
8345    (clobber (reg:CC FLAGS_REG))]
8346    "reload_completed
8347     && ANY_QI_REG_P (operands[0])
8348     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8349     && !(INTVAL (operands[2]) & ~255)
8350     && (INTVAL (operands[2]) & 128)
8351     && GET_MODE (operands[0]) != QImode"
8352   [(parallel [(set (strict_low_part (match_dup 0))
8353                    (any_or:QI (match_dup 1)
8354                               (match_dup 2)))
8355               (clobber (reg:CC FLAGS_REG))])]
8356   "operands[0] = gen_lowpart (QImode, operands[0]);
8357    operands[1] = gen_lowpart (QImode, operands[1]);
8358    operands[2] = gen_lowpart (QImode, operands[2]);")
8359
8360 (define_expand "xorqi_cc_ext_1"
8361   [(parallel [
8362      (set (reg:CCNO FLAGS_REG)
8363           (compare:CCNO
8364             (xor:SI
8365               (zero_extract:SI
8366                 (match_operand 1 "ext_register_operand" "")
8367                 (const_int 8)
8368                 (const_int 8))
8369               (match_operand:QI 2 "general_operand" ""))
8370             (const_int 0)))
8371      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8372                            (const_int 8)
8373                            (const_int 8))
8374           (xor:SI
8375             (zero_extract:SI
8376              (match_dup 1)
8377              (const_int 8)
8378              (const_int 8))
8379             (match_dup 2)))])])
8380
8381 (define_insn "*xorqi_cc_ext_1_rex64"
8382   [(set (reg FLAGS_REG)
8383         (compare
8384           (xor:SI
8385             (zero_extract:SI
8386               (match_operand 1 "ext_register_operand" "0")
8387               (const_int 8)
8388               (const_int 8))
8389             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8390           (const_int 0)))
8391    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8392                          (const_int 8)
8393                          (const_int 8))
8394         (xor:SI
8395           (zero_extract:SI
8396            (match_dup 1)
8397            (const_int 8)
8398            (const_int 8))
8399           (match_dup 2)))]
8400   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8401   "xor{b}\t{%2, %h0|%h0, %2}"
8402   [(set_attr "type" "alu")
8403    (set_attr "modrm" "1")
8404    (set_attr "mode" "QI")])
8405
8406 (define_insn "*xorqi_cc_ext_1"
8407   [(set (reg FLAGS_REG)
8408         (compare
8409           (xor:SI
8410             (zero_extract:SI
8411               (match_operand 1 "ext_register_operand" "0")
8412               (const_int 8)
8413               (const_int 8))
8414             (match_operand:QI 2 "general_operand" "qmn"))
8415           (const_int 0)))
8416    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8417                          (const_int 8)
8418                          (const_int 8))
8419         (xor:SI
8420           (zero_extract:SI
8421            (match_dup 1)
8422            (const_int 8)
8423            (const_int 8))
8424           (match_dup 2)))]
8425   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8426   "xor{b}\t{%2, %h0|%h0, %2}"
8427   [(set_attr "type" "alu")
8428    (set_attr "modrm" "1")
8429    (set_attr "mode" "QI")])
8430 \f
8431 ;; Negation instructions
8432
8433 (define_expand "neg<mode>2"
8434   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8435         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8436   ""
8437   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8438
8439 (define_insn_and_split "*neg<dwi>2_doubleword"
8440   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8441         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8442    (clobber (reg:CC FLAGS_REG))]
8443   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8444   "#"
8445   "reload_completed"
8446   [(parallel
8447     [(set (reg:CCZ FLAGS_REG)
8448           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8449      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8450    (parallel
8451     [(set (match_dup 2)
8452           (plus:DWIH (match_dup 3)
8453                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8454                                 (const_int 0))))
8455      (clobber (reg:CC FLAGS_REG))])
8456    (parallel
8457     [(set (match_dup 2)
8458           (neg:DWIH (match_dup 2)))
8459      (clobber (reg:CC FLAGS_REG))])]
8460   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8461
8462 (define_insn "*neg<mode>2_1"
8463   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8464         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8465    (clobber (reg:CC FLAGS_REG))]
8466   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8467   "neg{<imodesuffix>}\t%0"
8468   [(set_attr "type" "negnot")
8469    (set_attr "mode" "<MODE>")])
8470
8471 ;; Combine is quite creative about this pattern.
8472 (define_insn "*negsi2_1_zext"
8473   [(set (match_operand:DI 0 "register_operand" "=r")
8474         (lshiftrt:DI
8475           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8476                              (const_int 32)))
8477         (const_int 32)))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8480   "neg{l}\t%k0"
8481   [(set_attr "type" "negnot")
8482    (set_attr "mode" "SI")])
8483
8484 ;; The problem with neg is that it does not perform (compare x 0),
8485 ;; it really performs (compare 0 x), which leaves us with the zero
8486 ;; flag being the only useful item.
8487
8488 (define_insn "*neg<mode>2_cmpz"
8489   [(set (reg:CCZ FLAGS_REG)
8490         (compare:CCZ
8491           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8492                    (const_int 0)))
8493    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8494         (neg:SWI (match_dup 1)))]
8495   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8496   "neg{<imodesuffix>}\t%0"
8497   [(set_attr "type" "negnot")
8498    (set_attr "mode" "<MODE>")])
8499
8500 (define_insn "*negsi2_cmpz_zext"
8501   [(set (reg:CCZ FLAGS_REG)
8502         (compare:CCZ
8503           (lshiftrt:DI
8504             (neg:DI (ashift:DI
8505                       (match_operand:DI 1 "register_operand" "0")
8506                       (const_int 32)))
8507             (const_int 32))
8508           (const_int 0)))
8509    (set (match_operand:DI 0 "register_operand" "=r")
8510         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8511                                         (const_int 32)))
8512                      (const_int 32)))]
8513   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8514   "neg{l}\t%k0"
8515   [(set_attr "type" "negnot")
8516    (set_attr "mode" "SI")])
8517
8518 ;; Changing of sign for FP values is doable using integer unit too.
8519
8520 (define_expand "<code><mode>2"
8521   [(set (match_operand:X87MODEF 0 "register_operand" "")
8522         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8523   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8524   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8525
8526 (define_insn "*absneg<mode>2_mixed"
8527   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8528         (match_operator:MODEF 3 "absneg_operator"
8529           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8530    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8533   "#")
8534
8535 (define_insn "*absneg<mode>2_sse"
8536   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8537         (match_operator:MODEF 3 "absneg_operator"
8538           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8539    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8540    (clobber (reg:CC FLAGS_REG))]
8541   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8542   "#")
8543
8544 (define_insn "*absneg<mode>2_i387"
8545   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8546         (match_operator:X87MODEF 3 "absneg_operator"
8547           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8548    (use (match_operand 2 "" ""))
8549    (clobber (reg:CC FLAGS_REG))]
8550   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8551   "#")
8552
8553 (define_expand "<code>tf2"
8554   [(set (match_operand:TF 0 "register_operand" "")
8555         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8556   "TARGET_SSE2"
8557   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8558
8559 (define_insn "*absnegtf2_sse"
8560   [(set (match_operand:TF 0 "register_operand" "=x,x")
8561         (match_operator:TF 3 "absneg_operator"
8562           [(match_operand:TF 1 "register_operand" "0,x")]))
8563    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8564    (clobber (reg:CC FLAGS_REG))]
8565   "TARGET_SSE2"
8566   "#")
8567
8568 ;; Splitters for fp abs and neg.
8569
8570 (define_split
8571   [(set (match_operand 0 "fp_register_operand" "")
8572         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8573    (use (match_operand 2 "" ""))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "reload_completed"
8576   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8577
8578 (define_split
8579   [(set (match_operand 0 "register_operand" "")
8580         (match_operator 3 "absneg_operator"
8581           [(match_operand 1 "register_operand" "")]))
8582    (use (match_operand 2 "nonimmediate_operand" ""))
8583    (clobber (reg:CC FLAGS_REG))]
8584   "reload_completed && SSE_REG_P (operands[0])"
8585   [(set (match_dup 0) (match_dup 3))]
8586 {
8587   enum machine_mode mode = GET_MODE (operands[0]);
8588   enum machine_mode vmode = GET_MODE (operands[2]);
8589   rtx tmp;
8590
8591   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8592   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8593   if (operands_match_p (operands[0], operands[2]))
8594     {
8595       tmp = operands[1];
8596       operands[1] = operands[2];
8597       operands[2] = tmp;
8598     }
8599   if (GET_CODE (operands[3]) == ABS)
8600     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8601   else
8602     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8603   operands[3] = tmp;
8604 })
8605
8606 (define_split
8607   [(set (match_operand:SF 0 "register_operand" "")
8608         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8609    (use (match_operand:V4SF 2 "" ""))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "reload_completed"
8612   [(parallel [(set (match_dup 0) (match_dup 1))
8613               (clobber (reg:CC FLAGS_REG))])]
8614 {
8615   rtx tmp;
8616   operands[0] = gen_lowpart (SImode, operands[0]);
8617   if (GET_CODE (operands[1]) == ABS)
8618     {
8619       tmp = gen_int_mode (0x7fffffff, SImode);
8620       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8621     }
8622   else
8623     {
8624       tmp = gen_int_mode (0x80000000, SImode);
8625       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8626     }
8627   operands[1] = tmp;
8628 })
8629
8630 (define_split
8631   [(set (match_operand:DF 0 "register_operand" "")
8632         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8633    (use (match_operand 2 "" ""))
8634    (clobber (reg:CC FLAGS_REG))]
8635   "reload_completed"
8636   [(parallel [(set (match_dup 0) (match_dup 1))
8637               (clobber (reg:CC FLAGS_REG))])]
8638 {
8639   rtx tmp;
8640   if (TARGET_64BIT)
8641     {
8642       tmp = gen_lowpart (DImode, operands[0]);
8643       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8644       operands[0] = tmp;
8645
8646       if (GET_CODE (operands[1]) == ABS)
8647         tmp = const0_rtx;
8648       else
8649         tmp = gen_rtx_NOT (DImode, tmp);
8650     }
8651   else
8652     {
8653       operands[0] = gen_highpart (SImode, operands[0]);
8654       if (GET_CODE (operands[1]) == ABS)
8655         {
8656           tmp = gen_int_mode (0x7fffffff, SImode);
8657           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8658         }
8659       else
8660         {
8661           tmp = gen_int_mode (0x80000000, SImode);
8662           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8663         }
8664     }
8665   operands[1] = tmp;
8666 })
8667
8668 (define_split
8669   [(set (match_operand:XF 0 "register_operand" "")
8670         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8671    (use (match_operand 2 "" ""))
8672    (clobber (reg:CC FLAGS_REG))]
8673   "reload_completed"
8674   [(parallel [(set (match_dup 0) (match_dup 1))
8675               (clobber (reg:CC FLAGS_REG))])]
8676 {
8677   rtx tmp;
8678   operands[0] = gen_rtx_REG (SImode,
8679                              true_regnum (operands[0])
8680                              + (TARGET_64BIT ? 1 : 2));
8681   if (GET_CODE (operands[1]) == ABS)
8682     {
8683       tmp = GEN_INT (0x7fff);
8684       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8685     }
8686   else
8687     {
8688       tmp = GEN_INT (0x8000);
8689       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8690     }
8691   operands[1] = tmp;
8692 })
8693
8694 ;; Conditionalize these after reload. If they match before reload, we
8695 ;; lose the clobber and ability to use integer instructions.
8696
8697 (define_insn "*<code><mode>2_1"
8698   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8699         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8700   "TARGET_80387
8701    && (reload_completed
8702        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8703   "f<absneg_mnemonic>"
8704   [(set_attr "type" "fsgn")
8705    (set_attr "mode" "<MODE>")])
8706
8707 (define_insn "*<code>extendsfdf2"
8708   [(set (match_operand:DF 0 "register_operand" "=f")
8709         (absneg:DF (float_extend:DF
8710                      (match_operand:SF 1 "register_operand" "0"))))]
8711   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8712   "f<absneg_mnemonic>"
8713   [(set_attr "type" "fsgn")
8714    (set_attr "mode" "DF")])
8715
8716 (define_insn "*<code>extendsfxf2"
8717   [(set (match_operand:XF 0 "register_operand" "=f")
8718         (absneg:XF (float_extend:XF
8719                      (match_operand:SF 1 "register_operand" "0"))))]
8720   "TARGET_80387"
8721   "f<absneg_mnemonic>"
8722   [(set_attr "type" "fsgn")
8723    (set_attr "mode" "XF")])
8724
8725 (define_insn "*<code>extenddfxf2"
8726   [(set (match_operand:XF 0 "register_operand" "=f")
8727         (absneg:XF (float_extend:XF
8728                      (match_operand:DF 1 "register_operand" "0"))))]
8729   "TARGET_80387"
8730   "f<absneg_mnemonic>"
8731   [(set_attr "type" "fsgn")
8732    (set_attr "mode" "XF")])
8733
8734 ;; Copysign instructions
8735
8736 (define_mode_iterator CSGNMODE [SF DF TF])
8737 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8738
8739 (define_expand "copysign<mode>3"
8740   [(match_operand:CSGNMODE 0 "register_operand" "")
8741    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8742    (match_operand:CSGNMODE 2 "register_operand" "")]
8743   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8744    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8745   "ix86_expand_copysign (operands); DONE;")
8746
8747 (define_insn_and_split "copysign<mode>3_const"
8748   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8749         (unspec:CSGNMODE
8750           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8751            (match_operand:CSGNMODE 2 "register_operand" "0")
8752            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8753           UNSPEC_COPYSIGN))]
8754   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8755    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8756   "#"
8757   "&& reload_completed"
8758   [(const_int 0)]
8759   "ix86_split_copysign_const (operands); DONE;")
8760
8761 (define_insn "copysign<mode>3_var"
8762   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8763         (unspec:CSGNMODE
8764           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8765            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8766            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8767            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8768           UNSPEC_COPYSIGN))
8769    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8770   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8771    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8772   "#")
8773
8774 (define_split
8775   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8776         (unspec:CSGNMODE
8777           [(match_operand:CSGNMODE 2 "register_operand" "")
8778            (match_operand:CSGNMODE 3 "register_operand" "")
8779            (match_operand:<CSGNVMODE> 4 "" "")
8780            (match_operand:<CSGNVMODE> 5 "" "")]
8781           UNSPEC_COPYSIGN))
8782    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8783   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8784     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8785    && reload_completed"
8786   [(const_int 0)]
8787   "ix86_split_copysign_var (operands); DONE;")
8788 \f
8789 ;; One complement instructions
8790
8791 (define_expand "one_cmpl<mode>2"
8792   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8793         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8794   ""
8795   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8796
8797 (define_insn "*one_cmpl<mode>2_1"
8798   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8799         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8800   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8801   "not{<imodesuffix>}\t%0"
8802   [(set_attr "type" "negnot")
8803    (set_attr "mode" "<MODE>")])
8804
8805 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8806 (define_insn "*one_cmplqi2_1"
8807   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8808         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8809   "ix86_unary_operator_ok (NOT, QImode, operands)"
8810   "@
8811    not{b}\t%0
8812    not{l}\t%k0"
8813   [(set_attr "type" "negnot")
8814    (set_attr "mode" "QI,SI")])
8815
8816 ;; ??? Currently never generated - xor is used instead.
8817 (define_insn "*one_cmplsi2_1_zext"
8818   [(set (match_operand:DI 0 "register_operand" "=r")
8819         (zero_extend:DI
8820           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8821   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8822   "not{l}\t%k0"
8823   [(set_attr "type" "negnot")
8824    (set_attr "mode" "SI")])
8825
8826 (define_insn "*one_cmpl<mode>2_2"
8827   [(set (reg FLAGS_REG)
8828         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8829                  (const_int 0)))
8830    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8831         (not:SWI (match_dup 1)))]
8832   "ix86_match_ccmode (insn, CCNOmode)
8833    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8834   "#"
8835   [(set_attr "type" "alu1")
8836    (set_attr "mode" "<MODE>")])
8837
8838 (define_split
8839   [(set (match_operand 0 "flags_reg_operand" "")
8840         (match_operator 2 "compare_operator"
8841           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8842            (const_int 0)]))
8843    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8844         (not:SWI (match_dup 3)))]
8845   "ix86_match_ccmode (insn, CCNOmode)"
8846   [(parallel [(set (match_dup 0)
8847                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8848                                     (const_int 0)]))
8849               (set (match_dup 1)
8850                    (xor:SWI (match_dup 3) (const_int -1)))])])
8851
8852 ;; ??? Currently never generated - xor is used instead.
8853 (define_insn "*one_cmplsi2_2_zext"
8854   [(set (reg FLAGS_REG)
8855         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8856                  (const_int 0)))
8857    (set (match_operand:DI 0 "register_operand" "=r")
8858         (zero_extend:DI (not:SI (match_dup 1))))]
8859   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8860    && ix86_unary_operator_ok (NOT, SImode, operands)"
8861   "#"
8862   [(set_attr "type" "alu1")
8863    (set_attr "mode" "SI")])
8864
8865 (define_split
8866   [(set (match_operand 0 "flags_reg_operand" "")
8867         (match_operator 2 "compare_operator"
8868           [(not:SI (match_operand:SI 3 "register_operand" ""))
8869            (const_int 0)]))
8870    (set (match_operand:DI 1 "register_operand" "")
8871         (zero_extend:DI (not:SI (match_dup 3))))]
8872   "ix86_match_ccmode (insn, CCNOmode)"
8873   [(parallel [(set (match_dup 0)
8874                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8875                                     (const_int 0)]))
8876               (set (match_dup 1)
8877                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8878 \f
8879 ;; Shift instructions
8880
8881 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8882 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8883 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8884 ;; from the assembler input.
8885 ;;
8886 ;; This instruction shifts the target reg/mem as usual, but instead of
8887 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8888 ;; is a left shift double, bits are taken from the high order bits of
8889 ;; reg, else if the insn is a shift right double, bits are taken from the
8890 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8891 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8892 ;;
8893 ;; Since sh[lr]d does not change the `reg' operand, that is done
8894 ;; separately, making all shifts emit pairs of shift double and normal
8895 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8896 ;; support a 63 bit shift, each shift where the count is in a reg expands
8897 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8898 ;;
8899 ;; If the shift count is a constant, we need never emit more than one
8900 ;; shift pair, instead using moves and sign extension for counts greater
8901 ;; than 31.
8902
8903 (define_expand "ashl<mode>3"
8904   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8905         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8906                       (match_operand:QI 2 "nonmemory_operand" "")))]
8907   ""
8908   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8909
8910 (define_insn "*ashl<mode>3_doubleword"
8911   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8912         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8913                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8914    (clobber (reg:CC FLAGS_REG))]
8915   ""
8916   "#"
8917   [(set_attr "type" "multi")])
8918
8919 (define_split
8920   [(set (match_operand:DWI 0 "register_operand" "")
8921         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8922                     (match_operand:QI 2 "nonmemory_operand" "")))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8925   [(const_int 0)]
8926   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8927
8928 ;; By default we don't ask for a scratch register, because when DWImode
8929 ;; values are manipulated, registers are already at a premium.  But if
8930 ;; we have one handy, we won't turn it away.
8931
8932 (define_peephole2
8933   [(match_scratch:DWIH 3 "r")
8934    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8935                    (ashift:<DWI>
8936                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8937                      (match_operand:QI 2 "nonmemory_operand" "")))
8938               (clobber (reg:CC FLAGS_REG))])
8939    (match_dup 3)]
8940   "TARGET_CMOVE"
8941   [(const_int 0)]
8942   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8943
8944 (define_insn "x86_64_shld"
8945   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8946         (ior:DI (ashift:DI (match_dup 0)
8947                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8948                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8949                   (minus:QI (const_int 64) (match_dup 2)))))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "TARGET_64BIT"
8952   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8953   [(set_attr "type" "ishift")
8954    (set_attr "prefix_0f" "1")
8955    (set_attr "mode" "DI")
8956    (set_attr "athlon_decode" "vector")
8957    (set_attr "amdfam10_decode" "vector")
8958    (set_attr "bdver1_decode" "vector")])
8959
8960 (define_insn "x86_shld"
8961   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8962         (ior:SI (ashift:SI (match_dup 0)
8963                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8964                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8965                   (minus:QI (const_int 32) (match_dup 2)))))
8966    (clobber (reg:CC FLAGS_REG))]
8967   ""
8968   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8969   [(set_attr "type" "ishift")
8970    (set_attr "prefix_0f" "1")
8971    (set_attr "mode" "SI")
8972    (set_attr "pent_pair" "np")
8973    (set_attr "athlon_decode" "vector")
8974    (set_attr "amdfam10_decode" "vector")
8975    (set_attr "bdver1_decode" "vector")])
8976
8977 (define_expand "x86_shift<mode>_adj_1"
8978   [(set (reg:CCZ FLAGS_REG)
8979         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8980                              (match_dup 4))
8981                      (const_int 0)))
8982    (set (match_operand:SWI48 0 "register_operand" "")
8983         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8984                             (match_operand:SWI48 1 "register_operand" "")
8985                             (match_dup 0)))
8986    (set (match_dup 1)
8987         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8988                             (match_operand:SWI48 3 "register_operand" "r")
8989                             (match_dup 1)))]
8990   "TARGET_CMOVE"
8991   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8992
8993 (define_expand "x86_shift<mode>_adj_2"
8994   [(use (match_operand:SWI48 0 "register_operand" ""))
8995    (use (match_operand:SWI48 1 "register_operand" ""))
8996    (use (match_operand:QI 2 "register_operand" ""))]
8997   ""
8998 {
8999   rtx label = gen_label_rtx ();
9000   rtx tmp;
9001
9002   emit_insn (gen_testqi_ccz_1 (operands[2],
9003                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9004
9005   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9006   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9007   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9008                               gen_rtx_LABEL_REF (VOIDmode, label),
9009                               pc_rtx);
9010   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9011   JUMP_LABEL (tmp) = label;
9012
9013   emit_move_insn (operands[0], operands[1]);
9014   ix86_expand_clear (operands[1]);
9015
9016   emit_label (label);
9017   LABEL_NUSES (label) = 1;
9018
9019   DONE;
9020 })
9021
9022 ;; Avoid useless masking of count operand.
9023 (define_insn_and_split "*ashl<mode>3_mask"
9024   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9025         (ashift:SWI48
9026           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9027           (subreg:QI
9028             (and:SI
9029               (match_operand:SI 2 "nonimmediate_operand" "c")
9030               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9031    (clobber (reg:CC FLAGS_REG))]
9032   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9033    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9034       == GET_MODE_BITSIZE (<MODE>mode)-1"
9035   "#"
9036   "&& 1"
9037   [(parallel [(set (match_dup 0)
9038                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9039               (clobber (reg:CC FLAGS_REG))])]
9040 {
9041   if (can_create_pseudo_p ())
9042     operands [2] = force_reg (SImode, operands[2]);
9043
9044   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9045 }
9046   [(set_attr "type" "ishift")
9047    (set_attr "mode" "<MODE>")])
9048
9049 (define_insn "*ashl<mode>3_1"
9050   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9051         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9052                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9053    (clobber (reg:CC FLAGS_REG))]
9054   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9055 {
9056   switch (get_attr_type (insn))
9057     {
9058     case TYPE_LEA:
9059       return "#";
9060
9061     case TYPE_ALU:
9062       gcc_assert (operands[2] == const1_rtx);
9063       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9064       return "add{<imodesuffix>}\t%0, %0";
9065
9066     default:
9067       if (operands[2] == const1_rtx
9068           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9069         return "sal{<imodesuffix>}\t%0";
9070       else
9071         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9072     }
9073 }
9074   [(set (attr "type")
9075      (cond [(eq_attr "alternative" "1")
9076               (const_string "lea")
9077             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9078                           (const_int 0))
9079                       (match_operand 0 "register_operand" ""))
9080                  (match_operand 2 "const1_operand" ""))
9081               (const_string "alu")
9082            ]
9083            (const_string "ishift")))
9084    (set (attr "length_immediate")
9085      (if_then_else
9086        (ior (eq_attr "type" "alu")
9087             (and (eq_attr "type" "ishift")
9088                  (and (match_operand 2 "const1_operand" "")
9089                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9090                           (const_int 0)))))
9091        (const_string "0")
9092        (const_string "*")))
9093    (set_attr "mode" "<MODE>")])
9094
9095 (define_insn "*ashlsi3_1_zext"
9096   [(set (match_operand:DI 0 "register_operand" "=r,r")
9097         (zero_extend:DI
9098           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9099                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9100    (clobber (reg:CC FLAGS_REG))]
9101   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9102 {
9103   switch (get_attr_type (insn))
9104     {
9105     case TYPE_LEA:
9106       return "#";
9107
9108     case TYPE_ALU:
9109       gcc_assert (operands[2] == const1_rtx);
9110       return "add{l}\t%k0, %k0";
9111
9112     default:
9113       if (operands[2] == const1_rtx
9114           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9115         return "sal{l}\t%k0";
9116       else
9117         return "sal{l}\t{%2, %k0|%k0, %2}";
9118     }
9119 }
9120   [(set (attr "type")
9121      (cond [(eq_attr "alternative" "1")
9122               (const_string "lea")
9123             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9124                      (const_int 0))
9125                  (match_operand 2 "const1_operand" ""))
9126               (const_string "alu")
9127            ]
9128            (const_string "ishift")))
9129    (set (attr "length_immediate")
9130      (if_then_else
9131        (ior (eq_attr "type" "alu")
9132             (and (eq_attr "type" "ishift")
9133                  (and (match_operand 2 "const1_operand" "")
9134                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9135                           (const_int 0)))))
9136        (const_string "0")
9137        (const_string "*")))
9138    (set_attr "mode" "SI")])
9139
9140 (define_insn "*ashlhi3_1"
9141   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9142         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9143                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9144    (clobber (reg:CC FLAGS_REG))]
9145   "TARGET_PARTIAL_REG_STALL
9146    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9147 {
9148   switch (get_attr_type (insn))
9149     {
9150     case TYPE_ALU:
9151       gcc_assert (operands[2] == const1_rtx);
9152       return "add{w}\t%0, %0";
9153
9154     default:
9155       if (operands[2] == const1_rtx
9156           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9157         return "sal{w}\t%0";
9158       else
9159         return "sal{w}\t{%2, %0|%0, %2}";
9160     }
9161 }
9162   [(set (attr "type")
9163      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9164                           (const_int 0))
9165                       (match_operand 0 "register_operand" ""))
9166                  (match_operand 2 "const1_operand" ""))
9167               (const_string "alu")
9168            ]
9169            (const_string "ishift")))
9170    (set (attr "length_immediate")
9171      (if_then_else
9172        (ior (eq_attr "type" "alu")
9173             (and (eq_attr "type" "ishift")
9174                  (and (match_operand 2 "const1_operand" "")
9175                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9176                           (const_int 0)))))
9177        (const_string "0")
9178        (const_string "*")))
9179    (set_attr "mode" "HI")])
9180
9181 (define_insn "*ashlhi3_1_lea"
9182   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9183         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9184                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "!TARGET_PARTIAL_REG_STALL
9187    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9188 {
9189   switch (get_attr_type (insn))
9190     {
9191     case TYPE_LEA:
9192       return "#";
9193
9194     case TYPE_ALU:
9195       gcc_assert (operands[2] == const1_rtx);
9196       return "add{w}\t%0, %0";
9197
9198     default:
9199       if (operands[2] == const1_rtx
9200           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9201         return "sal{w}\t%0";
9202       else
9203         return "sal{w}\t{%2, %0|%0, %2}";
9204     }
9205 }
9206   [(set (attr "type")
9207      (cond [(eq_attr "alternative" "1")
9208               (const_string "lea")
9209             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9210                           (const_int 0))
9211                       (match_operand 0 "register_operand" ""))
9212                  (match_operand 2 "const1_operand" ""))
9213               (const_string "alu")
9214            ]
9215            (const_string "ishift")))
9216    (set (attr "length_immediate")
9217      (if_then_else
9218        (ior (eq_attr "type" "alu")
9219             (and (eq_attr "type" "ishift")
9220                  (and (match_operand 2 "const1_operand" "")
9221                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9222                           (const_int 0)))))
9223        (const_string "0")
9224        (const_string "*")))
9225    (set_attr "mode" "HI,SI")])
9226
9227 (define_insn "*ashlqi3_1"
9228   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9229         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9230                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "TARGET_PARTIAL_REG_STALL
9233    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9234 {
9235   switch (get_attr_type (insn))
9236     {
9237     case TYPE_ALU:
9238       gcc_assert (operands[2] == const1_rtx);
9239       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9240         return "add{l}\t%k0, %k0";
9241       else
9242         return "add{b}\t%0, %0";
9243
9244     default:
9245       if (operands[2] == const1_rtx
9246           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9247         {
9248           if (get_attr_mode (insn) == MODE_SI)
9249             return "sal{l}\t%k0";
9250           else
9251             return "sal{b}\t%0";
9252         }
9253       else
9254         {
9255           if (get_attr_mode (insn) == MODE_SI)
9256             return "sal{l}\t{%2, %k0|%k0, %2}";
9257           else
9258             return "sal{b}\t{%2, %0|%0, %2}";
9259         }
9260     }
9261 }
9262   [(set (attr "type")
9263      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9264                           (const_int 0))
9265                       (match_operand 0 "register_operand" ""))
9266                  (match_operand 2 "const1_operand" ""))
9267               (const_string "alu")
9268            ]
9269            (const_string "ishift")))
9270    (set (attr "length_immediate")
9271      (if_then_else
9272        (ior (eq_attr "type" "alu")
9273             (and (eq_attr "type" "ishift")
9274                  (and (match_operand 2 "const1_operand" "")
9275                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9276                           (const_int 0)))))
9277        (const_string "0")
9278        (const_string "*")))
9279    (set_attr "mode" "QI,SI")])
9280
9281 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9282 (define_insn "*ashlqi3_1_lea"
9283   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9284         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9285                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9286    (clobber (reg:CC FLAGS_REG))]
9287   "!TARGET_PARTIAL_REG_STALL
9288    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9289 {
9290   switch (get_attr_type (insn))
9291     {
9292     case TYPE_LEA:
9293       return "#";
9294
9295     case TYPE_ALU:
9296       gcc_assert (operands[2] == const1_rtx);
9297       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9298         return "add{l}\t%k0, %k0";
9299       else
9300         return "add{b}\t%0, %0";
9301
9302     default:
9303       if (operands[2] == const1_rtx
9304           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9305         {
9306           if (get_attr_mode (insn) == MODE_SI)
9307             return "sal{l}\t%k0";
9308           else
9309             return "sal{b}\t%0";
9310         }
9311       else
9312         {
9313           if (get_attr_mode (insn) == MODE_SI)
9314             return "sal{l}\t{%2, %k0|%k0, %2}";
9315           else
9316             return "sal{b}\t{%2, %0|%0, %2}";
9317         }
9318     }
9319 }
9320   [(set (attr "type")
9321      (cond [(eq_attr "alternative" "2")
9322               (const_string "lea")
9323             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9324                           (const_int 0))
9325                       (match_operand 0 "register_operand" ""))
9326                  (match_operand 2 "const1_operand" ""))
9327               (const_string "alu")
9328            ]
9329            (const_string "ishift")))
9330    (set (attr "length_immediate")
9331      (if_then_else
9332        (ior (eq_attr "type" "alu")
9333             (and (eq_attr "type" "ishift")
9334                  (and (match_operand 2 "const1_operand" "")
9335                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9336                           (const_int 0)))))
9337        (const_string "0")
9338        (const_string "*")))
9339    (set_attr "mode" "QI,SI,SI")])
9340
9341 (define_insn "*ashlqi3_1_slp"
9342   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9343         (ashift:QI (match_dup 0)
9344                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9345    (clobber (reg:CC FLAGS_REG))]
9346   "(optimize_function_for_size_p (cfun)
9347     || !TARGET_PARTIAL_FLAG_REG_STALL
9348     || (operands[1] == const1_rtx
9349         && (TARGET_SHIFT1
9350             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9351 {
9352   switch (get_attr_type (insn))
9353     {
9354     case TYPE_ALU:
9355       gcc_assert (operands[1] == const1_rtx);
9356       return "add{b}\t%0, %0";
9357
9358     default:
9359       if (operands[1] == const1_rtx
9360           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9361         return "sal{b}\t%0";
9362       else
9363         return "sal{b}\t{%1, %0|%0, %1}";
9364     }
9365 }
9366   [(set (attr "type")
9367      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9368                           (const_int 0))
9369                       (match_operand 0 "register_operand" ""))
9370                  (match_operand 1 "const1_operand" ""))
9371               (const_string "alu")
9372            ]
9373            (const_string "ishift1")))
9374    (set (attr "length_immediate")
9375      (if_then_else
9376        (ior (eq_attr "type" "alu")
9377             (and (eq_attr "type" "ishift1")
9378                  (and (match_operand 1 "const1_operand" "")
9379                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9380                           (const_int 0)))))
9381        (const_string "0")
9382        (const_string "*")))
9383    (set_attr "mode" "QI")])
9384
9385 ;; Convert lea to the lea pattern to avoid flags dependency.
9386 (define_split
9387   [(set (match_operand 0 "register_operand" "")
9388         (ashift (match_operand 1 "index_register_operand" "")
9389                 (match_operand:QI 2 "const_int_operand" "")))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "reload_completed
9392    && true_regnum (operands[0]) != true_regnum (operands[1])"
9393   [(const_int 0)]
9394 {
9395   rtx pat;
9396   enum machine_mode mode = GET_MODE (operands[0]);
9397
9398   if (mode != Pmode)
9399     operands[1] = gen_lowpart (Pmode, operands[1]);
9400   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9401
9402   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9403
9404   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9405     operands[0] = gen_lowpart (SImode, operands[0]);
9406
9407   if (TARGET_64BIT && mode != Pmode)
9408     pat = gen_rtx_SUBREG (SImode, pat, 0);
9409
9410   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9411   DONE;
9412 })
9413
9414 ;; Convert lea to the lea pattern to avoid flags dependency.
9415 (define_split
9416   [(set (match_operand:DI 0 "register_operand" "")
9417         (zero_extend:DI
9418           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9419                      (match_operand:QI 2 "const_int_operand" ""))))
9420    (clobber (reg:CC FLAGS_REG))]
9421   "TARGET_64BIT && reload_completed
9422    && true_regnum (operands[0]) != true_regnum (operands[1])"
9423   [(set (match_dup 0)
9424         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9425 {
9426   operands[1] = gen_lowpart (DImode, operands[1]);
9427   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9428 })
9429
9430 ;; This pattern can't accept a variable shift count, since shifts by
9431 ;; zero don't affect the flags.  We assume that shifts by constant
9432 ;; zero are optimized away.
9433 (define_insn "*ashl<mode>3_cmp"
9434   [(set (reg FLAGS_REG)
9435         (compare
9436           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9437                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9438           (const_int 0)))
9439    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9440         (ashift:SWI (match_dup 1) (match_dup 2)))]
9441   "(optimize_function_for_size_p (cfun)
9442     || !TARGET_PARTIAL_FLAG_REG_STALL
9443     || (operands[2] == const1_rtx
9444         && (TARGET_SHIFT1
9445             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9446    && ix86_match_ccmode (insn, CCGOCmode)
9447    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9448 {
9449   switch (get_attr_type (insn))
9450     {
9451     case TYPE_ALU:
9452       gcc_assert (operands[2] == const1_rtx);
9453       return "add{<imodesuffix>}\t%0, %0";
9454
9455     default:
9456       if (operands[2] == const1_rtx
9457           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9458         return "sal{<imodesuffix>}\t%0";
9459       else
9460         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9461     }
9462 }
9463   [(set (attr "type")
9464      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9465                           (const_int 0))
9466                       (match_operand 0 "register_operand" ""))
9467                  (match_operand 2 "const1_operand" ""))
9468               (const_string "alu")
9469            ]
9470            (const_string "ishift")))
9471    (set (attr "length_immediate")
9472      (if_then_else
9473        (ior (eq_attr "type" "alu")
9474             (and (eq_attr "type" "ishift")
9475                  (and (match_operand 2 "const1_operand" "")
9476                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9477                           (const_int 0)))))
9478        (const_string "0")
9479        (const_string "*")))
9480    (set_attr "mode" "<MODE>")])
9481
9482 (define_insn "*ashlsi3_cmp_zext"
9483   [(set (reg FLAGS_REG)
9484         (compare
9485           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9486                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9487           (const_int 0)))
9488    (set (match_operand:DI 0 "register_operand" "=r")
9489         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9490   "TARGET_64BIT
9491    && (optimize_function_for_size_p (cfun)
9492        || !TARGET_PARTIAL_FLAG_REG_STALL
9493        || (operands[2] == const1_rtx
9494            && (TARGET_SHIFT1
9495                || TARGET_DOUBLE_WITH_ADD)))
9496    && ix86_match_ccmode (insn, CCGOCmode)
9497    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9498 {
9499   switch (get_attr_type (insn))
9500     {
9501     case TYPE_ALU:
9502       gcc_assert (operands[2] == const1_rtx);
9503       return "add{l}\t%k0, %k0";
9504
9505     default:
9506       if (operands[2] == const1_rtx
9507           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9508         return "sal{l}\t%k0";
9509       else
9510         return "sal{l}\t{%2, %k0|%k0, %2}";
9511     }
9512 }
9513   [(set (attr "type")
9514      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9515                      (const_int 0))
9516                  (match_operand 2 "const1_operand" ""))
9517               (const_string "alu")
9518            ]
9519            (const_string "ishift")))
9520    (set (attr "length_immediate")
9521      (if_then_else
9522        (ior (eq_attr "type" "alu")
9523             (and (eq_attr "type" "ishift")
9524                  (and (match_operand 2 "const1_operand" "")
9525                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9526                           (const_int 0)))))
9527        (const_string "0")
9528        (const_string "*")))
9529    (set_attr "mode" "SI")])
9530
9531 (define_insn "*ashl<mode>3_cconly"
9532   [(set (reg FLAGS_REG)
9533         (compare
9534           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9535                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9536           (const_int 0)))
9537    (clobber (match_scratch:SWI 0 "=<r>"))]
9538   "(optimize_function_for_size_p (cfun)
9539     || !TARGET_PARTIAL_FLAG_REG_STALL
9540     || (operands[2] == const1_rtx
9541         && (TARGET_SHIFT1
9542             || TARGET_DOUBLE_WITH_ADD)))
9543    && ix86_match_ccmode (insn, CCGOCmode)"
9544 {
9545   switch (get_attr_type (insn))
9546     {
9547     case TYPE_ALU:
9548       gcc_assert (operands[2] == const1_rtx);
9549       return "add{<imodesuffix>}\t%0, %0";
9550
9551     default:
9552       if (operands[2] == const1_rtx
9553           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9554         return "sal{<imodesuffix>}\t%0";
9555       else
9556         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9557     }
9558 }
9559   [(set (attr "type")
9560      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9561                           (const_int 0))
9562                       (match_operand 0 "register_operand" ""))
9563                  (match_operand 2 "const1_operand" ""))
9564               (const_string "alu")
9565            ]
9566            (const_string "ishift")))
9567    (set (attr "length_immediate")
9568      (if_then_else
9569        (ior (eq_attr "type" "alu")
9570             (and (eq_attr "type" "ishift")
9571                  (and (match_operand 2 "const1_operand" "")
9572                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9573                           (const_int 0)))))
9574        (const_string "0")
9575        (const_string "*")))
9576    (set_attr "mode" "<MODE>")])
9577
9578 ;; See comment above `ashl<mode>3' about how this works.
9579
9580 (define_expand "<shiftrt_insn><mode>3"
9581   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9582         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9583                            (match_operand:QI 2 "nonmemory_operand" "")))]
9584   ""
9585   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9586
9587 ;; Avoid useless masking of count operand.
9588 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9589   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9590         (any_shiftrt:SWI48
9591           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9592           (subreg:QI
9593             (and:SI
9594               (match_operand:SI 2 "nonimmediate_operand" "c")
9595               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9596    (clobber (reg:CC FLAGS_REG))]
9597   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9598    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9599       == GET_MODE_BITSIZE (<MODE>mode)-1"
9600   "#"
9601   "&& 1"
9602   [(parallel [(set (match_dup 0)
9603                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9604               (clobber (reg:CC FLAGS_REG))])]
9605 {
9606   if (can_create_pseudo_p ())
9607     operands [2] = force_reg (SImode, operands[2]);
9608
9609   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9610 }
9611   [(set_attr "type" "ishift")
9612    (set_attr "mode" "<MODE>")])
9613
9614 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9615   [(set (match_operand:DWI 0 "register_operand" "=r")
9616         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9617                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9618    (clobber (reg:CC FLAGS_REG))]
9619   ""
9620   "#"
9621   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9622   [(const_int 0)]
9623   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9624   [(set_attr "type" "multi")])
9625
9626 ;; By default we don't ask for a scratch register, because when DWImode
9627 ;; values are manipulated, registers are already at a premium.  But if
9628 ;; we have one handy, we won't turn it away.
9629
9630 (define_peephole2
9631   [(match_scratch:DWIH 3 "r")
9632    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9633                    (any_shiftrt:<DWI>
9634                      (match_operand:<DWI> 1 "register_operand" "")
9635                      (match_operand:QI 2 "nonmemory_operand" "")))
9636               (clobber (reg:CC FLAGS_REG))])
9637    (match_dup 3)]
9638   "TARGET_CMOVE"
9639   [(const_int 0)]
9640   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9641
9642 (define_insn "x86_64_shrd"
9643   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9644         (ior:DI (ashiftrt:DI (match_dup 0)
9645                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9646                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9647                   (minus:QI (const_int 64) (match_dup 2)))))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "TARGET_64BIT"
9650   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9651   [(set_attr "type" "ishift")
9652    (set_attr "prefix_0f" "1")
9653    (set_attr "mode" "DI")
9654    (set_attr "athlon_decode" "vector")
9655    (set_attr "amdfam10_decode" "vector")
9656    (set_attr "bdver1_decode" "vector")])
9657
9658 (define_insn "x86_shrd"
9659   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9660         (ior:SI (ashiftrt:SI (match_dup 0)
9661                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9662                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9663                   (minus:QI (const_int 32) (match_dup 2)))))
9664    (clobber (reg:CC FLAGS_REG))]
9665   ""
9666   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9667   [(set_attr "type" "ishift")
9668    (set_attr "prefix_0f" "1")
9669    (set_attr "mode" "SI")
9670    (set_attr "pent_pair" "np")
9671    (set_attr "athlon_decode" "vector")
9672    (set_attr "amdfam10_decode" "vector")
9673    (set_attr "bdver1_decode" "vector")])
9674
9675 (define_insn "ashrdi3_cvt"
9676   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9677         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9678                      (match_operand:QI 2 "const_int_operand" "")))
9679    (clobber (reg:CC FLAGS_REG))]
9680   "TARGET_64BIT && INTVAL (operands[2]) == 63
9681    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9682    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9683   "@
9684    {cqto|cqo}
9685    sar{q}\t{%2, %0|%0, %2}"
9686   [(set_attr "type" "imovx,ishift")
9687    (set_attr "prefix_0f" "0,*")
9688    (set_attr "length_immediate" "0,*")
9689    (set_attr "modrm" "0,1")
9690    (set_attr "mode" "DI")])
9691
9692 (define_insn "ashrsi3_cvt"
9693   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9694         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9695                      (match_operand:QI 2 "const_int_operand" "")))
9696    (clobber (reg:CC FLAGS_REG))]
9697   "INTVAL (operands[2]) == 31
9698    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9699    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9700   "@
9701    {cltd|cdq}
9702    sar{l}\t{%2, %0|%0, %2}"
9703   [(set_attr "type" "imovx,ishift")
9704    (set_attr "prefix_0f" "0,*")
9705    (set_attr "length_immediate" "0,*")
9706    (set_attr "modrm" "0,1")
9707    (set_attr "mode" "SI")])
9708
9709 (define_insn "*ashrsi3_cvt_zext"
9710   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9711         (zero_extend:DI
9712           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9713                        (match_operand:QI 2 "const_int_operand" ""))))
9714    (clobber (reg:CC FLAGS_REG))]
9715   "TARGET_64BIT && INTVAL (operands[2]) == 31
9716    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9717    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9718   "@
9719    {cltd|cdq}
9720    sar{l}\t{%2, %k0|%k0, %2}"
9721   [(set_attr "type" "imovx,ishift")
9722    (set_attr "prefix_0f" "0,*")
9723    (set_attr "length_immediate" "0,*")
9724    (set_attr "modrm" "0,1")
9725    (set_attr "mode" "SI")])
9726
9727 (define_expand "x86_shift<mode>_adj_3"
9728   [(use (match_operand:SWI48 0 "register_operand" ""))
9729    (use (match_operand:SWI48 1 "register_operand" ""))
9730    (use (match_operand:QI 2 "register_operand" ""))]
9731   ""
9732 {
9733   rtx label = gen_label_rtx ();
9734   rtx tmp;
9735
9736   emit_insn (gen_testqi_ccz_1 (operands[2],
9737                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9738
9739   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9740   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9741   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9742                               gen_rtx_LABEL_REF (VOIDmode, label),
9743                               pc_rtx);
9744   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9745   JUMP_LABEL (tmp) = label;
9746
9747   emit_move_insn (operands[0], operands[1]);
9748   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9749                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9750   emit_label (label);
9751   LABEL_NUSES (label) = 1;
9752
9753   DONE;
9754 })
9755
9756 (define_insn "*<shiftrt_insn><mode>3_1"
9757   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9758         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9759                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9760    (clobber (reg:CC FLAGS_REG))]
9761   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9762 {
9763   if (operands[2] == const1_rtx
9764       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9765     return "<shiftrt>{<imodesuffix>}\t%0";
9766   else
9767     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9768 }
9769   [(set_attr "type" "ishift")
9770    (set (attr "length_immediate")
9771      (if_then_else
9772        (and (match_operand 2 "const1_operand" "")
9773             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9774                 (const_int 0)))
9775        (const_string "0")
9776        (const_string "*")))
9777    (set_attr "mode" "<MODE>")])
9778
9779 (define_insn "*<shiftrt_insn>si3_1_zext"
9780   [(set (match_operand:DI 0 "register_operand" "=r")
9781         (zero_extend:DI
9782           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9783                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9784    (clobber (reg:CC FLAGS_REG))]
9785   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9786 {
9787   if (operands[2] == const1_rtx
9788       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9789     return "<shiftrt>{l}\t%k0";
9790   else
9791     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9792 }
9793   [(set_attr "type" "ishift")
9794    (set (attr "length_immediate")
9795      (if_then_else
9796        (and (match_operand 2 "const1_operand" "")
9797             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9798                 (const_int 0)))
9799        (const_string "0")
9800        (const_string "*")))
9801    (set_attr "mode" "SI")])
9802
9803 (define_insn "*<shiftrt_insn>qi3_1_slp"
9804   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9805         (any_shiftrt:QI (match_dup 0)
9806                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9807    (clobber (reg:CC FLAGS_REG))]
9808   "(optimize_function_for_size_p (cfun)
9809     || !TARGET_PARTIAL_REG_STALL
9810     || (operands[1] == const1_rtx
9811         && TARGET_SHIFT1))"
9812 {
9813   if (operands[1] == const1_rtx
9814       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9815     return "<shiftrt>{b}\t%0";
9816   else
9817     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9818 }
9819   [(set_attr "type" "ishift1")
9820    (set (attr "length_immediate")
9821      (if_then_else
9822        (and (match_operand 1 "const1_operand" "")
9823             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9824                 (const_int 0)))
9825        (const_string "0")
9826        (const_string "*")))
9827    (set_attr "mode" "QI")])
9828
9829 ;; This pattern can't accept a variable shift count, since shifts by
9830 ;; zero don't affect the flags.  We assume that shifts by constant
9831 ;; zero are optimized away.
9832 (define_insn "*<shiftrt_insn><mode>3_cmp"
9833   [(set (reg FLAGS_REG)
9834         (compare
9835           (any_shiftrt:SWI
9836             (match_operand:SWI 1 "nonimmediate_operand" "0")
9837             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9838           (const_int 0)))
9839    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9840         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9841   "(optimize_function_for_size_p (cfun)
9842     || !TARGET_PARTIAL_FLAG_REG_STALL
9843     || (operands[2] == const1_rtx
9844         && TARGET_SHIFT1))
9845    && ix86_match_ccmode (insn, CCGOCmode)
9846    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9847 {
9848   if (operands[2] == const1_rtx
9849       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9850     return "<shiftrt>{<imodesuffix>}\t%0";
9851   else
9852     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9853 }
9854   [(set_attr "type" "ishift")
9855    (set (attr "length_immediate")
9856      (if_then_else
9857        (and (match_operand 2 "const1_operand" "")
9858             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9859                 (const_int 0)))
9860        (const_string "0")
9861        (const_string "*")))
9862    (set_attr "mode" "<MODE>")])
9863
9864 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9865   [(set (reg FLAGS_REG)
9866         (compare
9867           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9868                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9869           (const_int 0)))
9870    (set (match_operand:DI 0 "register_operand" "=r")
9871         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9872   "TARGET_64BIT
9873    && (optimize_function_for_size_p (cfun)
9874        || !TARGET_PARTIAL_FLAG_REG_STALL
9875        || (operands[2] == const1_rtx
9876            && TARGET_SHIFT1))
9877    && ix86_match_ccmode (insn, CCGOCmode)
9878    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9879 {
9880   if (operands[2] == const1_rtx
9881       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9882     return "<shiftrt>{l}\t%k0";
9883   else
9884     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9885 }
9886   [(set_attr "type" "ishift")
9887    (set (attr "length_immediate")
9888      (if_then_else
9889        (and (match_operand 2 "const1_operand" "")
9890             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9891                 (const_int 0)))
9892        (const_string "0")
9893        (const_string "*")))
9894    (set_attr "mode" "SI")])
9895
9896 (define_insn "*<shiftrt_insn><mode>3_cconly"
9897   [(set (reg FLAGS_REG)
9898         (compare
9899           (any_shiftrt:SWI
9900             (match_operand:SWI 1 "register_operand" "0")
9901             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9902           (const_int 0)))
9903    (clobber (match_scratch:SWI 0 "=<r>"))]
9904   "(optimize_function_for_size_p (cfun)
9905     || !TARGET_PARTIAL_FLAG_REG_STALL
9906     || (operands[2] == const1_rtx
9907         && TARGET_SHIFT1))
9908    && ix86_match_ccmode (insn, CCGOCmode)"
9909 {
9910   if (operands[2] == const1_rtx
9911       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9912     return "<shiftrt>{<imodesuffix>}\t%0";
9913   else
9914     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9915 }
9916   [(set_attr "type" "ishift")
9917    (set (attr "length_immediate")
9918      (if_then_else
9919        (and (match_operand 2 "const1_operand" "")
9920             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9921                 (const_int 0)))
9922        (const_string "0")
9923        (const_string "*")))
9924    (set_attr "mode" "<MODE>")])
9925 \f
9926 ;; Rotate instructions
9927
9928 (define_expand "<rotate_insn>ti3"
9929   [(set (match_operand:TI 0 "register_operand" "")
9930         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9931                        (match_operand:QI 2 "nonmemory_operand" "")))]
9932   "TARGET_64BIT"
9933 {
9934   if (const_1_to_63_operand (operands[2], VOIDmode))
9935     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9936                 (operands[0], operands[1], operands[2]));
9937   else
9938     FAIL;
9939
9940   DONE;
9941 })
9942
9943 (define_expand "<rotate_insn>di3"
9944   [(set (match_operand:DI 0 "shiftdi_operand" "")
9945         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9946                        (match_operand:QI 2 "nonmemory_operand" "")))]
9947  ""
9948 {
9949   if (TARGET_64BIT)
9950     ix86_expand_binary_operator (<CODE>, DImode, operands);
9951   else if (const_1_to_31_operand (operands[2], VOIDmode))
9952     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9953                 (operands[0], operands[1], operands[2]));
9954   else
9955     FAIL;
9956
9957   DONE;
9958 })
9959
9960 (define_expand "<rotate_insn><mode>3"
9961   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9962         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9963                             (match_operand:QI 2 "nonmemory_operand" "")))]
9964   ""
9965   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9966
9967 ;; Avoid useless masking of count operand.
9968 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9969   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9970         (any_rotate:SWI48
9971           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9972           (subreg:QI
9973             (and:SI
9974               (match_operand:SI 2 "nonimmediate_operand" "c")
9975               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9976    (clobber (reg:CC FLAGS_REG))]
9977   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9978    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9979       == GET_MODE_BITSIZE (<MODE>mode)-1"
9980   "#"
9981   "&& 1"
9982   [(parallel [(set (match_dup 0)
9983                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9984               (clobber (reg:CC FLAGS_REG))])]
9985 {
9986   if (can_create_pseudo_p ())
9987     operands [2] = force_reg (SImode, operands[2]);
9988
9989   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9990 }
9991   [(set_attr "type" "rotate")
9992    (set_attr "mode" "<MODE>")])
9993
9994 ;; Implement rotation using two double-precision
9995 ;; shift instructions and a scratch register.
9996
9997 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9998  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9999        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10000                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10001   (clobber (reg:CC FLAGS_REG))
10002   (clobber (match_scratch:DWIH 3 "=&r"))]
10003  ""
10004  "#"
10005  "reload_completed"
10006  [(set (match_dup 3) (match_dup 4))
10007   (parallel
10008    [(set (match_dup 4)
10009          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10010                    (lshiftrt:DWIH (match_dup 5)
10011                                   (minus:QI (match_dup 6) (match_dup 2)))))
10012     (clobber (reg:CC FLAGS_REG))])
10013   (parallel
10014    [(set (match_dup 5)
10015          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10016                    (lshiftrt:DWIH (match_dup 3)
10017                                   (minus:QI (match_dup 6) (match_dup 2)))))
10018     (clobber (reg:CC FLAGS_REG))])]
10019 {
10020   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10021
10022   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10023 })
10024
10025 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10026  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10027        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10028                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10029   (clobber (reg:CC FLAGS_REG))
10030   (clobber (match_scratch:DWIH 3 "=&r"))]
10031  ""
10032  "#"
10033  "reload_completed"
10034  [(set (match_dup 3) (match_dup 4))
10035   (parallel
10036    [(set (match_dup 4)
10037          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10038                    (ashift:DWIH (match_dup 5)
10039                                 (minus:QI (match_dup 6) (match_dup 2)))))
10040     (clobber (reg:CC FLAGS_REG))])
10041   (parallel
10042    [(set (match_dup 5)
10043          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10044                    (ashift:DWIH (match_dup 3)
10045                                 (minus:QI (match_dup 6) (match_dup 2)))))
10046     (clobber (reg:CC FLAGS_REG))])]
10047 {
10048   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10049
10050   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10051 })
10052
10053 (define_insn "*<rotate_insn><mode>3_1"
10054   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10055         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10056                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10057    (clobber (reg:CC FLAGS_REG))]
10058   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10059 {
10060   if (operands[2] == const1_rtx
10061       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062     return "<rotate>{<imodesuffix>}\t%0";
10063   else
10064     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10065 }
10066   [(set_attr "type" "rotate")
10067    (set (attr "length_immediate")
10068      (if_then_else
10069        (and (match_operand 2 "const1_operand" "")
10070             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10071                 (const_int 0)))
10072        (const_string "0")
10073        (const_string "*")))
10074    (set_attr "mode" "<MODE>")])
10075
10076 (define_insn "*<rotate_insn>si3_1_zext"
10077   [(set (match_operand:DI 0 "register_operand" "=r")
10078         (zero_extend:DI
10079           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10080                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10081    (clobber (reg:CC FLAGS_REG))]
10082   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10083 {
10084     if (operands[2] == const1_rtx
10085         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10086     return "<rotate>{l}\t%k0";
10087   else
10088     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10089 }
10090   [(set_attr "type" "rotate")
10091    (set (attr "length_immediate")
10092      (if_then_else
10093        (and (match_operand 2 "const1_operand" "")
10094             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10095                 (const_int 0)))
10096        (const_string "0")
10097        (const_string "*")))
10098    (set_attr "mode" "SI")])
10099
10100 (define_insn "*<rotate_insn>qi3_1_slp"
10101   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10102         (any_rotate:QI (match_dup 0)
10103                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10104    (clobber (reg:CC FLAGS_REG))]
10105   "(optimize_function_for_size_p (cfun)
10106     || !TARGET_PARTIAL_REG_STALL
10107     || (operands[1] == const1_rtx
10108         && TARGET_SHIFT1))"
10109 {
10110   if (operands[1] == const1_rtx
10111       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10112     return "<rotate>{b}\t%0";
10113   else
10114     return "<rotate>{b}\t{%1, %0|%0, %1}";
10115 }
10116   [(set_attr "type" "rotate1")
10117    (set (attr "length_immediate")
10118      (if_then_else
10119        (and (match_operand 1 "const1_operand" "")
10120             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10121                 (const_int 0)))
10122        (const_string "0")
10123        (const_string "*")))
10124    (set_attr "mode" "QI")])
10125
10126 (define_split
10127  [(set (match_operand:HI 0 "register_operand" "")
10128        (any_rotate:HI (match_dup 0) (const_int 8)))
10129   (clobber (reg:CC FLAGS_REG))]
10130  "reload_completed
10131   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10132  [(parallel [(set (strict_low_part (match_dup 0))
10133                   (bswap:HI (match_dup 0)))
10134              (clobber (reg:CC FLAGS_REG))])])
10135 \f
10136 ;; Bit set / bit test instructions
10137
10138 (define_expand "extv"
10139   [(set (match_operand:SI 0 "register_operand" "")
10140         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10141                          (match_operand:SI 2 "const8_operand" "")
10142                          (match_operand:SI 3 "const8_operand" "")))]
10143   ""
10144 {
10145   /* Handle extractions from %ah et al.  */
10146   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10147     FAIL;
10148
10149   /* From mips.md: extract_bit_field doesn't verify that our source
10150      matches the predicate, so check it again here.  */
10151   if (! ext_register_operand (operands[1], VOIDmode))
10152     FAIL;
10153 })
10154
10155 (define_expand "extzv"
10156   [(set (match_operand:SI 0 "register_operand" "")
10157         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10158                          (match_operand:SI 2 "const8_operand" "")
10159                          (match_operand:SI 3 "const8_operand" "")))]
10160   ""
10161 {
10162   /* Handle extractions from %ah et al.  */
10163   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10164     FAIL;
10165
10166   /* From mips.md: extract_bit_field doesn't verify that our source
10167      matches the predicate, so check it again here.  */
10168   if (! ext_register_operand (operands[1], VOIDmode))
10169     FAIL;
10170 })
10171
10172 (define_expand "insv"
10173   [(set (zero_extract (match_operand 0 "register_operand" "")
10174                       (match_operand 1 "const_int_operand" "")
10175                       (match_operand 2 "const_int_operand" ""))
10176         (match_operand 3 "register_operand" ""))]
10177   ""
10178 {
10179   rtx (*gen_mov_insv_1) (rtx, rtx);
10180
10181   if (ix86_expand_pinsr (operands))
10182     DONE;
10183
10184   /* Handle insertions to %ah et al.  */
10185   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10186     FAIL;
10187
10188   /* From mips.md: insert_bit_field doesn't verify that our source
10189      matches the predicate, so check it again here.  */
10190   if (! ext_register_operand (operands[0], VOIDmode))
10191     FAIL;
10192
10193   gen_mov_insv_1 = (TARGET_64BIT
10194                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10195
10196   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10197   DONE;
10198 })
10199
10200 ;; %%% bts, btr, btc, bt.
10201 ;; In general these instructions are *slow* when applied to memory,
10202 ;; since they enforce atomic operation.  When applied to registers,
10203 ;; it depends on the cpu implementation.  They're never faster than
10204 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10205 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10206 ;; within the instruction itself, so operating on bits in the high
10207 ;; 32-bits of a register becomes easier.
10208 ;;
10209 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10210 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10211 ;; negdf respectively, so they can never be disabled entirely.
10212
10213 (define_insn "*btsq"
10214   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10215                          (const_int 1)
10216                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10217         (const_int 1))
10218    (clobber (reg:CC FLAGS_REG))]
10219   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10220   "bts{q}\t{%1, %0|%0, %1}"
10221   [(set_attr "type" "alu1")
10222    (set_attr "prefix_0f" "1")
10223    (set_attr "mode" "DI")])
10224
10225 (define_insn "*btrq"
10226   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10227                          (const_int 1)
10228                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10229         (const_int 0))
10230    (clobber (reg:CC FLAGS_REG))]
10231   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10232   "btr{q}\t{%1, %0|%0, %1}"
10233   [(set_attr "type" "alu1")
10234    (set_attr "prefix_0f" "1")
10235    (set_attr "mode" "DI")])
10236
10237 (define_insn "*btcq"
10238   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10239                          (const_int 1)
10240                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10241         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10242    (clobber (reg:CC FLAGS_REG))]
10243   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10244   "btc{q}\t{%1, %0|%0, %1}"
10245   [(set_attr "type" "alu1")
10246    (set_attr "prefix_0f" "1")
10247    (set_attr "mode" "DI")])
10248
10249 ;; Allow Nocona to avoid these instructions if a register is available.
10250
10251 (define_peephole2
10252   [(match_scratch:DI 2 "r")
10253    (parallel [(set (zero_extract:DI
10254                      (match_operand:DI 0 "register_operand" "")
10255                      (const_int 1)
10256                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10257                    (const_int 1))
10258               (clobber (reg:CC FLAGS_REG))])]
10259   "TARGET_64BIT && !TARGET_USE_BT"
10260   [(const_int 0)]
10261 {
10262   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10263   rtx op1;
10264
10265   if (HOST_BITS_PER_WIDE_INT >= 64)
10266     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10267   else if (i < HOST_BITS_PER_WIDE_INT)
10268     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10269   else
10270     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10271
10272   op1 = immed_double_const (lo, hi, DImode);
10273   if (i >= 31)
10274     {
10275       emit_move_insn (operands[2], op1);
10276       op1 = operands[2];
10277     }
10278
10279   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10280   DONE;
10281 })
10282
10283 (define_peephole2
10284   [(match_scratch:DI 2 "r")
10285    (parallel [(set (zero_extract:DI
10286                      (match_operand:DI 0 "register_operand" "")
10287                      (const_int 1)
10288                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10289                    (const_int 0))
10290               (clobber (reg:CC FLAGS_REG))])]
10291   "TARGET_64BIT && !TARGET_USE_BT"
10292   [(const_int 0)]
10293 {
10294   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10295   rtx op1;
10296
10297   if (HOST_BITS_PER_WIDE_INT >= 64)
10298     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10299   else if (i < HOST_BITS_PER_WIDE_INT)
10300     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10301   else
10302     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10303
10304   op1 = immed_double_const (~lo, ~hi, DImode);
10305   if (i >= 32)
10306     {
10307       emit_move_insn (operands[2], op1);
10308       op1 = operands[2];
10309     }
10310
10311   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10312   DONE;
10313 })
10314
10315 (define_peephole2
10316   [(match_scratch:DI 2 "r")
10317    (parallel [(set (zero_extract:DI
10318                      (match_operand:DI 0 "register_operand" "")
10319                      (const_int 1)
10320                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10321               (not:DI (zero_extract:DI
10322                         (match_dup 0) (const_int 1) (match_dup 1))))
10323               (clobber (reg:CC FLAGS_REG))])]
10324   "TARGET_64BIT && !TARGET_USE_BT"
10325   [(const_int 0)]
10326 {
10327   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10328   rtx op1;
10329
10330   if (HOST_BITS_PER_WIDE_INT >= 64)
10331     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10332   else if (i < HOST_BITS_PER_WIDE_INT)
10333     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10334   else
10335     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10336
10337   op1 = immed_double_const (lo, hi, DImode);
10338   if (i >= 31)
10339     {
10340       emit_move_insn (operands[2], op1);
10341       op1 = operands[2];
10342     }
10343
10344   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10345   DONE;
10346 })
10347
10348 (define_insn "*bt<mode>"
10349   [(set (reg:CCC FLAGS_REG)
10350         (compare:CCC
10351           (zero_extract:SWI48
10352             (match_operand:SWI48 0 "register_operand" "r")
10353             (const_int 1)
10354             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10355           (const_int 0)))]
10356   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10357   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10358   [(set_attr "type" "alu1")
10359    (set_attr "prefix_0f" "1")
10360    (set_attr "mode" "<MODE>")])
10361 \f
10362 ;; Store-flag instructions.
10363
10364 ;; For all sCOND expanders, also expand the compare or test insn that
10365 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10366
10367 (define_insn_and_split "*setcc_di_1"
10368   [(set (match_operand:DI 0 "register_operand" "=q")
10369         (match_operator:DI 1 "ix86_comparison_operator"
10370           [(reg FLAGS_REG) (const_int 0)]))]
10371   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10372   "#"
10373   "&& reload_completed"
10374   [(set (match_dup 2) (match_dup 1))
10375    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10376 {
10377   PUT_MODE (operands[1], QImode);
10378   operands[2] = gen_lowpart (QImode, operands[0]);
10379 })
10380
10381 (define_insn_and_split "*setcc_si_1_and"
10382   [(set (match_operand:SI 0 "register_operand" "=q")
10383         (match_operator:SI 1 "ix86_comparison_operator"
10384           [(reg FLAGS_REG) (const_int 0)]))
10385    (clobber (reg:CC FLAGS_REG))]
10386   "!TARGET_PARTIAL_REG_STALL
10387    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10388   "#"
10389   "&& reload_completed"
10390   [(set (match_dup 2) (match_dup 1))
10391    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10392               (clobber (reg:CC FLAGS_REG))])]
10393 {
10394   PUT_MODE (operands[1], QImode);
10395   operands[2] = gen_lowpart (QImode, operands[0]);
10396 })
10397
10398 (define_insn_and_split "*setcc_si_1_movzbl"
10399   [(set (match_operand:SI 0 "register_operand" "=q")
10400         (match_operator:SI 1 "ix86_comparison_operator"
10401           [(reg FLAGS_REG) (const_int 0)]))]
10402   "!TARGET_PARTIAL_REG_STALL
10403    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10404   "#"
10405   "&& reload_completed"
10406   [(set (match_dup 2) (match_dup 1))
10407    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10408 {
10409   PUT_MODE (operands[1], QImode);
10410   operands[2] = gen_lowpart (QImode, operands[0]);
10411 })
10412
10413 (define_insn "*setcc_qi"
10414   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10415         (match_operator:QI 1 "ix86_comparison_operator"
10416           [(reg FLAGS_REG) (const_int 0)]))]
10417   ""
10418   "set%C1\t%0"
10419   [(set_attr "type" "setcc")
10420    (set_attr "mode" "QI")])
10421
10422 (define_insn "*setcc_qi_slp"
10423   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10424         (match_operator:QI 1 "ix86_comparison_operator"
10425           [(reg FLAGS_REG) (const_int 0)]))]
10426   ""
10427   "set%C1\t%0"
10428   [(set_attr "type" "setcc")
10429    (set_attr "mode" "QI")])
10430
10431 ;; In general it is not safe to assume too much about CCmode registers,
10432 ;; so simplify-rtx stops when it sees a second one.  Under certain
10433 ;; conditions this is safe on x86, so help combine not create
10434 ;;
10435 ;;      seta    %al
10436 ;;      testb   %al, %al
10437 ;;      sete    %al
10438
10439 (define_split
10440   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10441         (ne:QI (match_operator 1 "ix86_comparison_operator"
10442                  [(reg FLAGS_REG) (const_int 0)])
10443             (const_int 0)))]
10444   ""
10445   [(set (match_dup 0) (match_dup 1))]
10446   "PUT_MODE (operands[1], QImode);")
10447
10448 (define_split
10449   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10450         (ne:QI (match_operator 1 "ix86_comparison_operator"
10451                  [(reg FLAGS_REG) (const_int 0)])
10452             (const_int 0)))]
10453   ""
10454   [(set (match_dup 0) (match_dup 1))]
10455   "PUT_MODE (operands[1], QImode);")
10456
10457 (define_split
10458   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10459         (eq:QI (match_operator 1 "ix86_comparison_operator"
10460                  [(reg FLAGS_REG) (const_int 0)])
10461             (const_int 0)))]
10462   ""
10463   [(set (match_dup 0) (match_dup 1))]
10464 {
10465   rtx new_op1 = copy_rtx (operands[1]);
10466   operands[1] = new_op1;
10467   PUT_MODE (new_op1, QImode);
10468   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10469                                              GET_MODE (XEXP (new_op1, 0))));
10470
10471   /* Make sure that (a) the CCmode we have for the flags is strong
10472      enough for the reversed compare or (b) we have a valid FP compare.  */
10473   if (! ix86_comparison_operator (new_op1, VOIDmode))
10474     FAIL;
10475 })
10476
10477 (define_split
10478   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10479         (eq:QI (match_operator 1 "ix86_comparison_operator"
10480                  [(reg FLAGS_REG) (const_int 0)])
10481             (const_int 0)))]
10482   ""
10483   [(set (match_dup 0) (match_dup 1))]
10484 {
10485   rtx new_op1 = copy_rtx (operands[1]);
10486   operands[1] = new_op1;
10487   PUT_MODE (new_op1, QImode);
10488   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10489                                              GET_MODE (XEXP (new_op1, 0))));
10490
10491   /* Make sure that (a) the CCmode we have for the flags is strong
10492      enough for the reversed compare or (b) we have a valid FP compare.  */
10493   if (! ix86_comparison_operator (new_op1, VOIDmode))
10494     FAIL;
10495 })
10496
10497 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10498 ;; subsequent logical operations are used to imitate conditional moves.
10499 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10500 ;; it directly.
10501
10502 (define_insn "setcc_<mode>_sse"
10503   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10504         (match_operator:MODEF 3 "sse_comparison_operator"
10505           [(match_operand:MODEF 1 "register_operand" "0,x")
10506            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10507   "SSE_FLOAT_MODE_P (<MODE>mode)"
10508   "@
10509    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10510    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10511   [(set_attr "isa" "noavx,avx")
10512    (set_attr "type" "ssecmp")
10513    (set_attr "length_immediate" "1")
10514    (set_attr "prefix" "orig,vex")
10515    (set_attr "mode" "<MODE>")])
10516 \f
10517 ;; Basic conditional jump instructions.
10518 ;; We ignore the overflow flag for signed branch instructions.
10519
10520 (define_insn "*jcc_1"
10521   [(set (pc)
10522         (if_then_else (match_operator 1 "ix86_comparison_operator"
10523                                       [(reg FLAGS_REG) (const_int 0)])
10524                       (label_ref (match_operand 0 "" ""))
10525                       (pc)))]
10526   ""
10527   "%+j%C1\t%l0"
10528   [(set_attr "type" "ibr")
10529    (set_attr "modrm" "0")
10530    (set (attr "length")
10531            (if_then_else (and (ge (minus (match_dup 0) (pc))
10532                                   (const_int -126))
10533                               (lt (minus (match_dup 0) (pc))
10534                                   (const_int 128)))
10535              (const_int 2)
10536              (const_int 6)))])
10537
10538 (define_insn "*jcc_2"
10539   [(set (pc)
10540         (if_then_else (match_operator 1 "ix86_comparison_operator"
10541                                       [(reg FLAGS_REG) (const_int 0)])
10542                       (pc)
10543                       (label_ref (match_operand 0 "" ""))))]
10544   ""
10545   "%+j%c1\t%l0"
10546   [(set_attr "type" "ibr")
10547    (set_attr "modrm" "0")
10548    (set (attr "length")
10549            (if_then_else (and (ge (minus (match_dup 0) (pc))
10550                                   (const_int -126))
10551                               (lt (minus (match_dup 0) (pc))
10552                                   (const_int 128)))
10553              (const_int 2)
10554              (const_int 6)))])
10555
10556 ;; In general it is not safe to assume too much about CCmode registers,
10557 ;; so simplify-rtx stops when it sees a second one.  Under certain
10558 ;; conditions this is safe on x86, so help combine not create
10559 ;;
10560 ;;      seta    %al
10561 ;;      testb   %al, %al
10562 ;;      je      Lfoo
10563
10564 (define_split
10565   [(set (pc)
10566         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10567                                       [(reg FLAGS_REG) (const_int 0)])
10568                           (const_int 0))
10569                       (label_ref (match_operand 1 "" ""))
10570                       (pc)))]
10571   ""
10572   [(set (pc)
10573         (if_then_else (match_dup 0)
10574                       (label_ref (match_dup 1))
10575                       (pc)))]
10576   "PUT_MODE (operands[0], VOIDmode);")
10577
10578 (define_split
10579   [(set (pc)
10580         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10581                                       [(reg FLAGS_REG) (const_int 0)])
10582                           (const_int 0))
10583                       (label_ref (match_operand 1 "" ""))
10584                       (pc)))]
10585   ""
10586   [(set (pc)
10587         (if_then_else (match_dup 0)
10588                       (label_ref (match_dup 1))
10589                       (pc)))]
10590 {
10591   rtx new_op0 = copy_rtx (operands[0]);
10592   operands[0] = new_op0;
10593   PUT_MODE (new_op0, VOIDmode);
10594   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10595                                              GET_MODE (XEXP (new_op0, 0))));
10596
10597   /* Make sure that (a) the CCmode we have for the flags is strong
10598      enough for the reversed compare or (b) we have a valid FP compare.  */
10599   if (! ix86_comparison_operator (new_op0, VOIDmode))
10600     FAIL;
10601 })
10602
10603 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10604 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10605 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10606 ;; appropriate modulo of the bit offset value.
10607
10608 (define_insn_and_split "*jcc_bt<mode>"
10609   [(set (pc)
10610         (if_then_else (match_operator 0 "bt_comparison_operator"
10611                         [(zero_extract:SWI48
10612                            (match_operand:SWI48 1 "register_operand" "r")
10613                            (const_int 1)
10614                            (zero_extend:SI
10615                              (match_operand:QI 2 "register_operand" "r")))
10616                          (const_int 0)])
10617                       (label_ref (match_operand 3 "" ""))
10618                       (pc)))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10621   "#"
10622   "&& 1"
10623   [(set (reg:CCC FLAGS_REG)
10624         (compare:CCC
10625           (zero_extract:SWI48
10626             (match_dup 1)
10627             (const_int 1)
10628             (match_dup 2))
10629           (const_int 0)))
10630    (set (pc)
10631         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10632                       (label_ref (match_dup 3))
10633                       (pc)))]
10634 {
10635   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10636
10637   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10638 })
10639
10640 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10641 ;; also for DImode, this is what combine produces.
10642 (define_insn_and_split "*jcc_bt<mode>_mask"
10643   [(set (pc)
10644         (if_then_else (match_operator 0 "bt_comparison_operator"
10645                         [(zero_extract:SWI48
10646                            (match_operand:SWI48 1 "register_operand" "r")
10647                            (const_int 1)
10648                            (and:SI
10649                              (match_operand:SI 2 "register_operand" "r")
10650                              (match_operand:SI 3 "const_int_operand" "n")))])
10651                       (label_ref (match_operand 4 "" ""))
10652                       (pc)))
10653    (clobber (reg:CC FLAGS_REG))]
10654   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10655    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10656       == GET_MODE_BITSIZE (<MODE>mode)-1"
10657   "#"
10658   "&& 1"
10659   [(set (reg:CCC FLAGS_REG)
10660         (compare:CCC
10661           (zero_extract:SWI48
10662             (match_dup 1)
10663             (const_int 1)
10664             (match_dup 2))
10665           (const_int 0)))
10666    (set (pc)
10667         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10668                       (label_ref (match_dup 4))
10669                       (pc)))]
10670 {
10671   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10672
10673   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10674 })
10675
10676 (define_insn_and_split "*jcc_btsi_1"
10677   [(set (pc)
10678         (if_then_else (match_operator 0 "bt_comparison_operator"
10679                         [(and:SI
10680                            (lshiftrt:SI
10681                              (match_operand:SI 1 "register_operand" "r")
10682                              (match_operand:QI 2 "register_operand" "r"))
10683                            (const_int 1))
10684                          (const_int 0)])
10685                       (label_ref (match_operand 3 "" ""))
10686                       (pc)))
10687    (clobber (reg:CC FLAGS_REG))]
10688   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10689   "#"
10690   "&& 1"
10691   [(set (reg:CCC FLAGS_REG)
10692         (compare:CCC
10693           (zero_extract:SI
10694             (match_dup 1)
10695             (const_int 1)
10696             (match_dup 2))
10697           (const_int 0)))
10698    (set (pc)
10699         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10700                       (label_ref (match_dup 3))
10701                       (pc)))]
10702 {
10703   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10704
10705   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10706 })
10707
10708 ;; avoid useless masking of bit offset operand
10709 (define_insn_and_split "*jcc_btsi_mask_1"
10710   [(set (pc)
10711         (if_then_else
10712           (match_operator 0 "bt_comparison_operator"
10713             [(and:SI
10714                (lshiftrt:SI
10715                  (match_operand:SI 1 "register_operand" "r")
10716                  (subreg:QI
10717                    (and:SI
10718                      (match_operand:SI 2 "register_operand" "r")
10719                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10720                (const_int 1))
10721              (const_int 0)])
10722           (label_ref (match_operand 4 "" ""))
10723           (pc)))
10724    (clobber (reg:CC FLAGS_REG))]
10725   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10726    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10727   "#"
10728   "&& 1"
10729   [(set (reg:CCC FLAGS_REG)
10730         (compare:CCC
10731           (zero_extract:SI
10732             (match_dup 1)
10733             (const_int 1)
10734             (match_dup 2))
10735           (const_int 0)))
10736    (set (pc)
10737         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10738                       (label_ref (match_dup 4))
10739                       (pc)))]
10740   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10741
10742 ;; Define combination compare-and-branch fp compare instructions to help
10743 ;; combine.
10744
10745 (define_insn "*fp_jcc_1_387"
10746   [(set (pc)
10747         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10748                         [(match_operand 1 "register_operand" "f")
10749                          (match_operand 2 "nonimmediate_operand" "fm")])
10750           (label_ref (match_operand 3 "" ""))
10751           (pc)))
10752    (clobber (reg:CCFP FPSR_REG))
10753    (clobber (reg:CCFP FLAGS_REG))
10754    (clobber (match_scratch:HI 4 "=a"))]
10755   "TARGET_80387
10756    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10757    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10758    && SELECT_CC_MODE (GET_CODE (operands[0]),
10759                       operands[1], operands[2]) == CCFPmode
10760    && !TARGET_CMOVE"
10761   "#")
10762
10763 (define_insn "*fp_jcc_1r_387"
10764   [(set (pc)
10765         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10766                         [(match_operand 1 "register_operand" "f")
10767                          (match_operand 2 "nonimmediate_operand" "fm")])
10768           (pc)
10769           (label_ref (match_operand 3 "" ""))))
10770    (clobber (reg:CCFP FPSR_REG))
10771    (clobber (reg:CCFP FLAGS_REG))
10772    (clobber (match_scratch:HI 4 "=a"))]
10773   "TARGET_80387
10774    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10775    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10776    && SELECT_CC_MODE (GET_CODE (operands[0]),
10777                       operands[1], operands[2]) == CCFPmode
10778    && !TARGET_CMOVE"
10779   "#")
10780
10781 (define_insn "*fp_jcc_2_387"
10782   [(set (pc)
10783         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10784                         [(match_operand 1 "register_operand" "f")
10785                          (match_operand 2 "register_operand" "f")])
10786           (label_ref (match_operand 3 "" ""))
10787           (pc)))
10788    (clobber (reg:CCFP FPSR_REG))
10789    (clobber (reg:CCFP FLAGS_REG))
10790    (clobber (match_scratch:HI 4 "=a"))]
10791   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10792    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10793    && !TARGET_CMOVE"
10794   "#")
10795
10796 (define_insn "*fp_jcc_2r_387"
10797   [(set (pc)
10798         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10799                         [(match_operand 1 "register_operand" "f")
10800                          (match_operand 2 "register_operand" "f")])
10801           (pc)
10802           (label_ref (match_operand 3 "" ""))))
10803    (clobber (reg:CCFP FPSR_REG))
10804    (clobber (reg:CCFP FLAGS_REG))
10805    (clobber (match_scratch:HI 4 "=a"))]
10806   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10807    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10808    && !TARGET_CMOVE"
10809   "#")
10810
10811 (define_insn "*fp_jcc_3_387"
10812   [(set (pc)
10813         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10814                         [(match_operand 1 "register_operand" "f")
10815                          (match_operand 2 "const0_operand" "")])
10816           (label_ref (match_operand 3 "" ""))
10817           (pc)))
10818    (clobber (reg:CCFP FPSR_REG))
10819    (clobber (reg:CCFP FLAGS_REG))
10820    (clobber (match_scratch:HI 4 "=a"))]
10821   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10822    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10823    && SELECT_CC_MODE (GET_CODE (operands[0]),
10824                       operands[1], operands[2]) == CCFPmode
10825    && !TARGET_CMOVE"
10826   "#")
10827
10828 (define_split
10829   [(set (pc)
10830         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10831                         [(match_operand 1 "register_operand" "")
10832                          (match_operand 2 "nonimmediate_operand" "")])
10833           (match_operand 3 "" "")
10834           (match_operand 4 "" "")))
10835    (clobber (reg:CCFP FPSR_REG))
10836    (clobber (reg:CCFP FLAGS_REG))]
10837   "reload_completed"
10838   [(const_int 0)]
10839 {
10840   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10841                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10842   DONE;
10843 })
10844
10845 (define_split
10846   [(set (pc)
10847         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10848                         [(match_operand 1 "register_operand" "")
10849                          (match_operand 2 "general_operand" "")])
10850           (match_operand 3 "" "")
10851           (match_operand 4 "" "")))
10852    (clobber (reg:CCFP FPSR_REG))
10853    (clobber (reg:CCFP FLAGS_REG))
10854    (clobber (match_scratch:HI 5 "=a"))]
10855   "reload_completed"
10856   [(const_int 0)]
10857 {
10858   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10859                         operands[3], operands[4], operands[5], NULL_RTX);
10860   DONE;
10861 })
10862
10863 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10864 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10865 ;; with a precedence over other operators and is always put in the first
10866 ;; place. Swap condition and operands to match ficom instruction.
10867
10868 (define_insn "*fp_jcc_4_<mode>_387"
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 "nonimmediate_operand" "m,?r")])
10874              (match_operand 3 "register_operand" "f,f")])
10875           (label_ref (match_operand 4 "" ""))
10876           (pc)))
10877    (clobber (reg:CCFP FPSR_REG))
10878    (clobber (reg:CCFP FLAGS_REG))
10879    (clobber (match_scratch:HI 5 "=a,a"))]
10880   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10881    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10882    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10883    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10884    && !TARGET_CMOVE"
10885   "#")
10886
10887 (define_split
10888   [(set (pc)
10889         (if_then_else
10890           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10891             [(match_operator 1 "float_operator"
10892               [(match_operand:SWI24 2 "memory_operand" "")])
10893              (match_operand 3 "register_operand" "")])
10894           (match_operand 4 "" "")
10895           (match_operand 5 "" "")))
10896    (clobber (reg:CCFP FPSR_REG))
10897    (clobber (reg:CCFP FLAGS_REG))
10898    (clobber (match_scratch:HI 6 "=a"))]
10899   "reload_completed"
10900   [(const_int 0)]
10901 {
10902   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10903
10904   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10905                         operands[3], operands[7],
10906                         operands[4], operands[5], operands[6], NULL_RTX);
10907   DONE;
10908 })
10909
10910 ;; %%% Kill this when reload knows how to do it.
10911 (define_split
10912   [(set (pc)
10913         (if_then_else
10914           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10915             [(match_operator 1 "float_operator"
10916               [(match_operand:SWI24 2 "register_operand" "")])
10917              (match_operand 3 "register_operand" "")])
10918           (match_operand 4 "" "")
10919           (match_operand 5 "" "")))
10920    (clobber (reg:CCFP FPSR_REG))
10921    (clobber (reg:CCFP FLAGS_REG))
10922    (clobber (match_scratch:HI 6 "=a"))]
10923   "reload_completed"
10924   [(const_int 0)]
10925 {
10926   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10927   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10928
10929   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10930                         operands[3], operands[7],
10931                         operands[4], operands[5], operands[6], operands[2]);
10932   DONE;
10933 })
10934 \f
10935 ;; Unconditional and other jump instructions
10936
10937 (define_insn "jump"
10938   [(set (pc)
10939         (label_ref (match_operand 0 "" "")))]
10940   ""
10941   "jmp\t%l0"
10942   [(set_attr "type" "ibr")
10943    (set (attr "length")
10944            (if_then_else (and (ge (minus (match_dup 0) (pc))
10945                                   (const_int -126))
10946                               (lt (minus (match_dup 0) (pc))
10947                                   (const_int 128)))
10948              (const_int 2)
10949              (const_int 5)))
10950    (set_attr "modrm" "0")])
10951
10952 (define_expand "indirect_jump"
10953   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10954   ""
10955   "")
10956
10957 (define_insn "*indirect_jump"
10958   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10959   ""
10960   "jmp\t%A0"
10961   [(set_attr "type" "ibr")
10962    (set_attr "length_immediate" "0")])
10963
10964 (define_expand "tablejump"
10965   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10966               (use (label_ref (match_operand 1 "" "")))])]
10967   ""
10968 {
10969   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10970      relative.  Convert the relative address to an absolute address.  */
10971   if (flag_pic)
10972     {
10973       rtx op0, op1;
10974       enum rtx_code code;
10975
10976       /* We can't use @GOTOFF for text labels on VxWorks;
10977          see gotoff_operand.  */
10978       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10979         {
10980           code = PLUS;
10981           op0 = operands[0];
10982           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10983         }
10984       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10985         {
10986           code = PLUS;
10987           op0 = operands[0];
10988           op1 = pic_offset_table_rtx;
10989         }
10990       else
10991         {
10992           code = MINUS;
10993           op0 = pic_offset_table_rtx;
10994           op1 = operands[0];
10995         }
10996
10997       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10998                                          OPTAB_DIRECT);
10999     }
11000 })
11001
11002 (define_insn "*tablejump_1"
11003   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11004    (use (label_ref (match_operand 1 "" "")))]
11005   ""
11006   "jmp\t%A0"
11007   [(set_attr "type" "ibr")
11008    (set_attr "length_immediate" "0")])
11009 \f
11010 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11011
11012 (define_peephole2
11013   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11014    (set (match_operand:QI 1 "register_operand" "")
11015         (match_operator:QI 2 "ix86_comparison_operator"
11016           [(reg FLAGS_REG) (const_int 0)]))
11017    (set (match_operand 3 "q_regs_operand" "")
11018         (zero_extend (match_dup 1)))]
11019   "(peep2_reg_dead_p (3, operands[1])
11020     || operands_match_p (operands[1], operands[3]))
11021    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11022   [(set (match_dup 4) (match_dup 0))
11023    (set (strict_low_part (match_dup 5))
11024         (match_dup 2))]
11025 {
11026   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11027   operands[5] = gen_lowpart (QImode, operands[3]);
11028   ix86_expand_clear (operands[3]);
11029 })
11030
11031 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11032
11033 (define_peephole2
11034   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11035    (set (match_operand:QI 1 "register_operand" "")
11036         (match_operator:QI 2 "ix86_comparison_operator"
11037           [(reg FLAGS_REG) (const_int 0)]))
11038    (parallel [(set (match_operand 3 "q_regs_operand" "")
11039                    (zero_extend (match_dup 1)))
11040               (clobber (reg:CC FLAGS_REG))])]
11041   "(peep2_reg_dead_p (3, operands[1])
11042     || operands_match_p (operands[1], operands[3]))
11043    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11044   [(set (match_dup 4) (match_dup 0))
11045    (set (strict_low_part (match_dup 5))
11046         (match_dup 2))]
11047 {
11048   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11049   operands[5] = gen_lowpart (QImode, operands[3]);
11050   ix86_expand_clear (operands[3]);
11051 })
11052 \f
11053 ;; Call instructions.
11054
11055 ;; The predicates normally associated with named expanders are not properly
11056 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11057 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11058
11059 ;; P6 processors will jump to the address after the decrement when %esp
11060 ;; is used as a call operand, so they will execute return address as a code.
11061 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11062
11063 ;; Register constraint for call instruction.
11064 (define_mode_attr c [(SI "l") (DI "r")])
11065
11066 ;; Call subroutine returning no value.
11067
11068 (define_expand "call"
11069   [(call (match_operand:QI 0 "" "")
11070          (match_operand 1 "" ""))
11071    (use (match_operand 2 "" ""))]
11072   ""
11073 {
11074   ix86_expand_call (NULL, operands[0], operands[1],
11075                     operands[2], NULL, false);
11076   DONE;
11077 })
11078
11079 (define_expand "sibcall"
11080   [(call (match_operand:QI 0 "" "")
11081          (match_operand 1 "" ""))
11082    (use (match_operand 2 "" ""))]
11083   ""
11084 {
11085   ix86_expand_call (NULL, operands[0], operands[1],
11086                     operands[2], NULL, true);
11087   DONE;
11088 })
11089
11090 (define_insn_and_split "*call_vzeroupper"
11091   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11092          (match_operand 1 "" ""))
11093    (unspec [(match_operand 2 "const_int_operand" "")]
11094            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11095   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11096   "#"
11097   "&& reload_completed"
11098   [(const_int 0)]
11099   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11100   [(set_attr "type" "call")])
11101
11102 (define_insn "*call"
11103   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11104          (match_operand 1 "" ""))]
11105   "!SIBLING_CALL_P (insn)"
11106   "* return ix86_output_call_insn (insn, operands[0]);"
11107   [(set_attr "type" "call")])
11108
11109 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11110   [(parallel
11111     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11112            (match_operand 1 "" ""))
11113      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11114      (clobber (reg:TI XMM6_REG))
11115      (clobber (reg:TI XMM7_REG))
11116      (clobber (reg:TI XMM8_REG))
11117      (clobber (reg:TI XMM9_REG))
11118      (clobber (reg:TI XMM10_REG))
11119      (clobber (reg:TI XMM11_REG))
11120      (clobber (reg:TI XMM12_REG))
11121      (clobber (reg:TI XMM13_REG))
11122      (clobber (reg:TI XMM14_REG))
11123      (clobber (reg:TI XMM15_REG))
11124      (clobber (reg:DI SI_REG))
11125      (clobber (reg:DI DI_REG))])
11126    (unspec [(match_operand 2 "const_int_operand" "")]
11127            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11128   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11129   "#"
11130   "&& reload_completed"
11131   [(const_int 0)]
11132   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11133   [(set_attr "type" "call")])
11134
11135 (define_insn "*call_rex64_ms_sysv"
11136   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11137          (match_operand 1 "" ""))
11138    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11139    (clobber (reg:TI XMM6_REG))
11140    (clobber (reg:TI XMM7_REG))
11141    (clobber (reg:TI XMM8_REG))
11142    (clobber (reg:TI XMM9_REG))
11143    (clobber (reg:TI XMM10_REG))
11144    (clobber (reg:TI XMM11_REG))
11145    (clobber (reg:TI XMM12_REG))
11146    (clobber (reg:TI XMM13_REG))
11147    (clobber (reg:TI XMM14_REG))
11148    (clobber (reg:TI XMM15_REG))
11149    (clobber (reg:DI SI_REG))
11150    (clobber (reg:DI DI_REG))]
11151   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11152   "* return ix86_output_call_insn (insn, operands[0]);"
11153   [(set_attr "type" "call")])
11154
11155 (define_insn_and_split "*sibcall_vzeroupper"
11156   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11157          (match_operand 1 "" ""))
11158    (unspec [(match_operand 2 "const_int_operand" "")]
11159            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11160   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11161   "#"
11162   "&& reload_completed"
11163   [(const_int 0)]
11164   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11165   [(set_attr "type" "call")])
11166
11167 (define_insn "*sibcall"
11168   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11169          (match_operand 1 "" ""))]
11170   "SIBLING_CALL_P (insn)"
11171   "* return ix86_output_call_insn (insn, operands[0]);"
11172   [(set_attr "type" "call")])
11173
11174 (define_expand "call_pop"
11175   [(parallel [(call (match_operand:QI 0 "" "")
11176                     (match_operand:SI 1 "" ""))
11177               (set (reg:SI SP_REG)
11178                    (plus:SI (reg:SI SP_REG)
11179                             (match_operand:SI 3 "" "")))])]
11180   "!TARGET_64BIT"
11181 {
11182   ix86_expand_call (NULL, operands[0], operands[1],
11183                     operands[2], operands[3], false);
11184   DONE;
11185 })
11186
11187 (define_insn_and_split "*call_pop_vzeroupper"
11188   [(parallel
11189     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11190            (match_operand:SI 1 "" ""))
11191      (set (reg:SI SP_REG)
11192           (plus:SI (reg:SI SP_REG)
11193                    (match_operand:SI 2 "immediate_operand" "i")))])
11194    (unspec [(match_operand 3 "const_int_operand" "")]
11195            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11196   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11197   "#"
11198   "&& reload_completed"
11199   [(const_int 0)]
11200   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11201   [(set_attr "type" "call")])
11202
11203 (define_insn "*call_pop"
11204   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11205          (match_operand 1 "" ""))
11206    (set (reg:SI SP_REG)
11207         (plus:SI (reg:SI SP_REG)
11208                  (match_operand:SI 2 "immediate_operand" "i")))]
11209   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11210   "* return ix86_output_call_insn (insn, operands[0]);"
11211   [(set_attr "type" "call")])
11212
11213 (define_insn_and_split "*sibcall_pop_vzeroupper"
11214  [(parallel
11215    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11216           (match_operand 1 "" ""))
11217      (set (reg:SI SP_REG)
11218           (plus:SI (reg:SI SP_REG)
11219                    (match_operand:SI 2 "immediate_operand" "i")))])
11220    (unspec [(match_operand 3 "const_int_operand" "")]
11221            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11222   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11223   "#"
11224   "&& reload_completed"
11225   [(const_int 0)]
11226   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11227   [(set_attr "type" "call")])
11228
11229 (define_insn "*sibcall_pop"
11230   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11231          (match_operand 1 "" ""))
11232    (set (reg:SI SP_REG)
11233         (plus:SI (reg:SI SP_REG)
11234                  (match_operand:SI 2 "immediate_operand" "i")))]
11235   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11236   "* return ix86_output_call_insn (insn, operands[0]);"
11237   [(set_attr "type" "call")])
11238
11239 ;; Call subroutine, returning value in operand 0
11240
11241 (define_expand "call_value"
11242   [(set (match_operand 0 "" "")
11243         (call (match_operand:QI 1 "" "")
11244               (match_operand 2 "" "")))
11245    (use (match_operand 3 "" ""))]
11246   ""
11247 {
11248   ix86_expand_call (operands[0], operands[1], operands[2],
11249                     operands[3], NULL, false);
11250   DONE;
11251 })
11252
11253 (define_expand "sibcall_value"
11254   [(set (match_operand 0 "" "")
11255         (call (match_operand:QI 1 "" "")
11256               (match_operand 2 "" "")))
11257    (use (match_operand 3 "" ""))]
11258   ""
11259 {
11260   ix86_expand_call (operands[0], operands[1], operands[2],
11261                     operands[3], NULL, true);
11262   DONE;
11263 })
11264
11265 (define_insn_and_split "*call_value_vzeroupper"
11266   [(set (match_operand 0 "" "")
11267         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11268               (match_operand 2 "" "")))
11269    (unspec [(match_operand 3 "const_int_operand" "")]
11270            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11271   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11272   "#"
11273   "&& reload_completed"
11274   [(const_int 0)]
11275   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11276   [(set_attr "type" "callv")])
11277
11278 (define_insn "*call_value"
11279   [(set (match_operand 0 "" "")
11280         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11281               (match_operand 2 "" "")))]
11282   "!SIBLING_CALL_P (insn)"
11283   "* return ix86_output_call_insn (insn, operands[1]);"
11284   [(set_attr "type" "callv")])
11285
11286 (define_insn_and_split "*sibcall_value_vzeroupper"
11287   [(set (match_operand 0 "" "")
11288         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11289               (match_operand 2 "" "")))
11290    (unspec [(match_operand 3 "const_int_operand" "")]
11291            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11292   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11293   "#"
11294   "&& reload_completed"
11295   [(const_int 0)]
11296   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11297   [(set_attr "type" "callv")])
11298
11299 (define_insn "*sibcall_value"
11300   [(set (match_operand 0 "" "")
11301         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11302               (match_operand 2 "" "")))]
11303   "SIBLING_CALL_P (insn)"
11304   "* return ix86_output_call_insn (insn, operands[1]);"
11305   [(set_attr "type" "callv")])
11306
11307 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11308   [(parallel
11309     [(set (match_operand 0 "" "")
11310           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11311                 (match_operand 2 "" "")))
11312      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11313      (clobber (reg:TI XMM6_REG))
11314      (clobber (reg:TI XMM7_REG))
11315      (clobber (reg:TI XMM8_REG))
11316      (clobber (reg:TI XMM9_REG))
11317      (clobber (reg:TI XMM10_REG))
11318      (clobber (reg:TI XMM11_REG))
11319      (clobber (reg:TI XMM12_REG))
11320      (clobber (reg:TI XMM13_REG))
11321      (clobber (reg:TI XMM14_REG))
11322      (clobber (reg:TI XMM15_REG))
11323      (clobber (reg:DI SI_REG))
11324      (clobber (reg:DI DI_REG))])
11325    (unspec [(match_operand 3 "const_int_operand" "")]
11326            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11327   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11328   "#"
11329   "&& reload_completed"
11330   [(const_int 0)]
11331   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11332   [(set_attr "type" "callv")])
11333
11334 (define_insn "*call_value_rex64_ms_sysv"
11335   [(set (match_operand 0 "" "")
11336         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11337               (match_operand 2 "" "")))
11338    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11339    (clobber (reg:TI XMM6_REG))
11340    (clobber (reg:TI XMM7_REG))
11341    (clobber (reg:TI XMM8_REG))
11342    (clobber (reg:TI XMM9_REG))
11343    (clobber (reg:TI XMM10_REG))
11344    (clobber (reg:TI XMM11_REG))
11345    (clobber (reg:TI XMM12_REG))
11346    (clobber (reg:TI XMM13_REG))
11347    (clobber (reg:TI XMM14_REG))
11348    (clobber (reg:TI XMM15_REG))
11349    (clobber (reg:DI SI_REG))
11350    (clobber (reg:DI DI_REG))]
11351   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11352   "* return ix86_output_call_insn (insn, operands[1]);"
11353   [(set_attr "type" "callv")])
11354
11355 (define_expand "call_value_pop"
11356   [(parallel [(set (match_operand 0 "" "")
11357                    (call (match_operand:QI 1 "" "")
11358                          (match_operand:SI 2 "" "")))
11359               (set (reg:SI SP_REG)
11360                    (plus:SI (reg:SI SP_REG)
11361                             (match_operand:SI 4 "" "")))])]
11362   "!TARGET_64BIT"
11363 {
11364   ix86_expand_call (operands[0], operands[1], operands[2],
11365                     operands[3], operands[4], false);
11366   DONE;
11367 })
11368
11369 (define_insn_and_split "*call_value_pop_vzeroupper"
11370   [(parallel
11371     [(set (match_operand 0 "" "")
11372           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11373                 (match_operand 2 "" "")))
11374      (set (reg:SI SP_REG)
11375           (plus:SI (reg:SI SP_REG)
11376                    (match_operand:SI 3 "immediate_operand" "i")))])
11377    (unspec [(match_operand 4 "const_int_operand" "")]
11378            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11379   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11380   "#"
11381   "&& reload_completed"
11382   [(const_int 0)]
11383   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11384   [(set_attr "type" "callv")])
11385
11386 (define_insn "*call_value_pop"
11387   [(set (match_operand 0 "" "")
11388         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11389               (match_operand 2 "" "")))
11390    (set (reg:SI SP_REG)
11391         (plus:SI (reg:SI SP_REG)
11392                  (match_operand:SI 3 "immediate_operand" "i")))]
11393   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11394   "* return ix86_output_call_insn (insn, operands[1]);"
11395   [(set_attr "type" "callv")])
11396
11397 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11398  [(parallel
11399    [(set (match_operand 0 "" "")
11400           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11401                 (match_operand 2 "" "")))
11402      (set (reg:SI SP_REG)
11403           (plus:SI (reg:SI SP_REG)
11404                    (match_operand:SI 3 "immediate_operand" "i")))])
11405    (unspec [(match_operand 4 "const_int_operand" "")]
11406            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11407   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11408   "#"
11409   "&& reload_completed"
11410   [(const_int 0)]
11411   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11412   [(set_attr "type" "callv")])
11413
11414 (define_insn "*sibcall_value_pop"
11415   [(set (match_operand 0 "" "")
11416         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11417               (match_operand 2 "" "")))
11418    (set (reg:SI SP_REG)
11419         (plus:SI (reg:SI SP_REG)
11420                  (match_operand:SI 3 "immediate_operand" "i")))]
11421   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11422   "* return ix86_output_call_insn (insn, operands[1]);"
11423   [(set_attr "type" "callv")])
11424
11425 ;; Call subroutine returning any type.
11426
11427 (define_expand "untyped_call"
11428   [(parallel [(call (match_operand 0 "" "")
11429                     (const_int 0))
11430               (match_operand 1 "" "")
11431               (match_operand 2 "" "")])]
11432   ""
11433 {
11434   int i;
11435
11436   /* In order to give reg-stack an easier job in validating two
11437      coprocessor registers as containing a possible return value,
11438      simply pretend the untyped call returns a complex long double
11439      value. 
11440
11441      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11442      and should have the default ABI.  */
11443
11444   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11445                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11446                     operands[0], const0_rtx,
11447                     GEN_INT ((TARGET_64BIT
11448                               ? (ix86_abi == SYSV_ABI
11449                                  ? X86_64_SSE_REGPARM_MAX
11450                                  : X86_64_MS_SSE_REGPARM_MAX)
11451                               : X86_32_SSE_REGPARM_MAX)
11452                              - 1),
11453                     NULL, false);
11454
11455   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11456     {
11457       rtx set = XVECEXP (operands[2], 0, i);
11458       emit_move_insn (SET_DEST (set), SET_SRC (set));
11459     }
11460
11461   /* The optimizer does not know that the call sets the function value
11462      registers we stored in the result block.  We avoid problems by
11463      claiming that all hard registers are used and clobbered at this
11464      point.  */
11465   emit_insn (gen_blockage ());
11466
11467   DONE;
11468 })
11469 \f
11470 ;; Prologue and epilogue instructions
11471
11472 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11473 ;; all of memory.  This blocks insns from being moved across this point.
11474
11475 (define_insn "blockage"
11476   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11477   ""
11478   ""
11479   [(set_attr "length" "0")])
11480
11481 ;; Do not schedule instructions accessing memory across this point.
11482
11483 (define_expand "memory_blockage"
11484   [(set (match_dup 0)
11485         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11486   ""
11487 {
11488   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11489   MEM_VOLATILE_P (operands[0]) = 1;
11490 })
11491
11492 (define_insn "*memory_blockage"
11493   [(set (match_operand:BLK 0 "" "")
11494         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11495   ""
11496   ""
11497   [(set_attr "length" "0")])
11498
11499 ;; As USE insns aren't meaningful after reload, this is used instead
11500 ;; to prevent deleting instructions setting registers for PIC code
11501 (define_insn "prologue_use"
11502   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11503   ""
11504   ""
11505   [(set_attr "length" "0")])
11506
11507 ;; Insn emitted into the body of a function to return from a function.
11508 ;; This is only done if the function's epilogue is known to be simple.
11509 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11510
11511 (define_expand "return"
11512   [(return)]
11513   "ix86_can_use_return_insn_p ()"
11514 {
11515   if (crtl->args.pops_args)
11516     {
11517       rtx popc = GEN_INT (crtl->args.pops_args);
11518       emit_jump_insn (gen_return_pop_internal (popc));
11519       DONE;
11520     }
11521 })
11522
11523 (define_insn "return_internal"
11524   [(return)]
11525   "reload_completed"
11526   "ret"
11527   [(set_attr "length" "1")
11528    (set_attr "atom_unit" "jeu")
11529    (set_attr "length_immediate" "0")
11530    (set_attr "modrm" "0")])
11531
11532 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11533 ;; instruction Athlon and K8 have.
11534
11535 (define_insn "return_internal_long"
11536   [(return)
11537    (unspec [(const_int 0)] UNSPEC_REP)]
11538   "reload_completed"
11539   "rep\;ret"
11540   [(set_attr "length" "2")
11541    (set_attr "atom_unit" "jeu")
11542    (set_attr "length_immediate" "0")
11543    (set_attr "prefix_rep" "1")
11544    (set_attr "modrm" "0")])
11545
11546 (define_insn "return_pop_internal"
11547   [(return)
11548    (use (match_operand:SI 0 "const_int_operand" ""))]
11549   "reload_completed"
11550   "ret\t%0"
11551   [(set_attr "length" "3")
11552    (set_attr "atom_unit" "jeu")
11553    (set_attr "length_immediate" "2")
11554    (set_attr "modrm" "0")])
11555
11556 (define_insn "return_indirect_internal"
11557   [(return)
11558    (use (match_operand:SI 0 "register_operand" "r"))]
11559   "reload_completed"
11560   "jmp\t%A0"
11561   [(set_attr "type" "ibr")
11562    (set_attr "length_immediate" "0")])
11563
11564 (define_insn "nop"
11565   [(const_int 0)]
11566   ""
11567   "nop"
11568   [(set_attr "length" "1")
11569    (set_attr "length_immediate" "0")
11570    (set_attr "modrm" "0")])
11571
11572 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11573 (define_insn "nops"
11574   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11575                     UNSPECV_NOPS)]
11576   "reload_completed"
11577 {
11578   int num = INTVAL (operands[0]);
11579
11580   gcc_assert (num >= 1 && num <= 8);
11581
11582   while (num--)
11583     fputs ("\tnop\n", asm_out_file);
11584
11585   return "";
11586 }
11587   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11588    (set_attr "length_immediate" "0")
11589    (set_attr "modrm" "0")])
11590
11591 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11592 ;; branch prediction penalty for the third jump in a 16-byte
11593 ;; block on K8.
11594
11595 (define_insn "pad"
11596   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11597   ""
11598 {
11599 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11600   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11601 #else
11602   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11603      The align insn is used to avoid 3 jump instructions in the row to improve
11604      branch prediction and the benefits hardly outweigh the cost of extra 8
11605      nops on the average inserted by full alignment pseudo operation.  */
11606 #endif
11607   return "";
11608 }
11609   [(set_attr "length" "16")])
11610
11611 (define_expand "prologue"
11612   [(const_int 0)]
11613   ""
11614   "ix86_expand_prologue (); DONE;")
11615
11616 (define_insn "set_got"
11617   [(set (match_operand:SI 0 "register_operand" "=r")
11618         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11619    (clobber (reg:CC FLAGS_REG))]
11620   "!TARGET_64BIT"
11621   "* return output_set_got (operands[0], NULL_RTX);"
11622   [(set_attr "type" "multi")
11623    (set_attr "length" "12")])
11624
11625 (define_insn "set_got_labelled"
11626   [(set (match_operand:SI 0 "register_operand" "=r")
11627         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11628          UNSPEC_SET_GOT))
11629    (clobber (reg:CC FLAGS_REG))]
11630   "!TARGET_64BIT"
11631   "* return output_set_got (operands[0], operands[1]);"
11632   [(set_attr "type" "multi")
11633    (set_attr "length" "12")])
11634
11635 (define_insn "set_got_rex64"
11636   [(set (match_operand:DI 0 "register_operand" "=r")
11637         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11638   "TARGET_64BIT"
11639   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11640   [(set_attr "type" "lea")
11641    (set_attr "length_address" "4")
11642    (set_attr "mode" "DI")])
11643
11644 (define_insn "set_rip_rex64"
11645   [(set (match_operand:DI 0 "register_operand" "=r")
11646         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11647   "TARGET_64BIT"
11648   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11649   [(set_attr "type" "lea")
11650    (set_attr "length_address" "4")
11651    (set_attr "mode" "DI")])
11652
11653 (define_insn "set_got_offset_rex64"
11654   [(set (match_operand:DI 0 "register_operand" "=r")
11655         (unspec:DI
11656           [(label_ref (match_operand 1 "" ""))]
11657           UNSPEC_SET_GOT_OFFSET))]
11658   "TARGET_64BIT"
11659   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11660   [(set_attr "type" "imov")
11661    (set_attr "length_immediate" "0")
11662    (set_attr "length_address" "8")
11663    (set_attr "mode" "DI")])
11664
11665 (define_expand "epilogue"
11666   [(const_int 0)]
11667   ""
11668   "ix86_expand_epilogue (1); DONE;")
11669
11670 (define_expand "sibcall_epilogue"
11671   [(const_int 0)]
11672   ""
11673   "ix86_expand_epilogue (0); DONE;")
11674
11675 (define_expand "eh_return"
11676   [(use (match_operand 0 "register_operand" ""))]
11677   ""
11678 {
11679   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11680
11681   /* Tricky bit: we write the address of the handler to which we will
11682      be returning into someone else's stack frame, one word below the
11683      stack address we wish to restore.  */
11684   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11685   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11686   tmp = gen_rtx_MEM (Pmode, tmp);
11687   emit_move_insn (tmp, ra);
11688
11689   emit_jump_insn (gen_eh_return_internal ());
11690   emit_barrier ();
11691   DONE;
11692 })
11693
11694 (define_insn_and_split "eh_return_internal"
11695   [(eh_return)]
11696   ""
11697   "#"
11698   "epilogue_completed"
11699   [(const_int 0)]
11700   "ix86_expand_epilogue (2); DONE;")
11701
11702 (define_insn "leave"
11703   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11704    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11705    (clobber (mem:BLK (scratch)))]
11706   "!TARGET_64BIT"
11707   "leave"
11708   [(set_attr "type" "leave")])
11709
11710 (define_insn "leave_rex64"
11711   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11712    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11713    (clobber (mem:BLK (scratch)))]
11714   "TARGET_64BIT"
11715   "leave"
11716   [(set_attr "type" "leave")])
11717 \f
11718 ;; Handle -fsplit-stack.
11719
11720 (define_expand "split_stack_prologue"
11721   [(const_int 0)]
11722   ""
11723 {
11724   ix86_expand_split_stack_prologue ();
11725   DONE;
11726 })
11727
11728 ;; In order to support the call/return predictor, we use a return
11729 ;; instruction which the middle-end doesn't see.
11730 (define_insn "split_stack_return"
11731   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11732                      UNSPECV_SPLIT_STACK_RETURN)]
11733   ""
11734 {
11735   if (operands[0] == const0_rtx)
11736     return "ret";
11737   else
11738     return "ret\t%0";
11739 }
11740   [(set_attr "atom_unit" "jeu")
11741    (set_attr "modrm" "0")
11742    (set (attr "length")
11743         (if_then_else (match_operand:SI 0 "const0_operand" "")
11744                       (const_int 1)
11745                       (const_int 3)))
11746    (set (attr "length_immediate")
11747         (if_then_else (match_operand:SI 0 "const0_operand" "")
11748                       (const_int 0)
11749                       (const_int 2)))])
11750
11751 ;; If there are operand 0 bytes available on the stack, jump to
11752 ;; operand 1.
11753
11754 (define_expand "split_stack_space_check"
11755   [(set (pc) (if_then_else
11756               (ltu (minus (reg SP_REG)
11757                           (match_operand 0 "register_operand" ""))
11758                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11759               (label_ref (match_operand 1 "" ""))
11760               (pc)))]
11761   ""
11762 {
11763   rtx reg, size, limit;
11764
11765   reg = gen_reg_rtx (Pmode);
11766   size = force_reg (Pmode, operands[0]);
11767   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11768   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11769                           UNSPEC_STACK_CHECK);
11770   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11771   ix86_expand_branch (GEU, reg, limit, operands[1]);
11772
11773   DONE;
11774 })
11775 \f
11776 ;; Bit manipulation instructions.
11777
11778 (define_expand "ffs<mode>2"
11779   [(set (match_dup 2) (const_int -1))
11780    (parallel [(set (reg:CCZ FLAGS_REG)
11781                    (compare:CCZ
11782                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11783                      (const_int 0)))
11784               (set (match_operand:SWI48 0 "register_operand" "")
11785                    (ctz:SWI48 (match_dup 1)))])
11786    (set (match_dup 0) (if_then_else:SWI48
11787                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11788                         (match_dup 2)
11789                         (match_dup 0)))
11790    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11791               (clobber (reg:CC FLAGS_REG))])]
11792   ""
11793 {
11794   if (<MODE>mode == SImode && !TARGET_CMOVE)
11795     {
11796       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11797       DONE;
11798     }
11799   operands[2] = gen_reg_rtx (<MODE>mode);
11800 })
11801
11802 (define_insn_and_split "ffssi2_no_cmove"
11803   [(set (match_operand:SI 0 "register_operand" "=r")
11804         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11805    (clobber (match_scratch:SI 2 "=&q"))
11806    (clobber (reg:CC FLAGS_REG))]
11807   "!TARGET_CMOVE"
11808   "#"
11809   "&& reload_completed"
11810   [(parallel [(set (reg:CCZ FLAGS_REG)
11811                    (compare:CCZ (match_dup 1) (const_int 0)))
11812               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11813    (set (strict_low_part (match_dup 3))
11814         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11815    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11816               (clobber (reg:CC FLAGS_REG))])
11817    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11818               (clobber (reg:CC FLAGS_REG))])
11819    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11820               (clobber (reg:CC FLAGS_REG))])]
11821 {
11822   operands[3] = gen_lowpart (QImode, operands[2]);
11823   ix86_expand_clear (operands[2]);
11824 })
11825
11826 (define_insn "*ffs<mode>_1"
11827   [(set (reg:CCZ FLAGS_REG)
11828         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11829                      (const_int 0)))
11830    (set (match_operand:SWI48 0 "register_operand" "=r")
11831         (ctz:SWI48 (match_dup 1)))]
11832   ""
11833   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11834   [(set_attr "type" "alu1")
11835    (set_attr "prefix_0f" "1")
11836    (set_attr "mode" "<MODE>")])
11837
11838 (define_insn "ctz<mode>2"
11839   [(set (match_operand:SWI248 0 "register_operand" "=r")
11840         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   ""
11843 {
11844   if (TARGET_BMI)
11845     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11846   else
11847     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11848 }
11849   [(set_attr "type" "alu1")
11850    (set_attr "prefix_0f" "1")
11851    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11852    (set_attr "mode" "<MODE>")])
11853
11854 (define_expand "clz<mode>2"
11855   [(parallel
11856      [(set (match_operand:SWI248 0 "register_operand" "")
11857            (minus:SWI248
11858              (match_dup 2)
11859              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11860       (clobber (reg:CC FLAGS_REG))])
11861    (parallel
11862      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11863       (clobber (reg:CC FLAGS_REG))])]
11864   ""
11865 {
11866   if (TARGET_ABM)
11867     {
11868       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11869       DONE;
11870     }
11871   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11872 })
11873
11874 (define_insn "clz<mode>2_abm"
11875   [(set (match_operand:SWI248 0 "register_operand" "=r")
11876         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11877    (clobber (reg:CC FLAGS_REG))]
11878   "TARGET_ABM || TARGET_BMI"
11879   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11880   [(set_attr "prefix_rep" "1")
11881    (set_attr "type" "bitmanip")
11882    (set_attr "mode" "<MODE>")])
11883
11884 ;; BMI instructions.
11885 (define_insn "*bmi_andn_<mode>"
11886   [(set (match_operand:SWI48 0 "register_operand" "=r")
11887         (and:SWI48
11888           (not:SWI48
11889             (match_operand:SWI48 1 "register_operand" "r"))
11890             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11891    (clobber (reg:CC FLAGS_REG))]
11892   "TARGET_BMI"
11893   "andn\t{%2, %1, %0|%0, %1, %2}"
11894   [(set_attr "type" "bitmanip")
11895    (set_attr "mode" "<MODE>")])
11896
11897 (define_insn "bmi_bextr_<mode>"
11898   [(set (match_operand:SWI48 0 "register_operand" "=r")
11899         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11900                        (match_operand:SWI48 2 "register_operand" "r")]
11901                        UNSPEC_BEXTR))
11902    (clobber (reg:CC FLAGS_REG))]
11903   "TARGET_BMI"
11904   "bextr\t{%2, %1, %0|%0, %1, %2}"
11905   [(set_attr "type" "bitmanip")
11906    (set_attr "mode" "<MODE>")])
11907
11908 (define_insn "*bmi_blsi_<mode>"
11909   [(set (match_operand:SWI48 0 "register_operand" "=r")
11910         (and:SWI48
11911           (neg:SWI48
11912             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11913           (match_dup 1)))
11914    (clobber (reg:CC FLAGS_REG))]
11915   "TARGET_BMI"
11916   "blsi\t{%1, %0|%0, %1}"
11917   [(set_attr "type" "bitmanip")
11918    (set_attr "mode" "<MODE>")])
11919
11920 (define_insn "*bmi_blsmsk_<mode>"
11921   [(set (match_operand:SWI48 0 "register_operand" "=r")
11922         (xor:SWI48
11923           (plus:SWI48
11924             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11925             (const_int -1))
11926           (match_dup 1)))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "TARGET_BMI"
11929   "blsmsk\t{%1, %0|%0, %1}"
11930   [(set_attr "type" "bitmanip")
11931    (set_attr "mode" "<MODE>")])
11932
11933 (define_insn "*bmi_blsr_<mode>"
11934   [(set (match_operand:SWI48 0 "register_operand" "=r")
11935         (and:SWI48
11936           (plus:SWI48
11937             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11938             (const_int -1))
11939           (match_dup 1)))
11940    (clobber (reg:CC FLAGS_REG))]
11941    "TARGET_BMI"
11942    "blsr\t{%1, %0|%0, %1}"
11943   [(set_attr "type" "bitmanip")
11944    (set_attr "mode" "<MODE>")])
11945
11946 ;; TBM instructions.
11947 (define_insn "tbm_bextri_<mode>"
11948   [(set (match_operand:SWI48 0 "register_operand" "=r")
11949         (zero_extract:SWI48
11950           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11951           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11952           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11953    (clobber (reg:CC FLAGS_REG))]
11954    "TARGET_TBM"
11955 {
11956   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11957   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11958 }
11959   [(set_attr "type" "bitmanip")
11960    (set_attr "mode" "<MODE>")])
11961
11962 (define_insn "*tbm_blcfill_<mode>"
11963   [(set (match_operand:SWI48 0 "register_operand" "=r")
11964         (and:SWI48
11965           (plus:SWI48
11966             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11967             (const_int 1))
11968           (match_dup 1)))
11969    (clobber (reg:CC FLAGS_REG))]
11970    "TARGET_TBM"
11971    "blcfill\t{%1, %0|%0, %1}"
11972   [(set_attr "type" "bitmanip")
11973    (set_attr "mode" "<MODE>")])
11974
11975 (define_insn "*tbm_blci_<mode>"
11976   [(set (match_operand:SWI48 0 "register_operand" "=r")
11977         (ior:SWI48
11978           (not:SWI48
11979             (plus:SWI48
11980               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11981               (const_int 1)))
11982           (match_dup 1)))
11983    (clobber (reg:CC FLAGS_REG))]
11984    "TARGET_TBM"
11985    "blci\t{%1, %0|%0, %1}"
11986   [(set_attr "type" "bitmanip")
11987    (set_attr "mode" "<MODE>")])
11988
11989 (define_insn "*tbm_blcic_<mode>"
11990   [(set (match_operand:SWI48 0 "register_operand" "=r")
11991         (and:SWI48
11992           (plus:SWI48
11993             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11994             (const_int 1))
11995           (not:SWI48
11996             (match_dup 1))))
11997    (clobber (reg:CC FLAGS_REG))]
11998    "TARGET_TBM"
11999    "blcic\t{%1, %0|%0, %1}"
12000   [(set_attr "type" "bitmanip")
12001    (set_attr "mode" "<MODE>")])
12002
12003 (define_insn "*tbm_blcmsk_<mode>"
12004   [(set (match_operand:SWI48 0 "register_operand" "=r")
12005         (xor:SWI48
12006           (plus:SWI48
12007             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12008             (const_int 1))
12009           (match_dup 1)))
12010    (clobber (reg:CC FLAGS_REG))]
12011    "TARGET_TBM"
12012    "blcmsk\t{%1, %0|%0, %1}"
12013   [(set_attr "type" "bitmanip")
12014    (set_attr "mode" "<MODE>")])
12015
12016 (define_insn "*tbm_blcs_<mode>"
12017   [(set (match_operand:SWI48 0 "register_operand" "=r")
12018         (ior:SWI48
12019           (plus:SWI48
12020             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12021             (const_int 1))
12022           (match_dup 1)))
12023    (clobber (reg:CC FLAGS_REG))]
12024    "TARGET_TBM"
12025    "blcs\t{%1, %0|%0, %1}"
12026   [(set_attr "type" "bitmanip")
12027    (set_attr "mode" "<MODE>")])
12028
12029 (define_insn "*tbm_blsfill_<mode>"
12030   [(set (match_operand:SWI48 0 "register_operand" "=r")
12031         (ior:SWI48
12032           (plus:SWI48
12033             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12034             (const_int -1))
12035           (match_dup 1)))
12036    (clobber (reg:CC FLAGS_REG))]
12037    "TARGET_TBM"
12038    "blsfill\t{%1, %0|%0, %1}"
12039   [(set_attr "type" "bitmanip")
12040    (set_attr "mode" "<MODE>")])
12041
12042 (define_insn "*tbm_blsic_<mode>"
12043   [(set (match_operand:SWI48 0 "register_operand" "=r")
12044         (ior:SWI48
12045           (plus:SWI48
12046             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12047             (const_int -1))
12048           (not:SWI48
12049             (match_dup 1))))
12050    (clobber (reg:CC FLAGS_REG))]
12051    "TARGET_TBM"
12052    "blsic\t{%1, %0|%0, %1}"
12053   [(set_attr "type" "bitmanip")
12054    (set_attr "mode" "<MODE>")])
12055
12056 (define_insn "*tbm_t1mskc_<mode>"
12057   [(set (match_operand:SWI48 0 "register_operand" "=r")
12058         (ior:SWI48
12059           (plus:SWI48
12060             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12061             (const_int 1))
12062           (not:SWI48
12063             (match_dup 1))))
12064    (clobber (reg:CC FLAGS_REG))]
12065    "TARGET_TBM"
12066    "t1mskc\t{%1, %0|%0, %1}"
12067   [(set_attr "type" "bitmanip")
12068    (set_attr "mode" "<MODE>")])
12069
12070 (define_insn "*tbm_tzmsk_<mode>"
12071   [(set (match_operand:SWI48 0 "register_operand" "=r")
12072         (and:SWI48
12073           (plus:SWI48
12074             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12075             (const_int -1))
12076           (not:SWI48
12077             (match_dup 1))))
12078    (clobber (reg:CC FLAGS_REG))]
12079    "TARGET_TBM"
12080    "tzmsk\t{%1, %0|%0, %1}"
12081   [(set_attr "type" "bitmanip")
12082    (set_attr "mode" "<MODE>")])
12083
12084 (define_insn "bsr_rex64"
12085   [(set (match_operand:DI 0 "register_operand" "=r")
12086         (minus:DI (const_int 63)
12087                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "TARGET_64BIT"
12090   "bsr{q}\t{%1, %0|%0, %1}"
12091   [(set_attr "type" "alu1")
12092    (set_attr "prefix_0f" "1")
12093    (set_attr "mode" "DI")])
12094
12095 (define_insn "bsr"
12096   [(set (match_operand:SI 0 "register_operand" "=r")
12097         (minus:SI (const_int 31)
12098                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12099    (clobber (reg:CC FLAGS_REG))]
12100   ""
12101   "bsr{l}\t{%1, %0|%0, %1}"
12102   [(set_attr "type" "alu1")
12103    (set_attr "prefix_0f" "1")
12104    (set_attr "mode" "SI")])
12105
12106 (define_insn "*bsrhi"
12107   [(set (match_operand:HI 0 "register_operand" "=r")
12108         (minus:HI (const_int 15)
12109                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12110    (clobber (reg:CC FLAGS_REG))]
12111   ""
12112   "bsr{w}\t{%1, %0|%0, %1}"
12113   [(set_attr "type" "alu1")
12114    (set_attr "prefix_0f" "1")
12115    (set_attr "mode" "HI")])
12116
12117 (define_insn "popcount<mode>2"
12118   [(set (match_operand:SWI248 0 "register_operand" "=r")
12119         (popcount:SWI248
12120           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   "TARGET_POPCNT"
12123 {
12124 #if TARGET_MACHO
12125   return "popcnt\t{%1, %0|%0, %1}";
12126 #else
12127   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12128 #endif
12129 }
12130   [(set_attr "prefix_rep" "1")
12131    (set_attr "type" "bitmanip")
12132    (set_attr "mode" "<MODE>")])
12133
12134 (define_insn "*popcount<mode>2_cmp"
12135   [(set (reg FLAGS_REG)
12136         (compare
12137           (popcount:SWI248
12138             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12139           (const_int 0)))
12140    (set (match_operand:SWI248 0 "register_operand" "=r")
12141         (popcount:SWI248 (match_dup 1)))]
12142   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12143 {
12144 #if TARGET_MACHO
12145   return "popcnt\t{%1, %0|%0, %1}";
12146 #else
12147   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12148 #endif
12149 }
12150   [(set_attr "prefix_rep" "1")
12151    (set_attr "type" "bitmanip")
12152    (set_attr "mode" "<MODE>")])
12153
12154 (define_insn "*popcountsi2_cmp_zext"
12155   [(set (reg FLAGS_REG)
12156         (compare
12157           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12158           (const_int 0)))
12159    (set (match_operand:DI 0 "register_operand" "=r")
12160         (zero_extend:DI(popcount:SI (match_dup 1))))]
12161   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12162 {
12163 #if TARGET_MACHO
12164   return "popcnt\t{%1, %0|%0, %1}";
12165 #else
12166   return "popcnt{l}\t{%1, %0|%0, %1}";
12167 #endif
12168 }
12169   [(set_attr "prefix_rep" "1")
12170    (set_attr "type" "bitmanip")
12171    (set_attr "mode" "SI")])
12172
12173 (define_expand "bswap<mode>2"
12174   [(set (match_operand:SWI48 0 "register_operand" "")
12175         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12176   ""
12177 {
12178   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12179     {
12180       rtx x = operands[0];
12181
12182       emit_move_insn (x, operands[1]);
12183       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12184       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12185       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12186       DONE;
12187     }
12188 })
12189
12190 (define_insn "*bswap<mode>2_movbe"
12191   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12192         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12193   "TARGET_MOVBE
12194    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12195   "@
12196     bswap\t%0
12197     movbe\t{%1, %0|%0, %1}
12198     movbe\t{%1, %0|%0, %1}"
12199   [(set_attr "type" "bitmanip,imov,imov")
12200    (set_attr "modrm" "0,1,1")
12201    (set_attr "prefix_0f" "*,1,1")
12202    (set_attr "prefix_extra" "*,1,1")
12203    (set_attr "mode" "<MODE>")])
12204
12205 (define_insn "*bswap<mode>2_1"
12206   [(set (match_operand:SWI48 0 "register_operand" "=r")
12207         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12208   "TARGET_BSWAP"
12209   "bswap\t%0"
12210   [(set_attr "type" "bitmanip")
12211    (set_attr "modrm" "0")
12212    (set_attr "mode" "<MODE>")])
12213
12214 (define_insn "*bswaphi_lowpart_1"
12215   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12216         (bswap:HI (match_dup 0)))
12217    (clobber (reg:CC FLAGS_REG))]
12218   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12219   "@
12220     xchg{b}\t{%h0, %b0|%b0, %h0}
12221     rol{w}\t{$8, %0|%0, 8}"
12222   [(set_attr "length" "2,4")
12223    (set_attr "mode" "QI,HI")])
12224
12225 (define_insn "bswaphi_lowpart"
12226   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12227         (bswap:HI (match_dup 0)))
12228    (clobber (reg:CC FLAGS_REG))]
12229   ""
12230   "rol{w}\t{$8, %0|%0, 8}"
12231   [(set_attr "length" "4")
12232    (set_attr "mode" "HI")])
12233
12234 (define_expand "paritydi2"
12235   [(set (match_operand:DI 0 "register_operand" "")
12236         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12237   "! TARGET_POPCNT"
12238 {
12239   rtx scratch = gen_reg_rtx (QImode);
12240   rtx cond;
12241
12242   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12243                                 NULL_RTX, operands[1]));
12244
12245   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12246                          gen_rtx_REG (CCmode, FLAGS_REG),
12247                          const0_rtx);
12248   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12249
12250   if (TARGET_64BIT)
12251     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12252   else
12253     {
12254       rtx tmp = gen_reg_rtx (SImode);
12255
12256       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12257       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12258     }
12259   DONE;
12260 })
12261
12262 (define_expand "paritysi2"
12263   [(set (match_operand:SI 0 "register_operand" "")
12264         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12265   "! TARGET_POPCNT"
12266 {
12267   rtx scratch = gen_reg_rtx (QImode);
12268   rtx cond;
12269
12270   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12271
12272   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12273                          gen_rtx_REG (CCmode, FLAGS_REG),
12274                          const0_rtx);
12275   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12276
12277   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12278   DONE;
12279 })
12280
12281 (define_insn_and_split "paritydi2_cmp"
12282   [(set (reg:CC FLAGS_REG)
12283         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12284                    UNSPEC_PARITY))
12285    (clobber (match_scratch:DI 0 "=r"))
12286    (clobber (match_scratch:SI 1 "=&r"))
12287    (clobber (match_scratch:HI 2 "=Q"))]
12288   "! TARGET_POPCNT"
12289   "#"
12290   "&& reload_completed"
12291   [(parallel
12292      [(set (match_dup 1)
12293            (xor:SI (match_dup 1) (match_dup 4)))
12294       (clobber (reg:CC FLAGS_REG))])
12295    (parallel
12296      [(set (reg:CC FLAGS_REG)
12297            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12298       (clobber (match_dup 1))
12299       (clobber (match_dup 2))])]
12300 {
12301   operands[4] = gen_lowpart (SImode, operands[3]);
12302
12303   if (TARGET_64BIT)
12304     {
12305       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12306       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12307     }
12308   else
12309     operands[1] = gen_highpart (SImode, operands[3]);
12310 })
12311
12312 (define_insn_and_split "paritysi2_cmp"
12313   [(set (reg:CC FLAGS_REG)
12314         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12315                    UNSPEC_PARITY))
12316    (clobber (match_scratch:SI 0 "=r"))
12317    (clobber (match_scratch:HI 1 "=&Q"))]
12318   "! TARGET_POPCNT"
12319   "#"
12320   "&& reload_completed"
12321   [(parallel
12322      [(set (match_dup 1)
12323            (xor:HI (match_dup 1) (match_dup 3)))
12324       (clobber (reg:CC FLAGS_REG))])
12325    (parallel
12326      [(set (reg:CC FLAGS_REG)
12327            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12328       (clobber (match_dup 1))])]
12329 {
12330   operands[3] = gen_lowpart (HImode, operands[2]);
12331
12332   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12333   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12334 })
12335
12336 (define_insn "*parityhi2_cmp"
12337   [(set (reg:CC FLAGS_REG)
12338         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12339                    UNSPEC_PARITY))
12340    (clobber (match_scratch:HI 0 "=Q"))]
12341   "! TARGET_POPCNT"
12342   "xor{b}\t{%h0, %b0|%b0, %h0}"
12343   [(set_attr "length" "2")
12344    (set_attr "mode" "HI")])
12345 \f
12346 ;; Thread-local storage patterns for ELF.
12347 ;;
12348 ;; Note that these code sequences must appear exactly as shown
12349 ;; in order to allow linker relaxation.
12350
12351 (define_insn "*tls_global_dynamic_32_gnu"
12352   [(set (match_operand:SI 0 "register_operand" "=a")
12353         (unspec:SI
12354          [(match_operand:SI 1 "register_operand" "b")
12355           (match_operand:SI 2 "tls_symbolic_operand" "")
12356           (match_operand:SI 3 "constant_call_address_operand" "z")]
12357          UNSPEC_TLS_GD))
12358    (clobber (match_scratch:SI 4 "=d"))
12359    (clobber (match_scratch:SI 5 "=c"))
12360    (clobber (reg:CC FLAGS_REG))]
12361   "!TARGET_64BIT && TARGET_GNU_TLS"
12362 {
12363   output_asm_insn
12364     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12365   if (TARGET_SUN_TLS)
12366 #ifdef HAVE_AS_IX86_TLSGDPLT
12367     return "call\t%a2@tlsgdplt";
12368 #else
12369     return "call\t%p3@plt";
12370 #endif
12371   return "call\t%P3";
12372 }
12373   [(set_attr "type" "multi")
12374    (set_attr "length" "12")])
12375
12376 (define_expand "tls_global_dynamic_32"
12377   [(parallel
12378     [(set (match_operand:SI 0 "register_operand" "")
12379           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12380                       (match_operand:SI 1 "tls_symbolic_operand" "")
12381                       (match_operand:SI 3 "constant_call_address_operand" "")]
12382                      UNSPEC_TLS_GD))
12383      (clobber (match_scratch:SI 4 ""))
12384      (clobber (match_scratch:SI 5 ""))
12385      (clobber (reg:CC FLAGS_REG))])])
12386
12387 (define_insn "*tls_global_dynamic_64"
12388   [(set (match_operand:DI 0 "register_operand" "=a")
12389         (call:DI
12390          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12391          (match_operand:DI 3 "" "")))
12392    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12393               UNSPEC_TLS_GD)]
12394   "TARGET_64BIT"
12395 {
12396   fputs (ASM_BYTE "0x66\n", asm_out_file);
12397   output_asm_insn
12398     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12399   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12400   fputs ("\trex64\n", asm_out_file);
12401   if (TARGET_SUN_TLS)
12402     return "call\t%p2@plt";
12403   return "call\t%P2";
12404 }
12405   [(set_attr "type" "multi")
12406    (set_attr "length" "16")])
12407
12408 (define_expand "tls_global_dynamic_64"
12409   [(parallel
12410     [(set (match_operand:DI 0 "register_operand" "")
12411           (call:DI
12412            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12413            (const_int 0)))
12414      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12415                 UNSPEC_TLS_GD)])])
12416
12417 (define_insn "*tls_local_dynamic_base_32_gnu"
12418   [(set (match_operand:SI 0 "register_operand" "=a")
12419         (unspec:SI
12420          [(match_operand:SI 1 "register_operand" "b")
12421           (match_operand:SI 2 "constant_call_address_operand" "z")]
12422          UNSPEC_TLS_LD_BASE))
12423    (clobber (match_scratch:SI 3 "=d"))
12424    (clobber (match_scratch:SI 4 "=c"))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "!TARGET_64BIT && TARGET_GNU_TLS"
12427 {
12428   output_asm_insn
12429     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12430   if (TARGET_SUN_TLS)
12431 #ifdef HAVE_AS_IX86_TLSLDMPLT
12432     return "call\t%&@tlsldmplt";
12433 #else
12434     return "call\t%p2@plt";
12435 #endif
12436   return "call\t%P2";
12437 }
12438   [(set_attr "type" "multi")
12439    (set_attr "length" "11")])
12440
12441 (define_expand "tls_local_dynamic_base_32"
12442   [(parallel
12443      [(set (match_operand:SI 0 "register_operand" "")
12444            (unspec:SI
12445             [(match_operand:SI 1 "register_operand" "")
12446              (match_operand:SI 2 "constant_call_address_operand" "")]
12447             UNSPEC_TLS_LD_BASE))
12448       (clobber (match_scratch:SI 3 ""))
12449       (clobber (match_scratch:SI 4 ""))
12450       (clobber (reg:CC FLAGS_REG))])])
12451
12452 (define_insn "*tls_local_dynamic_base_64"
12453   [(set (match_operand:DI 0 "register_operand" "=a")
12454         (call:DI
12455          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12456          (match_operand:DI 2 "" "")))
12457    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12458   "TARGET_64BIT"
12459 {
12460   output_asm_insn
12461     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12462   if (TARGET_SUN_TLS)
12463     return "call\t%p1@plt";
12464   return "call\t%P1";
12465 }
12466   [(set_attr "type" "multi")
12467    (set_attr "length" "12")])
12468
12469 (define_expand "tls_local_dynamic_base_64"
12470   [(parallel
12471      [(set (match_operand:DI 0 "register_operand" "")
12472            (call:DI
12473             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12474             (const_int 0)))
12475       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12476
12477 ;; Local dynamic of a single variable is a lose.  Show combine how
12478 ;; to convert that back to global dynamic.
12479
12480 (define_insn_and_split "*tls_local_dynamic_32_once"
12481   [(set (match_operand:SI 0 "register_operand" "=a")
12482         (plus:SI
12483          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12484                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12485                     UNSPEC_TLS_LD_BASE)
12486          (const:SI (unspec:SI
12487                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12488                     UNSPEC_DTPOFF))))
12489    (clobber (match_scratch:SI 4 "=d"))
12490    (clobber (match_scratch:SI 5 "=c"))
12491    (clobber (reg:CC FLAGS_REG))]
12492   ""
12493   "#"
12494   ""
12495   [(parallel
12496      [(set (match_dup 0)
12497            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12498                       UNSPEC_TLS_GD))
12499       (clobber (match_dup 4))
12500       (clobber (match_dup 5))
12501       (clobber (reg:CC FLAGS_REG))])])
12502
12503 ;; Segment register for the thread base ptr load
12504 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12505
12506 ;; Load and add the thread base pointer from %<tp_seg>:0.
12507 (define_insn "*load_tp_<mode>"
12508   [(set (match_operand:P 0 "register_operand" "=r")
12509         (unspec:P [(const_int 0)] UNSPEC_TP))]
12510   ""
12511   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12512   [(set_attr "type" "imov")
12513    (set_attr "modrm" "0")
12514    (set_attr "length" "7")
12515    (set_attr "memory" "load")
12516    (set_attr "imm_disp" "false")])
12517
12518 (define_insn "*add_tp_<mode>"
12519   [(set (match_operand:P 0 "register_operand" "=r")
12520         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12521                 (match_operand:P 1 "register_operand" "0")))
12522    (clobber (reg:CC FLAGS_REG))]
12523   ""
12524   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12525   [(set_attr "type" "alu")
12526    (set_attr "modrm" "0")
12527    (set_attr "length" "7")
12528    (set_attr "memory" "load")
12529    (set_attr "imm_disp" "false")])
12530
12531 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12532 ;; %rax as destination of the initial executable code sequence.
12533 (define_insn "tls_initial_exec_64_sun"
12534   [(set (match_operand:DI 0 "register_operand" "=a")
12535         (unspec:DI
12536          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12537          UNSPEC_TLS_IE_SUN))
12538    (clobber (reg:CC FLAGS_REG))]
12539   "TARGET_64BIT && TARGET_SUN_TLS"
12540 {
12541   output_asm_insn
12542     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12543   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12544 }
12545   [(set_attr "type" "multi")])
12546
12547 ;; GNU2 TLS patterns can be split.
12548
12549 (define_expand "tls_dynamic_gnu2_32"
12550   [(set (match_dup 3)
12551         (plus:SI (match_operand:SI 2 "register_operand" "")
12552                  (const:SI
12553                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12554                              UNSPEC_TLSDESC))))
12555    (parallel
12556     [(set (match_operand:SI 0 "register_operand" "")
12557           (unspec:SI [(match_dup 1) (match_dup 3)
12558                       (match_dup 2) (reg:SI SP_REG)]
12559                       UNSPEC_TLSDESC))
12560      (clobber (reg:CC FLAGS_REG))])]
12561   "!TARGET_64BIT && TARGET_GNU2_TLS"
12562 {
12563   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12564   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12565 })
12566
12567 (define_insn "*tls_dynamic_lea_32"
12568   [(set (match_operand:SI 0 "register_operand" "=r")
12569         (plus:SI (match_operand:SI 1 "register_operand" "b")
12570                  (const:SI
12571                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12572                               UNSPEC_TLSDESC))))]
12573   "!TARGET_64BIT && TARGET_GNU2_TLS"
12574   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12575   [(set_attr "type" "lea")
12576    (set_attr "mode" "SI")
12577    (set_attr "length" "6")
12578    (set_attr "length_address" "4")])
12579
12580 (define_insn "*tls_dynamic_call_32"
12581   [(set (match_operand:SI 0 "register_operand" "=a")
12582         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12583                     (match_operand:SI 2 "register_operand" "0")
12584                     ;; we have to make sure %ebx still points to the GOT
12585                     (match_operand:SI 3 "register_operand" "b")
12586                     (reg:SI SP_REG)]
12587                    UNSPEC_TLSDESC))
12588    (clobber (reg:CC FLAGS_REG))]
12589   "!TARGET_64BIT && TARGET_GNU2_TLS"
12590   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12591   [(set_attr "type" "call")
12592    (set_attr "length" "2")
12593    (set_attr "length_address" "0")])
12594
12595 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12596   [(set (match_operand:SI 0 "register_operand" "=&a")
12597         (plus:SI
12598          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12599                      (match_operand:SI 4 "" "")
12600                      (match_operand:SI 2 "register_operand" "b")
12601                      (reg:SI SP_REG)]
12602                     UNSPEC_TLSDESC)
12603          (const:SI (unspec:SI
12604                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12605                     UNSPEC_DTPOFF))))
12606    (clobber (reg:CC FLAGS_REG))]
12607   "!TARGET_64BIT && TARGET_GNU2_TLS"
12608   "#"
12609   ""
12610   [(set (match_dup 0) (match_dup 5))]
12611 {
12612   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12613   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12614 })
12615
12616 (define_expand "tls_dynamic_gnu2_64"
12617   [(set (match_dup 2)
12618         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12619                    UNSPEC_TLSDESC))
12620    (parallel
12621     [(set (match_operand:DI 0 "register_operand" "")
12622           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12623                      UNSPEC_TLSDESC))
12624      (clobber (reg:CC FLAGS_REG))])]
12625   "TARGET_64BIT && TARGET_GNU2_TLS"
12626 {
12627   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12628   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12629 })
12630
12631 (define_insn "*tls_dynamic_lea_64"
12632   [(set (match_operand:DI 0 "register_operand" "=r")
12633         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12634                    UNSPEC_TLSDESC))]
12635   "TARGET_64BIT && TARGET_GNU2_TLS"
12636   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12637   [(set_attr "type" "lea")
12638    (set_attr "mode" "DI")
12639    (set_attr "length" "7")
12640    (set_attr "length_address" "4")])
12641
12642 (define_insn "*tls_dynamic_call_64"
12643   [(set (match_operand:DI 0 "register_operand" "=a")
12644         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12645                     (match_operand:DI 2 "register_operand" "0")
12646                     (reg:DI SP_REG)]
12647                    UNSPEC_TLSDESC))
12648    (clobber (reg:CC FLAGS_REG))]
12649   "TARGET_64BIT && TARGET_GNU2_TLS"
12650   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12651   [(set_attr "type" "call")
12652    (set_attr "length" "2")
12653    (set_attr "length_address" "0")])
12654
12655 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12656   [(set (match_operand:DI 0 "register_operand" "=&a")
12657         (plus:DI
12658          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12659                      (match_operand:DI 3 "" "")
12660                      (reg:DI SP_REG)]
12661                     UNSPEC_TLSDESC)
12662          (const:DI (unspec:DI
12663                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12664                     UNSPEC_DTPOFF))))
12665    (clobber (reg:CC FLAGS_REG))]
12666   "TARGET_64BIT && TARGET_GNU2_TLS"
12667   "#"
12668   ""
12669   [(set (match_dup 0) (match_dup 4))]
12670 {
12671   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12672   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12673 })
12674 \f
12675 ;; These patterns match the binary 387 instructions for addM3, subM3,
12676 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12677 ;; SFmode.  The first is the normal insn, the second the same insn but
12678 ;; with one operand a conversion, and the third the same insn but with
12679 ;; the other operand a conversion.  The conversion may be SFmode or
12680 ;; SImode if the target mode DFmode, but only SImode if the target mode
12681 ;; is SFmode.
12682
12683 ;; Gcc is slightly more smart about handling normal two address instructions
12684 ;; so use special patterns for add and mull.
12685
12686 (define_insn "*fop_<mode>_comm_mixed"
12687   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12688         (match_operator:MODEF 3 "binary_fp_operator"
12689           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12690            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12691   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12692    && COMMUTATIVE_ARITH_P (operands[3])
12693    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12694   "* return output_387_binary_op (insn, operands);"
12695   [(set (attr "type")
12696         (if_then_else (eq_attr "alternative" "1,2")
12697            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12698               (const_string "ssemul")
12699               (const_string "sseadd"))
12700            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12701               (const_string "fmul")
12702               (const_string "fop"))))
12703    (set_attr "isa" "base,noavx,avx")
12704    (set_attr "prefix" "orig,orig,vex")
12705    (set_attr "mode" "<MODE>")])
12706
12707 (define_insn "*fop_<mode>_comm_sse"
12708   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12709         (match_operator:MODEF 3 "binary_fp_operator"
12710           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12711            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12712   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12713    && COMMUTATIVE_ARITH_P (operands[3])
12714    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12715   "* return output_387_binary_op (insn, operands);"
12716   [(set (attr "type")
12717         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12718            (const_string "ssemul")
12719            (const_string "sseadd")))
12720    (set_attr "isa" "noavx,avx")
12721    (set_attr "prefix" "orig,vex")
12722    (set_attr "mode" "<MODE>")])
12723
12724 (define_insn "*fop_<mode>_comm_i387"
12725   [(set (match_operand:MODEF 0 "register_operand" "=f")
12726         (match_operator:MODEF 3 "binary_fp_operator"
12727           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12728            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12729   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12730    && COMMUTATIVE_ARITH_P (operands[3])
12731    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12732   "* return output_387_binary_op (insn, operands);"
12733   [(set (attr "type")
12734         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12735            (const_string "fmul")
12736            (const_string "fop")))
12737    (set_attr "mode" "<MODE>")])
12738
12739 (define_insn "*fop_<mode>_1_mixed"
12740   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12741         (match_operator:MODEF 3 "binary_fp_operator"
12742           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12743            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12744   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12745    && !COMMUTATIVE_ARITH_P (operands[3])
12746    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12747   "* return output_387_binary_op (insn, operands);"
12748   [(set (attr "type")
12749         (cond [(and (eq_attr "alternative" "2,3")
12750                     (match_operand:MODEF 3 "mult_operator" ""))
12751                  (const_string "ssemul")
12752                (and (eq_attr "alternative" "2,3")
12753                     (match_operand:MODEF 3 "div_operator" ""))
12754                  (const_string "ssediv")
12755                (eq_attr "alternative" "2,3")
12756                  (const_string "sseadd")
12757                (match_operand:MODEF 3 "mult_operator" "")
12758                  (const_string "fmul")
12759                (match_operand:MODEF 3 "div_operator" "")
12760                  (const_string "fdiv")
12761               ]
12762               (const_string "fop")))
12763    (set_attr "isa" "base,base,noavx,avx")
12764    (set_attr "prefix" "orig,orig,orig,vex")
12765    (set_attr "mode" "<MODE>")])
12766
12767 (define_insn "*rcpsf2_sse"
12768   [(set (match_operand:SF 0 "register_operand" "=x")
12769         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12770                    UNSPEC_RCP))]
12771   "TARGET_SSE_MATH"
12772   "%vrcpss\t{%1, %d0|%d0, %1}"
12773   [(set_attr "type" "sse")
12774    (set_attr "atom_sse_attr" "rcp")
12775    (set_attr "prefix" "maybe_vex")
12776    (set_attr "mode" "SF")])
12777
12778 (define_insn "*fop_<mode>_1_sse"
12779   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12780         (match_operator:MODEF 3 "binary_fp_operator"
12781           [(match_operand:MODEF 1 "register_operand" "0,x")
12782            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12783   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12784    && !COMMUTATIVE_ARITH_P (operands[3])"
12785   "* return output_387_binary_op (insn, operands);"
12786   [(set (attr "type")
12787         (cond [(match_operand:MODEF 3 "mult_operator" "")
12788                  (const_string "ssemul")
12789                (match_operand:MODEF 3 "div_operator" "")
12790                  (const_string "ssediv")
12791               ]
12792               (const_string "sseadd")))
12793    (set_attr "isa" "noavx,avx")
12794    (set_attr "prefix" "orig,vex")
12795    (set_attr "mode" "<MODE>")])
12796
12797 ;; This pattern is not fully shadowed by the pattern above.
12798 (define_insn "*fop_<mode>_1_i387"
12799   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12800         (match_operator:MODEF 3 "binary_fp_operator"
12801           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12802            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12803   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12804    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12805    && !COMMUTATIVE_ARITH_P (operands[3])
12806    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12807   "* return output_387_binary_op (insn, operands);"
12808   [(set (attr "type")
12809         (cond [(match_operand:MODEF 3 "mult_operator" "")
12810                  (const_string "fmul")
12811                (match_operand:MODEF 3 "div_operator" "")
12812                  (const_string "fdiv")
12813               ]
12814               (const_string "fop")))
12815    (set_attr "mode" "<MODE>")])
12816
12817 ;; ??? Add SSE splitters for these!
12818 (define_insn "*fop_<MODEF:mode>_2_i387"
12819   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12820         (match_operator:MODEF 3 "binary_fp_operator"
12821           [(float:MODEF
12822              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12823            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12824   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12825    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12826    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12827   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12828   [(set (attr "type")
12829         (cond [(match_operand:MODEF 3 "mult_operator" "")
12830                  (const_string "fmul")
12831                (match_operand:MODEF 3 "div_operator" "")
12832                  (const_string "fdiv")
12833               ]
12834               (const_string "fop")))
12835    (set_attr "fp_int_src" "true")
12836    (set_attr "mode" "<SWI24:MODE>")])
12837
12838 (define_insn "*fop_<MODEF:mode>_3_i387"
12839   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12840         (match_operator:MODEF 3 "binary_fp_operator"
12841           [(match_operand:MODEF 1 "register_operand" "0,0")
12842            (float:MODEF
12843              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12844   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12845    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12846    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12847   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12848   [(set (attr "type")
12849         (cond [(match_operand:MODEF 3 "mult_operator" "")
12850                  (const_string "fmul")
12851                (match_operand:MODEF 3 "div_operator" "")
12852                  (const_string "fdiv")
12853               ]
12854               (const_string "fop")))
12855    (set_attr "fp_int_src" "true")
12856    (set_attr "mode" "<MODE>")])
12857
12858 (define_insn "*fop_df_4_i387"
12859   [(set (match_operand:DF 0 "register_operand" "=f,f")
12860         (match_operator:DF 3 "binary_fp_operator"
12861            [(float_extend:DF
12862              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12863             (match_operand:DF 2 "register_operand" "0,f")]))]
12864   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12865    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12866    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12867   "* return output_387_binary_op (insn, operands);"
12868   [(set (attr "type")
12869         (cond [(match_operand:DF 3 "mult_operator" "")
12870                  (const_string "fmul")
12871                (match_operand:DF 3 "div_operator" "")
12872                  (const_string "fdiv")
12873               ]
12874               (const_string "fop")))
12875    (set_attr "mode" "SF")])
12876
12877 (define_insn "*fop_df_5_i387"
12878   [(set (match_operand:DF 0 "register_operand" "=f,f")
12879         (match_operator:DF 3 "binary_fp_operator"
12880           [(match_operand:DF 1 "register_operand" "0,f")
12881            (float_extend:DF
12882             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12883   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12884    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12885   "* return output_387_binary_op (insn, operands);"
12886   [(set (attr "type")
12887         (cond [(match_operand:DF 3 "mult_operator" "")
12888                  (const_string "fmul")
12889                (match_operand:DF 3 "div_operator" "")
12890                  (const_string "fdiv")
12891               ]
12892               (const_string "fop")))
12893    (set_attr "mode" "SF")])
12894
12895 (define_insn "*fop_df_6_i387"
12896   [(set (match_operand:DF 0 "register_operand" "=f,f")
12897         (match_operator:DF 3 "binary_fp_operator"
12898           [(float_extend:DF
12899             (match_operand:SF 1 "register_operand" "0,f"))
12900            (float_extend:DF
12901             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12902   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12903    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12904   "* return output_387_binary_op (insn, operands);"
12905   [(set (attr "type")
12906         (cond [(match_operand:DF 3 "mult_operator" "")
12907                  (const_string "fmul")
12908                (match_operand:DF 3 "div_operator" "")
12909                  (const_string "fdiv")
12910               ]
12911               (const_string "fop")))
12912    (set_attr "mode" "SF")])
12913
12914 (define_insn "*fop_xf_comm_i387"
12915   [(set (match_operand:XF 0 "register_operand" "=f")
12916         (match_operator:XF 3 "binary_fp_operator"
12917                         [(match_operand:XF 1 "register_operand" "%0")
12918                          (match_operand:XF 2 "register_operand" "f")]))]
12919   "TARGET_80387
12920    && COMMUTATIVE_ARITH_P (operands[3])"
12921   "* return output_387_binary_op (insn, operands);"
12922   [(set (attr "type")
12923         (if_then_else (match_operand:XF 3 "mult_operator" "")
12924            (const_string "fmul")
12925            (const_string "fop")))
12926    (set_attr "mode" "XF")])
12927
12928 (define_insn "*fop_xf_1_i387"
12929   [(set (match_operand:XF 0 "register_operand" "=f,f")
12930         (match_operator:XF 3 "binary_fp_operator"
12931                         [(match_operand:XF 1 "register_operand" "0,f")
12932                          (match_operand:XF 2 "register_operand" "f,0")]))]
12933   "TARGET_80387
12934    && !COMMUTATIVE_ARITH_P (operands[3])"
12935   "* return output_387_binary_op (insn, operands);"
12936   [(set (attr "type")
12937         (cond [(match_operand:XF 3 "mult_operator" "")
12938                  (const_string "fmul")
12939                (match_operand:XF 3 "div_operator" "")
12940                  (const_string "fdiv")
12941               ]
12942               (const_string "fop")))
12943    (set_attr "mode" "XF")])
12944
12945 (define_insn "*fop_xf_2_i387"
12946   [(set (match_operand:XF 0 "register_operand" "=f,f")
12947         (match_operator:XF 3 "binary_fp_operator"
12948           [(float:XF
12949              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12950            (match_operand:XF 2 "register_operand" "0,0")]))]
12951   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12952   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12953   [(set (attr "type")
12954         (cond [(match_operand:XF 3 "mult_operator" "")
12955                  (const_string "fmul")
12956                (match_operand:XF 3 "div_operator" "")
12957                  (const_string "fdiv")
12958               ]
12959               (const_string "fop")))
12960    (set_attr "fp_int_src" "true")
12961    (set_attr "mode" "<MODE>")])
12962
12963 (define_insn "*fop_xf_3_i387"
12964   [(set (match_operand:XF 0 "register_operand" "=f,f")
12965         (match_operator:XF 3 "binary_fp_operator"
12966           [(match_operand:XF 1 "register_operand" "0,0")
12967            (float:XF
12968              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12969   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12970   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12971   [(set (attr "type")
12972         (cond [(match_operand:XF 3 "mult_operator" "")
12973                  (const_string "fmul")
12974                (match_operand:XF 3 "div_operator" "")
12975                  (const_string "fdiv")
12976               ]
12977               (const_string "fop")))
12978    (set_attr "fp_int_src" "true")
12979    (set_attr "mode" "<MODE>")])
12980
12981 (define_insn "*fop_xf_4_i387"
12982   [(set (match_operand:XF 0 "register_operand" "=f,f")
12983         (match_operator:XF 3 "binary_fp_operator"
12984            [(float_extend:XF
12985               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12986             (match_operand:XF 2 "register_operand" "0,f")]))]
12987   "TARGET_80387"
12988   "* return output_387_binary_op (insn, operands);"
12989   [(set (attr "type")
12990         (cond [(match_operand:XF 3 "mult_operator" "")
12991                  (const_string "fmul")
12992                (match_operand:XF 3 "div_operator" "")
12993                  (const_string "fdiv")
12994               ]
12995               (const_string "fop")))
12996    (set_attr "mode" "<MODE>")])
12997
12998 (define_insn "*fop_xf_5_i387"
12999   [(set (match_operand:XF 0 "register_operand" "=f,f")
13000         (match_operator:XF 3 "binary_fp_operator"
13001           [(match_operand:XF 1 "register_operand" "0,f")
13002            (float_extend:XF
13003              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13004   "TARGET_80387"
13005   "* return output_387_binary_op (insn, operands);"
13006   [(set (attr "type")
13007         (cond [(match_operand:XF 3 "mult_operator" "")
13008                  (const_string "fmul")
13009                (match_operand:XF 3 "div_operator" "")
13010                  (const_string "fdiv")
13011               ]
13012               (const_string "fop")))
13013    (set_attr "mode" "<MODE>")])
13014
13015 (define_insn "*fop_xf_6_i387"
13016   [(set (match_operand:XF 0 "register_operand" "=f,f")
13017         (match_operator:XF 3 "binary_fp_operator"
13018           [(float_extend:XF
13019              (match_operand:MODEF 1 "register_operand" "0,f"))
13020            (float_extend:XF
13021              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13022   "TARGET_80387"
13023   "* return output_387_binary_op (insn, operands);"
13024   [(set (attr "type")
13025         (cond [(match_operand:XF 3 "mult_operator" "")
13026                  (const_string "fmul")
13027                (match_operand:XF 3 "div_operator" "")
13028                  (const_string "fdiv")
13029               ]
13030               (const_string "fop")))
13031    (set_attr "mode" "<MODE>")])
13032
13033 (define_split
13034   [(set (match_operand 0 "register_operand" "")
13035         (match_operator 3 "binary_fp_operator"
13036            [(float (match_operand:SWI24 1 "register_operand" ""))
13037             (match_operand 2 "register_operand" "")]))]
13038   "reload_completed
13039    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13040    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13041   [(const_int 0)]
13042 {
13043   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13044   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13045   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13046                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13047                                           GET_MODE (operands[3]),
13048                                           operands[4],
13049                                           operands[2])));
13050   ix86_free_from_memory (GET_MODE (operands[1]));
13051   DONE;
13052 })
13053
13054 (define_split
13055   [(set (match_operand 0 "register_operand" "")
13056         (match_operator 3 "binary_fp_operator"
13057            [(match_operand 1 "register_operand" "")
13058             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13059   "reload_completed
13060    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13061    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13062   [(const_int 0)]
13063 {
13064   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13065   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13066   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13067                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13068                                           GET_MODE (operands[3]),
13069                                           operands[1],
13070                                           operands[4])));
13071   ix86_free_from_memory (GET_MODE (operands[2]));
13072   DONE;
13073 })
13074 \f
13075 ;; FPU special functions.
13076
13077 ;; This pattern implements a no-op XFmode truncation for
13078 ;; all fancy i386 XFmode math functions.
13079
13080 (define_insn "truncxf<mode>2_i387_noop_unspec"
13081   [(set (match_operand:MODEF 0 "register_operand" "=f")
13082         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13083         UNSPEC_TRUNC_NOOP))]
13084   "TARGET_USE_FANCY_MATH_387"
13085   "* return output_387_reg_move (insn, operands);"
13086   [(set_attr "type" "fmov")
13087    (set_attr "mode" "<MODE>")])
13088
13089 (define_insn "sqrtxf2"
13090   [(set (match_operand:XF 0 "register_operand" "=f")
13091         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13092   "TARGET_USE_FANCY_MATH_387"
13093   "fsqrt"
13094   [(set_attr "type" "fpspc")
13095    (set_attr "mode" "XF")
13096    (set_attr "athlon_decode" "direct")
13097    (set_attr "amdfam10_decode" "direct")
13098    (set_attr "bdver1_decode" "direct")])
13099
13100 (define_insn "sqrt_extend<mode>xf2_i387"
13101   [(set (match_operand:XF 0 "register_operand" "=f")
13102         (sqrt:XF
13103           (float_extend:XF
13104             (match_operand:MODEF 1 "register_operand" "0"))))]
13105   "TARGET_USE_FANCY_MATH_387"
13106   "fsqrt"
13107   [(set_attr "type" "fpspc")
13108    (set_attr "mode" "XF")
13109    (set_attr "athlon_decode" "direct")
13110    (set_attr "amdfam10_decode" "direct")
13111    (set_attr "bdver1_decode" "direct")])
13112
13113 (define_insn "*rsqrtsf2_sse"
13114   [(set (match_operand:SF 0 "register_operand" "=x")
13115         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13116                    UNSPEC_RSQRT))]
13117   "TARGET_SSE_MATH"
13118   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13119   [(set_attr "type" "sse")
13120    (set_attr "atom_sse_attr" "rcp")
13121    (set_attr "prefix" "maybe_vex")
13122    (set_attr "mode" "SF")])
13123
13124 (define_expand "rsqrtsf2"
13125   [(set (match_operand:SF 0 "register_operand" "")
13126         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13127                    UNSPEC_RSQRT))]
13128   "TARGET_SSE_MATH"
13129 {
13130   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13131   DONE;
13132 })
13133
13134 (define_insn "*sqrt<mode>2_sse"
13135   [(set (match_operand:MODEF 0 "register_operand" "=x")
13136         (sqrt:MODEF
13137           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13138   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13139   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13140   [(set_attr "type" "sse")
13141    (set_attr "atom_sse_attr" "sqrt")
13142    (set_attr "prefix" "maybe_vex")
13143    (set_attr "mode" "<MODE>")
13144    (set_attr "athlon_decode" "*")
13145    (set_attr "amdfam10_decode" "*")
13146    (set_attr "bdver1_decode" "*")])
13147
13148 (define_expand "sqrt<mode>2"
13149   [(set (match_operand:MODEF 0 "register_operand" "")
13150         (sqrt:MODEF
13151           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13152   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13153    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13154 {
13155   if (<MODE>mode == SFmode
13156       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13157       && flag_finite_math_only && !flag_trapping_math
13158       && flag_unsafe_math_optimizations)
13159     {
13160       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13161       DONE;
13162     }
13163
13164   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13165     {
13166       rtx op0 = gen_reg_rtx (XFmode);
13167       rtx op1 = force_reg (<MODE>mode, operands[1]);
13168
13169       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13170       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13171       DONE;
13172    }
13173 })
13174
13175 (define_insn "fpremxf4_i387"
13176   [(set (match_operand:XF 0 "register_operand" "=f")
13177         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13178                     (match_operand:XF 3 "register_operand" "1")]
13179                    UNSPEC_FPREM_F))
13180    (set (match_operand:XF 1 "register_operand" "=u")
13181         (unspec:XF [(match_dup 2) (match_dup 3)]
13182                    UNSPEC_FPREM_U))
13183    (set (reg:CCFP FPSR_REG)
13184         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13185                      UNSPEC_C2_FLAG))]
13186   "TARGET_USE_FANCY_MATH_387"
13187   "fprem"
13188   [(set_attr "type" "fpspc")
13189    (set_attr "mode" "XF")])
13190
13191 (define_expand "fmodxf3"
13192   [(use (match_operand:XF 0 "register_operand" ""))
13193    (use (match_operand:XF 1 "general_operand" ""))
13194    (use (match_operand:XF 2 "general_operand" ""))]
13195   "TARGET_USE_FANCY_MATH_387"
13196 {
13197   rtx label = gen_label_rtx ();
13198
13199   rtx op1 = gen_reg_rtx (XFmode);
13200   rtx op2 = gen_reg_rtx (XFmode);
13201
13202   emit_move_insn (op2, operands[2]);
13203   emit_move_insn (op1, operands[1]);
13204
13205   emit_label (label);
13206   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13207   ix86_emit_fp_unordered_jump (label);
13208   LABEL_NUSES (label) = 1;
13209
13210   emit_move_insn (operands[0], op1);
13211   DONE;
13212 })
13213
13214 (define_expand "fmod<mode>3"
13215   [(use (match_operand:MODEF 0 "register_operand" ""))
13216    (use (match_operand:MODEF 1 "general_operand" ""))
13217    (use (match_operand:MODEF 2 "general_operand" ""))]
13218   "TARGET_USE_FANCY_MATH_387"
13219 {
13220   rtx (*gen_truncxf) (rtx, rtx);
13221
13222   rtx label = gen_label_rtx ();
13223
13224   rtx op1 = gen_reg_rtx (XFmode);
13225   rtx op2 = gen_reg_rtx (XFmode);
13226
13227   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13228   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13229
13230   emit_label (label);
13231   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13232   ix86_emit_fp_unordered_jump (label);
13233   LABEL_NUSES (label) = 1;
13234
13235   /* Truncate the result properly for strict SSE math.  */
13236   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13237       && !TARGET_MIX_SSE_I387)
13238     gen_truncxf = gen_truncxf<mode>2;
13239   else
13240     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13241
13242   emit_insn (gen_truncxf (operands[0], op1));
13243   DONE;
13244 })
13245
13246 (define_insn "fprem1xf4_i387"
13247   [(set (match_operand:XF 0 "register_operand" "=f")
13248         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13249                     (match_operand:XF 3 "register_operand" "1")]
13250                    UNSPEC_FPREM1_F))
13251    (set (match_operand:XF 1 "register_operand" "=u")
13252         (unspec:XF [(match_dup 2) (match_dup 3)]
13253                    UNSPEC_FPREM1_U))
13254    (set (reg:CCFP FPSR_REG)
13255         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13256                      UNSPEC_C2_FLAG))]
13257   "TARGET_USE_FANCY_MATH_387"
13258   "fprem1"
13259   [(set_attr "type" "fpspc")
13260    (set_attr "mode" "XF")])
13261
13262 (define_expand "remainderxf3"
13263   [(use (match_operand:XF 0 "register_operand" ""))
13264    (use (match_operand:XF 1 "general_operand" ""))
13265    (use (match_operand:XF 2 "general_operand" ""))]
13266   "TARGET_USE_FANCY_MATH_387"
13267 {
13268   rtx label = gen_label_rtx ();
13269
13270   rtx op1 = gen_reg_rtx (XFmode);
13271   rtx op2 = gen_reg_rtx (XFmode);
13272
13273   emit_move_insn (op2, operands[2]);
13274   emit_move_insn (op1, operands[1]);
13275
13276   emit_label (label);
13277   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13278   ix86_emit_fp_unordered_jump (label);
13279   LABEL_NUSES (label) = 1;
13280
13281   emit_move_insn (operands[0], op1);
13282   DONE;
13283 })
13284
13285 (define_expand "remainder<mode>3"
13286   [(use (match_operand:MODEF 0 "register_operand" ""))
13287    (use (match_operand:MODEF 1 "general_operand" ""))
13288    (use (match_operand:MODEF 2 "general_operand" ""))]
13289   "TARGET_USE_FANCY_MATH_387"
13290 {
13291   rtx (*gen_truncxf) (rtx, rtx);
13292
13293   rtx label = gen_label_rtx ();
13294
13295   rtx op1 = gen_reg_rtx (XFmode);
13296   rtx op2 = gen_reg_rtx (XFmode);
13297
13298   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13299   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13300
13301   emit_label (label);
13302
13303   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13304   ix86_emit_fp_unordered_jump (label);
13305   LABEL_NUSES (label) = 1;
13306
13307   /* Truncate the result properly for strict SSE math.  */
13308   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13309       && !TARGET_MIX_SSE_I387)
13310     gen_truncxf = gen_truncxf<mode>2;
13311   else
13312     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13313
13314   emit_insn (gen_truncxf (operands[0], op1));
13315   DONE;
13316 })
13317
13318 (define_insn "*sinxf2_i387"
13319   [(set (match_operand:XF 0 "register_operand" "=f")
13320         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13321   "TARGET_USE_FANCY_MATH_387
13322    && flag_unsafe_math_optimizations"
13323   "fsin"
13324   [(set_attr "type" "fpspc")
13325    (set_attr "mode" "XF")])
13326
13327 (define_insn "*sin_extend<mode>xf2_i387"
13328   [(set (match_operand:XF 0 "register_operand" "=f")
13329         (unspec:XF [(float_extend:XF
13330                       (match_operand:MODEF 1 "register_operand" "0"))]
13331                    UNSPEC_SIN))]
13332   "TARGET_USE_FANCY_MATH_387
13333    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13334        || TARGET_MIX_SSE_I387)
13335    && flag_unsafe_math_optimizations"
13336   "fsin"
13337   [(set_attr "type" "fpspc")
13338    (set_attr "mode" "XF")])
13339
13340 (define_insn "*cosxf2_i387"
13341   [(set (match_operand:XF 0 "register_operand" "=f")
13342         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13343   "TARGET_USE_FANCY_MATH_387
13344    && flag_unsafe_math_optimizations"
13345   "fcos"
13346   [(set_attr "type" "fpspc")
13347    (set_attr "mode" "XF")])
13348
13349 (define_insn "*cos_extend<mode>xf2_i387"
13350   [(set (match_operand:XF 0 "register_operand" "=f")
13351         (unspec:XF [(float_extend:XF
13352                       (match_operand:MODEF 1 "register_operand" "0"))]
13353                    UNSPEC_COS))]
13354   "TARGET_USE_FANCY_MATH_387
13355    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13356        || TARGET_MIX_SSE_I387)
13357    && flag_unsafe_math_optimizations"
13358   "fcos"
13359   [(set_attr "type" "fpspc")
13360    (set_attr "mode" "XF")])
13361
13362 ;; When sincos pattern is defined, sin and cos builtin functions will be
13363 ;; expanded to sincos pattern with one of its outputs left unused.
13364 ;; CSE pass will figure out if two sincos patterns can be combined,
13365 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13366 ;; depending on the unused output.
13367
13368 (define_insn "sincosxf3"
13369   [(set (match_operand:XF 0 "register_operand" "=f")
13370         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13371                    UNSPEC_SINCOS_COS))
13372    (set (match_operand:XF 1 "register_operand" "=u")
13373         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13374   "TARGET_USE_FANCY_MATH_387
13375    && flag_unsafe_math_optimizations"
13376   "fsincos"
13377   [(set_attr "type" "fpspc")
13378    (set_attr "mode" "XF")])
13379
13380 (define_split
13381   [(set (match_operand:XF 0 "register_operand" "")
13382         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13383                    UNSPEC_SINCOS_COS))
13384    (set (match_operand:XF 1 "register_operand" "")
13385         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13386   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13387    && can_create_pseudo_p ()"
13388   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13389
13390 (define_split
13391   [(set (match_operand:XF 0 "register_operand" "")
13392         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13393                    UNSPEC_SINCOS_COS))
13394    (set (match_operand:XF 1 "register_operand" "")
13395         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13396   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13397    && can_create_pseudo_p ()"
13398   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13399
13400 (define_insn "sincos_extend<mode>xf3_i387"
13401   [(set (match_operand:XF 0 "register_operand" "=f")
13402         (unspec:XF [(float_extend:XF
13403                       (match_operand:MODEF 2 "register_operand" "0"))]
13404                    UNSPEC_SINCOS_COS))
13405    (set (match_operand:XF 1 "register_operand" "=u")
13406         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13407   "TARGET_USE_FANCY_MATH_387
13408    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13409        || TARGET_MIX_SSE_I387)
13410    && flag_unsafe_math_optimizations"
13411   "fsincos"
13412   [(set_attr "type" "fpspc")
13413    (set_attr "mode" "XF")])
13414
13415 (define_split
13416   [(set (match_operand:XF 0 "register_operand" "")
13417         (unspec:XF [(float_extend:XF
13418                       (match_operand:MODEF 2 "register_operand" ""))]
13419                    UNSPEC_SINCOS_COS))
13420    (set (match_operand:XF 1 "register_operand" "")
13421         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13422   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13423    && can_create_pseudo_p ()"
13424   [(set (match_dup 1)
13425         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13426
13427 (define_split
13428   [(set (match_operand:XF 0 "register_operand" "")
13429         (unspec:XF [(float_extend:XF
13430                       (match_operand:MODEF 2 "register_operand" ""))]
13431                    UNSPEC_SINCOS_COS))
13432    (set (match_operand:XF 1 "register_operand" "")
13433         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13434   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13435    && can_create_pseudo_p ()"
13436   [(set (match_dup 0)
13437         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13438
13439 (define_expand "sincos<mode>3"
13440   [(use (match_operand:MODEF 0 "register_operand" ""))
13441    (use (match_operand:MODEF 1 "register_operand" ""))
13442    (use (match_operand:MODEF 2 "register_operand" ""))]
13443   "TARGET_USE_FANCY_MATH_387
13444    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13445        || TARGET_MIX_SSE_I387)
13446    && flag_unsafe_math_optimizations"
13447 {
13448   rtx op0 = gen_reg_rtx (XFmode);
13449   rtx op1 = gen_reg_rtx (XFmode);
13450
13451   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13452   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13453   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13454   DONE;
13455 })
13456
13457 (define_insn "fptanxf4_i387"
13458   [(set (match_operand:XF 0 "register_operand" "=f")
13459         (match_operand:XF 3 "const_double_operand" "F"))
13460    (set (match_operand:XF 1 "register_operand" "=u")
13461         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13462                    UNSPEC_TAN))]
13463   "TARGET_USE_FANCY_MATH_387
13464    && flag_unsafe_math_optimizations
13465    && standard_80387_constant_p (operands[3]) == 2"
13466   "fptan"
13467   [(set_attr "type" "fpspc")
13468    (set_attr "mode" "XF")])
13469
13470 (define_insn "fptan_extend<mode>xf4_i387"
13471   [(set (match_operand:MODEF 0 "register_operand" "=f")
13472         (match_operand:MODEF 3 "const_double_operand" "F"))
13473    (set (match_operand:XF 1 "register_operand" "=u")
13474         (unspec:XF [(float_extend:XF
13475                       (match_operand:MODEF 2 "register_operand" "0"))]
13476                    UNSPEC_TAN))]
13477   "TARGET_USE_FANCY_MATH_387
13478    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13479        || TARGET_MIX_SSE_I387)
13480    && flag_unsafe_math_optimizations
13481    && standard_80387_constant_p (operands[3]) == 2"
13482   "fptan"
13483   [(set_attr "type" "fpspc")
13484    (set_attr "mode" "XF")])
13485
13486 (define_expand "tanxf2"
13487   [(use (match_operand:XF 0 "register_operand" ""))
13488    (use (match_operand:XF 1 "register_operand" ""))]
13489   "TARGET_USE_FANCY_MATH_387
13490    && flag_unsafe_math_optimizations"
13491 {
13492   rtx one = gen_reg_rtx (XFmode);
13493   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13494
13495   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13496   DONE;
13497 })
13498
13499 (define_expand "tan<mode>2"
13500   [(use (match_operand:MODEF 0 "register_operand" ""))
13501    (use (match_operand:MODEF 1 "register_operand" ""))]
13502   "TARGET_USE_FANCY_MATH_387
13503    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13504        || TARGET_MIX_SSE_I387)
13505    && flag_unsafe_math_optimizations"
13506 {
13507   rtx op0 = gen_reg_rtx (XFmode);
13508
13509   rtx one = gen_reg_rtx (<MODE>mode);
13510   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13511
13512   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13513                                              operands[1], op2));
13514   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13515   DONE;
13516 })
13517
13518 (define_insn "*fpatanxf3_i387"
13519   [(set (match_operand:XF 0 "register_operand" "=f")
13520         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13521                     (match_operand:XF 2 "register_operand" "u")]
13522                    UNSPEC_FPATAN))
13523    (clobber (match_scratch:XF 3 "=2"))]
13524   "TARGET_USE_FANCY_MATH_387
13525    && flag_unsafe_math_optimizations"
13526   "fpatan"
13527   [(set_attr "type" "fpspc")
13528    (set_attr "mode" "XF")])
13529
13530 (define_insn "fpatan_extend<mode>xf3_i387"
13531   [(set (match_operand:XF 0 "register_operand" "=f")
13532         (unspec:XF [(float_extend:XF
13533                       (match_operand:MODEF 1 "register_operand" "0"))
13534                     (float_extend:XF
13535                       (match_operand:MODEF 2 "register_operand" "u"))]
13536                    UNSPEC_FPATAN))
13537    (clobber (match_scratch:XF 3 "=2"))]
13538   "TARGET_USE_FANCY_MATH_387
13539    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13540        || TARGET_MIX_SSE_I387)
13541    && flag_unsafe_math_optimizations"
13542   "fpatan"
13543   [(set_attr "type" "fpspc")
13544    (set_attr "mode" "XF")])
13545
13546 (define_expand "atan2xf3"
13547   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13548                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13549                                (match_operand:XF 1 "register_operand" "")]
13550                               UNSPEC_FPATAN))
13551               (clobber (match_scratch:XF 3 ""))])]
13552   "TARGET_USE_FANCY_MATH_387
13553    && flag_unsafe_math_optimizations")
13554
13555 (define_expand "atan2<mode>3"
13556   [(use (match_operand:MODEF 0 "register_operand" ""))
13557    (use (match_operand:MODEF 1 "register_operand" ""))
13558    (use (match_operand:MODEF 2 "register_operand" ""))]
13559   "TARGET_USE_FANCY_MATH_387
13560    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13561        || TARGET_MIX_SSE_I387)
13562    && flag_unsafe_math_optimizations"
13563 {
13564   rtx op0 = gen_reg_rtx (XFmode);
13565
13566   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13567   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13568   DONE;
13569 })
13570
13571 (define_expand "atanxf2"
13572   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13573                    (unspec:XF [(match_dup 2)
13574                                (match_operand:XF 1 "register_operand" "")]
13575                               UNSPEC_FPATAN))
13576               (clobber (match_scratch:XF 3 ""))])]
13577   "TARGET_USE_FANCY_MATH_387
13578    && flag_unsafe_math_optimizations"
13579 {
13580   operands[2] = gen_reg_rtx (XFmode);
13581   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13582 })
13583
13584 (define_expand "atan<mode>2"
13585   [(use (match_operand:MODEF 0 "register_operand" ""))
13586    (use (match_operand:MODEF 1 "register_operand" ""))]
13587   "TARGET_USE_FANCY_MATH_387
13588    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13589        || TARGET_MIX_SSE_I387)
13590    && flag_unsafe_math_optimizations"
13591 {
13592   rtx op0 = gen_reg_rtx (XFmode);
13593
13594   rtx op2 = gen_reg_rtx (<MODE>mode);
13595   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13596
13597   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13598   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13599   DONE;
13600 })
13601
13602 (define_expand "asinxf2"
13603   [(set (match_dup 2)
13604         (mult:XF (match_operand:XF 1 "register_operand" "")
13605                  (match_dup 1)))
13606    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13607    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13608    (parallel [(set (match_operand:XF 0 "register_operand" "")
13609                    (unspec:XF [(match_dup 5) (match_dup 1)]
13610                               UNSPEC_FPATAN))
13611               (clobber (match_scratch:XF 6 ""))])]
13612   "TARGET_USE_FANCY_MATH_387
13613    && flag_unsafe_math_optimizations"
13614 {
13615   int i;
13616
13617   if (optimize_insn_for_size_p ())
13618     FAIL;
13619
13620   for (i = 2; i < 6; i++)
13621     operands[i] = gen_reg_rtx (XFmode);
13622
13623   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13624 })
13625
13626 (define_expand "asin<mode>2"
13627   [(use (match_operand:MODEF 0 "register_operand" ""))
13628    (use (match_operand:MODEF 1 "general_operand" ""))]
13629  "TARGET_USE_FANCY_MATH_387
13630    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13631        || TARGET_MIX_SSE_I387)
13632    && flag_unsafe_math_optimizations"
13633 {
13634   rtx op0 = gen_reg_rtx (XFmode);
13635   rtx op1 = gen_reg_rtx (XFmode);
13636
13637   if (optimize_insn_for_size_p ())
13638     FAIL;
13639
13640   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13641   emit_insn (gen_asinxf2 (op0, op1));
13642   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13643   DONE;
13644 })
13645
13646 (define_expand "acosxf2"
13647   [(set (match_dup 2)
13648         (mult:XF (match_operand:XF 1 "register_operand" "")
13649                  (match_dup 1)))
13650    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13651    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13652    (parallel [(set (match_operand:XF 0 "register_operand" "")
13653                    (unspec:XF [(match_dup 1) (match_dup 5)]
13654                               UNSPEC_FPATAN))
13655               (clobber (match_scratch:XF 6 ""))])]
13656   "TARGET_USE_FANCY_MATH_387
13657    && flag_unsafe_math_optimizations"
13658 {
13659   int i;
13660
13661   if (optimize_insn_for_size_p ())
13662     FAIL;
13663
13664   for (i = 2; i < 6; i++)
13665     operands[i] = gen_reg_rtx (XFmode);
13666
13667   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13668 })
13669
13670 (define_expand "acos<mode>2"
13671   [(use (match_operand:MODEF 0 "register_operand" ""))
13672    (use (match_operand:MODEF 1 "general_operand" ""))]
13673  "TARGET_USE_FANCY_MATH_387
13674    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13675        || TARGET_MIX_SSE_I387)
13676    && flag_unsafe_math_optimizations"
13677 {
13678   rtx op0 = gen_reg_rtx (XFmode);
13679   rtx op1 = gen_reg_rtx (XFmode);
13680
13681   if (optimize_insn_for_size_p ())
13682     FAIL;
13683
13684   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13685   emit_insn (gen_acosxf2 (op0, op1));
13686   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13687   DONE;
13688 })
13689
13690 (define_insn "fyl2xxf3_i387"
13691   [(set (match_operand:XF 0 "register_operand" "=f")
13692         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13693                     (match_operand:XF 2 "register_operand" "u")]
13694                    UNSPEC_FYL2X))
13695    (clobber (match_scratch:XF 3 "=2"))]
13696   "TARGET_USE_FANCY_MATH_387
13697    && flag_unsafe_math_optimizations"
13698   "fyl2x"
13699   [(set_attr "type" "fpspc")
13700    (set_attr "mode" "XF")])
13701
13702 (define_insn "fyl2x_extend<mode>xf3_i387"
13703   [(set (match_operand:XF 0 "register_operand" "=f")
13704         (unspec:XF [(float_extend:XF
13705                       (match_operand:MODEF 1 "register_operand" "0"))
13706                     (match_operand:XF 2 "register_operand" "u")]
13707                    UNSPEC_FYL2X))
13708    (clobber (match_scratch:XF 3 "=2"))]
13709   "TARGET_USE_FANCY_MATH_387
13710    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13711        || TARGET_MIX_SSE_I387)
13712    && flag_unsafe_math_optimizations"
13713   "fyl2x"
13714   [(set_attr "type" "fpspc")
13715    (set_attr "mode" "XF")])
13716
13717 (define_expand "logxf2"
13718   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13719                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13720                                (match_dup 2)] UNSPEC_FYL2X))
13721               (clobber (match_scratch:XF 3 ""))])]
13722   "TARGET_USE_FANCY_MATH_387
13723    && flag_unsafe_math_optimizations"
13724 {
13725   operands[2] = gen_reg_rtx (XFmode);
13726   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13727 })
13728
13729 (define_expand "log<mode>2"
13730   [(use (match_operand:MODEF 0 "register_operand" ""))
13731    (use (match_operand:MODEF 1 "register_operand" ""))]
13732   "TARGET_USE_FANCY_MATH_387
13733    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13734        || TARGET_MIX_SSE_I387)
13735    && flag_unsafe_math_optimizations"
13736 {
13737   rtx op0 = gen_reg_rtx (XFmode);
13738
13739   rtx op2 = gen_reg_rtx (XFmode);
13740   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13741
13742   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13743   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13744   DONE;
13745 })
13746
13747 (define_expand "log10xf2"
13748   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13749                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13750                                (match_dup 2)] UNSPEC_FYL2X))
13751               (clobber (match_scratch:XF 3 ""))])]
13752   "TARGET_USE_FANCY_MATH_387
13753    && flag_unsafe_math_optimizations"
13754 {
13755   operands[2] = gen_reg_rtx (XFmode);
13756   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13757 })
13758
13759 (define_expand "log10<mode>2"
13760   [(use (match_operand:MODEF 0 "register_operand" ""))
13761    (use (match_operand:MODEF 1 "register_operand" ""))]
13762   "TARGET_USE_FANCY_MATH_387
13763    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13764        || TARGET_MIX_SSE_I387)
13765    && flag_unsafe_math_optimizations"
13766 {
13767   rtx op0 = gen_reg_rtx (XFmode);
13768
13769   rtx op2 = gen_reg_rtx (XFmode);
13770   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13771
13772   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13773   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13774   DONE;
13775 })
13776
13777 (define_expand "log2xf2"
13778   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13779                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13780                                (match_dup 2)] UNSPEC_FYL2X))
13781               (clobber (match_scratch:XF 3 ""))])]
13782   "TARGET_USE_FANCY_MATH_387
13783    && flag_unsafe_math_optimizations"
13784 {
13785   operands[2] = gen_reg_rtx (XFmode);
13786   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13787 })
13788
13789 (define_expand "log2<mode>2"
13790   [(use (match_operand:MODEF 0 "register_operand" ""))
13791    (use (match_operand:MODEF 1 "register_operand" ""))]
13792   "TARGET_USE_FANCY_MATH_387
13793    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13794        || TARGET_MIX_SSE_I387)
13795    && flag_unsafe_math_optimizations"
13796 {
13797   rtx op0 = gen_reg_rtx (XFmode);
13798
13799   rtx op2 = gen_reg_rtx (XFmode);
13800   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13801
13802   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13803   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13804   DONE;
13805 })
13806
13807 (define_insn "fyl2xp1xf3_i387"
13808   [(set (match_operand:XF 0 "register_operand" "=f")
13809         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13810                     (match_operand:XF 2 "register_operand" "u")]
13811                    UNSPEC_FYL2XP1))
13812    (clobber (match_scratch:XF 3 "=2"))]
13813   "TARGET_USE_FANCY_MATH_387
13814    && flag_unsafe_math_optimizations"
13815   "fyl2xp1"
13816   [(set_attr "type" "fpspc")
13817    (set_attr "mode" "XF")])
13818
13819 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13820   [(set (match_operand:XF 0 "register_operand" "=f")
13821         (unspec:XF [(float_extend:XF
13822                       (match_operand:MODEF 1 "register_operand" "0"))
13823                     (match_operand:XF 2 "register_operand" "u")]
13824                    UNSPEC_FYL2XP1))
13825    (clobber (match_scratch:XF 3 "=2"))]
13826   "TARGET_USE_FANCY_MATH_387
13827    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828        || TARGET_MIX_SSE_I387)
13829    && flag_unsafe_math_optimizations"
13830   "fyl2xp1"
13831   [(set_attr "type" "fpspc")
13832    (set_attr "mode" "XF")])
13833
13834 (define_expand "log1pxf2"
13835   [(use (match_operand:XF 0 "register_operand" ""))
13836    (use (match_operand:XF 1 "register_operand" ""))]
13837   "TARGET_USE_FANCY_MATH_387
13838    && flag_unsafe_math_optimizations"
13839 {
13840   if (optimize_insn_for_size_p ())
13841     FAIL;
13842
13843   ix86_emit_i387_log1p (operands[0], operands[1]);
13844   DONE;
13845 })
13846
13847 (define_expand "log1p<mode>2"
13848   [(use (match_operand:MODEF 0 "register_operand" ""))
13849    (use (match_operand:MODEF 1 "register_operand" ""))]
13850   "TARGET_USE_FANCY_MATH_387
13851    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13852        || TARGET_MIX_SSE_I387)
13853    && flag_unsafe_math_optimizations"
13854 {
13855   rtx op0;
13856
13857   if (optimize_insn_for_size_p ())
13858     FAIL;
13859
13860   op0 = gen_reg_rtx (XFmode);
13861
13862   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13863
13864   ix86_emit_i387_log1p (op0, operands[1]);
13865   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13866   DONE;
13867 })
13868
13869 (define_insn "fxtractxf3_i387"
13870   [(set (match_operand:XF 0 "register_operand" "=f")
13871         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13872                    UNSPEC_XTRACT_FRACT))
13873    (set (match_operand:XF 1 "register_operand" "=u")
13874         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13875   "TARGET_USE_FANCY_MATH_387
13876    && flag_unsafe_math_optimizations"
13877   "fxtract"
13878   [(set_attr "type" "fpspc")
13879    (set_attr "mode" "XF")])
13880
13881 (define_insn "fxtract_extend<mode>xf3_i387"
13882   [(set (match_operand:XF 0 "register_operand" "=f")
13883         (unspec:XF [(float_extend:XF
13884                       (match_operand:MODEF 2 "register_operand" "0"))]
13885                    UNSPEC_XTRACT_FRACT))
13886    (set (match_operand:XF 1 "register_operand" "=u")
13887         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13888   "TARGET_USE_FANCY_MATH_387
13889    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13890        || TARGET_MIX_SSE_I387)
13891    && flag_unsafe_math_optimizations"
13892   "fxtract"
13893   [(set_attr "type" "fpspc")
13894    (set_attr "mode" "XF")])
13895
13896 (define_expand "logbxf2"
13897   [(parallel [(set (match_dup 2)
13898                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13899                               UNSPEC_XTRACT_FRACT))
13900               (set (match_operand:XF 0 "register_operand" "")
13901                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13902   "TARGET_USE_FANCY_MATH_387
13903    && flag_unsafe_math_optimizations"
13904   "operands[2] = gen_reg_rtx (XFmode);")
13905
13906 (define_expand "logb<mode>2"
13907   [(use (match_operand:MODEF 0 "register_operand" ""))
13908    (use (match_operand:MODEF 1 "register_operand" ""))]
13909   "TARGET_USE_FANCY_MATH_387
13910    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13911        || TARGET_MIX_SSE_I387)
13912    && flag_unsafe_math_optimizations"
13913 {
13914   rtx op0 = gen_reg_rtx (XFmode);
13915   rtx op1 = gen_reg_rtx (XFmode);
13916
13917   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13918   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13919   DONE;
13920 })
13921
13922 (define_expand "ilogbxf2"
13923   [(use (match_operand:SI 0 "register_operand" ""))
13924    (use (match_operand:XF 1 "register_operand" ""))]
13925   "TARGET_USE_FANCY_MATH_387
13926    && flag_unsafe_math_optimizations"
13927 {
13928   rtx op0, op1;
13929
13930   if (optimize_insn_for_size_p ())
13931     FAIL;
13932
13933   op0 = gen_reg_rtx (XFmode);
13934   op1 = gen_reg_rtx (XFmode);
13935
13936   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13937   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13938   DONE;
13939 })
13940
13941 (define_expand "ilogb<mode>2"
13942   [(use (match_operand:SI 0 "register_operand" ""))
13943    (use (match_operand:MODEF 1 "register_operand" ""))]
13944   "TARGET_USE_FANCY_MATH_387
13945    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13946        || TARGET_MIX_SSE_I387)
13947    && flag_unsafe_math_optimizations"
13948 {
13949   rtx op0, op1;
13950
13951   if (optimize_insn_for_size_p ())
13952     FAIL;
13953
13954   op0 = gen_reg_rtx (XFmode);
13955   op1 = gen_reg_rtx (XFmode);
13956
13957   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13958   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13959   DONE;
13960 })
13961
13962 (define_insn "*f2xm1xf2_i387"
13963   [(set (match_operand:XF 0 "register_operand" "=f")
13964         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13965                    UNSPEC_F2XM1))]
13966   "TARGET_USE_FANCY_MATH_387
13967    && flag_unsafe_math_optimizations"
13968   "f2xm1"
13969   [(set_attr "type" "fpspc")
13970    (set_attr "mode" "XF")])
13971
13972 (define_insn "*fscalexf4_i387"
13973   [(set (match_operand:XF 0 "register_operand" "=f")
13974         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13975                     (match_operand:XF 3 "register_operand" "1")]
13976                    UNSPEC_FSCALE_FRACT))
13977    (set (match_operand:XF 1 "register_operand" "=u")
13978         (unspec:XF [(match_dup 2) (match_dup 3)]
13979                    UNSPEC_FSCALE_EXP))]
13980   "TARGET_USE_FANCY_MATH_387
13981    && flag_unsafe_math_optimizations"
13982   "fscale"
13983   [(set_attr "type" "fpspc")
13984    (set_attr "mode" "XF")])
13985
13986 (define_expand "expNcorexf3"
13987   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13988                                (match_operand:XF 2 "register_operand" "")))
13989    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13990    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13991    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13992    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13993    (parallel [(set (match_operand:XF 0 "register_operand" "")
13994                    (unspec:XF [(match_dup 8) (match_dup 4)]
13995                               UNSPEC_FSCALE_FRACT))
13996               (set (match_dup 9)
13997                    (unspec:XF [(match_dup 8) (match_dup 4)]
13998                               UNSPEC_FSCALE_EXP))])]
13999   "TARGET_USE_FANCY_MATH_387
14000    && flag_unsafe_math_optimizations"
14001 {
14002   int i;
14003
14004   if (optimize_insn_for_size_p ())
14005     FAIL;
14006
14007   for (i = 3; i < 10; i++)
14008     operands[i] = gen_reg_rtx (XFmode);
14009
14010   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14011 })
14012
14013 (define_expand "expxf2"
14014   [(use (match_operand:XF 0 "register_operand" ""))
14015    (use (match_operand:XF 1 "register_operand" ""))]
14016   "TARGET_USE_FANCY_MATH_387
14017    && flag_unsafe_math_optimizations"
14018 {
14019   rtx op2;
14020
14021   if (optimize_insn_for_size_p ())
14022     FAIL;
14023
14024   op2 = gen_reg_rtx (XFmode);
14025   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14026
14027   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14028   DONE;
14029 })
14030
14031 (define_expand "exp<mode>2"
14032   [(use (match_operand:MODEF 0 "register_operand" ""))
14033    (use (match_operand:MODEF 1 "general_operand" ""))]
14034  "TARGET_USE_FANCY_MATH_387
14035    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14036        || TARGET_MIX_SSE_I387)
14037    && flag_unsafe_math_optimizations"
14038 {
14039   rtx op0, op1;
14040
14041   if (optimize_insn_for_size_p ())
14042     FAIL;
14043
14044   op0 = gen_reg_rtx (XFmode);
14045   op1 = gen_reg_rtx (XFmode);
14046
14047   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14048   emit_insn (gen_expxf2 (op0, op1));
14049   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050   DONE;
14051 })
14052
14053 (define_expand "exp10xf2"
14054   [(use (match_operand:XF 0 "register_operand" ""))
14055    (use (match_operand:XF 1 "register_operand" ""))]
14056   "TARGET_USE_FANCY_MATH_387
14057    && flag_unsafe_math_optimizations"
14058 {
14059   rtx op2;
14060
14061   if (optimize_insn_for_size_p ())
14062     FAIL;
14063
14064   op2 = gen_reg_rtx (XFmode);
14065   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14066
14067   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14068   DONE;
14069 })
14070
14071 (define_expand "exp10<mode>2"
14072   [(use (match_operand:MODEF 0 "register_operand" ""))
14073    (use (match_operand:MODEF 1 "general_operand" ""))]
14074  "TARGET_USE_FANCY_MATH_387
14075    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076        || TARGET_MIX_SSE_I387)
14077    && flag_unsafe_math_optimizations"
14078 {
14079   rtx op0, op1;
14080
14081   if (optimize_insn_for_size_p ())
14082     FAIL;
14083
14084   op0 = gen_reg_rtx (XFmode);
14085   op1 = gen_reg_rtx (XFmode);
14086
14087   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14088   emit_insn (gen_exp10xf2 (op0, op1));
14089   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14090   DONE;
14091 })
14092
14093 (define_expand "exp2xf2"
14094   [(use (match_operand:XF 0 "register_operand" ""))
14095    (use (match_operand:XF 1 "register_operand" ""))]
14096   "TARGET_USE_FANCY_MATH_387
14097    && flag_unsafe_math_optimizations"
14098 {
14099   rtx op2;
14100
14101   if (optimize_insn_for_size_p ())
14102     FAIL;
14103
14104   op2 = gen_reg_rtx (XFmode);
14105   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14106
14107   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14108   DONE;
14109 })
14110
14111 (define_expand "exp2<mode>2"
14112   [(use (match_operand:MODEF 0 "register_operand" ""))
14113    (use (match_operand:MODEF 1 "general_operand" ""))]
14114  "TARGET_USE_FANCY_MATH_387
14115    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14116        || TARGET_MIX_SSE_I387)
14117    && flag_unsafe_math_optimizations"
14118 {
14119   rtx op0, op1;
14120
14121   if (optimize_insn_for_size_p ())
14122     FAIL;
14123
14124   op0 = gen_reg_rtx (XFmode);
14125   op1 = gen_reg_rtx (XFmode);
14126
14127   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14128   emit_insn (gen_exp2xf2 (op0, op1));
14129   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14130   DONE;
14131 })
14132
14133 (define_expand "expm1xf2"
14134   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14135                                (match_dup 2)))
14136    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14137    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14138    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14139    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14140    (parallel [(set (match_dup 7)
14141                    (unspec:XF [(match_dup 6) (match_dup 4)]
14142                               UNSPEC_FSCALE_FRACT))
14143               (set (match_dup 8)
14144                    (unspec:XF [(match_dup 6) (match_dup 4)]
14145                               UNSPEC_FSCALE_EXP))])
14146    (parallel [(set (match_dup 10)
14147                    (unspec:XF [(match_dup 9) (match_dup 8)]
14148                               UNSPEC_FSCALE_FRACT))
14149               (set (match_dup 11)
14150                    (unspec:XF [(match_dup 9) (match_dup 8)]
14151                               UNSPEC_FSCALE_EXP))])
14152    (set (match_dup 12) (minus:XF (match_dup 10)
14153                                  (float_extend:XF (match_dup 13))))
14154    (set (match_operand:XF 0 "register_operand" "")
14155         (plus:XF (match_dup 12) (match_dup 7)))]
14156   "TARGET_USE_FANCY_MATH_387
14157    && flag_unsafe_math_optimizations"
14158 {
14159   int i;
14160
14161   if (optimize_insn_for_size_p ())
14162     FAIL;
14163
14164   for (i = 2; i < 13; i++)
14165     operands[i] = gen_reg_rtx (XFmode);
14166
14167   operands[13]
14168     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14169
14170   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14171 })
14172
14173 (define_expand "expm1<mode>2"
14174   [(use (match_operand:MODEF 0 "register_operand" ""))
14175    (use (match_operand:MODEF 1 "general_operand" ""))]
14176  "TARGET_USE_FANCY_MATH_387
14177    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14178        || TARGET_MIX_SSE_I387)
14179    && flag_unsafe_math_optimizations"
14180 {
14181   rtx op0, op1;
14182
14183   if (optimize_insn_for_size_p ())
14184     FAIL;
14185
14186   op0 = gen_reg_rtx (XFmode);
14187   op1 = gen_reg_rtx (XFmode);
14188
14189   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14190   emit_insn (gen_expm1xf2 (op0, op1));
14191   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14192   DONE;
14193 })
14194
14195 (define_expand "ldexpxf3"
14196   [(set (match_dup 3)
14197         (float:XF (match_operand:SI 2 "register_operand" "")))
14198    (parallel [(set (match_operand:XF 0 " register_operand" "")
14199                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14200                                (match_dup 3)]
14201                               UNSPEC_FSCALE_FRACT))
14202               (set (match_dup 4)
14203                    (unspec:XF [(match_dup 1) (match_dup 3)]
14204                               UNSPEC_FSCALE_EXP))])]
14205   "TARGET_USE_FANCY_MATH_387
14206    && flag_unsafe_math_optimizations"
14207 {
14208   if (optimize_insn_for_size_p ())
14209     FAIL;
14210
14211   operands[3] = gen_reg_rtx (XFmode);
14212   operands[4] = gen_reg_rtx (XFmode);
14213 })
14214
14215 (define_expand "ldexp<mode>3"
14216   [(use (match_operand:MODEF 0 "register_operand" ""))
14217    (use (match_operand:MODEF 1 "general_operand" ""))
14218    (use (match_operand:SI 2 "register_operand" ""))]
14219  "TARGET_USE_FANCY_MATH_387
14220    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14221        || TARGET_MIX_SSE_I387)
14222    && flag_unsafe_math_optimizations"
14223 {
14224   rtx op0, op1;
14225
14226   if (optimize_insn_for_size_p ())
14227     FAIL;
14228
14229   op0 = gen_reg_rtx (XFmode);
14230   op1 = gen_reg_rtx (XFmode);
14231
14232   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14233   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14234   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14235   DONE;
14236 })
14237
14238 (define_expand "scalbxf3"
14239   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14240                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14241                                (match_operand:XF 2 "register_operand" "")]
14242                               UNSPEC_FSCALE_FRACT))
14243               (set (match_dup 3)
14244                    (unspec:XF [(match_dup 1) (match_dup 2)]
14245                               UNSPEC_FSCALE_EXP))])]
14246   "TARGET_USE_FANCY_MATH_387
14247    && flag_unsafe_math_optimizations"
14248 {
14249   if (optimize_insn_for_size_p ())
14250     FAIL;
14251
14252   operands[3] = gen_reg_rtx (XFmode);
14253 })
14254
14255 (define_expand "scalb<mode>3"
14256   [(use (match_operand:MODEF 0 "register_operand" ""))
14257    (use (match_operand:MODEF 1 "general_operand" ""))
14258    (use (match_operand:MODEF 2 "general_operand" ""))]
14259  "TARGET_USE_FANCY_MATH_387
14260    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14261        || TARGET_MIX_SSE_I387)
14262    && flag_unsafe_math_optimizations"
14263 {
14264   rtx op0, op1, op2;
14265
14266   if (optimize_insn_for_size_p ())
14267     FAIL;
14268
14269   op0 = gen_reg_rtx (XFmode);
14270   op1 = gen_reg_rtx (XFmode);
14271   op2 = gen_reg_rtx (XFmode);
14272
14273   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14274   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14275   emit_insn (gen_scalbxf3 (op0, op1, op2));
14276   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14277   DONE;
14278 })
14279
14280 (define_expand "significandxf2"
14281   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14282                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14283                               UNSPEC_XTRACT_FRACT))
14284               (set (match_dup 2)
14285                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14286   "TARGET_USE_FANCY_MATH_387
14287    && flag_unsafe_math_optimizations"
14288   "operands[2] = gen_reg_rtx (XFmode);")
14289
14290 (define_expand "significand<mode>2"
14291   [(use (match_operand:MODEF 0 "register_operand" ""))
14292    (use (match_operand:MODEF 1 "register_operand" ""))]
14293   "TARGET_USE_FANCY_MATH_387
14294    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14295        || TARGET_MIX_SSE_I387)
14296    && flag_unsafe_math_optimizations"
14297 {
14298   rtx op0 = gen_reg_rtx (XFmode);
14299   rtx op1 = gen_reg_rtx (XFmode);
14300
14301   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14302   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14303   DONE;
14304 })
14305 \f
14306
14307 (define_insn "sse4_1_round<mode>2"
14308   [(set (match_operand:MODEF 0 "register_operand" "=x")
14309         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14310                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14311                       UNSPEC_ROUND))]
14312   "TARGET_ROUND"
14313   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14314   [(set_attr "type" "ssecvt")
14315    (set_attr "prefix_extra" "1")
14316    (set_attr "prefix" "maybe_vex")
14317    (set_attr "mode" "<MODE>")])
14318
14319 (define_insn "rintxf2"
14320   [(set (match_operand:XF 0 "register_operand" "=f")
14321         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14322                    UNSPEC_FRNDINT))]
14323   "TARGET_USE_FANCY_MATH_387
14324    && flag_unsafe_math_optimizations"
14325   "frndint"
14326   [(set_attr "type" "fpspc")
14327    (set_attr "mode" "XF")])
14328
14329 (define_expand "rint<mode>2"
14330   [(use (match_operand:MODEF 0 "register_operand" ""))
14331    (use (match_operand:MODEF 1 "register_operand" ""))]
14332   "(TARGET_USE_FANCY_MATH_387
14333     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14334         || TARGET_MIX_SSE_I387)
14335     && flag_unsafe_math_optimizations)
14336    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14337        && !flag_trapping_math)"
14338 {
14339   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14340       && !flag_trapping_math)
14341     {
14342       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14343         FAIL;
14344       if (TARGET_ROUND)
14345         emit_insn (gen_sse4_1_round<mode>2
14346                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14347       else
14348         ix86_expand_rint (operand0, operand1);
14349     }
14350   else
14351     {
14352       rtx op0 = gen_reg_rtx (XFmode);
14353       rtx op1 = gen_reg_rtx (XFmode);
14354
14355       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14356       emit_insn (gen_rintxf2 (op0, op1));
14357
14358       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14359     }
14360   DONE;
14361 })
14362
14363 (define_expand "round<mode>2"
14364   [(match_operand:MODEF 0 "register_operand" "")
14365    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14366   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14367    && !flag_trapping_math && !flag_rounding_math"
14368 {
14369   if (optimize_insn_for_size_p ())
14370     FAIL;
14371   if (TARGET_64BIT || (<MODE>mode != DFmode))
14372     ix86_expand_round (operand0, operand1);
14373   else
14374     ix86_expand_rounddf_32 (operand0, operand1);
14375   DONE;
14376 })
14377
14378 (define_insn_and_split "*fistdi2_1"
14379   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14380         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14381                    UNSPEC_FIST))]
14382   "TARGET_USE_FANCY_MATH_387
14383    && can_create_pseudo_p ()"
14384   "#"
14385   "&& 1"
14386   [(const_int 0)]
14387 {
14388   if (memory_operand (operands[0], VOIDmode))
14389     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14390   else
14391     {
14392       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14393       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14394                                          operands[2]));
14395     }
14396   DONE;
14397 }
14398   [(set_attr "type" "fpspc")
14399    (set_attr "mode" "DI")])
14400
14401 (define_insn "fistdi2"
14402   [(set (match_operand:DI 0 "memory_operand" "=m")
14403         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14404                    UNSPEC_FIST))
14405    (clobber (match_scratch:XF 2 "=&1f"))]
14406   "TARGET_USE_FANCY_MATH_387"
14407   "* return output_fix_trunc (insn, operands, false);"
14408   [(set_attr "type" "fpspc")
14409    (set_attr "mode" "DI")])
14410
14411 (define_insn "fistdi2_with_temp"
14412   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14413         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14414                    UNSPEC_FIST))
14415    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14416    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14417   "TARGET_USE_FANCY_MATH_387"
14418   "#"
14419   [(set_attr "type" "fpspc")
14420    (set_attr "mode" "DI")])
14421
14422 (define_split
14423   [(set (match_operand:DI 0 "register_operand" "")
14424         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14425                    UNSPEC_FIST))
14426    (clobber (match_operand:DI 2 "memory_operand" ""))
14427    (clobber (match_scratch 3 ""))]
14428   "reload_completed"
14429   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14430               (clobber (match_dup 3))])
14431    (set (match_dup 0) (match_dup 2))])
14432
14433 (define_split
14434   [(set (match_operand:DI 0 "memory_operand" "")
14435         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14436                    UNSPEC_FIST))
14437    (clobber (match_operand:DI 2 "memory_operand" ""))
14438    (clobber (match_scratch 3 ""))]
14439   "reload_completed"
14440   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14441               (clobber (match_dup 3))])])
14442
14443 (define_insn_and_split "*fist<mode>2_1"
14444   [(set (match_operand:SWI24 0 "register_operand" "")
14445         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14446                       UNSPEC_FIST))]
14447   "TARGET_USE_FANCY_MATH_387
14448    && can_create_pseudo_p ()"
14449   "#"
14450   "&& 1"
14451   [(const_int 0)]
14452 {
14453   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14454   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14455                                         operands[2]));
14456   DONE;
14457 }
14458   [(set_attr "type" "fpspc")
14459    (set_attr "mode" "<MODE>")])
14460
14461 (define_insn "fist<mode>2"
14462   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14463         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14464                       UNSPEC_FIST))]
14465   "TARGET_USE_FANCY_MATH_387"
14466   "* return output_fix_trunc (insn, operands, false);"
14467   [(set_attr "type" "fpspc")
14468    (set_attr "mode" "<MODE>")])
14469
14470 (define_insn "fist<mode>2_with_temp"
14471   [(set (match_operand:SWI24 0 "register_operand" "=r")
14472         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14473                       UNSPEC_FIST))
14474    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14475   "TARGET_USE_FANCY_MATH_387"
14476   "#"
14477   [(set_attr "type" "fpspc")
14478    (set_attr "mode" "<MODE>")])
14479
14480 (define_split
14481   [(set (match_operand:SWI24 0 "register_operand" "")
14482         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14483                       UNSPEC_FIST))
14484    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14485   "reload_completed"
14486   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14487    (set (match_dup 0) (match_dup 2))])
14488
14489 (define_split
14490   [(set (match_operand:SWI24 0 "memory_operand" "")
14491         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14492                       UNSPEC_FIST))
14493    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14494   "reload_completed"
14495   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14496
14497 (define_expand "lrintxf<mode>2"
14498   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14499      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14500                      UNSPEC_FIST))]
14501   "TARGET_USE_FANCY_MATH_387")
14502
14503 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14504   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14505      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14506                         UNSPEC_FIX_NOTRUNC))]
14507   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14508    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14509
14510 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14511   [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14512    (match_operand:MODEF 1 "register_operand" "")]
14513   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14514    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14515    && !flag_trapping_math && !flag_rounding_math"
14516 {
14517   if (optimize_insn_for_size_p ())
14518     FAIL;
14519   ix86_expand_lround (operand0, operand1);
14520   DONE;
14521 })
14522
14523 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14524 (define_insn_and_split "frndintxf2_floor"
14525   [(set (match_operand:XF 0 "register_operand" "")
14526         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14527          UNSPEC_FRNDINT_FLOOR))
14528    (clobber (reg:CC FLAGS_REG))]
14529   "TARGET_USE_FANCY_MATH_387
14530    && flag_unsafe_math_optimizations
14531    && can_create_pseudo_p ()"
14532   "#"
14533   "&& 1"
14534   [(const_int 0)]
14535 {
14536   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14537
14538   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14539   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14540
14541   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14542                                         operands[2], operands[3]));
14543   DONE;
14544 }
14545   [(set_attr "type" "frndint")
14546    (set_attr "i387_cw" "floor")
14547    (set_attr "mode" "XF")])
14548
14549 (define_insn "frndintxf2_floor_i387"
14550   [(set (match_operand:XF 0 "register_operand" "=f")
14551         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14552          UNSPEC_FRNDINT_FLOOR))
14553    (use (match_operand:HI 2 "memory_operand" "m"))
14554    (use (match_operand:HI 3 "memory_operand" "m"))]
14555   "TARGET_USE_FANCY_MATH_387
14556    && flag_unsafe_math_optimizations"
14557   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14558   [(set_attr "type" "frndint")
14559    (set_attr "i387_cw" "floor")
14560    (set_attr "mode" "XF")])
14561
14562 (define_expand "floorxf2"
14563   [(use (match_operand:XF 0 "register_operand" ""))
14564    (use (match_operand:XF 1 "register_operand" ""))]
14565   "TARGET_USE_FANCY_MATH_387
14566    && flag_unsafe_math_optimizations"
14567 {
14568   if (optimize_insn_for_size_p ())
14569     FAIL;
14570   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14571   DONE;
14572 })
14573
14574 (define_expand "floor<mode>2"
14575   [(use (match_operand:MODEF 0 "register_operand" ""))
14576    (use (match_operand:MODEF 1 "register_operand" ""))]
14577   "(TARGET_USE_FANCY_MATH_387
14578     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14579         || TARGET_MIX_SSE_I387)
14580     && flag_unsafe_math_optimizations)
14581    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14582        && !flag_trapping_math)"
14583 {
14584   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585       && !flag_trapping_math
14586       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14587     {
14588       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14589         FAIL;
14590       if (TARGET_ROUND)
14591         emit_insn (gen_sse4_1_round<mode>2
14592                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14593       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14594         ix86_expand_floorceil (operand0, operand1, true);
14595       else
14596         ix86_expand_floorceildf_32 (operand0, operand1, true);
14597     }
14598   else
14599     {
14600       rtx op0, op1;
14601
14602       if (optimize_insn_for_size_p ())
14603         FAIL;
14604
14605       op0 = gen_reg_rtx (XFmode);
14606       op1 = gen_reg_rtx (XFmode);
14607       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14608       emit_insn (gen_frndintxf2_floor (op0, op1));
14609
14610       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14611     }
14612   DONE;
14613 })
14614
14615 (define_insn_and_split "*fist<mode>2_floor_1"
14616   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14617         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14618                         UNSPEC_FIST_FLOOR))
14619    (clobber (reg:CC FLAGS_REG))]
14620   "TARGET_USE_FANCY_MATH_387
14621    && flag_unsafe_math_optimizations
14622    && can_create_pseudo_p ()"
14623   "#"
14624   "&& 1"
14625   [(const_int 0)]
14626 {
14627   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14628
14629   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14630   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14631   if (memory_operand (operands[0], VOIDmode))
14632     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14633                                       operands[2], operands[3]));
14634   else
14635     {
14636       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14637       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14638                                                   operands[2], operands[3],
14639                                                   operands[4]));
14640     }
14641   DONE;
14642 }
14643   [(set_attr "type" "fistp")
14644    (set_attr "i387_cw" "floor")
14645    (set_attr "mode" "<MODE>")])
14646
14647 (define_insn "fistdi2_floor"
14648   [(set (match_operand:DI 0 "memory_operand" "=m")
14649         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14650                    UNSPEC_FIST_FLOOR))
14651    (use (match_operand:HI 2 "memory_operand" "m"))
14652    (use (match_operand:HI 3 "memory_operand" "m"))
14653    (clobber (match_scratch:XF 4 "=&1f"))]
14654   "TARGET_USE_FANCY_MATH_387
14655    && flag_unsafe_math_optimizations"
14656   "* return output_fix_trunc (insn, operands, false);"
14657   [(set_attr "type" "fistp")
14658    (set_attr "i387_cw" "floor")
14659    (set_attr "mode" "DI")])
14660
14661 (define_insn "fistdi2_floor_with_temp"
14662   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14663         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14664                    UNSPEC_FIST_FLOOR))
14665    (use (match_operand:HI 2 "memory_operand" "m,m"))
14666    (use (match_operand:HI 3 "memory_operand" "m,m"))
14667    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14668    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14669   "TARGET_USE_FANCY_MATH_387
14670    && flag_unsafe_math_optimizations"
14671   "#"
14672   [(set_attr "type" "fistp")
14673    (set_attr "i387_cw" "floor")
14674    (set_attr "mode" "DI")])
14675
14676 (define_split
14677   [(set (match_operand:DI 0 "register_operand" "")
14678         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14679                    UNSPEC_FIST_FLOOR))
14680    (use (match_operand:HI 2 "memory_operand" ""))
14681    (use (match_operand:HI 3 "memory_operand" ""))
14682    (clobber (match_operand:DI 4 "memory_operand" ""))
14683    (clobber (match_scratch 5 ""))]
14684   "reload_completed"
14685   [(parallel [(set (match_dup 4)
14686                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14687               (use (match_dup 2))
14688               (use (match_dup 3))
14689               (clobber (match_dup 5))])
14690    (set (match_dup 0) (match_dup 4))])
14691
14692 (define_split
14693   [(set (match_operand:DI 0 "memory_operand" "")
14694         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14695                    UNSPEC_FIST_FLOOR))
14696    (use (match_operand:HI 2 "memory_operand" ""))
14697    (use (match_operand:HI 3 "memory_operand" ""))
14698    (clobber (match_operand:DI 4 "memory_operand" ""))
14699    (clobber (match_scratch 5 ""))]
14700   "reload_completed"
14701   [(parallel [(set (match_dup 0)
14702                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14703               (use (match_dup 2))
14704               (use (match_dup 3))
14705               (clobber (match_dup 5))])])
14706
14707 (define_insn "fist<mode>2_floor"
14708   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14709         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14710                       UNSPEC_FIST_FLOOR))
14711    (use (match_operand:HI 2 "memory_operand" "m"))
14712    (use (match_operand:HI 3 "memory_operand" "m"))]
14713   "TARGET_USE_FANCY_MATH_387
14714    && flag_unsafe_math_optimizations"
14715   "* return output_fix_trunc (insn, operands, false);"
14716   [(set_attr "type" "fistp")
14717    (set_attr "i387_cw" "floor")
14718    (set_attr "mode" "<MODE>")])
14719
14720 (define_insn "fist<mode>2_floor_with_temp"
14721   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14722         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14723                       UNSPEC_FIST_FLOOR))
14724    (use (match_operand:HI 2 "memory_operand" "m,m"))
14725    (use (match_operand:HI 3 "memory_operand" "m,m"))
14726    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14727   "TARGET_USE_FANCY_MATH_387
14728    && flag_unsafe_math_optimizations"
14729   "#"
14730   [(set_attr "type" "fistp")
14731    (set_attr "i387_cw" "floor")
14732    (set_attr "mode" "<MODE>")])
14733
14734 (define_split
14735   [(set (match_operand:SWI24 0 "register_operand" "")
14736         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14737                       UNSPEC_FIST_FLOOR))
14738    (use (match_operand:HI 2 "memory_operand" ""))
14739    (use (match_operand:HI 3 "memory_operand" ""))
14740    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14741   "reload_completed"
14742   [(parallel [(set (match_dup 4)
14743                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14744               (use (match_dup 2))
14745               (use (match_dup 3))])
14746    (set (match_dup 0) (match_dup 4))])
14747
14748 (define_split
14749   [(set (match_operand:SWI24 0 "memory_operand" "")
14750         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14751                       UNSPEC_FIST_FLOOR))
14752    (use (match_operand:HI 2 "memory_operand" ""))
14753    (use (match_operand:HI 3 "memory_operand" ""))
14754    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14755   "reload_completed"
14756   [(parallel [(set (match_dup 0)
14757                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14758               (use (match_dup 2))
14759               (use (match_dup 3))])])
14760
14761 (define_expand "lfloorxf<mode>2"
14762   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14763                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14764                                    UNSPEC_FIST_FLOOR))
14765               (clobber (reg:CC FLAGS_REG))])]
14766   "TARGET_USE_FANCY_MATH_387
14767    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14768    && flag_unsafe_math_optimizations")
14769
14770 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14771   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14772    (match_operand:MODEF 1 "register_operand" "")]
14773   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14774    && !flag_trapping_math"
14775 {
14776   if (TARGET_64BIT && optimize_insn_for_size_p ())
14777     FAIL;
14778   ix86_expand_lfloorceil (operand0, operand1, true);
14779   DONE;
14780 })
14781
14782 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14783 (define_insn_and_split "frndintxf2_ceil"
14784   [(set (match_operand:XF 0 "register_operand" "")
14785         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14786          UNSPEC_FRNDINT_CEIL))
14787    (clobber (reg:CC FLAGS_REG))]
14788   "TARGET_USE_FANCY_MATH_387
14789    && flag_unsafe_math_optimizations
14790    && can_create_pseudo_p ()"
14791   "#"
14792   "&& 1"
14793   [(const_int 0)]
14794 {
14795   ix86_optimize_mode_switching[I387_CEIL] = 1;
14796
14797   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14798   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14799
14800   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14801                                        operands[2], operands[3]));
14802   DONE;
14803 }
14804   [(set_attr "type" "frndint")
14805    (set_attr "i387_cw" "ceil")
14806    (set_attr "mode" "XF")])
14807
14808 (define_insn "frndintxf2_ceil_i387"
14809   [(set (match_operand:XF 0 "register_operand" "=f")
14810         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14811          UNSPEC_FRNDINT_CEIL))
14812    (use (match_operand:HI 2 "memory_operand" "m"))
14813    (use (match_operand:HI 3 "memory_operand" "m"))]
14814   "TARGET_USE_FANCY_MATH_387
14815    && flag_unsafe_math_optimizations"
14816   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14817   [(set_attr "type" "frndint")
14818    (set_attr "i387_cw" "ceil")
14819    (set_attr "mode" "XF")])
14820
14821 (define_expand "ceilxf2"
14822   [(use (match_operand:XF 0 "register_operand" ""))
14823    (use (match_operand:XF 1 "register_operand" ""))]
14824   "TARGET_USE_FANCY_MATH_387
14825    && flag_unsafe_math_optimizations"
14826 {
14827   if (optimize_insn_for_size_p ())
14828     FAIL;
14829   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14830   DONE;
14831 })
14832
14833 (define_expand "ceil<mode>2"
14834   [(use (match_operand:MODEF 0 "register_operand" ""))
14835    (use (match_operand:MODEF 1 "register_operand" ""))]
14836   "(TARGET_USE_FANCY_MATH_387
14837     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838         || TARGET_MIX_SSE_I387)
14839     && flag_unsafe_math_optimizations)
14840    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14841        && !flag_trapping_math)"
14842 {
14843   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844       && !flag_trapping_math
14845       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14846     {
14847       if (TARGET_ROUND)
14848         emit_insn (gen_sse4_1_round<mode>2
14849                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14850       else if (optimize_insn_for_size_p ())
14851         FAIL;
14852       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14853         ix86_expand_floorceil (operand0, operand1, false);
14854       else
14855         ix86_expand_floorceildf_32 (operand0, operand1, false);
14856     }
14857   else
14858     {
14859       rtx op0, op1;
14860
14861       if (optimize_insn_for_size_p ())
14862         FAIL;
14863
14864       op0 = gen_reg_rtx (XFmode);
14865       op1 = gen_reg_rtx (XFmode);
14866       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14867       emit_insn (gen_frndintxf2_ceil (op0, op1));
14868
14869       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14870     }
14871   DONE;
14872 })
14873
14874 (define_insn_and_split "*fist<mode>2_ceil_1"
14875   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14876         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14877                         UNSPEC_FIST_CEIL))
14878    (clobber (reg:CC FLAGS_REG))]
14879   "TARGET_USE_FANCY_MATH_387
14880    && flag_unsafe_math_optimizations
14881    && can_create_pseudo_p ()"
14882   "#"
14883   "&& 1"
14884   [(const_int 0)]
14885 {
14886   ix86_optimize_mode_switching[I387_CEIL] = 1;
14887
14888   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14889   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14890   if (memory_operand (operands[0], VOIDmode))
14891     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14892                                      operands[2], operands[3]));
14893   else
14894     {
14895       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14896       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14897                                                  operands[2], operands[3],
14898                                                  operands[4]));
14899     }
14900   DONE;
14901 }
14902   [(set_attr "type" "fistp")
14903    (set_attr "i387_cw" "ceil")
14904    (set_attr "mode" "<MODE>")])
14905
14906 (define_insn "fistdi2_ceil"
14907   [(set (match_operand:DI 0 "memory_operand" "=m")
14908         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14909                    UNSPEC_FIST_CEIL))
14910    (use (match_operand:HI 2 "memory_operand" "m"))
14911    (use (match_operand:HI 3 "memory_operand" "m"))
14912    (clobber (match_scratch:XF 4 "=&1f"))]
14913   "TARGET_USE_FANCY_MATH_387
14914    && flag_unsafe_math_optimizations"
14915   "* return output_fix_trunc (insn, operands, false);"
14916   [(set_attr "type" "fistp")
14917    (set_attr "i387_cw" "ceil")
14918    (set_attr "mode" "DI")])
14919
14920 (define_insn "fistdi2_ceil_with_temp"
14921   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14922         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14923                    UNSPEC_FIST_CEIL))
14924    (use (match_operand:HI 2 "memory_operand" "m,m"))
14925    (use (match_operand:HI 3 "memory_operand" "m,m"))
14926    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14927    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14928   "TARGET_USE_FANCY_MATH_387
14929    && flag_unsafe_math_optimizations"
14930   "#"
14931   [(set_attr "type" "fistp")
14932    (set_attr "i387_cw" "ceil")
14933    (set_attr "mode" "DI")])
14934
14935 (define_split
14936   [(set (match_operand:DI 0 "register_operand" "")
14937         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14938                    UNSPEC_FIST_CEIL))
14939    (use (match_operand:HI 2 "memory_operand" ""))
14940    (use (match_operand:HI 3 "memory_operand" ""))
14941    (clobber (match_operand:DI 4 "memory_operand" ""))
14942    (clobber (match_scratch 5 ""))]
14943   "reload_completed"
14944   [(parallel [(set (match_dup 4)
14945                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14946               (use (match_dup 2))
14947               (use (match_dup 3))
14948               (clobber (match_dup 5))])
14949    (set (match_dup 0) (match_dup 4))])
14950
14951 (define_split
14952   [(set (match_operand:DI 0 "memory_operand" "")
14953         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14954                    UNSPEC_FIST_CEIL))
14955    (use (match_operand:HI 2 "memory_operand" ""))
14956    (use (match_operand:HI 3 "memory_operand" ""))
14957    (clobber (match_operand:DI 4 "memory_operand" ""))
14958    (clobber (match_scratch 5 ""))]
14959   "reload_completed"
14960   [(parallel [(set (match_dup 0)
14961                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14962               (use (match_dup 2))
14963               (use (match_dup 3))
14964               (clobber (match_dup 5))])])
14965
14966 (define_insn "fist<mode>2_ceil"
14967   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14968         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14969                       UNSPEC_FIST_CEIL))
14970    (use (match_operand:HI 2 "memory_operand" "m"))
14971    (use (match_operand:HI 3 "memory_operand" "m"))]
14972   "TARGET_USE_FANCY_MATH_387
14973    && flag_unsafe_math_optimizations"
14974   "* return output_fix_trunc (insn, operands, false);"
14975   [(set_attr "type" "fistp")
14976    (set_attr "i387_cw" "ceil")
14977    (set_attr "mode" "<MODE>")])
14978
14979 (define_insn "fist<mode>2_ceil_with_temp"
14980   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14981         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14982                       UNSPEC_FIST_CEIL))
14983    (use (match_operand:HI 2 "memory_operand" "m,m"))
14984    (use (match_operand:HI 3 "memory_operand" "m,m"))
14985    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14986   "TARGET_USE_FANCY_MATH_387
14987    && flag_unsafe_math_optimizations"
14988   "#"
14989   [(set_attr "type" "fistp")
14990    (set_attr "i387_cw" "ceil")
14991    (set_attr "mode" "<MODE>")])
14992
14993 (define_split
14994   [(set (match_operand:SWI24 0 "register_operand" "")
14995         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14996                       UNSPEC_FIST_CEIL))
14997    (use (match_operand:HI 2 "memory_operand" ""))
14998    (use (match_operand:HI 3 "memory_operand" ""))
14999    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15000   "reload_completed"
15001   [(parallel [(set (match_dup 4)
15002                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15003               (use (match_dup 2))
15004               (use (match_dup 3))])
15005    (set (match_dup 0) (match_dup 4))])
15006
15007 (define_split
15008   [(set (match_operand:SWI24 0 "memory_operand" "")
15009         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15010                       UNSPEC_FIST_CEIL))
15011    (use (match_operand:HI 2 "memory_operand" ""))
15012    (use (match_operand:HI 3 "memory_operand" ""))
15013    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15014   "reload_completed"
15015   [(parallel [(set (match_dup 0)
15016                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15017               (use (match_dup 2))
15018               (use (match_dup 3))])])
15019
15020 (define_expand "lceilxf<mode>2"
15021   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15022                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15023                                    UNSPEC_FIST_CEIL))
15024               (clobber (reg:CC FLAGS_REG))])]
15025   "TARGET_USE_FANCY_MATH_387
15026    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15027    && flag_unsafe_math_optimizations")
15028
15029 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15030   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15031    (match_operand:MODEF 1 "register_operand" "")]
15032   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15033    && !flag_trapping_math"
15034 {
15035   ix86_expand_lfloorceil (operand0, operand1, false);
15036   DONE;
15037 })
15038
15039 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15040 (define_insn_and_split "frndintxf2_trunc"
15041   [(set (match_operand:XF 0 "register_operand" "")
15042         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15043          UNSPEC_FRNDINT_TRUNC))
15044    (clobber (reg:CC FLAGS_REG))]
15045   "TARGET_USE_FANCY_MATH_387
15046    && flag_unsafe_math_optimizations
15047    && can_create_pseudo_p ()"
15048   "#"
15049   "&& 1"
15050   [(const_int 0)]
15051 {
15052   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15053
15054   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15055   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15056
15057   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15058                                         operands[2], operands[3]));
15059   DONE;
15060 }
15061   [(set_attr "type" "frndint")
15062    (set_attr "i387_cw" "trunc")
15063    (set_attr "mode" "XF")])
15064
15065 (define_insn "frndintxf2_trunc_i387"
15066   [(set (match_operand:XF 0 "register_operand" "=f")
15067         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15068          UNSPEC_FRNDINT_TRUNC))
15069    (use (match_operand:HI 2 "memory_operand" "m"))
15070    (use (match_operand:HI 3 "memory_operand" "m"))]
15071   "TARGET_USE_FANCY_MATH_387
15072    && flag_unsafe_math_optimizations"
15073   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15074   [(set_attr "type" "frndint")
15075    (set_attr "i387_cw" "trunc")
15076    (set_attr "mode" "XF")])
15077
15078 (define_expand "btruncxf2"
15079   [(use (match_operand:XF 0 "register_operand" ""))
15080    (use (match_operand:XF 1 "register_operand" ""))]
15081   "TARGET_USE_FANCY_MATH_387
15082    && flag_unsafe_math_optimizations"
15083 {
15084   if (optimize_insn_for_size_p ())
15085     FAIL;
15086   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15087   DONE;
15088 })
15089
15090 (define_expand "btrunc<mode>2"
15091   [(use (match_operand:MODEF 0 "register_operand" ""))
15092    (use (match_operand:MODEF 1 "register_operand" ""))]
15093   "(TARGET_USE_FANCY_MATH_387
15094     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15095         || TARGET_MIX_SSE_I387)
15096     && flag_unsafe_math_optimizations)
15097    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15098        && !flag_trapping_math)"
15099 {
15100   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15101       && !flag_trapping_math
15102       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15103     {
15104       if (TARGET_ROUND)
15105         emit_insn (gen_sse4_1_round<mode>2
15106                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15107       else if (optimize_insn_for_size_p ())
15108         FAIL;
15109       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15110         ix86_expand_trunc (operand0, operand1);
15111       else
15112         ix86_expand_truncdf_32 (operand0, operand1);
15113     }
15114   else
15115     {
15116       rtx op0, op1;
15117
15118       if (optimize_insn_for_size_p ())
15119         FAIL;
15120
15121       op0 = gen_reg_rtx (XFmode);
15122       op1 = gen_reg_rtx (XFmode);
15123       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15124       emit_insn (gen_frndintxf2_trunc (op0, op1));
15125
15126       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15127     }
15128   DONE;
15129 })
15130
15131 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15132 (define_insn_and_split "frndintxf2_mask_pm"
15133   [(set (match_operand:XF 0 "register_operand" "")
15134         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15135          UNSPEC_FRNDINT_MASK_PM))
15136    (clobber (reg:CC FLAGS_REG))]
15137   "TARGET_USE_FANCY_MATH_387
15138    && flag_unsafe_math_optimizations
15139    && can_create_pseudo_p ()"
15140   "#"
15141   "&& 1"
15142   [(const_int 0)]
15143 {
15144   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15145
15146   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15147   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15148
15149   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15150                                           operands[2], operands[3]));
15151   DONE;
15152 }
15153   [(set_attr "type" "frndint")
15154    (set_attr "i387_cw" "mask_pm")
15155    (set_attr "mode" "XF")])
15156
15157 (define_insn "frndintxf2_mask_pm_i387"
15158   [(set (match_operand:XF 0 "register_operand" "=f")
15159         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15160          UNSPEC_FRNDINT_MASK_PM))
15161    (use (match_operand:HI 2 "memory_operand" "m"))
15162    (use (match_operand:HI 3 "memory_operand" "m"))]
15163   "TARGET_USE_FANCY_MATH_387
15164    && flag_unsafe_math_optimizations"
15165   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15166   [(set_attr "type" "frndint")
15167    (set_attr "i387_cw" "mask_pm")
15168    (set_attr "mode" "XF")])
15169
15170 (define_expand "nearbyintxf2"
15171   [(use (match_operand:XF 0 "register_operand" ""))
15172    (use (match_operand:XF 1 "register_operand" ""))]
15173   "TARGET_USE_FANCY_MATH_387
15174    && flag_unsafe_math_optimizations"
15175 {
15176   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15177   DONE;
15178 })
15179
15180 (define_expand "nearbyint<mode>2"
15181   [(use (match_operand:MODEF 0 "register_operand" ""))
15182    (use (match_operand:MODEF 1 "register_operand" ""))]
15183   "TARGET_USE_FANCY_MATH_387
15184    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15185        || TARGET_MIX_SSE_I387)
15186    && flag_unsafe_math_optimizations"
15187 {
15188   rtx op0 = gen_reg_rtx (XFmode);
15189   rtx op1 = gen_reg_rtx (XFmode);
15190
15191   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15192   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15193
15194   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15195   DONE;
15196 })
15197
15198 (define_insn "fxam<mode>2_i387"
15199   [(set (match_operand:HI 0 "register_operand" "=a")
15200         (unspec:HI
15201           [(match_operand:X87MODEF 1 "register_operand" "f")]
15202           UNSPEC_FXAM))]
15203   "TARGET_USE_FANCY_MATH_387"
15204   "fxam\n\tfnstsw\t%0"
15205   [(set_attr "type" "multi")
15206    (set_attr "length" "4")
15207    (set_attr "unit" "i387")
15208    (set_attr "mode" "<MODE>")])
15209
15210 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15211   [(set (match_operand:HI 0 "register_operand" "")
15212         (unspec:HI
15213           [(match_operand:MODEF 1 "memory_operand" "")]
15214           UNSPEC_FXAM_MEM))]
15215   "TARGET_USE_FANCY_MATH_387
15216    && can_create_pseudo_p ()"
15217   "#"
15218   "&& 1"
15219   [(set (match_dup 2)(match_dup 1))
15220    (set (match_dup 0)
15221         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15222 {
15223   operands[2] = gen_reg_rtx (<MODE>mode);
15224
15225   MEM_VOLATILE_P (operands[1]) = 1;
15226 }
15227   [(set_attr "type" "multi")
15228    (set_attr "unit" "i387")
15229    (set_attr "mode" "<MODE>")])
15230
15231 (define_expand "isinfxf2"
15232   [(use (match_operand:SI 0 "register_operand" ""))
15233    (use (match_operand:XF 1 "register_operand" ""))]
15234   "TARGET_USE_FANCY_MATH_387
15235    && TARGET_C99_FUNCTIONS"
15236 {
15237   rtx mask = GEN_INT (0x45);
15238   rtx val = GEN_INT (0x05);
15239
15240   rtx cond;
15241
15242   rtx scratch = gen_reg_rtx (HImode);
15243   rtx res = gen_reg_rtx (QImode);
15244
15245   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15246
15247   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15248   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15249   cond = gen_rtx_fmt_ee (EQ, QImode,
15250                          gen_rtx_REG (CCmode, FLAGS_REG),
15251                          const0_rtx);
15252   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15253   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15254   DONE;
15255 })
15256
15257 (define_expand "isinf<mode>2"
15258   [(use (match_operand:SI 0 "register_operand" ""))
15259    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15260   "TARGET_USE_FANCY_MATH_387
15261    && TARGET_C99_FUNCTIONS
15262    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15263 {
15264   rtx mask = GEN_INT (0x45);
15265   rtx val = GEN_INT (0x05);
15266
15267   rtx cond;
15268
15269   rtx scratch = gen_reg_rtx (HImode);
15270   rtx res = gen_reg_rtx (QImode);
15271
15272   /* Remove excess precision by forcing value through memory. */
15273   if (memory_operand (operands[1], VOIDmode))
15274     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15275   else
15276     {
15277       enum ix86_stack_slot slot = (virtuals_instantiated
15278                                    ? SLOT_TEMP
15279                                    : SLOT_VIRTUAL);
15280       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15281
15282       emit_move_insn (temp, operands[1]);
15283       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15284     }
15285
15286   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15287   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15288   cond = gen_rtx_fmt_ee (EQ, QImode,
15289                          gen_rtx_REG (CCmode, FLAGS_REG),
15290                          const0_rtx);
15291   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15292   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15293   DONE;
15294 })
15295
15296 (define_expand "signbitxf2"
15297   [(use (match_operand:SI 0 "register_operand" ""))
15298    (use (match_operand:XF 1 "register_operand" ""))]
15299   "TARGET_USE_FANCY_MATH_387"
15300 {
15301   rtx scratch = gen_reg_rtx (HImode);
15302
15303   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15304   emit_insn (gen_andsi3 (operands[0],
15305              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15306   DONE;
15307 })
15308
15309 (define_insn "movmsk_df"
15310   [(set (match_operand:SI 0 "register_operand" "=r")
15311         (unspec:SI
15312           [(match_operand:DF 1 "register_operand" "x")]
15313           UNSPEC_MOVMSK))]
15314   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15315   "%vmovmskpd\t{%1, %0|%0, %1}"
15316   [(set_attr "type" "ssemov")
15317    (set_attr "prefix" "maybe_vex")
15318    (set_attr "mode" "DF")])
15319
15320 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15321 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15322 (define_expand "signbitdf2"
15323   [(use (match_operand:SI 0 "register_operand" ""))
15324    (use (match_operand:DF 1 "register_operand" ""))]
15325   "TARGET_USE_FANCY_MATH_387
15326    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15327 {
15328   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15329     {
15330       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15331       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15332     }
15333   else
15334     {
15335       rtx scratch = gen_reg_rtx (HImode);
15336
15337       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15338       emit_insn (gen_andsi3 (operands[0],
15339                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15340     }
15341   DONE;
15342 })
15343
15344 (define_expand "signbitsf2"
15345   [(use (match_operand:SI 0 "register_operand" ""))
15346    (use (match_operand:SF 1 "register_operand" ""))]
15347   "TARGET_USE_FANCY_MATH_387
15348    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15349 {
15350   rtx scratch = gen_reg_rtx (HImode);
15351
15352   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15353   emit_insn (gen_andsi3 (operands[0],
15354              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15355   DONE;
15356 })
15357 \f
15358 ;; Block operation instructions
15359
15360 (define_insn "cld"
15361   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15362   ""
15363   "cld"
15364   [(set_attr "length" "1")
15365    (set_attr "length_immediate" "0")
15366    (set_attr "modrm" "0")])
15367
15368 (define_expand "movmem<mode>"
15369   [(use (match_operand:BLK 0 "memory_operand" ""))
15370    (use (match_operand:BLK 1 "memory_operand" ""))
15371    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15372    (use (match_operand:SWI48 3 "const_int_operand" ""))
15373    (use (match_operand:SI 4 "const_int_operand" ""))
15374    (use (match_operand:SI 5 "const_int_operand" ""))]
15375   ""
15376 {
15377  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15378                          operands[4], operands[5]))
15379    DONE;
15380  else
15381    FAIL;
15382 })
15383
15384 ;; Most CPUs don't like single string operations
15385 ;; Handle this case here to simplify previous expander.
15386
15387 (define_expand "strmov"
15388   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15389    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15390    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15391               (clobber (reg:CC FLAGS_REG))])
15392    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15393               (clobber (reg:CC FLAGS_REG))])]
15394   ""
15395 {
15396   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15397
15398   /* If .md ever supports :P for Pmode, these can be directly
15399      in the pattern above.  */
15400   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15401   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15402
15403   /* Can't use this if the user has appropriated esi or edi.  */
15404   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15405       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15406     {
15407       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15408                                       operands[2], operands[3],
15409                                       operands[5], operands[6]));
15410       DONE;
15411     }
15412
15413   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15414 })
15415
15416 (define_expand "strmov_singleop"
15417   [(parallel [(set (match_operand 1 "memory_operand" "")
15418                    (match_operand 3 "memory_operand" ""))
15419               (set (match_operand 0 "register_operand" "")
15420                    (match_operand 4 "" ""))
15421               (set (match_operand 2 "register_operand" "")
15422                    (match_operand 5 "" ""))])]
15423   ""
15424   "ix86_current_function_needs_cld = 1;")
15425
15426 (define_insn "*strmovdi_rex_1"
15427   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15428         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15429    (set (match_operand:DI 0 "register_operand" "=D")
15430         (plus:DI (match_dup 2)
15431                  (const_int 8)))
15432    (set (match_operand:DI 1 "register_operand" "=S")
15433         (plus:DI (match_dup 3)
15434                  (const_int 8)))]
15435   "TARGET_64BIT"
15436   "movsq"
15437   [(set_attr "type" "str")
15438    (set_attr "memory" "both")
15439    (set_attr "mode" "DI")])
15440
15441 (define_insn "*strmovsi_1"
15442   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15443         (mem:SI (match_operand:P 3 "register_operand" "1")))
15444    (set (match_operand:P 0 "register_operand" "=D")
15445         (plus:P (match_dup 2)
15446                 (const_int 4)))
15447    (set (match_operand:P 1 "register_operand" "=S")
15448         (plus:P (match_dup 3)
15449                 (const_int 4)))]
15450   ""
15451   "movs{l|d}"
15452   [(set_attr "type" "str")
15453    (set_attr "memory" "both")
15454    (set_attr "mode" "SI")])
15455
15456 (define_insn "*strmovhi_1"
15457   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15458         (mem:HI (match_operand:P 3 "register_operand" "1")))
15459    (set (match_operand:P 0 "register_operand" "=D")
15460         (plus:P (match_dup 2)
15461                 (const_int 2)))
15462    (set (match_operand:P 1 "register_operand" "=S")
15463         (plus:P (match_dup 3)
15464                 (const_int 2)))]
15465   ""
15466   "movsw"
15467   [(set_attr "type" "str")
15468    (set_attr "memory" "both")
15469    (set_attr "mode" "HI")])
15470
15471 (define_insn "*strmovqi_1"
15472   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15473         (mem:QI (match_operand:P 3 "register_operand" "1")))
15474    (set (match_operand:P 0 "register_operand" "=D")
15475         (plus:P (match_dup 2)
15476                 (const_int 1)))
15477    (set (match_operand:P 1 "register_operand" "=S")
15478         (plus:P (match_dup 3)
15479                 (const_int 1)))]
15480   ""
15481   "movsb"
15482   [(set_attr "type" "str")
15483    (set_attr "memory" "both")
15484    (set (attr "prefix_rex")
15485         (if_then_else
15486           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15487           (const_string "0")
15488           (const_string "*")))
15489    (set_attr "mode" "QI")])
15490
15491 (define_expand "rep_mov"
15492   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15493               (set (match_operand 0 "register_operand" "")
15494                    (match_operand 5 "" ""))
15495               (set (match_operand 2 "register_operand" "")
15496                    (match_operand 6 "" ""))
15497               (set (match_operand 1 "memory_operand" "")
15498                    (match_operand 3 "memory_operand" ""))
15499               (use (match_dup 4))])]
15500   ""
15501   "ix86_current_function_needs_cld = 1;")
15502
15503 (define_insn "*rep_movdi_rex64"
15504   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15505    (set (match_operand:DI 0 "register_operand" "=D")
15506         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15507                             (const_int 3))
15508                  (match_operand:DI 3 "register_operand" "0")))
15509    (set (match_operand:DI 1 "register_operand" "=S")
15510         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15511                  (match_operand:DI 4 "register_operand" "1")))
15512    (set (mem:BLK (match_dup 3))
15513         (mem:BLK (match_dup 4)))
15514    (use (match_dup 5))]
15515   "TARGET_64BIT"
15516   "rep{%;} movsq"
15517   [(set_attr "type" "str")
15518    (set_attr "prefix_rep" "1")
15519    (set_attr "memory" "both")
15520    (set_attr "mode" "DI")])
15521
15522 (define_insn "*rep_movsi"
15523   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15524    (set (match_operand:P 0 "register_operand" "=D")
15525         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15526                           (const_int 2))
15527                  (match_operand:P 3 "register_operand" "0")))
15528    (set (match_operand:P 1 "register_operand" "=S")
15529         (plus:P (ashift:P (match_dup 5) (const_int 2))
15530                 (match_operand:P 4 "register_operand" "1")))
15531    (set (mem:BLK (match_dup 3))
15532         (mem:BLK (match_dup 4)))
15533    (use (match_dup 5))]
15534   ""
15535   "rep{%;} movs{l|d}"
15536   [(set_attr "type" "str")
15537    (set_attr "prefix_rep" "1")
15538    (set_attr "memory" "both")
15539    (set_attr "mode" "SI")])
15540
15541 (define_insn "*rep_movqi"
15542   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15543    (set (match_operand:P 0 "register_operand" "=D")
15544         (plus:P (match_operand:P 3 "register_operand" "0")
15545                 (match_operand:P 5 "register_operand" "2")))
15546    (set (match_operand:P 1 "register_operand" "=S")
15547         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15548    (set (mem:BLK (match_dup 3))
15549         (mem:BLK (match_dup 4)))
15550    (use (match_dup 5))]
15551   ""
15552   "rep{%;} movsb"
15553   [(set_attr "type" "str")
15554    (set_attr "prefix_rep" "1")
15555    (set_attr "memory" "both")
15556    (set_attr "mode" "QI")])
15557
15558 (define_expand "setmem<mode>"
15559    [(use (match_operand:BLK 0 "memory_operand" ""))
15560     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15561     (use (match_operand:QI 2 "nonmemory_operand" ""))
15562     (use (match_operand 3 "const_int_operand" ""))
15563     (use (match_operand:SI 4 "const_int_operand" ""))
15564     (use (match_operand:SI 5 "const_int_operand" ""))]
15565   ""
15566 {
15567  if (ix86_expand_setmem (operands[0], operands[1],
15568                          operands[2], operands[3],
15569                          operands[4], operands[5]))
15570    DONE;
15571  else
15572    FAIL;
15573 })
15574
15575 ;; Most CPUs don't like single string operations
15576 ;; Handle this case here to simplify previous expander.
15577
15578 (define_expand "strset"
15579   [(set (match_operand 1 "memory_operand" "")
15580         (match_operand 2 "register_operand" ""))
15581    (parallel [(set (match_operand 0 "register_operand" "")
15582                    (match_dup 3))
15583               (clobber (reg:CC FLAGS_REG))])]
15584   ""
15585 {
15586   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15587     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15588
15589   /* If .md ever supports :P for Pmode, this can be directly
15590      in the pattern above.  */
15591   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15592                               GEN_INT (GET_MODE_SIZE (GET_MODE
15593                                                       (operands[2]))));
15594   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15595     {
15596       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15597                                       operands[3]));
15598       DONE;
15599     }
15600 })
15601
15602 (define_expand "strset_singleop"
15603   [(parallel [(set (match_operand 1 "memory_operand" "")
15604                    (match_operand 2 "register_operand" ""))
15605               (set (match_operand 0 "register_operand" "")
15606                    (match_operand 3 "" ""))])]
15607   ""
15608   "ix86_current_function_needs_cld = 1;")
15609
15610 (define_insn "*strsetdi_rex_1"
15611   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15612         (match_operand:DI 2 "register_operand" "a"))
15613    (set (match_operand:DI 0 "register_operand" "=D")
15614         (plus:DI (match_dup 1)
15615                  (const_int 8)))]
15616   "TARGET_64BIT"
15617   "stosq"
15618   [(set_attr "type" "str")
15619    (set_attr "memory" "store")
15620    (set_attr "mode" "DI")])
15621
15622 (define_insn "*strsetsi_1"
15623   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15624         (match_operand:SI 2 "register_operand" "a"))
15625    (set (match_operand:P 0 "register_operand" "=D")
15626         (plus:P (match_dup 1)
15627                 (const_int 4)))]
15628   ""
15629   "stos{l|d}"
15630   [(set_attr "type" "str")
15631    (set_attr "memory" "store")
15632    (set_attr "mode" "SI")])
15633
15634 (define_insn "*strsethi_1"
15635   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15636         (match_operand:HI 2 "register_operand" "a"))
15637    (set (match_operand:P 0 "register_operand" "=D")
15638         (plus:P (match_dup 1)
15639                 (const_int 2)))]
15640   ""
15641   "stosw"
15642   [(set_attr "type" "str")
15643    (set_attr "memory" "store")
15644    (set_attr "mode" "HI")])
15645
15646 (define_insn "*strsetqi_1"
15647   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15648         (match_operand:QI 2 "register_operand" "a"))
15649    (set (match_operand:P 0 "register_operand" "=D")
15650         (plus:P (match_dup 1)
15651                 (const_int 1)))]
15652   ""
15653   "stosb"
15654   [(set_attr "type" "str")
15655    (set_attr "memory" "store")
15656    (set (attr "prefix_rex")
15657         (if_then_else
15658           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15659           (const_string "0")
15660           (const_string "*")))
15661    (set_attr "mode" "QI")])
15662
15663 (define_expand "rep_stos"
15664   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15665               (set (match_operand 0 "register_operand" "")
15666                    (match_operand 4 "" ""))
15667               (set (match_operand 2 "memory_operand" "") (const_int 0))
15668               (use (match_operand 3 "register_operand" ""))
15669               (use (match_dup 1))])]
15670   ""
15671   "ix86_current_function_needs_cld = 1;")
15672
15673 (define_insn "*rep_stosdi_rex64"
15674   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15675    (set (match_operand:DI 0 "register_operand" "=D")
15676         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15677                             (const_int 3))
15678                  (match_operand:DI 3 "register_operand" "0")))
15679    (set (mem:BLK (match_dup 3))
15680         (const_int 0))
15681    (use (match_operand:DI 2 "register_operand" "a"))
15682    (use (match_dup 4))]
15683   "TARGET_64BIT"
15684   "rep{%;} stosq"
15685   [(set_attr "type" "str")
15686    (set_attr "prefix_rep" "1")
15687    (set_attr "memory" "store")
15688    (set_attr "mode" "DI")])
15689
15690 (define_insn "*rep_stossi"
15691   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15692    (set (match_operand:P 0 "register_operand" "=D")
15693         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15694                           (const_int 2))
15695                  (match_operand:P 3 "register_operand" "0")))
15696    (set (mem:BLK (match_dup 3))
15697         (const_int 0))
15698    (use (match_operand:SI 2 "register_operand" "a"))
15699    (use (match_dup 4))]
15700   ""
15701   "rep{%;} stos{l|d}"
15702   [(set_attr "type" "str")
15703    (set_attr "prefix_rep" "1")
15704    (set_attr "memory" "store")
15705    (set_attr "mode" "SI")])
15706
15707 (define_insn "*rep_stosqi"
15708   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15709    (set (match_operand:P 0 "register_operand" "=D")
15710         (plus:P (match_operand:P 3 "register_operand" "0")
15711                 (match_operand:P 4 "register_operand" "1")))
15712    (set (mem:BLK (match_dup 3))
15713         (const_int 0))
15714    (use (match_operand:QI 2 "register_operand" "a"))
15715    (use (match_dup 4))]
15716   ""
15717   "rep{%;} stosb"
15718   [(set_attr "type" "str")
15719    (set_attr "prefix_rep" "1")
15720    (set_attr "memory" "store")
15721    (set (attr "prefix_rex")
15722         (if_then_else
15723           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15724           (const_string "0")
15725           (const_string "*")))
15726    (set_attr "mode" "QI")])
15727
15728 (define_expand "cmpstrnsi"
15729   [(set (match_operand:SI 0 "register_operand" "")
15730         (compare:SI (match_operand:BLK 1 "general_operand" "")
15731                     (match_operand:BLK 2 "general_operand" "")))
15732    (use (match_operand 3 "general_operand" ""))
15733    (use (match_operand 4 "immediate_operand" ""))]
15734   ""
15735 {
15736   rtx addr1, addr2, out, outlow, count, countreg, align;
15737
15738   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15739     FAIL;
15740
15741   /* Can't use this if the user has appropriated esi or edi.  */
15742   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15743     FAIL;
15744
15745   out = operands[0];
15746   if (!REG_P (out))
15747     out = gen_reg_rtx (SImode);
15748
15749   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15750   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15751   if (addr1 != XEXP (operands[1], 0))
15752     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15753   if (addr2 != XEXP (operands[2], 0))
15754     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15755
15756   count = operands[3];
15757   countreg = ix86_zero_extend_to_Pmode (count);
15758
15759   /* %%% Iff we are testing strict equality, we can use known alignment
15760      to good advantage.  This may be possible with combine, particularly
15761      once cc0 is dead.  */
15762   align = operands[4];
15763
15764   if (CONST_INT_P (count))
15765     {
15766       if (INTVAL (count) == 0)
15767         {
15768           emit_move_insn (operands[0], const0_rtx);
15769           DONE;
15770         }
15771       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15772                                      operands[1], operands[2]));
15773     }
15774   else
15775     {
15776       rtx (*gen_cmp) (rtx, rtx);
15777
15778       gen_cmp = (TARGET_64BIT
15779                  ? gen_cmpdi_1 : gen_cmpsi_1);
15780
15781       emit_insn (gen_cmp (countreg, countreg));
15782       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15783                                   operands[1], operands[2]));
15784     }
15785
15786   outlow = gen_lowpart (QImode, out);
15787   emit_insn (gen_cmpintqi (outlow));
15788   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15789
15790   if (operands[0] != out)
15791     emit_move_insn (operands[0], out);
15792
15793   DONE;
15794 })
15795
15796 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15797
15798 (define_expand "cmpintqi"
15799   [(set (match_dup 1)
15800         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15801    (set (match_dup 2)
15802         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15803    (parallel [(set (match_operand:QI 0 "register_operand" "")
15804                    (minus:QI (match_dup 1)
15805                              (match_dup 2)))
15806               (clobber (reg:CC FLAGS_REG))])]
15807   ""
15808 {
15809   operands[1] = gen_reg_rtx (QImode);
15810   operands[2] = gen_reg_rtx (QImode);
15811 })
15812
15813 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15814 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15815
15816 (define_expand "cmpstrnqi_nz_1"
15817   [(parallel [(set (reg:CC FLAGS_REG)
15818                    (compare:CC (match_operand 4 "memory_operand" "")
15819                                (match_operand 5 "memory_operand" "")))
15820               (use (match_operand 2 "register_operand" ""))
15821               (use (match_operand:SI 3 "immediate_operand" ""))
15822               (clobber (match_operand 0 "register_operand" ""))
15823               (clobber (match_operand 1 "register_operand" ""))
15824               (clobber (match_dup 2))])]
15825   ""
15826   "ix86_current_function_needs_cld = 1;")
15827
15828 (define_insn "*cmpstrnqi_nz_1"
15829   [(set (reg:CC FLAGS_REG)
15830         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15831                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15832    (use (match_operand:P 6 "register_operand" "2"))
15833    (use (match_operand:SI 3 "immediate_operand" "i"))
15834    (clobber (match_operand:P 0 "register_operand" "=S"))
15835    (clobber (match_operand:P 1 "register_operand" "=D"))
15836    (clobber (match_operand:P 2 "register_operand" "=c"))]
15837   ""
15838   "repz{%;} cmpsb"
15839   [(set_attr "type" "str")
15840    (set_attr "mode" "QI")
15841    (set (attr "prefix_rex")
15842         (if_then_else
15843           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15844           (const_string "0")
15845           (const_string "*")))
15846    (set_attr "prefix_rep" "1")])
15847
15848 ;; The same, but the count is not known to not be zero.
15849
15850 (define_expand "cmpstrnqi_1"
15851   [(parallel [(set (reg:CC FLAGS_REG)
15852                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15853                                      (const_int 0))
15854                   (compare:CC (match_operand 4 "memory_operand" "")
15855                               (match_operand 5 "memory_operand" ""))
15856                   (const_int 0)))
15857               (use (match_operand:SI 3 "immediate_operand" ""))
15858               (use (reg:CC FLAGS_REG))
15859               (clobber (match_operand 0 "register_operand" ""))
15860               (clobber (match_operand 1 "register_operand" ""))
15861               (clobber (match_dup 2))])]
15862   ""
15863   "ix86_current_function_needs_cld = 1;")
15864
15865 (define_insn "*cmpstrnqi_1"
15866   [(set (reg:CC FLAGS_REG)
15867         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15868                              (const_int 0))
15869           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15870                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15871           (const_int 0)))
15872    (use (match_operand:SI 3 "immediate_operand" "i"))
15873    (use (reg:CC FLAGS_REG))
15874    (clobber (match_operand:P 0 "register_operand" "=S"))
15875    (clobber (match_operand:P 1 "register_operand" "=D"))
15876    (clobber (match_operand:P 2 "register_operand" "=c"))]
15877   ""
15878   "repz{%;} cmpsb"
15879   [(set_attr "type" "str")
15880    (set_attr "mode" "QI")
15881    (set (attr "prefix_rex")
15882         (if_then_else
15883           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15884           (const_string "0")
15885           (const_string "*")))
15886    (set_attr "prefix_rep" "1")])
15887
15888 (define_expand "strlen<mode>"
15889   [(set (match_operand:SWI48x 0 "register_operand" "")
15890         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15891                         (match_operand:QI 2 "immediate_operand" "")
15892                         (match_operand 3 "immediate_operand" "")]
15893                        UNSPEC_SCAS))]
15894   ""
15895 {
15896  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15897    DONE;
15898  else
15899    FAIL;
15900 })
15901
15902 (define_expand "strlenqi_1"
15903   [(parallel [(set (match_operand 0 "register_operand" "")
15904                    (match_operand 2 "" ""))
15905               (clobber (match_operand 1 "register_operand" ""))
15906               (clobber (reg:CC FLAGS_REG))])]
15907   ""
15908   "ix86_current_function_needs_cld = 1;")
15909
15910 (define_insn "*strlenqi_1"
15911   [(set (match_operand:P 0 "register_operand" "=&c")
15912         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15913                    (match_operand:QI 2 "register_operand" "a")
15914                    (match_operand:P 3 "immediate_operand" "i")
15915                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15916    (clobber (match_operand:P 1 "register_operand" "=D"))
15917    (clobber (reg:CC FLAGS_REG))]
15918   ""
15919   "repnz{%;} scasb"
15920   [(set_attr "type" "str")
15921    (set_attr "mode" "QI")
15922    (set (attr "prefix_rex")
15923         (if_then_else
15924           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15925           (const_string "0")
15926           (const_string "*")))
15927    (set_attr "prefix_rep" "1")])
15928
15929 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15930 ;; handled in combine, but it is not currently up to the task.
15931 ;; When used for their truth value, the cmpstrn* expanders generate
15932 ;; code like this:
15933 ;;
15934 ;;   repz cmpsb
15935 ;;   seta       %al
15936 ;;   setb       %dl
15937 ;;   cmpb       %al, %dl
15938 ;;   jcc        label
15939 ;;
15940 ;; The intermediate three instructions are unnecessary.
15941
15942 ;; This one handles cmpstrn*_nz_1...
15943 (define_peephole2
15944   [(parallel[
15945      (set (reg:CC FLAGS_REG)
15946           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15947                       (mem:BLK (match_operand 5 "register_operand" ""))))
15948      (use (match_operand 6 "register_operand" ""))
15949      (use (match_operand:SI 3 "immediate_operand" ""))
15950      (clobber (match_operand 0 "register_operand" ""))
15951      (clobber (match_operand 1 "register_operand" ""))
15952      (clobber (match_operand 2 "register_operand" ""))])
15953    (set (match_operand:QI 7 "register_operand" "")
15954         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15955    (set (match_operand:QI 8 "register_operand" "")
15956         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15957    (set (reg FLAGS_REG)
15958         (compare (match_dup 7) (match_dup 8)))
15959   ]
15960   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15961   [(parallel[
15962      (set (reg:CC FLAGS_REG)
15963           (compare:CC (mem:BLK (match_dup 4))
15964                       (mem:BLK (match_dup 5))))
15965      (use (match_dup 6))
15966      (use (match_dup 3))
15967      (clobber (match_dup 0))
15968      (clobber (match_dup 1))
15969      (clobber (match_dup 2))])])
15970
15971 ;; ...and this one handles cmpstrn*_1.
15972 (define_peephole2
15973   [(parallel[
15974      (set (reg:CC FLAGS_REG)
15975           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15976                                (const_int 0))
15977             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15978                         (mem:BLK (match_operand 5 "register_operand" "")))
15979             (const_int 0)))
15980      (use (match_operand:SI 3 "immediate_operand" ""))
15981      (use (reg:CC FLAGS_REG))
15982      (clobber (match_operand 0 "register_operand" ""))
15983      (clobber (match_operand 1 "register_operand" ""))
15984      (clobber (match_operand 2 "register_operand" ""))])
15985    (set (match_operand:QI 7 "register_operand" "")
15986         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15987    (set (match_operand:QI 8 "register_operand" "")
15988         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15989    (set (reg FLAGS_REG)
15990         (compare (match_dup 7) (match_dup 8)))
15991   ]
15992   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15993   [(parallel[
15994      (set (reg:CC FLAGS_REG)
15995           (if_then_else:CC (ne (match_dup 6)
15996                                (const_int 0))
15997             (compare:CC (mem:BLK (match_dup 4))
15998                         (mem:BLK (match_dup 5)))
15999             (const_int 0)))
16000      (use (match_dup 3))
16001      (use (reg:CC FLAGS_REG))
16002      (clobber (match_dup 0))
16003      (clobber (match_dup 1))
16004      (clobber (match_dup 2))])])
16005 \f
16006 ;; Conditional move instructions.
16007
16008 (define_expand "mov<mode>cc"
16009   [(set (match_operand:SWIM 0 "register_operand" "")
16010         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16011                            (match_operand:SWIM 2 "general_operand" "")
16012                            (match_operand:SWIM 3 "general_operand" "")))]
16013   ""
16014   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16015
16016 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16017 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16018 ;; So just document what we're doing explicitly.
16019
16020 (define_expand "x86_mov<mode>cc_0_m1"
16021   [(parallel
16022     [(set (match_operand:SWI48 0 "register_operand" "")
16023           (if_then_else:SWI48
16024             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16025              [(match_operand 1 "flags_reg_operand" "")
16026               (const_int 0)])
16027             (const_int -1)
16028             (const_int 0)))
16029      (clobber (reg:CC FLAGS_REG))])])
16030
16031 (define_insn "*x86_mov<mode>cc_0_m1"
16032   [(set (match_operand:SWI48 0 "register_operand" "=r")
16033         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16034                              [(reg FLAGS_REG) (const_int 0)])
16035           (const_int -1)
16036           (const_int 0)))
16037    (clobber (reg:CC FLAGS_REG))]
16038   ""
16039   "sbb{<imodesuffix>}\t%0, %0"
16040   ; Since we don't have the proper number of operands for an alu insn,
16041   ; fill in all the blanks.
16042   [(set_attr "type" "alu")
16043    (set_attr "use_carry" "1")
16044    (set_attr "pent_pair" "pu")
16045    (set_attr "memory" "none")
16046    (set_attr "imm_disp" "false")
16047    (set_attr "mode" "<MODE>")
16048    (set_attr "length_immediate" "0")])
16049
16050 (define_insn "*x86_mov<mode>cc_0_m1_se"
16051   [(set (match_operand:SWI48 0 "register_operand" "=r")
16052         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16053                              [(reg FLAGS_REG) (const_int 0)])
16054                             (const_int 1)
16055                             (const_int 0)))
16056    (clobber (reg:CC FLAGS_REG))]
16057   ""
16058   "sbb{<imodesuffix>}\t%0, %0"
16059   [(set_attr "type" "alu")
16060    (set_attr "use_carry" "1")
16061    (set_attr "pent_pair" "pu")
16062    (set_attr "memory" "none")
16063    (set_attr "imm_disp" "false")
16064    (set_attr "mode" "<MODE>")
16065    (set_attr "length_immediate" "0")])
16066
16067 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16068   [(set (match_operand:SWI48 0 "register_operand" "=r")
16069         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16070                     [(reg FLAGS_REG) (const_int 0)])))]
16071   ""
16072   "sbb{<imodesuffix>}\t%0, %0"
16073   [(set_attr "type" "alu")
16074    (set_attr "use_carry" "1")
16075    (set_attr "pent_pair" "pu")
16076    (set_attr "memory" "none")
16077    (set_attr "imm_disp" "false")
16078    (set_attr "mode" "<MODE>")
16079    (set_attr "length_immediate" "0")])
16080
16081 (define_insn "*mov<mode>cc_noc"
16082   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16083         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16084                                [(reg FLAGS_REG) (const_int 0)])
16085           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16086           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16087   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16088   "@
16089    cmov%O2%C1\t{%2, %0|%0, %2}
16090    cmov%O2%c1\t{%3, %0|%0, %3}"
16091   [(set_attr "type" "icmov")
16092    (set_attr "mode" "<MODE>")])
16093
16094 (define_insn_and_split "*movqicc_noc"
16095   [(set (match_operand:QI 0 "register_operand" "=r,r")
16096         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16097                            [(match_operand 4 "flags_reg_operand" "")
16098                             (const_int 0)])
16099                       (match_operand:QI 2 "register_operand" "r,0")
16100                       (match_operand:QI 3 "register_operand" "0,r")))]
16101   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16102   "#"
16103   "&& reload_completed"
16104   [(set (match_dup 0)
16105         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16106                       (match_dup 2)
16107                       (match_dup 3)))]
16108   "operands[0] = gen_lowpart (SImode, operands[0]);
16109    operands[2] = gen_lowpart (SImode, operands[2]);
16110    operands[3] = gen_lowpart (SImode, operands[3]);"
16111   [(set_attr "type" "icmov")
16112    (set_attr "mode" "SI")])
16113
16114 (define_expand "mov<mode>cc"
16115   [(set (match_operand:X87MODEF 0 "register_operand" "")
16116         (if_then_else:X87MODEF
16117           (match_operand 1 "ix86_fp_comparison_operator" "")
16118           (match_operand:X87MODEF 2 "register_operand" "")
16119           (match_operand:X87MODEF 3 "register_operand" "")))]
16120   "(TARGET_80387 && TARGET_CMOVE)
16121    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16122   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16123
16124 (define_insn "*movxfcc_1"
16125   [(set (match_operand:XF 0 "register_operand" "=f,f")
16126         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16127                                 [(reg FLAGS_REG) (const_int 0)])
16128                       (match_operand:XF 2 "register_operand" "f,0")
16129                       (match_operand:XF 3 "register_operand" "0,f")))]
16130   "TARGET_80387 && TARGET_CMOVE"
16131   "@
16132    fcmov%F1\t{%2, %0|%0, %2}
16133    fcmov%f1\t{%3, %0|%0, %3}"
16134   [(set_attr "type" "fcmov")
16135    (set_attr "mode" "XF")])
16136
16137 (define_insn "*movdfcc_1_rex64"
16138   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16139         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16140                                 [(reg FLAGS_REG) (const_int 0)])
16141                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16142                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16143   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16144    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16145   "@
16146    fcmov%F1\t{%2, %0|%0, %2}
16147    fcmov%f1\t{%3, %0|%0, %3}
16148    cmov%O2%C1\t{%2, %0|%0, %2}
16149    cmov%O2%c1\t{%3, %0|%0, %3}"
16150   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16151    (set_attr "mode" "DF,DF,DI,DI")])
16152
16153 (define_insn "*movdfcc_1"
16154   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16155         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16156                                 [(reg FLAGS_REG) (const_int 0)])
16157                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16158                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16159   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16160    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16161   "@
16162    fcmov%F1\t{%2, %0|%0, %2}
16163    fcmov%f1\t{%3, %0|%0, %3}
16164    #
16165    #"
16166   [(set_attr "type" "fcmov,fcmov,multi,multi")
16167    (set_attr "mode" "DF,DF,DI,DI")])
16168
16169 (define_split
16170   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16171         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16172                                 [(match_operand 4 "flags_reg_operand" "")
16173                                  (const_int 0)])
16174                       (match_operand:DF 2 "nonimmediate_operand" "")
16175                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16176   "!TARGET_64BIT && reload_completed"
16177   [(set (match_dup 2)
16178         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16179                       (match_dup 5)
16180                       (match_dup 6)))
16181    (set (match_dup 3)
16182         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16183                       (match_dup 7)
16184                       (match_dup 8)))]
16185 {
16186   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16187   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16188 })
16189
16190 (define_insn "*movsfcc_1_387"
16191   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16192         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16193                                 [(reg FLAGS_REG) (const_int 0)])
16194                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16195                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16196   "TARGET_80387 && TARGET_CMOVE
16197    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16198   "@
16199    fcmov%F1\t{%2, %0|%0, %2}
16200    fcmov%f1\t{%3, %0|%0, %3}
16201    cmov%O2%C1\t{%2, %0|%0, %2}
16202    cmov%O2%c1\t{%3, %0|%0, %3}"
16203   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16204    (set_attr "mode" "SF,SF,SI,SI")])
16205
16206 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16207 ;; the scalar versions to have only XMM registers as operands.
16208
16209 ;; XOP conditional move
16210 (define_insn "*xop_pcmov_<mode>"
16211   [(set (match_operand:MODEF 0 "register_operand" "=x")
16212         (if_then_else:MODEF
16213           (match_operand:MODEF 1 "register_operand" "x")
16214           (match_operand:MODEF 2 "register_operand" "x")
16215           (match_operand:MODEF 3 "register_operand" "x")))]
16216   "TARGET_XOP"
16217   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16218   [(set_attr "type" "sse4arg")])
16219
16220 ;; These versions of the min/max patterns are intentionally ignorant of
16221 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16222 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16223 ;; are undefined in this condition, we're certain this is correct.
16224
16225 (define_insn "<code><mode>3"
16226   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16227         (smaxmin:MODEF
16228           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16229           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16230   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16231   "@
16232    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16233    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16234   [(set_attr "isa" "noavx,avx")
16235    (set_attr "prefix" "orig,vex")
16236    (set_attr "type" "sseadd")
16237    (set_attr "mode" "<MODE>")])
16238
16239 ;; These versions of the min/max patterns implement exactly the operations
16240 ;;   min = (op1 < op2 ? op1 : op2)
16241 ;;   max = (!(op1 < op2) ? op1 : op2)
16242 ;; Their operands are not commutative, and thus they may be used in the
16243 ;; presence of -0.0 and NaN.
16244
16245 (define_insn "*ieee_smin<mode>3"
16246   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16247         (unspec:MODEF
16248           [(match_operand:MODEF 1 "register_operand" "0,x")
16249            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16250          UNSPEC_IEEE_MIN))]
16251   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16252   "@
16253    min<ssemodesuffix>\t{%2, %0|%0, %2}
16254    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16255   [(set_attr "isa" "noavx,avx")
16256    (set_attr "prefix" "orig,vex")
16257    (set_attr "type" "sseadd")
16258    (set_attr "mode" "<MODE>")])
16259
16260 (define_insn "*ieee_smax<mode>3"
16261   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16262         (unspec:MODEF
16263           [(match_operand:MODEF 1 "register_operand" "0,x")
16264            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16265          UNSPEC_IEEE_MAX))]
16266   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16267   "@
16268    max<ssemodesuffix>\t{%2, %0|%0, %2}
16269    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16270   [(set_attr "isa" "noavx,avx")
16271    (set_attr "prefix" "orig,vex")
16272    (set_attr "type" "sseadd")
16273    (set_attr "mode" "<MODE>")])
16274
16275 ;; Make two stack loads independent:
16276 ;;   fld aa              fld aa
16277 ;;   fld %st(0)     ->   fld bb
16278 ;;   fmul bb             fmul %st(1), %st
16279 ;;
16280 ;; Actually we only match the last two instructions for simplicity.
16281 (define_peephole2
16282   [(set (match_operand 0 "fp_register_operand" "")
16283         (match_operand 1 "fp_register_operand" ""))
16284    (set (match_dup 0)
16285         (match_operator 2 "binary_fp_operator"
16286            [(match_dup 0)
16287             (match_operand 3 "memory_operand" "")]))]
16288   "REGNO (operands[0]) != REGNO (operands[1])"
16289   [(set (match_dup 0) (match_dup 3))
16290    (set (match_dup 0) (match_dup 4))]
16291
16292   ;; The % modifier is not operational anymore in peephole2's, so we have to
16293   ;; swap the operands manually in the case of addition and multiplication.
16294   "if (COMMUTATIVE_ARITH_P (operands[2]))
16295      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16296                                    GET_MODE (operands[2]),
16297                                    operands[0], operands[1]);
16298    else
16299      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16300                                    GET_MODE (operands[2]),
16301                                    operands[1], operands[0]);")
16302
16303 ;; Conditional addition patterns
16304 (define_expand "add<mode>cc"
16305   [(match_operand:SWI 0 "register_operand" "")
16306    (match_operand 1 "ordered_comparison_operator" "")
16307    (match_operand:SWI 2 "register_operand" "")
16308    (match_operand:SWI 3 "const_int_operand" "")]
16309   ""
16310   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16311 \f
16312 ;; Misc patterns (?)
16313
16314 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16315 ;; Otherwise there will be nothing to keep
16316 ;;
16317 ;; [(set (reg ebp) (reg esp))]
16318 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16319 ;;  (clobber (eflags)]
16320 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16321 ;;
16322 ;; in proper program order.
16323
16324 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16325   [(set (match_operand:P 0 "register_operand" "=r,r")
16326         (plus:P (match_operand:P 1 "register_operand" "0,r")
16327                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16328    (clobber (reg:CC FLAGS_REG))
16329    (clobber (mem:BLK (scratch)))]
16330   ""
16331 {
16332   switch (get_attr_type (insn))
16333     {
16334     case TYPE_IMOV:
16335       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16336
16337     case TYPE_ALU:
16338       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16339       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16340         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16341
16342       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16343
16344     default:
16345       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16346       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16347     }
16348 }
16349   [(set (attr "type")
16350         (cond [(and (eq_attr "alternative" "0")
16351                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16352                  (const_string "alu")
16353                (match_operand:<MODE> 2 "const0_operand" "")
16354                  (const_string "imov")
16355               ]
16356               (const_string "lea")))
16357    (set (attr "length_immediate")
16358         (cond [(eq_attr "type" "imov")
16359                  (const_string "0")
16360                (and (eq_attr "type" "alu")
16361                     (match_operand 2 "const128_operand" ""))
16362                  (const_string "1")
16363               ]
16364               (const_string "*")))
16365    (set_attr "mode" "<MODE>")])
16366
16367 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16368   [(set (match_operand:P 0 "register_operand" "=r")
16369         (minus:P (match_operand:P 1 "register_operand" "0")
16370                  (match_operand:P 2 "register_operand" "r")))
16371    (clobber (reg:CC FLAGS_REG))
16372    (clobber (mem:BLK (scratch)))]
16373   ""
16374   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16375   [(set_attr "type" "alu")
16376    (set_attr "mode" "<MODE>")])
16377
16378 (define_insn "allocate_stack_worker_probe_<mode>"
16379   [(set (match_operand:P 0 "register_operand" "=a")
16380         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16381                             UNSPECV_STACK_PROBE))
16382    (clobber (reg:CC FLAGS_REG))]
16383   "ix86_target_stack_probe ()"
16384   "call\t___chkstk_ms"
16385   [(set_attr "type" "multi")
16386    (set_attr "length" "5")])
16387
16388 (define_expand "allocate_stack"
16389   [(match_operand 0 "register_operand" "")
16390    (match_operand 1 "general_operand" "")]
16391   "ix86_target_stack_probe ()"
16392 {
16393   rtx x;
16394
16395 #ifndef CHECK_STACK_LIMIT
16396 #define CHECK_STACK_LIMIT 0
16397 #endif
16398
16399   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16400       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16401     {
16402       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16403                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16404       if (x != stack_pointer_rtx)
16405         emit_move_insn (stack_pointer_rtx, x);
16406     }
16407   else
16408     {
16409       x = copy_to_mode_reg (Pmode, operands[1]);
16410       if (TARGET_64BIT)
16411         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16412       else
16413         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16414       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16415                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16416       if (x != stack_pointer_rtx)
16417         emit_move_insn (stack_pointer_rtx, x);
16418     }
16419
16420   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16421   DONE;
16422 })
16423
16424 ;; Use IOR for stack probes, this is shorter.
16425 (define_expand "probe_stack"
16426   [(match_operand 0 "memory_operand" "")]
16427   ""
16428 {
16429   rtx (*gen_ior3) (rtx, rtx, rtx);
16430
16431   gen_ior3 = (GET_MODE (operands[0]) == DImode
16432               ? gen_iordi3 : gen_iorsi3);
16433
16434   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16435   DONE;
16436 })
16437
16438 (define_insn "adjust_stack_and_probe<mode>"
16439   [(set (match_operand:P 0 "register_operand" "=r")
16440         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16441                             UNSPECV_PROBE_STACK_RANGE))
16442    (set (reg:P SP_REG)
16443         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16444    (clobber (reg:CC FLAGS_REG))
16445    (clobber (mem:BLK (scratch)))]
16446   ""
16447   "* return output_adjust_stack_and_probe (operands[0]);"
16448   [(set_attr "type" "multi")])
16449
16450 (define_insn "probe_stack_range<mode>"
16451   [(set (match_operand:P 0 "register_operand" "=r")
16452         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16453                             (match_operand:P 2 "const_int_operand" "n")]
16454                             UNSPECV_PROBE_STACK_RANGE))
16455    (clobber (reg:CC FLAGS_REG))]
16456   ""
16457   "* return output_probe_stack_range (operands[0], operands[2]);"
16458   [(set_attr "type" "multi")])
16459
16460 (define_expand "builtin_setjmp_receiver"
16461   [(label_ref (match_operand 0 "" ""))]
16462   "!TARGET_64BIT && flag_pic"
16463 {
16464 #if TARGET_MACHO
16465   if (TARGET_MACHO)
16466     {
16467       rtx xops[3];
16468       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16469       rtx label_rtx = gen_label_rtx ();
16470       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16471       xops[0] = xops[1] = picreg;
16472       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16473       ix86_expand_binary_operator (MINUS, SImode, xops);
16474     }
16475   else
16476 #endif
16477     emit_insn (gen_set_got (pic_offset_table_rtx));
16478   DONE;
16479 })
16480 \f
16481 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16482
16483 (define_split
16484   [(set (match_operand 0 "register_operand" "")
16485         (match_operator 3 "promotable_binary_operator"
16486            [(match_operand 1 "register_operand" "")
16487             (match_operand 2 "aligned_operand" "")]))
16488    (clobber (reg:CC FLAGS_REG))]
16489   "! TARGET_PARTIAL_REG_STALL && reload_completed
16490    && ((GET_MODE (operands[0]) == HImode
16491         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16492             /* ??? next two lines just !satisfies_constraint_K (...) */
16493             || !CONST_INT_P (operands[2])
16494             || satisfies_constraint_K (operands[2])))
16495        || (GET_MODE (operands[0]) == QImode
16496            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16497   [(parallel [(set (match_dup 0)
16498                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16499               (clobber (reg:CC FLAGS_REG))])]
16500   "operands[0] = gen_lowpart (SImode, operands[0]);
16501    operands[1] = gen_lowpart (SImode, operands[1]);
16502    if (GET_CODE (operands[3]) != ASHIFT)
16503      operands[2] = gen_lowpart (SImode, operands[2]);
16504    PUT_MODE (operands[3], SImode);")
16505
16506 ; Promote the QImode tests, as i386 has encoding of the AND
16507 ; instruction with 32-bit sign-extended immediate and thus the
16508 ; instruction size is unchanged, except in the %eax case for
16509 ; which it is increased by one byte, hence the ! optimize_size.
16510 (define_split
16511   [(set (match_operand 0 "flags_reg_operand" "")
16512         (match_operator 2 "compare_operator"
16513           [(and (match_operand 3 "aligned_operand" "")
16514                 (match_operand 4 "const_int_operand" ""))
16515            (const_int 0)]))
16516    (set (match_operand 1 "register_operand" "")
16517         (and (match_dup 3) (match_dup 4)))]
16518   "! TARGET_PARTIAL_REG_STALL && reload_completed
16519    && optimize_insn_for_speed_p ()
16520    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16521        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16522    /* Ensure that the operand will remain sign-extended immediate.  */
16523    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16524   [(parallel [(set (match_dup 0)
16525                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16526                                     (const_int 0)]))
16527               (set (match_dup 1)
16528                    (and:SI (match_dup 3) (match_dup 4)))])]
16529 {
16530   operands[4]
16531     = gen_int_mode (INTVAL (operands[4])
16532                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16533   operands[1] = gen_lowpart (SImode, operands[1]);
16534   operands[3] = gen_lowpart (SImode, operands[3]);
16535 })
16536
16537 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16538 ; the TEST instruction with 32-bit sign-extended immediate and thus
16539 ; the instruction size would at least double, which is not what we
16540 ; want even with ! optimize_size.
16541 (define_split
16542   [(set (match_operand 0 "flags_reg_operand" "")
16543         (match_operator 1 "compare_operator"
16544           [(and (match_operand:HI 2 "aligned_operand" "")
16545                 (match_operand:HI 3 "const_int_operand" ""))
16546            (const_int 0)]))]
16547   "! TARGET_PARTIAL_REG_STALL && reload_completed
16548    && ! TARGET_FAST_PREFIX
16549    && optimize_insn_for_speed_p ()
16550    /* Ensure that the operand will remain sign-extended immediate.  */
16551    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16552   [(set (match_dup 0)
16553         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16554                          (const_int 0)]))]
16555 {
16556   operands[3]
16557     = gen_int_mode (INTVAL (operands[3])
16558                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16559   operands[2] = gen_lowpart (SImode, operands[2]);
16560 })
16561
16562 (define_split
16563   [(set (match_operand 0 "register_operand" "")
16564         (neg (match_operand 1 "register_operand" "")))
16565    (clobber (reg:CC FLAGS_REG))]
16566   "! TARGET_PARTIAL_REG_STALL && reload_completed
16567    && (GET_MODE (operands[0]) == HImode
16568        || (GET_MODE (operands[0]) == QImode
16569            && (TARGET_PROMOTE_QImode
16570                || optimize_insn_for_size_p ())))"
16571   [(parallel [(set (match_dup 0)
16572                    (neg:SI (match_dup 1)))
16573               (clobber (reg:CC FLAGS_REG))])]
16574   "operands[0] = gen_lowpart (SImode, operands[0]);
16575    operands[1] = gen_lowpart (SImode, operands[1]);")
16576
16577 (define_split
16578   [(set (match_operand 0 "register_operand" "")
16579         (not (match_operand 1 "register_operand" "")))]
16580   "! TARGET_PARTIAL_REG_STALL && reload_completed
16581    && (GET_MODE (operands[0]) == HImode
16582        || (GET_MODE (operands[0]) == QImode
16583            && (TARGET_PROMOTE_QImode
16584                || optimize_insn_for_size_p ())))"
16585   [(set (match_dup 0)
16586         (not:SI (match_dup 1)))]
16587   "operands[0] = gen_lowpart (SImode, operands[0]);
16588    operands[1] = gen_lowpart (SImode, operands[1]);")
16589
16590 (define_split
16591   [(set (match_operand 0 "register_operand" "")
16592         (if_then_else (match_operator 1 "ordered_comparison_operator"
16593                                 [(reg FLAGS_REG) (const_int 0)])
16594                       (match_operand 2 "register_operand" "")
16595                       (match_operand 3 "register_operand" "")))]
16596   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16597    && (GET_MODE (operands[0]) == HImode
16598        || (GET_MODE (operands[0]) == QImode
16599            && (TARGET_PROMOTE_QImode
16600                || optimize_insn_for_size_p ())))"
16601   [(set (match_dup 0)
16602         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16603   "operands[0] = gen_lowpart (SImode, operands[0]);
16604    operands[2] = gen_lowpart (SImode, operands[2]);
16605    operands[3] = gen_lowpart (SImode, operands[3]);")
16606 \f
16607 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16608 ;; transform a complex memory operation into two memory to register operations.
16609
16610 ;; Don't push memory operands
16611 (define_peephole2
16612   [(set (match_operand:SWI 0 "push_operand" "")
16613         (match_operand:SWI 1 "memory_operand" ""))
16614    (match_scratch:SWI 2 "<r>")]
16615   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16616    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16617   [(set (match_dup 2) (match_dup 1))
16618    (set (match_dup 0) (match_dup 2))])
16619
16620 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16621 ;; SImode pushes.
16622 (define_peephole2
16623   [(set (match_operand:SF 0 "push_operand" "")
16624         (match_operand:SF 1 "memory_operand" ""))
16625    (match_scratch:SF 2 "r")]
16626   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16627    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16628   [(set (match_dup 2) (match_dup 1))
16629    (set (match_dup 0) (match_dup 2))])
16630
16631 ;; Don't move an immediate directly to memory when the instruction
16632 ;; gets too big.
16633 (define_peephole2
16634   [(match_scratch:SWI124 1 "<r>")
16635    (set (match_operand:SWI124 0 "memory_operand" "")
16636         (const_int 0))]
16637   "optimize_insn_for_speed_p ()
16638    && !TARGET_USE_MOV0
16639    && TARGET_SPLIT_LONG_MOVES
16640    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16641    && peep2_regno_dead_p (0, FLAGS_REG)"
16642   [(parallel [(set (match_dup 2) (const_int 0))
16643               (clobber (reg:CC FLAGS_REG))])
16644    (set (match_dup 0) (match_dup 1))]
16645   "operands[2] = gen_lowpart (SImode, operands[1]);")
16646
16647 (define_peephole2
16648   [(match_scratch:SWI124 2 "<r>")
16649    (set (match_operand:SWI124 0 "memory_operand" "")
16650         (match_operand:SWI124 1 "immediate_operand" ""))]
16651   "optimize_insn_for_speed_p ()
16652    && TARGET_SPLIT_LONG_MOVES
16653    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16654   [(set (match_dup 2) (match_dup 1))
16655    (set (match_dup 0) (match_dup 2))])
16656
16657 ;; Don't compare memory with zero, load and use a test instead.
16658 (define_peephole2
16659   [(set (match_operand 0 "flags_reg_operand" "")
16660         (match_operator 1 "compare_operator"
16661           [(match_operand:SI 2 "memory_operand" "")
16662            (const_int 0)]))
16663    (match_scratch:SI 3 "r")]
16664   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16665   [(set (match_dup 3) (match_dup 2))
16666    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16667
16668 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16669 ;; Don't split NOTs with a displacement operand, because resulting XOR
16670 ;; will not be pairable anyway.
16671 ;;
16672 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16673 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16674 ;; so this split helps here as well.
16675 ;;
16676 ;; Note: Can't do this as a regular split because we can't get proper
16677 ;; lifetime information then.
16678
16679 (define_peephole2
16680   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16681         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16682   "optimize_insn_for_speed_p ()
16683    && ((TARGET_NOT_UNPAIRABLE
16684         && (!MEM_P (operands[0])
16685             || !memory_displacement_operand (operands[0], <MODE>mode)))
16686        || (TARGET_NOT_VECTORMODE
16687            && long_memory_operand (operands[0], <MODE>mode)))
16688    && peep2_regno_dead_p (0, FLAGS_REG)"
16689   [(parallel [(set (match_dup 0)
16690                    (xor:SWI124 (match_dup 1) (const_int -1)))
16691               (clobber (reg:CC FLAGS_REG))])])
16692
16693 ;; Non pairable "test imm, reg" instructions can be translated to
16694 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16695 ;; byte opcode instead of two, have a short form for byte operands),
16696 ;; so do it for other CPUs as well.  Given that the value was dead,
16697 ;; this should not create any new dependencies.  Pass on the sub-word
16698 ;; versions if we're concerned about partial register stalls.
16699
16700 (define_peephole2
16701   [(set (match_operand 0 "flags_reg_operand" "")
16702         (match_operator 1 "compare_operator"
16703           [(and:SI (match_operand:SI 2 "register_operand" "")
16704                    (match_operand:SI 3 "immediate_operand" ""))
16705            (const_int 0)]))]
16706   "ix86_match_ccmode (insn, CCNOmode)
16707    && (true_regnum (operands[2]) != AX_REG
16708        || satisfies_constraint_K (operands[3]))
16709    && peep2_reg_dead_p (1, operands[2])"
16710   [(parallel
16711      [(set (match_dup 0)
16712            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16713                             (const_int 0)]))
16714       (set (match_dup 2)
16715            (and:SI (match_dup 2) (match_dup 3)))])])
16716
16717 ;; We don't need to handle HImode case, because it will be promoted to SImode
16718 ;; on ! TARGET_PARTIAL_REG_STALL
16719
16720 (define_peephole2
16721   [(set (match_operand 0 "flags_reg_operand" "")
16722         (match_operator 1 "compare_operator"
16723           [(and:QI (match_operand:QI 2 "register_operand" "")
16724                    (match_operand:QI 3 "immediate_operand" ""))
16725            (const_int 0)]))]
16726   "! TARGET_PARTIAL_REG_STALL
16727    && ix86_match_ccmode (insn, CCNOmode)
16728    && true_regnum (operands[2]) != AX_REG
16729    && peep2_reg_dead_p (1, operands[2])"
16730   [(parallel
16731      [(set (match_dup 0)
16732            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16733                             (const_int 0)]))
16734       (set (match_dup 2)
16735            (and:QI (match_dup 2) (match_dup 3)))])])
16736
16737 (define_peephole2
16738   [(set (match_operand 0 "flags_reg_operand" "")
16739         (match_operator 1 "compare_operator"
16740           [(and:SI
16741              (zero_extract:SI
16742                (match_operand 2 "ext_register_operand" "")
16743                (const_int 8)
16744                (const_int 8))
16745              (match_operand 3 "const_int_operand" ""))
16746            (const_int 0)]))]
16747   "! TARGET_PARTIAL_REG_STALL
16748    && ix86_match_ccmode (insn, CCNOmode)
16749    && true_regnum (operands[2]) != AX_REG
16750    && peep2_reg_dead_p (1, operands[2])"
16751   [(parallel [(set (match_dup 0)
16752                    (match_op_dup 1
16753                      [(and:SI
16754                         (zero_extract:SI
16755                           (match_dup 2)
16756                           (const_int 8)
16757                           (const_int 8))
16758                         (match_dup 3))
16759                       (const_int 0)]))
16760               (set (zero_extract:SI (match_dup 2)
16761                                     (const_int 8)
16762                                     (const_int 8))
16763                    (and:SI
16764                      (zero_extract:SI
16765                        (match_dup 2)
16766                        (const_int 8)
16767                        (const_int 8))
16768                      (match_dup 3)))])])
16769
16770 ;; Don't do logical operations with memory inputs.
16771 (define_peephole2
16772   [(match_scratch:SI 2 "r")
16773    (parallel [(set (match_operand:SI 0 "register_operand" "")
16774                    (match_operator:SI 3 "arith_or_logical_operator"
16775                      [(match_dup 0)
16776                       (match_operand:SI 1 "memory_operand" "")]))
16777               (clobber (reg:CC FLAGS_REG))])]
16778   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16779   [(set (match_dup 2) (match_dup 1))
16780    (parallel [(set (match_dup 0)
16781                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16782               (clobber (reg:CC FLAGS_REG))])])
16783
16784 (define_peephole2
16785   [(match_scratch:SI 2 "r")
16786    (parallel [(set (match_operand:SI 0 "register_operand" "")
16787                    (match_operator:SI 3 "arith_or_logical_operator"
16788                      [(match_operand:SI 1 "memory_operand" "")
16789                       (match_dup 0)]))
16790               (clobber (reg:CC FLAGS_REG))])]
16791   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16792   [(set (match_dup 2) (match_dup 1))
16793    (parallel [(set (match_dup 0)
16794                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16795               (clobber (reg:CC FLAGS_REG))])])
16796
16797 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16798 ;; refers to the destination of the load!
16799
16800 (define_peephole2
16801   [(set (match_operand:SI 0 "register_operand" "")
16802         (match_operand:SI 1 "register_operand" ""))
16803    (parallel [(set (match_dup 0)
16804                    (match_operator:SI 3 "commutative_operator"
16805                      [(match_dup 0)
16806                       (match_operand:SI 2 "memory_operand" "")]))
16807               (clobber (reg:CC FLAGS_REG))])]
16808   "REGNO (operands[0]) != REGNO (operands[1])
16809    && GENERAL_REGNO_P (REGNO (operands[0]))
16810    && GENERAL_REGNO_P (REGNO (operands[1]))"
16811   [(set (match_dup 0) (match_dup 4))
16812    (parallel [(set (match_dup 0)
16813                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16814               (clobber (reg:CC FLAGS_REG))])]
16815   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16816
16817 (define_peephole2
16818   [(set (match_operand 0 "register_operand" "")
16819         (match_operand 1 "register_operand" ""))
16820    (set (match_dup 0)
16821                    (match_operator 3 "commutative_operator"
16822                      [(match_dup 0)
16823                       (match_operand 2 "memory_operand" "")]))]
16824   "REGNO (operands[0]) != REGNO (operands[1])
16825    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16826        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16827   [(set (match_dup 0) (match_dup 2))
16828    (set (match_dup 0)
16829         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16830
16831 ; Don't do logical operations with memory outputs
16832 ;
16833 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16834 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16835 ; the same decoder scheduling characteristics as the original.
16836
16837 (define_peephole2
16838   [(match_scratch:SI 2 "r")
16839    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16840                    (match_operator:SI 3 "arith_or_logical_operator"
16841                      [(match_dup 0)
16842                       (match_operand:SI 1 "nonmemory_operand" "")]))
16843               (clobber (reg:CC FLAGS_REG))])]
16844   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16845    /* Do not split stack checking probes.  */
16846    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16847   [(set (match_dup 2) (match_dup 0))
16848    (parallel [(set (match_dup 2)
16849                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16850               (clobber (reg:CC FLAGS_REG))])
16851    (set (match_dup 0) (match_dup 2))])
16852
16853 (define_peephole2
16854   [(match_scratch:SI 2 "r")
16855    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16856                    (match_operator:SI 3 "arith_or_logical_operator"
16857                      [(match_operand:SI 1 "nonmemory_operand" "")
16858                       (match_dup 0)]))
16859               (clobber (reg:CC FLAGS_REG))])]
16860   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16861    /* Do not split stack checking probes.  */
16862    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16863   [(set (match_dup 2) (match_dup 0))
16864    (parallel [(set (match_dup 2)
16865                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16866               (clobber (reg:CC FLAGS_REG))])
16867    (set (match_dup 0) (match_dup 2))])
16868
16869 ;; Attempt to use arith or logical operations with memory outputs with
16870 ;; setting of flags.
16871 (define_peephole2
16872   [(set (match_operand:SWI 0 "register_operand" "")
16873         (match_operand:SWI 1 "memory_operand" ""))
16874    (parallel [(set (match_dup 0)
16875                    (match_operator:SWI 3 "plusminuslogic_operator"
16876                      [(match_dup 0)
16877                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16878               (clobber (reg:CC FLAGS_REG))])
16879    (set (match_dup 1) (match_dup 0))
16880    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16881   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16882    && peep2_reg_dead_p (4, operands[0])
16883    && !reg_overlap_mentioned_p (operands[0], operands[1])
16884    && ix86_match_ccmode (peep2_next_insn (3),
16885                          (GET_CODE (operands[3]) == PLUS
16886                           || GET_CODE (operands[3]) == MINUS)
16887                          ? CCGOCmode : CCNOmode)"
16888   [(parallel [(set (match_dup 4) (match_dup 5))
16889               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16890                                                   (match_dup 2)]))])]
16891   "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16892    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16893                                  copy_rtx (operands[1]),
16894                                  copy_rtx (operands[2]));
16895    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16896                                   operands[5], const0_rtx);")
16897
16898 (define_peephole2
16899   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16900                    (match_operator:SWI 2 "plusminuslogic_operator"
16901                      [(match_dup 0)
16902                       (match_operand:SWI 1 "memory_operand" "")]))
16903               (clobber (reg:CC FLAGS_REG))])
16904    (set (match_dup 1) (match_dup 0))
16905    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16906   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16907    && GET_CODE (operands[2]) != MINUS
16908    && peep2_reg_dead_p (3, operands[0])
16909    && !reg_overlap_mentioned_p (operands[0], operands[1])
16910    && ix86_match_ccmode (peep2_next_insn (2),
16911                          GET_CODE (operands[2]) == PLUS
16912                          ? CCGOCmode : CCNOmode)"
16913   [(parallel [(set (match_dup 3) (match_dup 4))
16914               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16915                                                   (match_dup 0)]))])]
16916   "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16917    operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16918                                  copy_rtx (operands[1]),
16919                                  copy_rtx (operands[0]));
16920    operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16921                                   operands[4], const0_rtx);")
16922
16923 (define_peephole2
16924   [(set (match_operand:SWI12 0 "register_operand" "")
16925         (match_operand:SWI12 1 "memory_operand" ""))
16926    (parallel [(set (match_operand:SI 4 "register_operand" "")
16927                    (match_operator:SI 3 "plusminuslogic_operator"
16928                      [(match_dup 4)
16929                       (match_operand:SI 2 "nonmemory_operand" "")]))
16930               (clobber (reg:CC FLAGS_REG))])
16931    (set (match_dup 1) (match_dup 0))
16932    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16933   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16934    && REG_P (operands[0]) && REG_P (operands[4])
16935    && REGNO (operands[0]) == REGNO (operands[4])
16936    && peep2_reg_dead_p (4, operands[0])
16937    && !reg_overlap_mentioned_p (operands[0], operands[1])
16938    && ix86_match_ccmode (peep2_next_insn (3),
16939                          (GET_CODE (operands[3]) == PLUS
16940                           || GET_CODE (operands[3]) == MINUS)
16941                          ? CCGOCmode : CCNOmode)"
16942   [(parallel [(set (match_dup 4) (match_dup 5))
16943               (set (match_dup 1) (match_dup 6))])]
16944   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16945    operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16946    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16947                                  copy_rtx (operands[1]), operands[2]);
16948    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16949                                   operands[5], const0_rtx);
16950    operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16951                                  copy_rtx (operands[1]),
16952                                  copy_rtx (operands[2]));")
16953
16954 ;; Attempt to always use XOR for zeroing registers.
16955 (define_peephole2
16956   [(set (match_operand 0 "register_operand" "")
16957         (match_operand 1 "const0_operand" ""))]
16958   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16959    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16960    && GENERAL_REG_P (operands[0])
16961    && peep2_regno_dead_p (0, FLAGS_REG)"
16962   [(parallel [(set (match_dup 0) (const_int 0))
16963               (clobber (reg:CC FLAGS_REG))])]
16964   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16965
16966 (define_peephole2
16967   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16968         (const_int 0))]
16969   "(GET_MODE (operands[0]) == QImode
16970     || GET_MODE (operands[0]) == HImode)
16971    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16972    && peep2_regno_dead_p (0, FLAGS_REG)"
16973   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16974               (clobber (reg:CC FLAGS_REG))])])
16975
16976 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16977 (define_peephole2
16978   [(set (match_operand:SWI248 0 "register_operand" "")
16979         (const_int -1))]
16980   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16981    && peep2_regno_dead_p (0, FLAGS_REG)"
16982   [(parallel [(set (match_dup 0) (const_int -1))
16983               (clobber (reg:CC FLAGS_REG))])]
16984 {
16985   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16986     operands[0] = gen_lowpart (SImode, operands[0]);
16987 })
16988
16989 ;; Attempt to convert simple lea to add/shift.
16990 ;; These can be created by move expanders.
16991
16992 (define_peephole2
16993   [(set (match_operand:SWI48 0 "register_operand" "")
16994         (plus:SWI48 (match_dup 0)
16995                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16996   "peep2_regno_dead_p (0, FLAGS_REG)"
16997   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16998               (clobber (reg:CC FLAGS_REG))])])
16999
17000 (define_peephole2
17001   [(set (match_operand:SI 0 "register_operand" "")
17002         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17003                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17004   "TARGET_64BIT
17005    && peep2_regno_dead_p (0, FLAGS_REG)
17006    && REGNO (operands[0]) == REGNO (operands[1])"
17007   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17008               (clobber (reg:CC FLAGS_REG))])]
17009   "operands[2] = gen_lowpart (SImode, operands[2]);")
17010
17011 (define_peephole2
17012   [(set (match_operand:SWI48 0 "register_operand" "")
17013         (mult:SWI48 (match_dup 0)
17014                     (match_operand:SWI48 1 "const_int_operand" "")))]
17015   "exact_log2 (INTVAL (operands[1])) >= 0
17016    && peep2_regno_dead_p (0, FLAGS_REG)"
17017   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17018               (clobber (reg:CC FLAGS_REG))])]
17019   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17020
17021 (define_peephole2
17022   [(set (match_operand:SI 0 "register_operand" "")
17023         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17024                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17025   "TARGET_64BIT
17026    && exact_log2 (INTVAL (operands[2])) >= 0
17027    && REGNO (operands[0]) == REGNO (operands[1])
17028    && peep2_regno_dead_p (0, FLAGS_REG)"
17029   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17030               (clobber (reg:CC FLAGS_REG))])]
17031   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17032
17033 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17034 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17035 ;; On many CPUs it is also faster, since special hardware to avoid esp
17036 ;; dependencies is present.
17037
17038 ;; While some of these conversions may be done using splitters, we use
17039 ;; peepholes in order to allow combine_stack_adjustments pass to see
17040 ;; nonobfuscated RTL.
17041
17042 ;; Convert prologue esp subtractions to push.
17043 ;; We need register to push.  In order to keep verify_flow_info happy we have
17044 ;; two choices
17045 ;; - use scratch and clobber it in order to avoid dependencies
17046 ;; - use already live register
17047 ;; We can't use the second way right now, since there is no reliable way how to
17048 ;; verify that given register is live.  First choice will also most likely in
17049 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17050 ;; call clobbered registers are dead.  We may want to use base pointer as an
17051 ;; alternative when no register is available later.
17052
17053 (define_peephole2
17054   [(match_scratch:P 1 "r")
17055    (parallel [(set (reg:P SP_REG)
17056                    (plus:P (reg:P SP_REG)
17057                            (match_operand:P 0 "const_int_operand" "")))
17058               (clobber (reg:CC FLAGS_REG))
17059               (clobber (mem:BLK (scratch)))])]
17060   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17061    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17062   [(clobber (match_dup 1))
17063    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17064               (clobber (mem:BLK (scratch)))])])
17065
17066 (define_peephole2
17067   [(match_scratch:P 1 "r")
17068    (parallel [(set (reg:P SP_REG)
17069                    (plus:P (reg:P SP_REG)
17070                            (match_operand:P 0 "const_int_operand" "")))
17071               (clobber (reg:CC FLAGS_REG))
17072               (clobber (mem:BLK (scratch)))])]
17073   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17074    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17075   [(clobber (match_dup 1))
17076    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17077    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17078               (clobber (mem:BLK (scratch)))])])
17079
17080 ;; Convert esp subtractions to push.
17081 (define_peephole2
17082   [(match_scratch:P 1 "r")
17083    (parallel [(set (reg:P SP_REG)
17084                    (plus:P (reg:P SP_REG)
17085                            (match_operand:P 0 "const_int_operand" "")))
17086               (clobber (reg:CC FLAGS_REG))])]
17087   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17088    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17089   [(clobber (match_dup 1))
17090    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17091
17092 (define_peephole2
17093   [(match_scratch:P 1 "r")
17094    (parallel [(set (reg:P SP_REG)
17095                    (plus:P (reg:P SP_REG)
17096                            (match_operand:P 0 "const_int_operand" "")))
17097               (clobber (reg:CC FLAGS_REG))])]
17098   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17099    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17100   [(clobber (match_dup 1))
17101    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17102    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17103
17104 ;; Convert epilogue deallocator to pop.
17105 (define_peephole2
17106   [(match_scratch:P 1 "r")
17107    (parallel [(set (reg:P SP_REG)
17108                    (plus:P (reg:P SP_REG)
17109                            (match_operand:P 0 "const_int_operand" "")))
17110               (clobber (reg:CC FLAGS_REG))
17111               (clobber (mem:BLK (scratch)))])]
17112   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17113    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17114   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17115               (clobber (mem:BLK (scratch)))])])
17116
17117 ;; Two pops case is tricky, since pop causes dependency
17118 ;; on destination register.  We use two registers if available.
17119 (define_peephole2
17120   [(match_scratch:P 1 "r")
17121    (match_scratch:P 2 "r")
17122    (parallel [(set (reg:P SP_REG)
17123                    (plus:P (reg:P SP_REG)
17124                            (match_operand:P 0 "const_int_operand" "")))
17125               (clobber (reg:CC FLAGS_REG))
17126               (clobber (mem:BLK (scratch)))])]
17127   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17128    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17129   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17130               (clobber (mem:BLK (scratch)))])
17131    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17132
17133 (define_peephole2
17134   [(match_scratch:P 1 "r")
17135    (parallel [(set (reg:P SP_REG)
17136                    (plus:P (reg:P SP_REG)
17137                            (match_operand:P 0 "const_int_operand" "")))
17138               (clobber (reg:CC FLAGS_REG))
17139               (clobber (mem:BLK (scratch)))])]
17140   "optimize_insn_for_size_p ()
17141    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17142   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17143               (clobber (mem:BLK (scratch)))])
17144    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17145
17146 ;; Convert esp additions to pop.
17147 (define_peephole2
17148   [(match_scratch:P 1 "r")
17149    (parallel [(set (reg:P SP_REG)
17150                    (plus:P (reg:P SP_REG)
17151                            (match_operand:P 0 "const_int_operand" "")))
17152               (clobber (reg:CC FLAGS_REG))])]
17153   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17154   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17155
17156 ;; Two pops case is tricky, since pop causes dependency
17157 ;; on destination register.  We use two registers if available.
17158 (define_peephole2
17159   [(match_scratch:P 1 "r")
17160    (match_scratch:P 2 "r")
17161    (parallel [(set (reg:P SP_REG)
17162                    (plus:P (reg:P SP_REG)
17163                            (match_operand:P 0 "const_int_operand" "")))
17164               (clobber (reg:CC FLAGS_REG))])]
17165   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17166   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17167    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17168
17169 (define_peephole2
17170   [(match_scratch:P 1 "r")
17171    (parallel [(set (reg:P SP_REG)
17172                    (plus:P (reg:P SP_REG)
17173                            (match_operand:P 0 "const_int_operand" "")))
17174               (clobber (reg:CC FLAGS_REG))])]
17175   "optimize_insn_for_size_p ()
17176    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17177   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17178    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17179 \f
17180 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17181 ;; required and register dies.  Similarly for 128 to -128.
17182 (define_peephole2
17183   [(set (match_operand 0 "flags_reg_operand" "")
17184         (match_operator 1 "compare_operator"
17185           [(match_operand 2 "register_operand" "")
17186            (match_operand 3 "const_int_operand" "")]))]
17187   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17188      && incdec_operand (operands[3], GET_MODE (operands[3])))
17189     || (!TARGET_FUSE_CMP_AND_BRANCH
17190         && INTVAL (operands[3]) == 128))
17191    && ix86_match_ccmode (insn, CCGCmode)
17192    && peep2_reg_dead_p (1, operands[2])"
17193   [(parallel [(set (match_dup 0)
17194                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17195               (clobber (match_dup 2))])])
17196 \f
17197 ;; Convert imul by three, five and nine into lea
17198 (define_peephole2
17199   [(parallel
17200     [(set (match_operand:SWI48 0 "register_operand" "")
17201           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17202                       (match_operand:SWI48 2 "const_int_operand" "")))
17203      (clobber (reg:CC FLAGS_REG))])]
17204   "INTVAL (operands[2]) == 3
17205    || INTVAL (operands[2]) == 5
17206    || INTVAL (operands[2]) == 9"
17207   [(set (match_dup 0)
17208         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17209                     (match_dup 1)))]
17210   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17211
17212 (define_peephole2
17213   [(parallel
17214     [(set (match_operand:SWI48 0 "register_operand" "")
17215           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17216                       (match_operand:SWI48 2 "const_int_operand" "")))
17217      (clobber (reg:CC FLAGS_REG))])]
17218   "optimize_insn_for_speed_p ()
17219    && (INTVAL (operands[2]) == 3
17220        || INTVAL (operands[2]) == 5
17221        || INTVAL (operands[2]) == 9)"
17222   [(set (match_dup 0) (match_dup 1))
17223    (set (match_dup 0)
17224         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17225                     (match_dup 0)))]
17226   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17227
17228 ;; imul $32bit_imm, mem, reg is vector decoded, while
17229 ;; imul $32bit_imm, reg, reg is direct decoded.
17230 (define_peephole2
17231   [(match_scratch:SWI48 3 "r")
17232    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17233                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17234                                (match_operand:SWI48 2 "immediate_operand" "")))
17235               (clobber (reg:CC FLAGS_REG))])]
17236   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17237    && !satisfies_constraint_K (operands[2])"
17238   [(set (match_dup 3) (match_dup 1))
17239    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17240               (clobber (reg:CC FLAGS_REG))])])
17241
17242 (define_peephole2
17243   [(match_scratch:SI 3 "r")
17244    (parallel [(set (match_operand:DI 0 "register_operand" "")
17245                    (zero_extend:DI
17246                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17247                               (match_operand:SI 2 "immediate_operand" ""))))
17248               (clobber (reg:CC FLAGS_REG))])]
17249   "TARGET_64BIT
17250    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17251    && !satisfies_constraint_K (operands[2])"
17252   [(set (match_dup 3) (match_dup 1))
17253    (parallel [(set (match_dup 0)
17254                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17255               (clobber (reg:CC FLAGS_REG))])])
17256
17257 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17258 ;; Convert it into imul reg, reg
17259 ;; It would be better to force assembler to encode instruction using long
17260 ;; immediate, but there is apparently no way to do so.
17261 (define_peephole2
17262   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17263                    (mult:SWI248
17264                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17265                     (match_operand:SWI248 2 "const_int_operand" "")))
17266               (clobber (reg:CC FLAGS_REG))])
17267    (match_scratch:SWI248 3 "r")]
17268   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17269    && satisfies_constraint_K (operands[2])"
17270   [(set (match_dup 3) (match_dup 2))
17271    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17272               (clobber (reg:CC FLAGS_REG))])]
17273 {
17274   if (!rtx_equal_p (operands[0], operands[1]))
17275     emit_move_insn (operands[0], operands[1]);
17276 })
17277
17278 ;; After splitting up read-modify operations, array accesses with memory
17279 ;; operands might end up in form:
17280 ;;  sall    $2, %eax
17281 ;;  movl    4(%esp), %edx
17282 ;;  addl    %edx, %eax
17283 ;; instead of pre-splitting:
17284 ;;  sall    $2, %eax
17285 ;;  addl    4(%esp), %eax
17286 ;; Turn it into:
17287 ;;  movl    4(%esp), %edx
17288 ;;  leal    (%edx,%eax,4), %eax
17289
17290 (define_peephole2
17291   [(match_scratch:P 5 "r")
17292    (parallel [(set (match_operand 0 "register_operand" "")
17293                    (ashift (match_operand 1 "register_operand" "")
17294                            (match_operand 2 "const_int_operand" "")))
17295                (clobber (reg:CC FLAGS_REG))])
17296    (parallel [(set (match_operand 3 "register_operand" "")
17297                    (plus (match_dup 0)
17298                          (match_operand 4 "x86_64_general_operand" "")))
17299                    (clobber (reg:CC FLAGS_REG))])]
17300   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17301    /* Validate MODE for lea.  */
17302    && ((!TARGET_PARTIAL_REG_STALL
17303         && (GET_MODE (operands[0]) == QImode
17304             || GET_MODE (operands[0]) == HImode))
17305        || GET_MODE (operands[0]) == SImode
17306        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17307    && (rtx_equal_p (operands[0], operands[3])
17308        || peep2_reg_dead_p (2, operands[0]))
17309    /* We reorder load and the shift.  */
17310    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17311   [(set (match_dup 5) (match_dup 4))
17312    (set (match_dup 0) (match_dup 1))]
17313 {
17314   enum machine_mode op1mode = GET_MODE (operands[1]);
17315   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17316   int scale = 1 << INTVAL (operands[2]);
17317   rtx index = gen_lowpart (Pmode, operands[1]);
17318   rtx base = gen_lowpart (Pmode, operands[5]);
17319   rtx dest = gen_lowpart (mode, operands[3]);
17320
17321   operands[1] = gen_rtx_PLUS (Pmode, base,
17322                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17323   operands[5] = base;
17324   if (mode != Pmode)
17325     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17326   if (op1mode != Pmode)
17327     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17328   operands[0] = dest;
17329 })
17330 \f
17331 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17332 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17333 ;; caught for use by garbage collectors and the like.  Using an insn that
17334 ;; maps to SIGILL makes it more likely the program will rightfully die.
17335 ;; Keeping with tradition, "6" is in honor of #UD.
17336 (define_insn "trap"
17337   [(trap_if (const_int 1) (const_int 6))]
17338   ""
17339   { return ASM_SHORT "0x0b0f"; }
17340   [(set_attr "length" "2")])
17341
17342 (define_expand "prefetch"
17343   [(prefetch (match_operand 0 "address_operand" "")
17344              (match_operand:SI 1 "const_int_operand" "")
17345              (match_operand:SI 2 "const_int_operand" ""))]
17346   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17347 {
17348   int rw = INTVAL (operands[1]);
17349   int locality = INTVAL (operands[2]);
17350
17351   gcc_assert (rw == 0 || rw == 1);
17352   gcc_assert (locality >= 0 && locality <= 3);
17353   gcc_assert (GET_MODE (operands[0]) == Pmode
17354               || GET_MODE (operands[0]) == VOIDmode);
17355
17356   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17357      supported by SSE counterpart or the SSE prefetch is not available
17358      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17359      of locality.  */
17360   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17361     operands[2] = GEN_INT (3);
17362   else
17363     operands[1] = const0_rtx;
17364 })
17365
17366 (define_insn "*prefetch_sse_<mode>"
17367   [(prefetch (match_operand:P 0 "address_operand" "p")
17368              (const_int 0)
17369              (match_operand:SI 1 "const_int_operand" ""))]
17370   "TARGET_PREFETCH_SSE"
17371 {
17372   static const char * const patterns[4] = {
17373    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17374   };
17375
17376   int locality = INTVAL (operands[1]);
17377   gcc_assert (locality >= 0 && locality <= 3);
17378
17379   return patterns[locality];
17380 }
17381   [(set_attr "type" "sse")
17382    (set_attr "atom_sse_attr" "prefetch")
17383    (set (attr "length_address")
17384         (symbol_ref "memory_address_length (operands[0])"))
17385    (set_attr "memory" "none")])
17386
17387 (define_insn "*prefetch_3dnow_<mode>"
17388   [(prefetch (match_operand:P 0 "address_operand" "p")
17389              (match_operand:SI 1 "const_int_operand" "n")
17390              (const_int 3))]
17391   "TARGET_3DNOW"
17392 {
17393   if (INTVAL (operands[1]) == 0)
17394     return "prefetch\t%a0";
17395   else
17396     return "prefetchw\t%a0";
17397 }
17398   [(set_attr "type" "mmx")
17399    (set (attr "length_address")
17400         (symbol_ref "memory_address_length (operands[0])"))
17401    (set_attr "memory" "none")])
17402
17403 (define_expand "stack_protect_set"
17404   [(match_operand 0 "memory_operand" "")
17405    (match_operand 1 "memory_operand" "")]
17406   ""
17407 {
17408   rtx (*insn)(rtx, rtx);
17409
17410 #ifdef TARGET_THREAD_SSP_OFFSET
17411   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17412   insn = (TARGET_64BIT
17413           ? gen_stack_tls_protect_set_di
17414           : gen_stack_tls_protect_set_si);
17415 #else
17416   insn = (TARGET_64BIT
17417           ? gen_stack_protect_set_di
17418           : gen_stack_protect_set_si);
17419 #endif
17420
17421   emit_insn (insn (operands[0], operands[1]));
17422   DONE;
17423 })
17424
17425 (define_insn "stack_protect_set_<mode>"
17426   [(set (match_operand:P 0 "memory_operand" "=m")
17427         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17428    (set (match_scratch:P 2 "=&r") (const_int 0))
17429    (clobber (reg:CC FLAGS_REG))]
17430   ""
17431   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17432   [(set_attr "type" "multi")])
17433
17434 (define_insn "stack_tls_protect_set_<mode>"
17435   [(set (match_operand:P 0 "memory_operand" "=m")
17436         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17437                   UNSPEC_SP_TLS_SET))
17438    (set (match_scratch:P 2 "=&r") (const_int 0))
17439    (clobber (reg:CC FLAGS_REG))]
17440   ""
17441   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17442   [(set_attr "type" "multi")])
17443
17444 (define_expand "stack_protect_test"
17445   [(match_operand 0 "memory_operand" "")
17446    (match_operand 1 "memory_operand" "")
17447    (match_operand 2 "" "")]
17448   ""
17449 {
17450   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17451
17452   rtx (*insn)(rtx, rtx, rtx);
17453
17454 #ifdef TARGET_THREAD_SSP_OFFSET
17455   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17456   insn = (TARGET_64BIT
17457           ? gen_stack_tls_protect_test_di
17458           : gen_stack_tls_protect_test_si);
17459 #else
17460   insn = (TARGET_64BIT
17461           ? gen_stack_protect_test_di
17462           : gen_stack_protect_test_si);
17463 #endif
17464
17465   emit_insn (insn (flags, operands[0], operands[1]));
17466
17467   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17468                                   flags, const0_rtx, operands[2]));
17469   DONE;
17470 })
17471
17472 (define_insn "stack_protect_test_<mode>"
17473   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17474         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17475                      (match_operand:P 2 "memory_operand" "m")]
17476                     UNSPEC_SP_TEST))
17477    (clobber (match_scratch:P 3 "=&r"))]
17478   ""
17479   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17480   [(set_attr "type" "multi")])
17481
17482 (define_insn "stack_tls_protect_test_<mode>"
17483   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17484         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17485                      (match_operand:P 2 "const_int_operand" "i")]
17486                     UNSPEC_SP_TLS_TEST))
17487    (clobber (match_scratch:P 3 "=r"))]
17488   ""
17489   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17490   [(set_attr "type" "multi")])
17491
17492 (define_insn "sse4_2_crc32<mode>"
17493   [(set (match_operand:SI 0 "register_operand" "=r")
17494         (unspec:SI
17495           [(match_operand:SI 1 "register_operand" "0")
17496            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17497           UNSPEC_CRC32))]
17498   "TARGET_SSE4_2 || TARGET_CRC32"
17499   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17500   [(set_attr "type" "sselog1")
17501    (set_attr "prefix_rep" "1")
17502    (set_attr "prefix_extra" "1")
17503    (set (attr "prefix_data16")
17504      (if_then_else (match_operand:HI 2 "" "")
17505        (const_string "1")
17506        (const_string "*")))
17507    (set (attr "prefix_rex")
17508      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17509        (const_string "1")
17510        (const_string "*")))
17511    (set_attr "mode" "SI")])
17512
17513 (define_insn "sse4_2_crc32di"
17514   [(set (match_operand:DI 0 "register_operand" "=r")
17515         (unspec:DI
17516           [(match_operand:DI 1 "register_operand" "0")
17517            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17518           UNSPEC_CRC32))]
17519   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17520   "crc32{q}\t{%2, %0|%0, %2}"
17521   [(set_attr "type" "sselog1")
17522    (set_attr "prefix_rep" "1")
17523    (set_attr "prefix_extra" "1")
17524    (set_attr "mode" "DI")])
17525
17526 (define_expand "rdpmc"
17527   [(match_operand:DI 0 "register_operand" "")
17528    (match_operand:SI 1 "register_operand" "")]
17529   ""
17530 {
17531   rtx reg = gen_reg_rtx (DImode);
17532   rtx si;
17533
17534   /* Force operand 1 into ECX.  */
17535   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17536   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17537   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17538                                 UNSPECV_RDPMC);
17539
17540   if (TARGET_64BIT)
17541     {
17542       rtvec vec = rtvec_alloc (2);
17543       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17544       rtx upper = gen_reg_rtx (DImode);
17545       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17546                                         gen_rtvec (1, const0_rtx),
17547                                         UNSPECV_RDPMC);
17548       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17549       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17550       emit_insn (load);
17551       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17552                                    NULL, 1, OPTAB_DIRECT);
17553       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17554                                  OPTAB_DIRECT);
17555     }
17556   else
17557     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17558   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17559   DONE;
17560 })
17561
17562 (define_insn "*rdpmc"
17563   [(set (match_operand:DI 0 "register_operand" "=A")
17564         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17565                             UNSPECV_RDPMC))]
17566   "!TARGET_64BIT"
17567   "rdpmc"
17568   [(set_attr "type" "other")
17569    (set_attr "length" "2")])
17570
17571 (define_insn "*rdpmc_rex64"
17572   [(set (match_operand:DI 0 "register_operand" "=a")
17573         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17574                             UNSPECV_RDPMC))
17575   (set (match_operand:DI 1 "register_operand" "=d")
17576        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17577   "TARGET_64BIT"
17578   "rdpmc"
17579   [(set_attr "type" "other")
17580    (set_attr "length" "2")])
17581
17582 (define_expand "rdtsc"
17583   [(set (match_operand:DI 0 "register_operand" "")
17584         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17585   ""
17586 {
17587   if (TARGET_64BIT)
17588     {
17589       rtvec vec = rtvec_alloc (2);
17590       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17591       rtx upper = gen_reg_rtx (DImode);
17592       rtx lower = gen_reg_rtx (DImode);
17593       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17594                                          gen_rtvec (1, const0_rtx),
17595                                          UNSPECV_RDTSC);
17596       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17597       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17598       emit_insn (load);
17599       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17600                                    NULL, 1, OPTAB_DIRECT);
17601       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17602                                    OPTAB_DIRECT);
17603       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17604       DONE;
17605     }
17606 })
17607
17608 (define_insn "*rdtsc"
17609   [(set (match_operand:DI 0 "register_operand" "=A")
17610         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17611   "!TARGET_64BIT"
17612   "rdtsc"
17613   [(set_attr "type" "other")
17614    (set_attr "length" "2")])
17615
17616 (define_insn "*rdtsc_rex64"
17617   [(set (match_operand:DI 0 "register_operand" "=a")
17618         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17619    (set (match_operand:DI 1 "register_operand" "=d")
17620         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17621   "TARGET_64BIT"
17622   "rdtsc"
17623   [(set_attr "type" "other")
17624    (set_attr "length" "2")])
17625
17626 (define_expand "rdtscp"
17627   [(match_operand:DI 0 "register_operand" "")
17628    (match_operand:SI 1 "memory_operand" "")]
17629   ""
17630 {
17631   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17632                                     gen_rtvec (1, const0_rtx),
17633                                     UNSPECV_RDTSCP);
17634   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17635                                     gen_rtvec (1, const0_rtx),
17636                                     UNSPECV_RDTSCP);
17637   rtx reg = gen_reg_rtx (DImode);
17638   rtx tmp = gen_reg_rtx (SImode);
17639
17640   if (TARGET_64BIT)
17641     {
17642       rtvec vec = rtvec_alloc (3);
17643       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17644       rtx upper = gen_reg_rtx (DImode);
17645       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17646       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17647       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17648       emit_insn (load);
17649       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17650                                    NULL, 1, OPTAB_DIRECT);
17651       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17652                                  OPTAB_DIRECT);
17653     }
17654   else
17655     {
17656       rtvec vec = rtvec_alloc (2);
17657       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17658       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17659       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17660       emit_insn (load);
17661     }
17662   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17663   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17664   DONE;
17665 })
17666
17667 (define_insn "*rdtscp"
17668   [(set (match_operand:DI 0 "register_operand" "=A")
17669         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17670    (set (match_operand:SI 1 "register_operand" "=c")
17671         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17672   "!TARGET_64BIT"
17673   "rdtscp"
17674   [(set_attr "type" "other")
17675    (set_attr "length" "3")])
17676
17677 (define_insn "*rdtscp_rex64"
17678   [(set (match_operand:DI 0 "register_operand" "=a")
17679         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17680    (set (match_operand:DI 1 "register_operand" "=d")
17681         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17682    (set (match_operand:SI 2 "register_operand" "=c")
17683         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17684   "TARGET_64BIT"
17685   "rdtscp"
17686   [(set_attr "type" "other")
17687    (set_attr "length" "3")])
17688
17689 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17690 ;;
17691 ;; LWP instructions
17692 ;;
17693 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17694
17695 (define_expand "lwp_llwpcb"
17696   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17697                     UNSPECV_LLWP_INTRINSIC)]
17698   "TARGET_LWP")
17699
17700 (define_insn "*lwp_llwpcb<mode>1"
17701   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17702                     UNSPECV_LLWP_INTRINSIC)]
17703   "TARGET_LWP"
17704   "llwpcb\t%0"
17705   [(set_attr "type" "lwp")
17706    (set_attr "mode" "<MODE>")
17707    (set_attr "length" "5")])
17708
17709 (define_expand "lwp_slwpcb"
17710   [(set (match_operand 0 "register_operand" "=r")
17711         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17712   "TARGET_LWP"
17713 {
17714   rtx (*insn)(rtx);
17715
17716   insn = (TARGET_64BIT
17717           ? gen_lwp_slwpcbdi
17718           : gen_lwp_slwpcbsi);
17719
17720   emit_insn (insn (operands[0]));
17721   DONE;
17722 })
17723
17724 (define_insn "lwp_slwpcb<mode>"
17725   [(set (match_operand:P 0 "register_operand" "=r")
17726         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17727   "TARGET_LWP"
17728   "slwpcb\t%0"
17729   [(set_attr "type" "lwp")
17730    (set_attr "mode" "<MODE>")
17731    (set_attr "length" "5")])
17732
17733 (define_expand "lwp_lwpval<mode>3"
17734   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17735                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17736                      (match_operand:SI 3 "const_int_operand" "i")]
17737                     UNSPECV_LWPVAL_INTRINSIC)]
17738   "TARGET_LWP"
17739   "/* Avoid unused variable warning.  */
17740    (void) operand0;")
17741
17742 (define_insn "*lwp_lwpval<mode>3_1"
17743   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17744                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17745                      (match_operand:SI 2 "const_int_operand" "i")]
17746                     UNSPECV_LWPVAL_INTRINSIC)]
17747   "TARGET_LWP"
17748   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17749   [(set_attr "type" "lwp")
17750    (set_attr "mode" "<MODE>")
17751    (set (attr "length")
17752         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17753
17754 (define_expand "lwp_lwpins<mode>3"
17755   [(set (reg:CCC FLAGS_REG)
17756         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17757                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17758                               (match_operand:SI 3 "const_int_operand" "i")]
17759                              UNSPECV_LWPINS_INTRINSIC))
17760    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17761         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17762   "TARGET_LWP")
17763
17764 (define_insn "*lwp_lwpins<mode>3_1"
17765   [(set (reg:CCC FLAGS_REG)
17766         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17767                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17768                               (match_operand:SI 2 "const_int_operand" "i")]
17769                              UNSPECV_LWPINS_INTRINSIC))]
17770   "TARGET_LWP"
17771   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17772   [(set_attr "type" "lwp")
17773    (set_attr "mode" "<MODE>")
17774    (set (attr "length")
17775         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17776
17777 (define_insn "rdfsbase<mode>"
17778   [(set (match_operand:SWI48 0 "register_operand" "=r")
17779         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17780   "TARGET_64BIT && TARGET_FSGSBASE"
17781   "rdfsbase %0"
17782   [(set_attr "type" "other")
17783    (set_attr "prefix_extra" "2")])
17784
17785 (define_insn "rdgsbase<mode>"
17786   [(set (match_operand:SWI48 0 "register_operand" "=r")
17787         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17788   "TARGET_64BIT && TARGET_FSGSBASE"
17789   "rdgsbase %0"
17790   [(set_attr "type" "other")
17791    (set_attr "prefix_extra" "2")])
17792
17793 (define_insn "wrfsbase<mode>"
17794   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17795                     UNSPECV_WRFSBASE)]
17796   "TARGET_64BIT && TARGET_FSGSBASE"
17797   "wrfsbase %0"
17798   [(set_attr "type" "other")
17799    (set_attr "prefix_extra" "2")])
17800
17801 (define_insn "wrgsbase<mode>"
17802   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17803                     UNSPECV_WRGSBASE)]
17804   "TARGET_64BIT && TARGET_FSGSBASE"
17805   "wrgsbase %0"
17806   [(set_attr "type" "other")
17807    (set_attr "prefix_extra" "2")])
17808
17809 (define_insn "rdrand<mode>_1"
17810   [(set (match_operand:SWI248 0 "register_operand" "=r")
17811         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17812    (set (reg:CCC FLAGS_REG)
17813         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17814   "TARGET_RDRND"
17815   "rdrand\t%0"
17816   [(set_attr "type" "other")
17817    (set_attr "prefix_extra" "1")])
17818
17819 (define_expand "pause"
17820   [(set (match_dup 0)
17821         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17822   ""
17823 {
17824   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17825   MEM_VOLATILE_P (operands[0]) = 1;
17826 })
17827
17828 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17829 ;; They have the same encoding.
17830 (define_insn "*pause"
17831   [(set (match_operand:BLK 0 "" "")
17832         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17833   ""
17834   "rep; nop"
17835   [(set_attr "length" "2")
17836    (set_attr "memory" "unknown")])
17837
17838 (include "mmx.md")
17839 (include "sse.md")
17840 (include "sync.md")