OSDN Git Service

a021e7c75e7261ab1aa66d0cd9754e398a32c073
[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
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 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
61
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
70
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_PFRCP                49)
99    (UNSPEC_PFRCPIT1             40)
100    (UNSPEC_PFRCPIT2             41)
101    (UNSPEC_PFRSQRT              42)
102    (UNSPEC_PFRSQIT1             43)
103    (UNSPEC_MFENCE               44)
104    (UNSPEC_LFENCE               45)
105    (UNSPEC_PSADBW               46)
106    (UNSPEC_LDDQU                47)
107
108    ; Generic math support
109    (UNSPEC_COPYSIGN             50)
110    (UNSPEC_IEEE_MIN             51)     ; not commutative
111    (UNSPEC_IEEE_MAX             52)     ; not commutative
112
113    ; x87 Floating point
114    (UNSPEC_SIN                  60)
115    (UNSPEC_COS                  61)
116    (UNSPEC_FPATAN               62)
117    (UNSPEC_FYL2X                63)
118    (UNSPEC_FYL2XP1              64)
119    (UNSPEC_FRNDINT              65)
120    (UNSPEC_FIST                 66)
121    (UNSPEC_F2XM1                67)
122    (UNSPEC_TAN                  68)
123    (UNSPEC_FXAM                 69)
124
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
132
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_XTRACT_FRACT         84)
137    (UNSPEC_XTRACT_EXP           85)
138    (UNSPEC_FSCALE_FRACT         86)
139    (UNSPEC_FSCALE_EXP           87)
140    (UNSPEC_FPREM_F              88)
141    (UNSPEC_FPREM_U              89)
142    (UNSPEC_FPREM1_F             90)
143    (UNSPEC_FPREM1_U             91)
144
145    (UNSPEC_C2_FLAG              95)
146
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
152
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
157
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
163
164    ; For SSE4.1 support
165    (UNSPEC_BLENDV               134)
166    (UNSPEC_INSERTPS             135)
167    (UNSPEC_DP                   136)
168    (UNSPEC_MOVNTDQA             137)
169    (UNSPEC_MPSADBW              138)
170    (UNSPEC_PHMINPOSUW           139)
171    (UNSPEC_PTEST                140)
172    (UNSPEC_ROUND                141)
173
174    ; For SSE4.2 support
175    (UNSPEC_CRC32                143)
176    (UNSPEC_PCMPESTR             144)
177    (UNSPEC_PCMPISTR             145)
178
179    ;; For SSE5
180    (UNSPEC_SSE5_INTRINSIC       150)
181    (UNSPEC_SSE5_UNSIGNED_CMP    151)
182    (UNSPEC_SSE5_TRUEFALSE       152)
183    (UNSPEC_SSE5_PERMUTE         153)
184    (UNSPEC_FRCZ                 154)
185    (UNSPEC_CVTPH2PS             155)
186    (UNSPEC_CVTPS2PH             156)
187
188    ; For AES support
189    (UNSPEC_AESENC               159)
190    (UNSPEC_AESENCLAST           160)
191    (UNSPEC_AESDEC               161)
192    (UNSPEC_AESDECLAST           162)
193    (UNSPEC_AESIMC               163)
194    (UNSPEC_AESKEYGENASSIST      164)
195
196    ; For PCLMUL support
197    (UNSPEC_PCLMUL               165)
198   ])
199
200 (define_constants
201   [(UNSPECV_BLOCKAGE            0)
202    (UNSPECV_STACK_PROBE         1)
203    (UNSPECV_EMMS                2)
204    (UNSPECV_LDMXCSR             3)
205    (UNSPECV_STMXCSR             4)
206    (UNSPECV_FEMMS               5)
207    (UNSPECV_CLFLUSH             6)
208    (UNSPECV_ALIGN               7)
209    (UNSPECV_MONITOR             8)
210    (UNSPECV_MWAIT               9)
211    (UNSPECV_CMPXCHG_1           10)
212    (UNSPECV_CMPXCHG_2           11)
213    (UNSPECV_XCHG                12)
214    (UNSPECV_LOCK                13)
215    (UNSPECV_PROLOGUE_USE        14)
216   ])
217
218 ;; Constants to represent pcomtrue/pcomfalse variants
219 (define_constants
220   [(PCOM_FALSE                  0)
221    (PCOM_TRUE                   1)
222    (COM_FALSE_S                 2)
223    (COM_FALSE_P                 3)
224    (COM_TRUE_S                  4)
225    (COM_TRUE_P                  5)
226   ])
227
228 ;; Constants used in the SSE5 pperm instruction
229 (define_constants
230   [(PPERM_SRC                   0x00)   /* copy source */
231    (PPERM_INVERT                0x20)   /* invert source */
232    (PPERM_REVERSE               0x40)   /* bit reverse source */
233    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
234    (PPERM_ZERO                  0x80)   /* all 0's */
235    (PPERM_ONES                  0xa0)   /* all 1's */
236    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
237    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
238    (PPERM_SRC1                  0x00)   /* use first source byte */
239    (PPERM_SRC2                  0x10)   /* use second source byte */
240    ])
241
242 ;; Registers by name.
243 (define_constants
244   [(AX_REG                       0)
245    (DX_REG                       1)
246    (CX_REG                       2)
247    (SI_REG                       4)
248    (DI_REG                       5)
249    (BP_REG                       6)
250    (SP_REG                       7)
251    (FLAGS_REG                   17)
252    (FPSR_REG                    18)
253    (FPCR_REG                    19)
254    (R10_REG                     39)
255    (R11_REG                     40)
256   ])
257
258 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
259 ;; from i386.c.
260
261 ;; In C guard expressions, put expressions which may be compile-time
262 ;; constants first.  This allows for better optimization.  For
263 ;; example, write "TARGET_64BIT && reload_completed", not
264 ;; "reload_completed && TARGET_64BIT".
265
266 \f
267 ;; Processor type.  This attribute must exactly match the processor_type
268 ;; enumeration in i386.h.
269 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
270                     nocona,core2,generic32,generic64,amdfam10"
271   (const (symbol_ref "ix86_tune")))
272
273 ;; A basic instruction type.  Refinements due to arguments to be
274 ;; provided in other attributes.
275 (define_attr "type"
276   "other,multi,
277    alu,alu1,negnot,imov,imovx,lea,
278    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
279    icmp,test,ibr,setcc,icmov,
280    push,pop,call,callv,leave,
281    str,bitmanip,
282    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
283    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
284    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
285    ssemuladd,sse4arg,
286    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
287   (const_string "other"))
288
289 ;; Main data type used by the insn
290 (define_attr "mode"
291   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
292   (const_string "unknown"))
293
294 ;; The CPU unit operations uses.
295 (define_attr "unit" "integer,i387,sse,mmx,unknown"
296   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
297            (const_string "i387")
298          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
299                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
300                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
301            (const_string "sse")
302          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
303            (const_string "mmx")
304          (eq_attr "type" "other")
305            (const_string "unknown")]
306          (const_string "integer")))
307
308 ;; The (bounding maximum) length of an instruction immediate.
309 (define_attr "length_immediate" ""
310   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
311                           bitmanip")
312            (const_int 0)
313          (eq_attr "unit" "i387,sse,mmx")
314            (const_int 0)
315          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
316                           imul,icmp,push,pop")
317            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
318          (eq_attr "type" "imov,test")
319            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
320          (eq_attr "type" "call")
321            (if_then_else (match_operand 0 "constant_call_address_operand" "")
322              (const_int 4)
323              (const_int 0))
324          (eq_attr "type" "callv")
325            (if_then_else (match_operand 1 "constant_call_address_operand" "")
326              (const_int 4)
327              (const_int 0))
328          ;; We don't know the size before shorten_branches.  Expect
329          ;; the instruction to fit for better scheduling.
330          (eq_attr "type" "ibr")
331            (const_int 1)
332          ]
333          (symbol_ref "/* Update immediate_length and other attributes! */
334                       gcc_unreachable (),1")))
335
336 ;; The (bounding maximum) length of an instruction address.
337 (define_attr "length_address" ""
338   (cond [(eq_attr "type" "str,other,multi,fxch")
339            (const_int 0)
340          (and (eq_attr "type" "call")
341               (match_operand 0 "constant_call_address_operand" ""))
342              (const_int 0)
343          (and (eq_attr "type" "callv")
344               (match_operand 1 "constant_call_address_operand" ""))
345              (const_int 0)
346          ]
347          (symbol_ref "ix86_attr_length_address_default (insn)")))
348
349 ;; Set when length prefix is used.
350 (define_attr "prefix_data16" ""
351   (if_then_else (ior (eq_attr "mode" "HI")
352                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
353     (const_int 1)
354     (const_int 0)))
355
356 ;; Set when string REP prefix is used.
357 (define_attr "prefix_rep" ""
358   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
359     (const_int 1)
360     (const_int 0)))
361
362 ;; Set when 0f opcode prefix is used.
363 (define_attr "prefix_0f" ""
364   (if_then_else
365     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
366          (eq_attr "unit" "sse,mmx"))
367     (const_int 1)
368     (const_int 0)))
369
370 ;; Set when REX opcode prefix is used.
371 (define_attr "prefix_rex" ""
372   (cond [(and (eq_attr "mode" "DI")
373               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
374            (const_int 1)
375          (and (eq_attr "mode" "QI")
376               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
377                   (const_int 0)))
378            (const_int 1)
379          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
380              (const_int 0))
381            (const_int 1)
382         ]
383         (const_int 0)))
384
385 ;; There are also additional prefixes in SSSE3.
386 (define_attr "prefix_extra" "" (const_int 0))
387
388 ;; Set when modrm byte is used.
389 (define_attr "modrm" ""
390   (cond [(eq_attr "type" "str,leave")
391            (const_int 0)
392          (eq_attr "unit" "i387")
393            (const_int 0)
394          (and (eq_attr "type" "incdec")
395               (ior (match_operand:SI 1 "register_operand" "")
396                    (match_operand:HI 1 "register_operand" "")))
397            (const_int 0)
398          (and (eq_attr "type" "push")
399               (not (match_operand 1 "memory_operand" "")))
400            (const_int 0)
401          (and (eq_attr "type" "pop")
402               (not (match_operand 0 "memory_operand" "")))
403            (const_int 0)
404          (and (eq_attr "type" "imov")
405               (ior (and (match_operand 0 "register_operand" "")
406                         (match_operand 1 "immediate_operand" ""))
407                    (ior (and (match_operand 0 "ax_reg_operand" "")
408                              (match_operand 1 "memory_displacement_only_operand" ""))
409                         (and (match_operand 0 "memory_displacement_only_operand" "")
410                              (match_operand 1 "ax_reg_operand" "")))))
411            (const_int 0)
412          (and (eq_attr "type" "call")
413               (match_operand 0 "constant_call_address_operand" ""))
414              (const_int 0)
415          (and (eq_attr "type" "callv")
416               (match_operand 1 "constant_call_address_operand" ""))
417              (const_int 0)
418          ]
419          (const_int 1)))
420
421 ;; The (bounding maximum) length of an instruction in bytes.
422 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
423 ;; Later we may want to split them and compute proper length as for
424 ;; other insns.
425 (define_attr "length" ""
426   (cond [(eq_attr "type" "other,multi,fistp,frndint")
427            (const_int 16)
428          (eq_attr "type" "fcmp")
429            (const_int 4)
430          (eq_attr "unit" "i387")
431            (plus (const_int 2)
432                  (plus (attr "prefix_data16")
433                        (attr "length_address")))]
434          (plus (plus (attr "modrm")
435                      (plus (attr "prefix_0f")
436                            (plus (attr "prefix_rex")
437                                  (plus (attr "prefix_extra")
438                                        (const_int 1)))))
439                (plus (attr "prefix_rep")
440                      (plus (attr "prefix_data16")
441                            (plus (attr "length_immediate")
442                                  (attr "length_address")))))))
443
444 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
445 ;; `store' if there is a simple memory reference therein, or `unknown'
446 ;; if the instruction is complex.
447
448 (define_attr "memory" "none,load,store,both,unknown"
449   (cond [(eq_attr "type" "other,multi,str")
450            (const_string "unknown")
451          (eq_attr "type" "lea,fcmov,fpspc")
452            (const_string "none")
453          (eq_attr "type" "fistp,leave")
454            (const_string "both")
455          (eq_attr "type" "frndint")
456            (const_string "load")
457          (eq_attr "type" "push")
458            (if_then_else (match_operand 1 "memory_operand" "")
459              (const_string "both")
460              (const_string "store"))
461          (eq_attr "type" "pop")
462            (if_then_else (match_operand 0 "memory_operand" "")
463              (const_string "both")
464              (const_string "load"))
465          (eq_attr "type" "setcc")
466            (if_then_else (match_operand 0 "memory_operand" "")
467              (const_string "store")
468              (const_string "none"))
469          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
470            (if_then_else (ior (match_operand 0 "memory_operand" "")
471                               (match_operand 1 "memory_operand" ""))
472              (const_string "load")
473              (const_string "none"))
474          (eq_attr "type" "ibr")
475            (if_then_else (match_operand 0 "memory_operand" "")
476              (const_string "load")
477              (const_string "none"))
478          (eq_attr "type" "call")
479            (if_then_else (match_operand 0 "constant_call_address_operand" "")
480              (const_string "none")
481              (const_string "load"))
482          (eq_attr "type" "callv")
483            (if_then_else (match_operand 1 "constant_call_address_operand" "")
484              (const_string "none")
485              (const_string "load"))
486          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
487               (match_operand 1 "memory_operand" ""))
488            (const_string "both")
489          (and (match_operand 0 "memory_operand" "")
490               (match_operand 1 "memory_operand" ""))
491            (const_string "both")
492          (match_operand 0 "memory_operand" "")
493            (const_string "store")
494          (match_operand 1 "memory_operand" "")
495            (const_string "load")
496          (and (eq_attr "type"
497                  "!alu1,negnot,ishift1,
498                    imov,imovx,icmp,test,bitmanip,
499                    fmov,fcmp,fsgn,
500                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
501                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
502               (match_operand 2 "memory_operand" ""))
503            (const_string "load")
504          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
505               (match_operand 3 "memory_operand" ""))
506            (const_string "load")
507         ]
508         (const_string "none")))
509
510 ;; Indicates if an instruction has both an immediate and a displacement.
511
512 (define_attr "imm_disp" "false,true,unknown"
513   (cond [(eq_attr "type" "other,multi")
514            (const_string "unknown")
515          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
516               (and (match_operand 0 "memory_displacement_operand" "")
517                    (match_operand 1 "immediate_operand" "")))
518            (const_string "true")
519          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
520               (and (match_operand 0 "memory_displacement_operand" "")
521                    (match_operand 2 "immediate_operand" "")))
522            (const_string "true")
523         ]
524         (const_string "false")))
525
526 ;; Indicates if an FP operation has an integer source.
527
528 (define_attr "fp_int_src" "false,true"
529   (const_string "false"))
530
531 ;; Defines rounding mode of an FP operation.
532
533 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
534   (const_string "any"))
535
536 ;; Describe a user's asm statement.
537 (define_asm_attributes
538   [(set_attr "length" "128")
539    (set_attr "type" "multi")])
540
541 ;; All integer comparison codes.
542 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
543
544 ;; All floating-point comparison codes.
545 (define_code_iterator fp_cond [unordered ordered
546                                uneq unge ungt unle unlt ltgt ])
547
548 (define_code_iterator plusminus [plus minus])
549
550 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
551
552 ;; Base name for define_insn
553 (define_code_attr plusminus_insn
554   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
555    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
556
557 ;; Base name for insn mnemonic.
558 (define_code_attr plusminus_mnemonic
559   [(plus "add") (ss_plus "adds") (us_plus "addus")
560    (minus "sub") (ss_minus "subs") (us_minus "subus")])
561
562 ;; Mark commutative operators as such in constraints.
563 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
564                         (minus "") (ss_minus "") (us_minus "")])
565
566 ;; Mapping of signed max and min
567 (define_code_iterator smaxmin [smax smin])
568
569 ;; Mapping of unsigned max and min
570 (define_code_iterator umaxmin [umax umin])
571
572 ;; Base name for integer and FP insn mnemonic
573 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
574                                  (umax "maxu") (umin "minu")])
575 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
576
577 ;; Mapping of parallel logic operators
578 (define_code_iterator plogic [and ior xor])
579
580 ;; Base name for insn mnemonic.
581 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
582
583 ;; Mapping of abs neg operators
584 (define_code_iterator absneg [abs neg])
585
586 ;; Base name for x87 insn mnemonic.
587 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
588
589 ;; All single word integer modes.
590 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
591
592 ;; Instruction suffix for integer modes.
593 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
594
595 ;; Register class for integer modes.
596 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
597
598 ;; Immediate operand constraint for integer modes.
599 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
600
601 ;; General operand predicate for integer modes.
602 (define_mode_attr general_operand
603         [(QI "general_operand")
604          (HI "general_operand")
605          (SI "general_operand")
606          (DI "x86_64_general_operand")])
607
608 ;; SSE and x87 SFmode and DFmode floating point modes
609 (define_mode_iterator MODEF [SF DF])
610
611 ;; All x87 floating point modes
612 (define_mode_iterator X87MODEF [SF DF XF])
613
614 ;; All integer modes handled by x87 fisttp operator.
615 (define_mode_iterator X87MODEI [HI SI DI])
616
617 ;; All integer modes handled by integer x87 operators.
618 (define_mode_iterator X87MODEI12 [HI SI])
619
620 ;; All integer modes handled by SSE cvtts?2si* operators.
621 (define_mode_iterator SSEMODEI24 [SI DI])
622
623 ;; SSE asm suffix for floating point modes
624 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
625
626 ;; SSE vector mode corresponding to a scalar mode
627 (define_mode_attr ssevecmode
628   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
629
630 ;; Instruction suffix for REX 64bit operators.
631 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
632 \f
633 ;; Scheduling descriptions
634
635 (include "pentium.md")
636 (include "ppro.md")
637 (include "k6.md")
638 (include "athlon.md")
639 (include "geode.md")
640
641 \f
642 ;; Operand and operator predicates and constraints
643
644 (include "predicates.md")
645 (include "constraints.md")
646
647 \f
648 ;; Compare instructions.
649
650 ;; All compare insns have expanders that save the operands away without
651 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
652 ;; after the cmp) will actually emit the cmpM.
653
654 (define_expand "cmpti"
655   [(set (reg:CC FLAGS_REG)
656         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
657                     (match_operand:TI 1 "x86_64_general_operand" "")))]
658   "TARGET_64BIT"
659 {
660   if (MEM_P (operands[0]) && MEM_P (operands[1]))
661     operands[0] = force_reg (TImode, operands[0]);
662   ix86_compare_op0 = operands[0];
663   ix86_compare_op1 = operands[1];
664   DONE;
665 })
666
667 (define_expand "cmpdi"
668   [(set (reg:CC FLAGS_REG)
669         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
670                     (match_operand:DI 1 "x86_64_general_operand" "")))]
671   ""
672 {
673   if (MEM_P (operands[0]) && MEM_P (operands[1]))
674     operands[0] = force_reg (DImode, operands[0]);
675   ix86_compare_op0 = operands[0];
676   ix86_compare_op1 = operands[1];
677   DONE;
678 })
679
680 (define_expand "cmpsi"
681   [(set (reg:CC FLAGS_REG)
682         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
683                     (match_operand:SI 1 "general_operand" "")))]
684   ""
685 {
686   if (MEM_P (operands[0]) && MEM_P (operands[1]))
687     operands[0] = force_reg (SImode, operands[0]);
688   ix86_compare_op0 = operands[0];
689   ix86_compare_op1 = operands[1];
690   DONE;
691 })
692
693 (define_expand "cmphi"
694   [(set (reg:CC FLAGS_REG)
695         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
696                     (match_operand:HI 1 "general_operand" "")))]
697   ""
698 {
699   if (MEM_P (operands[0]) && MEM_P (operands[1]))
700     operands[0] = force_reg (HImode, operands[0]);
701   ix86_compare_op0 = operands[0];
702   ix86_compare_op1 = operands[1];
703   DONE;
704 })
705
706 (define_expand "cmpqi"
707   [(set (reg:CC FLAGS_REG)
708         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
709                     (match_operand:QI 1 "general_operand" "")))]
710   "TARGET_QIMODE_MATH"
711 {
712   if (MEM_P (operands[0]) && MEM_P (operands[1]))
713     operands[0] = force_reg (QImode, operands[0]);
714   ix86_compare_op0 = operands[0];
715   ix86_compare_op1 = operands[1];
716   DONE;
717 })
718
719 (define_insn "cmpdi_ccno_1_rex64"
720   [(set (reg FLAGS_REG)
721         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
722                  (match_operand:DI 1 "const0_operand" "n,n")))]
723   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
724   "@
725    test{q}\t%0, %0
726    cmp{q}\t{%1, %0|%0, %1}"
727   [(set_attr "type" "test,icmp")
728    (set_attr "length_immediate" "0,1")
729    (set_attr "mode" "DI")])
730
731 (define_insn "*cmpdi_minus_1_rex64"
732   [(set (reg FLAGS_REG)
733         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
734                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
735                  (const_int 0)))]
736   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
737   "cmp{q}\t{%1, %0|%0, %1}"
738   [(set_attr "type" "icmp")
739    (set_attr "mode" "DI")])
740
741 (define_expand "cmpdi_1_rex64"
742   [(set (reg:CC FLAGS_REG)
743         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
744                     (match_operand:DI 1 "general_operand" "")))]
745   "TARGET_64BIT"
746   "")
747
748 (define_insn "cmpdi_1_insn_rex64"
749   [(set (reg FLAGS_REG)
750         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
751                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
752   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
753   "cmp{q}\t{%1, %0|%0, %1}"
754   [(set_attr "type" "icmp")
755    (set_attr "mode" "DI")])
756
757
758 (define_insn "*cmpsi_ccno_1"
759   [(set (reg FLAGS_REG)
760         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
761                  (match_operand:SI 1 "const0_operand" "n,n")))]
762   "ix86_match_ccmode (insn, CCNOmode)"
763   "@
764    test{l}\t%0, %0
765    cmp{l}\t{%1, %0|%0, %1}"
766   [(set_attr "type" "test,icmp")
767    (set_attr "length_immediate" "0,1")
768    (set_attr "mode" "SI")])
769
770 (define_insn "*cmpsi_minus_1"
771   [(set (reg FLAGS_REG)
772         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
773                            (match_operand:SI 1 "general_operand" "ri,mr"))
774                  (const_int 0)))]
775   "ix86_match_ccmode (insn, CCGOCmode)"
776   "cmp{l}\t{%1, %0|%0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "SI")])
779
780 (define_expand "cmpsi_1"
781   [(set (reg:CC FLAGS_REG)
782         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
783                     (match_operand:SI 1 "general_operand" "")))]
784   ""
785   "")
786
787 (define_insn "*cmpsi_1_insn"
788   [(set (reg FLAGS_REG)
789         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
790                  (match_operand:SI 1 "general_operand" "ri,mr")))]
791   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
792     && ix86_match_ccmode (insn, CCmode)"
793   "cmp{l}\t{%1, %0|%0, %1}"
794   [(set_attr "type" "icmp")
795    (set_attr "mode" "SI")])
796
797 (define_insn "*cmphi_ccno_1"
798   [(set (reg FLAGS_REG)
799         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
800                  (match_operand:HI 1 "const0_operand" "n,n")))]
801   "ix86_match_ccmode (insn, CCNOmode)"
802   "@
803    test{w}\t%0, %0
804    cmp{w}\t{%1, %0|%0, %1}"
805   [(set_attr "type" "test,icmp")
806    (set_attr "length_immediate" "0,1")
807    (set_attr "mode" "HI")])
808
809 (define_insn "*cmphi_minus_1"
810   [(set (reg FLAGS_REG)
811         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
812                            (match_operand:HI 1 "general_operand" "ri,mr"))
813                  (const_int 0)))]
814   "ix86_match_ccmode (insn, CCGOCmode)"
815   "cmp{w}\t{%1, %0|%0, %1}"
816   [(set_attr "type" "icmp")
817    (set_attr "mode" "HI")])
818
819 (define_insn "*cmphi_1"
820   [(set (reg FLAGS_REG)
821         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
822                  (match_operand:HI 1 "general_operand" "ri,mr")))]
823   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
824    && ix86_match_ccmode (insn, CCmode)"
825   "cmp{w}\t{%1, %0|%0, %1}"
826   [(set_attr "type" "icmp")
827    (set_attr "mode" "HI")])
828
829 (define_insn "*cmpqi_ccno_1"
830   [(set (reg FLAGS_REG)
831         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
832                  (match_operand:QI 1 "const0_operand" "n,n")))]
833   "ix86_match_ccmode (insn, CCNOmode)"
834   "@
835    test{b}\t%0, %0
836    cmp{b}\t{$0, %0|%0, 0}"
837   [(set_attr "type" "test,icmp")
838    (set_attr "length_immediate" "0,1")
839    (set_attr "mode" "QI")])
840
841 (define_insn "*cmpqi_1"
842   [(set (reg FLAGS_REG)
843         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
844                  (match_operand:QI 1 "general_operand" "qi,mq")))]
845   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
846     && ix86_match_ccmode (insn, CCmode)"
847   "cmp{b}\t{%1, %0|%0, %1}"
848   [(set_attr "type" "icmp")
849    (set_attr "mode" "QI")])
850
851 (define_insn "*cmpqi_minus_1"
852   [(set (reg FLAGS_REG)
853         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
854                            (match_operand:QI 1 "general_operand" "qi,mq"))
855                  (const_int 0)))]
856   "ix86_match_ccmode (insn, CCGOCmode)"
857   "cmp{b}\t{%1, %0|%0, %1}"
858   [(set_attr "type" "icmp")
859    (set_attr "mode" "QI")])
860
861 (define_insn "*cmpqi_ext_1"
862   [(set (reg FLAGS_REG)
863         (compare
864           (match_operand:QI 0 "general_operand" "Qm")
865           (subreg:QI
866             (zero_extract:SI
867               (match_operand 1 "ext_register_operand" "Q")
868               (const_int 8)
869               (const_int 8)) 0)))]
870   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
871   "cmp{b}\t{%h1, %0|%0, %h1}"
872   [(set_attr "type" "icmp")
873    (set_attr "mode" "QI")])
874
875 (define_insn "*cmpqi_ext_1_rex64"
876   [(set (reg FLAGS_REG)
877         (compare
878           (match_operand:QI 0 "register_operand" "Q")
879           (subreg:QI
880             (zero_extract:SI
881               (match_operand 1 "ext_register_operand" "Q")
882               (const_int 8)
883               (const_int 8)) 0)))]
884   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
885   "cmp{b}\t{%h1, %0|%0, %h1}"
886   [(set_attr "type" "icmp")
887    (set_attr "mode" "QI")])
888
889 (define_insn "*cmpqi_ext_2"
890   [(set (reg FLAGS_REG)
891         (compare
892           (subreg:QI
893             (zero_extract:SI
894               (match_operand 0 "ext_register_operand" "Q")
895               (const_int 8)
896               (const_int 8)) 0)
897           (match_operand:QI 1 "const0_operand" "n")))]
898   "ix86_match_ccmode (insn, CCNOmode)"
899   "test{b}\t%h0, %h0"
900   [(set_attr "type" "test")
901    (set_attr "length_immediate" "0")
902    (set_attr "mode" "QI")])
903
904 (define_expand "cmpqi_ext_3"
905   [(set (reg:CC FLAGS_REG)
906         (compare:CC
907           (subreg:QI
908             (zero_extract:SI
909               (match_operand 0 "ext_register_operand" "")
910               (const_int 8)
911               (const_int 8)) 0)
912           (match_operand:QI 1 "general_operand" "")))]
913   ""
914   "")
915
916 (define_insn "cmpqi_ext_3_insn"
917   [(set (reg FLAGS_REG)
918         (compare
919           (subreg:QI
920             (zero_extract:SI
921               (match_operand 0 "ext_register_operand" "Q")
922               (const_int 8)
923               (const_int 8)) 0)
924           (match_operand:QI 1 "general_operand" "Qmn")))]
925   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
926   "cmp{b}\t{%1, %h0|%h0, %1}"
927   [(set_attr "type" "icmp")
928    (set_attr "mode" "QI")])
929
930 (define_insn "cmpqi_ext_3_insn_rex64"
931   [(set (reg FLAGS_REG)
932         (compare
933           (subreg:QI
934             (zero_extract:SI
935               (match_operand 0 "ext_register_operand" "Q")
936               (const_int 8)
937               (const_int 8)) 0)
938           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
939   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
940   "cmp{b}\t{%1, %h0|%h0, %1}"
941   [(set_attr "type" "icmp")
942    (set_attr "mode" "QI")])
943
944 (define_insn "*cmpqi_ext_4"
945   [(set (reg FLAGS_REG)
946         (compare
947           (subreg:QI
948             (zero_extract:SI
949               (match_operand 0 "ext_register_operand" "Q")
950               (const_int 8)
951               (const_int 8)) 0)
952           (subreg:QI
953             (zero_extract:SI
954               (match_operand 1 "ext_register_operand" "Q")
955               (const_int 8)
956               (const_int 8)) 0)))]
957   "ix86_match_ccmode (insn, CCmode)"
958   "cmp{b}\t{%h1, %h0|%h0, %h1}"
959   [(set_attr "type" "icmp")
960    (set_attr "mode" "QI")])
961
962 ;; These implement float point compares.
963 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
964 ;; which would allow mix and match FP modes on the compares.  Which is what
965 ;; the old patterns did, but with many more of them.
966
967 (define_expand "cmpxf"
968   [(set (reg:CC FLAGS_REG)
969         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
970                     (match_operand:XF 1 "nonmemory_operand" "")))]
971   "TARGET_80387"
972 {
973   ix86_compare_op0 = operands[0];
974   ix86_compare_op1 = operands[1];
975   DONE;
976 })
977
978 (define_expand "cmp<mode>"
979   [(set (reg:CC FLAGS_REG)
980         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
981                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
982   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
983 {
984   ix86_compare_op0 = operands[0];
985   ix86_compare_op1 = operands[1];
986   DONE;
987 })
988
989 ;; FP compares, step 1:
990 ;; Set the FP condition codes.
991 ;;
992 ;; CCFPmode     compare with exceptions
993 ;; CCFPUmode    compare with no exceptions
994
995 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
996 ;; used to manage the reg stack popping would not be preserved.
997
998 (define_insn "*cmpfp_0"
999   [(set (match_operand:HI 0 "register_operand" "=a")
1000         (unspec:HI
1001           [(compare:CCFP
1002              (match_operand 1 "register_operand" "f")
1003              (match_operand 2 "const0_operand" "X"))]
1004         UNSPEC_FNSTSW))]
1005   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1006    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1007   "* return output_fp_compare (insn, operands, 0, 0);"
1008   [(set_attr "type" "multi")
1009    (set_attr "unit" "i387")
1010    (set (attr "mode")
1011      (cond [(match_operand:SF 1 "" "")
1012               (const_string "SF")
1013             (match_operand:DF 1 "" "")
1014               (const_string "DF")
1015            ]
1016            (const_string "XF")))])
1017
1018 (define_insn_and_split "*cmpfp_0_cc"
1019   [(set (reg:CCFP FLAGS_REG)
1020         (compare:CCFP
1021           (match_operand 1 "register_operand" "f")
1022           (match_operand 2 "const0_operand" "X")))
1023    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1024   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1025    && TARGET_SAHF && !TARGET_CMOVE
1026    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1027   "#"
1028   "&& reload_completed"
1029   [(set (match_dup 0)
1030         (unspec:HI
1031           [(compare:CCFP (match_dup 1)(match_dup 2))]
1032         UNSPEC_FNSTSW))
1033    (set (reg:CC FLAGS_REG)
1034         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1035   ""
1036   [(set_attr "type" "multi")
1037    (set_attr "unit" "i387")
1038    (set (attr "mode")
1039      (cond [(match_operand:SF 1 "" "")
1040               (const_string "SF")
1041             (match_operand:DF 1 "" "")
1042               (const_string "DF")
1043            ]
1044            (const_string "XF")))])
1045
1046 (define_insn "*cmpfp_xf"
1047   [(set (match_operand:HI 0 "register_operand" "=a")
1048         (unspec:HI
1049           [(compare:CCFP
1050              (match_operand:XF 1 "register_operand" "f")
1051              (match_operand:XF 2 "register_operand" "f"))]
1052           UNSPEC_FNSTSW))]
1053   "TARGET_80387"
1054   "* return output_fp_compare (insn, operands, 0, 0);"
1055   [(set_attr "type" "multi")
1056    (set_attr "unit" "i387")
1057    (set_attr "mode" "XF")])
1058
1059 (define_insn_and_split "*cmpfp_xf_cc"
1060   [(set (reg:CCFP FLAGS_REG)
1061         (compare:CCFP
1062           (match_operand:XF 1 "register_operand" "f")
1063           (match_operand:XF 2 "register_operand" "f")))
1064    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1065   "TARGET_80387
1066    && TARGET_SAHF && !TARGET_CMOVE"
1067   "#"
1068   "&& reload_completed"
1069   [(set (match_dup 0)
1070         (unspec:HI
1071           [(compare:CCFP (match_dup 1)(match_dup 2))]
1072         UNSPEC_FNSTSW))
1073    (set (reg:CC FLAGS_REG)
1074         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1075   ""
1076   [(set_attr "type" "multi")
1077    (set_attr "unit" "i387")
1078    (set_attr "mode" "XF")])
1079
1080 (define_insn "*cmpfp_<mode>"
1081   [(set (match_operand:HI 0 "register_operand" "=a")
1082         (unspec:HI
1083           [(compare:CCFP
1084              (match_operand:MODEF 1 "register_operand" "f")
1085              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1086           UNSPEC_FNSTSW))]
1087   "TARGET_80387"
1088   "* return output_fp_compare (insn, operands, 0, 0);"
1089   [(set_attr "type" "multi")
1090    (set_attr "unit" "i387")
1091    (set_attr "mode" "<MODE>")])
1092
1093 (define_insn_and_split "*cmpfp_<mode>_cc"
1094   [(set (reg:CCFP FLAGS_REG)
1095         (compare:CCFP
1096           (match_operand:MODEF 1 "register_operand" "f")
1097           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1098    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1099   "TARGET_80387
1100    && TARGET_SAHF && !TARGET_CMOVE"
1101   "#"
1102   "&& reload_completed"
1103   [(set (match_dup 0)
1104         (unspec:HI
1105           [(compare:CCFP (match_dup 1)(match_dup 2))]
1106         UNSPEC_FNSTSW))
1107    (set (reg:CC FLAGS_REG)
1108         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1109   ""
1110   [(set_attr "type" "multi")
1111    (set_attr "unit" "i387")
1112    (set_attr "mode" "<MODE>")])
1113
1114 (define_insn "*cmpfp_u"
1115   [(set (match_operand:HI 0 "register_operand" "=a")
1116         (unspec:HI
1117           [(compare:CCFPU
1118              (match_operand 1 "register_operand" "f")
1119              (match_operand 2 "register_operand" "f"))]
1120           UNSPEC_FNSTSW))]
1121   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1123   "* return output_fp_compare (insn, operands, 0, 1);"
1124   [(set_attr "type" "multi")
1125    (set_attr "unit" "i387")
1126    (set (attr "mode")
1127      (cond [(match_operand:SF 1 "" "")
1128               (const_string "SF")
1129             (match_operand:DF 1 "" "")
1130               (const_string "DF")
1131            ]
1132            (const_string "XF")))])
1133
1134 (define_insn_and_split "*cmpfp_u_cc"
1135   [(set (reg:CCFPU FLAGS_REG)
1136         (compare:CCFPU
1137           (match_operand 1 "register_operand" "f")
1138           (match_operand 2 "register_operand" "f")))
1139    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1140   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1141    && TARGET_SAHF && !TARGET_CMOVE
1142    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1143   "#"
1144   "&& reload_completed"
1145   [(set (match_dup 0)
1146         (unspec:HI
1147           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1148         UNSPEC_FNSTSW))
1149    (set (reg:CC FLAGS_REG)
1150         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1151   ""
1152   [(set_attr "type" "multi")
1153    (set_attr "unit" "i387")
1154    (set (attr "mode")
1155      (cond [(match_operand:SF 1 "" "")
1156               (const_string "SF")
1157             (match_operand:DF 1 "" "")
1158               (const_string "DF")
1159            ]
1160            (const_string "XF")))])
1161
1162 (define_insn "*cmpfp_<mode>"
1163   [(set (match_operand:HI 0 "register_operand" "=a")
1164         (unspec:HI
1165           [(compare:CCFP
1166              (match_operand 1 "register_operand" "f")
1167              (match_operator 3 "float_operator"
1168                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1169           UNSPEC_FNSTSW))]
1170   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1171    && TARGET_USE_<MODE>MODE_FIOP
1172    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1173   "* return output_fp_compare (insn, operands, 0, 0);"
1174   [(set_attr "type" "multi")
1175    (set_attr "unit" "i387")
1176    (set_attr "fp_int_src" "true")
1177    (set_attr "mode" "<MODE>")])
1178
1179 (define_insn_and_split "*cmpfp_<mode>_cc"
1180   [(set (reg:CCFP FLAGS_REG)
1181         (compare:CCFP
1182           (match_operand 1 "register_operand" "f")
1183           (match_operator 3 "float_operator"
1184             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1185    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1186   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1187    && TARGET_SAHF && !TARGET_CMOVE
1188    && TARGET_USE_<MODE>MODE_FIOP
1189    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1190   "#"
1191   "&& reload_completed"
1192   [(set (match_dup 0)
1193         (unspec:HI
1194           [(compare:CCFP
1195              (match_dup 1)
1196              (match_op_dup 3 [(match_dup 2)]))]
1197         UNSPEC_FNSTSW))
1198    (set (reg:CC FLAGS_REG)
1199         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1200   ""
1201   [(set_attr "type" "multi")
1202    (set_attr "unit" "i387")
1203    (set_attr "fp_int_src" "true")
1204    (set_attr "mode" "<MODE>")])
1205
1206 ;; FP compares, step 2
1207 ;; Move the fpsw to ax.
1208
1209 (define_insn "x86_fnstsw_1"
1210   [(set (match_operand:HI 0 "register_operand" "=a")
1211         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1212   "TARGET_80387"
1213   "fnstsw\t%0"
1214   [(set_attr "length" "2")
1215    (set_attr "mode" "SI")
1216    (set_attr "unit" "i387")])
1217
1218 ;; FP compares, step 3
1219 ;; Get ax into flags, general case.
1220
1221 (define_insn "x86_sahf_1"
1222   [(set (reg:CC FLAGS_REG)
1223         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1224                    UNSPEC_SAHF))]
1225   "TARGET_SAHF"
1226 {
1227 #ifdef HAVE_AS_IX86_SAHF
1228   return "sahf";
1229 #else
1230   return ".byte\t0x9e";
1231 #endif
1232 }
1233   [(set_attr "length" "1")
1234    (set_attr "athlon_decode" "vector")
1235    (set_attr "amdfam10_decode" "direct")
1236    (set_attr "mode" "SI")])
1237
1238 ;; Pentium Pro can do steps 1 through 3 in one go.
1239 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1240 (define_insn "*cmpfp_i_mixed"
1241   [(set (reg:CCFP FLAGS_REG)
1242         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1243                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1244   "TARGET_MIX_SSE_I387
1245    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1246    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1247   "* return output_fp_compare (insn, operands, 1, 0);"
1248   [(set_attr "type" "fcmp,ssecomi")
1249    (set (attr "mode")
1250      (if_then_else (match_operand:SF 1 "" "")
1251         (const_string "SF")
1252         (const_string "DF")))
1253    (set_attr "athlon_decode" "vector")
1254    (set_attr "amdfam10_decode" "direct")])
1255
1256 (define_insn "*cmpfp_i_sse"
1257   [(set (reg:CCFP FLAGS_REG)
1258         (compare:CCFP (match_operand 0 "register_operand" "x")
1259                       (match_operand 1 "nonimmediate_operand" "xm")))]
1260   "TARGET_SSE_MATH
1261    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1262    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1263   "* return output_fp_compare (insn, operands, 1, 0);"
1264   [(set_attr "type" "ssecomi")
1265    (set (attr "mode")
1266      (if_then_else (match_operand:SF 1 "" "")
1267         (const_string "SF")
1268         (const_string "DF")))
1269    (set_attr "athlon_decode" "vector")
1270    (set_attr "amdfam10_decode" "direct")])
1271
1272 (define_insn "*cmpfp_i_i387"
1273   [(set (reg:CCFP FLAGS_REG)
1274         (compare:CCFP (match_operand 0 "register_operand" "f")
1275                       (match_operand 1 "register_operand" "f")))]
1276   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1277    && TARGET_CMOVE
1278    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1279    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1280   "* return output_fp_compare (insn, operands, 1, 0);"
1281   [(set_attr "type" "fcmp")
1282    (set (attr "mode")
1283      (cond [(match_operand:SF 1 "" "")
1284               (const_string "SF")
1285             (match_operand:DF 1 "" "")
1286               (const_string "DF")
1287            ]
1288            (const_string "XF")))
1289    (set_attr "athlon_decode" "vector")
1290    (set_attr "amdfam10_decode" "direct")])
1291
1292 (define_insn "*cmpfp_iu_mixed"
1293   [(set (reg:CCFPU FLAGS_REG)
1294         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1295                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1296   "TARGET_MIX_SSE_I387
1297    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1298    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1299   "* return output_fp_compare (insn, operands, 1, 1);"
1300   [(set_attr "type" "fcmp,ssecomi")
1301    (set (attr "mode")
1302      (if_then_else (match_operand:SF 1 "" "")
1303         (const_string "SF")
1304         (const_string "DF")))
1305    (set_attr "athlon_decode" "vector")
1306    (set_attr "amdfam10_decode" "direct")])
1307
1308 (define_insn "*cmpfp_iu_sse"
1309   [(set (reg:CCFPU FLAGS_REG)
1310         (compare:CCFPU (match_operand 0 "register_operand" "x")
1311                        (match_operand 1 "nonimmediate_operand" "xm")))]
1312   "TARGET_SSE_MATH
1313    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1314    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1315   "* return output_fp_compare (insn, operands, 1, 1);"
1316   [(set_attr "type" "ssecomi")
1317    (set (attr "mode")
1318      (if_then_else (match_operand:SF 1 "" "")
1319         (const_string "SF")
1320         (const_string "DF")))
1321    (set_attr "athlon_decode" "vector")
1322    (set_attr "amdfam10_decode" "direct")])
1323
1324 (define_insn "*cmpfp_iu_387"
1325   [(set (reg:CCFPU FLAGS_REG)
1326         (compare:CCFPU (match_operand 0 "register_operand" "f")
1327                        (match_operand 1 "register_operand" "f")))]
1328   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1329    && TARGET_CMOVE
1330    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1331    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1332   "* return output_fp_compare (insn, operands, 1, 1);"
1333   [(set_attr "type" "fcmp")
1334    (set (attr "mode")
1335      (cond [(match_operand:SF 1 "" "")
1336               (const_string "SF")
1337             (match_operand:DF 1 "" "")
1338               (const_string "DF")
1339            ]
1340            (const_string "XF")))
1341    (set_attr "athlon_decode" "vector")
1342    (set_attr "amdfam10_decode" "direct")])
1343 \f
1344 ;; Move instructions.
1345
1346 ;; General case of fullword move.
1347
1348 (define_expand "movsi"
1349   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1350         (match_operand:SI 1 "general_operand" ""))]
1351   ""
1352   "ix86_expand_move (SImode, operands); DONE;")
1353
1354 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1355 ;; general_operand.
1356 ;;
1357 ;; %%% We don't use a post-inc memory reference because x86 is not a
1358 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1359 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1360 ;; targets without our curiosities, and it is just as easy to represent
1361 ;; this differently.
1362
1363 (define_insn "*pushsi2"
1364   [(set (match_operand:SI 0 "push_operand" "=<")
1365         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1366   "!TARGET_64BIT"
1367   "push{l}\t%1"
1368   [(set_attr "type" "push")
1369    (set_attr "mode" "SI")])
1370
1371 ;; For 64BIT abi we always round up to 8 bytes.
1372 (define_insn "*pushsi2_rex64"
1373   [(set (match_operand:SI 0 "push_operand" "=X")
1374         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1375   "TARGET_64BIT"
1376   "push{q}\t%q1"
1377   [(set_attr "type" "push")
1378    (set_attr "mode" "SI")])
1379
1380 (define_insn "*pushsi2_prologue"
1381   [(set (match_operand:SI 0 "push_operand" "=<")
1382         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1383    (clobber (mem:BLK (scratch)))]
1384   "!TARGET_64BIT"
1385   "push{l}\t%1"
1386   [(set_attr "type" "push")
1387    (set_attr "mode" "SI")])
1388
1389 (define_insn "*popsi1_epilogue"
1390   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1391         (mem:SI (reg:SI SP_REG)))
1392    (set (reg:SI SP_REG)
1393         (plus:SI (reg:SI SP_REG) (const_int 4)))
1394    (clobber (mem:BLK (scratch)))]
1395   "!TARGET_64BIT"
1396   "pop{l}\t%0"
1397   [(set_attr "type" "pop")
1398    (set_attr "mode" "SI")])
1399
1400 (define_insn "popsi1"
1401   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1402         (mem:SI (reg:SI SP_REG)))
1403    (set (reg:SI SP_REG)
1404         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1405   "!TARGET_64BIT"
1406   "pop{l}\t%0"
1407   [(set_attr "type" "pop")
1408    (set_attr "mode" "SI")])
1409
1410 (define_insn "*movsi_xor"
1411   [(set (match_operand:SI 0 "register_operand" "=r")
1412         (match_operand:SI 1 "const0_operand" "i"))
1413    (clobber (reg:CC FLAGS_REG))]
1414   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1415   "xor{l}\t%0, %0"
1416   [(set_attr "type" "alu1")
1417    (set_attr "mode" "SI")
1418    (set_attr "length_immediate" "0")])
1419
1420 (define_insn "*movsi_or"
1421   [(set (match_operand:SI 0 "register_operand" "=r")
1422         (match_operand:SI 1 "immediate_operand" "i"))
1423    (clobber (reg:CC FLAGS_REG))]
1424   "reload_completed
1425    && operands[1] == constm1_rtx
1426    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1427 {
1428   operands[1] = constm1_rtx;
1429   return "or{l}\t{%1, %0|%0, %1}";
1430 }
1431   [(set_attr "type" "alu1")
1432    (set_attr "mode" "SI")
1433    (set_attr "length_immediate" "1")])
1434
1435 (define_insn "*movsi_1"
1436   [(set (match_operand:SI 0 "nonimmediate_operand"
1437                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1438         (match_operand:SI 1 "general_operand"
1439                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1440   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1441 {
1442   switch (get_attr_type (insn))
1443     {
1444     case TYPE_SSELOG1:
1445       if (get_attr_mode (insn) == MODE_TI)
1446         return "pxor\t%0, %0";
1447       return "xorps\t%0, %0";
1448
1449     case TYPE_SSEMOV:
1450       switch (get_attr_mode (insn))
1451         {
1452         case MODE_TI:
1453           return "movdqa\t{%1, %0|%0, %1}";
1454         case MODE_V4SF:
1455           return "movaps\t{%1, %0|%0, %1}";
1456         case MODE_SI:
1457           return "movd\t{%1, %0|%0, %1}";
1458         case MODE_SF:
1459           return "movss\t{%1, %0|%0, %1}";
1460         default:
1461           gcc_unreachable ();
1462         }
1463
1464     case TYPE_MMXADD:
1465       return "pxor\t%0, %0";
1466
1467     case TYPE_MMXMOV:
1468       if (get_attr_mode (insn) == MODE_DI)
1469         return "movq\t{%1, %0|%0, %1}";
1470       return "movd\t{%1, %0|%0, %1}";
1471
1472     case TYPE_LEA:
1473       return "lea{l}\t{%1, %0|%0, %1}";
1474
1475     default:
1476       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1477       return "mov{l}\t{%1, %0|%0, %1}";
1478     }
1479 }
1480   [(set (attr "type")
1481      (cond [(eq_attr "alternative" "2")
1482               (const_string "mmxadd")
1483             (eq_attr "alternative" "3,4,5")
1484               (const_string "mmxmov")
1485             (eq_attr "alternative" "6")
1486               (const_string "sselog1")
1487             (eq_attr "alternative" "7,8,9,10,11")
1488               (const_string "ssemov")
1489             (match_operand:DI 1 "pic_32bit_operand" "")
1490               (const_string "lea")
1491            ]
1492            (const_string "imov")))
1493    (set (attr "mode")
1494      (cond [(eq_attr "alternative" "2,3")
1495               (const_string "DI")
1496             (eq_attr "alternative" "6,7")
1497               (if_then_else
1498                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1499                 (const_string "V4SF")
1500                 (const_string "TI"))
1501             (and (eq_attr "alternative" "8,9,10,11")
1502                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1503               (const_string "SF")
1504            ]
1505            (const_string "SI")))])
1506
1507 ;; Stores and loads of ax to arbitrary constant address.
1508 ;; We fake an second form of instruction to force reload to load address
1509 ;; into register when rax is not available
1510 (define_insn "*movabssi_1_rex64"
1511   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1512         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1513   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1514   "@
1515    movabs{l}\t{%1, %P0|%P0, %1}
1516    mov{l}\t{%1, %a0|%a0, %1}"
1517   [(set_attr "type" "imov")
1518    (set_attr "modrm" "0,*")
1519    (set_attr "length_address" "8,0")
1520    (set_attr "length_immediate" "0,*")
1521    (set_attr "memory" "store")
1522    (set_attr "mode" "SI")])
1523
1524 (define_insn "*movabssi_2_rex64"
1525   [(set (match_operand:SI 0 "register_operand" "=a,r")
1526         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1527   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1528   "@
1529    movabs{l}\t{%P1, %0|%0, %P1}
1530    mov{l}\t{%a1, %0|%0, %a1}"
1531   [(set_attr "type" "imov")
1532    (set_attr "modrm" "0,*")
1533    (set_attr "length_address" "8,0")
1534    (set_attr "length_immediate" "0")
1535    (set_attr "memory" "load")
1536    (set_attr "mode" "SI")])
1537
1538 (define_insn "*swapsi"
1539   [(set (match_operand:SI 0 "register_operand" "+r")
1540         (match_operand:SI 1 "register_operand" "+r"))
1541    (set (match_dup 1)
1542         (match_dup 0))]
1543   ""
1544   "xchg{l}\t%1, %0"
1545   [(set_attr "type" "imov")
1546    (set_attr "mode" "SI")
1547    (set_attr "pent_pair" "np")
1548    (set_attr "athlon_decode" "vector")
1549    (set_attr "amdfam10_decode" "double")])
1550
1551 (define_expand "movhi"
1552   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1553         (match_operand:HI 1 "general_operand" ""))]
1554   ""
1555   "ix86_expand_move (HImode, operands); DONE;")
1556
1557 (define_insn "*pushhi2"
1558   [(set (match_operand:HI 0 "push_operand" "=X")
1559         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1560   "!TARGET_64BIT"
1561   "push{l}\t%k1"
1562   [(set_attr "type" "push")
1563    (set_attr "mode" "SI")])
1564
1565 ;; For 64BIT abi we always round up to 8 bytes.
1566 (define_insn "*pushhi2_rex64"
1567   [(set (match_operand:HI 0 "push_operand" "=X")
1568         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1569   "TARGET_64BIT"
1570   "push{q}\t%q1"
1571   [(set_attr "type" "push")
1572    (set_attr "mode" "DI")])
1573
1574 (define_insn "*movhi_1"
1575   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1576         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1577   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1578 {
1579   switch (get_attr_type (insn))
1580     {
1581     case TYPE_IMOVX:
1582       /* movzwl is faster than movw on p2 due to partial word stalls,
1583          though not as fast as an aligned movl.  */
1584       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1585     default:
1586       if (get_attr_mode (insn) == MODE_SI)
1587         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1588       else
1589         return "mov{w}\t{%1, %0|%0, %1}";
1590     }
1591 }
1592   [(set (attr "type")
1593      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1594               (const_string "imov")
1595             (and (eq_attr "alternative" "0")
1596                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1597                           (const_int 0))
1598                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1599                           (const_int 0))))
1600               (const_string "imov")
1601             (and (eq_attr "alternative" "1,2")
1602                  (match_operand:HI 1 "aligned_operand" ""))
1603               (const_string "imov")
1604             (and (ne (symbol_ref "TARGET_MOVX")
1605                      (const_int 0))
1606                  (eq_attr "alternative" "0,2"))
1607               (const_string "imovx")
1608            ]
1609            (const_string "imov")))
1610     (set (attr "mode")
1611       (cond [(eq_attr "type" "imovx")
1612                (const_string "SI")
1613              (and (eq_attr "alternative" "1,2")
1614                   (match_operand:HI 1 "aligned_operand" ""))
1615                (const_string "SI")
1616              (and (eq_attr "alternative" "0")
1617                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1618                            (const_int 0))
1619                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1620                            (const_int 0))))
1621                (const_string "SI")
1622             ]
1623             (const_string "HI")))])
1624
1625 ;; Stores and loads of ax to arbitrary constant address.
1626 ;; We fake an second form of instruction to force reload to load address
1627 ;; into register when rax is not available
1628 (define_insn "*movabshi_1_rex64"
1629   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1630         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1631   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1632   "@
1633    movabs{w}\t{%1, %P0|%P0, %1}
1634    mov{w}\t{%1, %a0|%a0, %1}"
1635   [(set_attr "type" "imov")
1636    (set_attr "modrm" "0,*")
1637    (set_attr "length_address" "8,0")
1638    (set_attr "length_immediate" "0,*")
1639    (set_attr "memory" "store")
1640    (set_attr "mode" "HI")])
1641
1642 (define_insn "*movabshi_2_rex64"
1643   [(set (match_operand:HI 0 "register_operand" "=a,r")
1644         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1645   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1646   "@
1647    movabs{w}\t{%P1, %0|%0, %P1}
1648    mov{w}\t{%a1, %0|%0, %a1}"
1649   [(set_attr "type" "imov")
1650    (set_attr "modrm" "0,*")
1651    (set_attr "length_address" "8,0")
1652    (set_attr "length_immediate" "0")
1653    (set_attr "memory" "load")
1654    (set_attr "mode" "HI")])
1655
1656 (define_insn "*swaphi_1"
1657   [(set (match_operand:HI 0 "register_operand" "+r")
1658         (match_operand:HI 1 "register_operand" "+r"))
1659    (set (match_dup 1)
1660         (match_dup 0))]
1661   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1662   "xchg{l}\t%k1, %k0"
1663   [(set_attr "type" "imov")
1664    (set_attr "mode" "SI")
1665    (set_attr "pent_pair" "np")
1666    (set_attr "athlon_decode" "vector")
1667    (set_attr "amdfam10_decode" "double")])
1668
1669 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1670 (define_insn "*swaphi_2"
1671   [(set (match_operand:HI 0 "register_operand" "+r")
1672         (match_operand:HI 1 "register_operand" "+r"))
1673    (set (match_dup 1)
1674         (match_dup 0))]
1675   "TARGET_PARTIAL_REG_STALL"
1676   "xchg{w}\t%1, %0"
1677   [(set_attr "type" "imov")
1678    (set_attr "mode" "HI")
1679    (set_attr "pent_pair" "np")
1680    (set_attr "athlon_decode" "vector")])
1681
1682 (define_expand "movstricthi"
1683   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1684         (match_operand:HI 1 "general_operand" ""))]
1685   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1686 {
1687   /* Don't generate memory->memory moves, go through a register */
1688   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1689     operands[1] = force_reg (HImode, operands[1]);
1690 })
1691
1692 (define_insn "*movstricthi_1"
1693   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1694         (match_operand:HI 1 "general_operand" "rn,m"))]
1695   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1696    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1697   "mov{w}\t{%1, %0|%0, %1}"
1698   [(set_attr "type" "imov")
1699    (set_attr "mode" "HI")])
1700
1701 (define_insn "*movstricthi_xor"
1702   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1703         (match_operand:HI 1 "const0_operand" "i"))
1704    (clobber (reg:CC FLAGS_REG))]
1705   "reload_completed
1706    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1707   "xor{w}\t%0, %0"
1708   [(set_attr "type" "alu1")
1709    (set_attr "mode" "HI")
1710    (set_attr "length_immediate" "0")])
1711
1712 (define_expand "movqi"
1713   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1714         (match_operand:QI 1 "general_operand" ""))]
1715   ""
1716   "ix86_expand_move (QImode, operands); DONE;")
1717
1718 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1719 ;; "push a byte".  But actually we use pushl, which has the effect
1720 ;; of rounding the amount pushed up to a word.
1721
1722 (define_insn "*pushqi2"
1723   [(set (match_operand:QI 0 "push_operand" "=X")
1724         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1725   "!TARGET_64BIT"
1726   "push{l}\t%k1"
1727   [(set_attr "type" "push")
1728    (set_attr "mode" "SI")])
1729
1730 ;; For 64BIT abi we always round up to 8 bytes.
1731 (define_insn "*pushqi2_rex64"
1732   [(set (match_operand:QI 0 "push_operand" "=X")
1733         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1734   "TARGET_64BIT"
1735   "push{q}\t%q1"
1736   [(set_attr "type" "push")
1737    (set_attr "mode" "DI")])
1738
1739 ;; Situation is quite tricky about when to choose full sized (SImode) move
1740 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1741 ;; partial register dependency machines (such as AMD Athlon), where QImode
1742 ;; moves issue extra dependency and for partial register stalls machines
1743 ;; that don't use QImode patterns (and QImode move cause stall on the next
1744 ;; instruction).
1745 ;;
1746 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1747 ;; register stall machines with, where we use QImode instructions, since
1748 ;; partial register stall can be caused there.  Then we use movzx.
1749 (define_insn "*movqi_1"
1750   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1751         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1752   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1753 {
1754   switch (get_attr_type (insn))
1755     {
1756     case TYPE_IMOVX:
1757       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1758       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1759     default:
1760       if (get_attr_mode (insn) == MODE_SI)
1761         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1762       else
1763         return "mov{b}\t{%1, %0|%0, %1}";
1764     }
1765 }
1766   [(set (attr "type")
1767      (cond [(and (eq_attr "alternative" "5")
1768                  (not (match_operand:QI 1 "aligned_operand" "")))
1769               (const_string "imovx")
1770             (ne (symbol_ref "optimize_size") (const_int 0))
1771               (const_string "imov")
1772             (and (eq_attr "alternative" "3")
1773                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1774                           (const_int 0))
1775                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1776                           (const_int 0))))
1777               (const_string "imov")
1778             (eq_attr "alternative" "3,5")
1779               (const_string "imovx")
1780             (and (ne (symbol_ref "TARGET_MOVX")
1781                      (const_int 0))
1782                  (eq_attr "alternative" "2"))
1783               (const_string "imovx")
1784            ]
1785            (const_string "imov")))
1786    (set (attr "mode")
1787       (cond [(eq_attr "alternative" "3,4,5")
1788                (const_string "SI")
1789              (eq_attr "alternative" "6")
1790                (const_string "QI")
1791              (eq_attr "type" "imovx")
1792                (const_string "SI")
1793              (and (eq_attr "type" "imov")
1794                   (and (eq_attr "alternative" "0,1")
1795                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1796                                 (const_int 0))
1797                             (and (eq (symbol_ref "optimize_size")
1798                                      (const_int 0))
1799                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1800                                      (const_int 0))))))
1801                (const_string "SI")
1802              ;; Avoid partial register stalls when not using QImode arithmetic
1803              (and (eq_attr "type" "imov")
1804                   (and (eq_attr "alternative" "0,1")
1805                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1806                                 (const_int 0))
1807                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1808                                 (const_int 0)))))
1809                (const_string "SI")
1810            ]
1811            (const_string "QI")))])
1812
1813 (define_insn "*swapqi_1"
1814   [(set (match_operand:QI 0 "register_operand" "+r")
1815         (match_operand:QI 1 "register_operand" "+r"))
1816    (set (match_dup 1)
1817         (match_dup 0))]
1818   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1819   "xchg{l}\t%k1, %k0"
1820   [(set_attr "type" "imov")
1821    (set_attr "mode" "SI")
1822    (set_attr "pent_pair" "np")
1823    (set_attr "athlon_decode" "vector")
1824    (set_attr "amdfam10_decode" "vector")])
1825
1826 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1827 (define_insn "*swapqi_2"
1828   [(set (match_operand:QI 0 "register_operand" "+q")
1829         (match_operand:QI 1 "register_operand" "+q"))
1830    (set (match_dup 1)
1831         (match_dup 0))]
1832   "TARGET_PARTIAL_REG_STALL"
1833   "xchg{b}\t%1, %0"
1834   [(set_attr "type" "imov")
1835    (set_attr "mode" "QI")
1836    (set_attr "pent_pair" "np")
1837    (set_attr "athlon_decode" "vector")])
1838
1839 (define_expand "movstrictqi"
1840   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1841         (match_operand:QI 1 "general_operand" ""))]
1842   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1843 {
1844   /* Don't generate memory->memory moves, go through a register.  */
1845   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1846     operands[1] = force_reg (QImode, operands[1]);
1847 })
1848
1849 (define_insn "*movstrictqi_1"
1850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1851         (match_operand:QI 1 "general_operand" "*qn,m"))]
1852   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1853    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1854   "mov{b}\t{%1, %0|%0, %1}"
1855   [(set_attr "type" "imov")
1856    (set_attr "mode" "QI")])
1857
1858 (define_insn "*movstrictqi_xor"
1859   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1860         (match_operand:QI 1 "const0_operand" "i"))
1861    (clobber (reg:CC FLAGS_REG))]
1862   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1863   "xor{b}\t%0, %0"
1864   [(set_attr "type" "alu1")
1865    (set_attr "mode" "QI")
1866    (set_attr "length_immediate" "0")])
1867
1868 (define_insn "*movsi_extv_1"
1869   [(set (match_operand:SI 0 "register_operand" "=R")
1870         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1871                          (const_int 8)
1872                          (const_int 8)))]
1873   ""
1874   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1875   [(set_attr "type" "imovx")
1876    (set_attr "mode" "SI")])
1877
1878 (define_insn "*movhi_extv_1"
1879   [(set (match_operand:HI 0 "register_operand" "=R")
1880         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1881                          (const_int 8)
1882                          (const_int 8)))]
1883   ""
1884   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1885   [(set_attr "type" "imovx")
1886    (set_attr "mode" "SI")])
1887
1888 (define_insn "*movqi_extv_1"
1889   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1890         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1891                          (const_int 8)
1892                          (const_int 8)))]
1893   "!TARGET_64BIT"
1894 {
1895   switch (get_attr_type (insn))
1896     {
1897     case TYPE_IMOVX:
1898       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1899     default:
1900       return "mov{b}\t{%h1, %0|%0, %h1}";
1901     }
1902 }
1903   [(set (attr "type")
1904      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1905                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1906                              (ne (symbol_ref "TARGET_MOVX")
1907                                  (const_int 0))))
1908         (const_string "imovx")
1909         (const_string "imov")))
1910    (set (attr "mode")
1911      (if_then_else (eq_attr "type" "imovx")
1912         (const_string "SI")
1913         (const_string "QI")))])
1914
1915 (define_insn "*movqi_extv_1_rex64"
1916   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1917         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1918                          (const_int 8)
1919                          (const_int 8)))]
1920   "TARGET_64BIT"
1921 {
1922   switch (get_attr_type (insn))
1923     {
1924     case TYPE_IMOVX:
1925       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1926     default:
1927       return "mov{b}\t{%h1, %0|%0, %h1}";
1928     }
1929 }
1930   [(set (attr "type")
1931      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1932                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1933                              (ne (symbol_ref "TARGET_MOVX")
1934                                  (const_int 0))))
1935         (const_string "imovx")
1936         (const_string "imov")))
1937    (set (attr "mode")
1938      (if_then_else (eq_attr "type" "imovx")
1939         (const_string "SI")
1940         (const_string "QI")))])
1941
1942 ;; Stores and loads of ax to arbitrary constant address.
1943 ;; We fake an second form of instruction to force reload to load address
1944 ;; into register when rax is not available
1945 (define_insn "*movabsqi_1_rex64"
1946   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1947         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1948   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1949   "@
1950    movabs{b}\t{%1, %P0|%P0, %1}
1951    mov{b}\t{%1, %a0|%a0, %1}"
1952   [(set_attr "type" "imov")
1953    (set_attr "modrm" "0,*")
1954    (set_attr "length_address" "8,0")
1955    (set_attr "length_immediate" "0,*")
1956    (set_attr "memory" "store")
1957    (set_attr "mode" "QI")])
1958
1959 (define_insn "*movabsqi_2_rex64"
1960   [(set (match_operand:QI 0 "register_operand" "=a,r")
1961         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1962   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1963   "@
1964    movabs{b}\t{%P1, %0|%0, %P1}
1965    mov{b}\t{%a1, %0|%0, %a1}"
1966   [(set_attr "type" "imov")
1967    (set_attr "modrm" "0,*")
1968    (set_attr "length_address" "8,0")
1969    (set_attr "length_immediate" "0")
1970    (set_attr "memory" "load")
1971    (set_attr "mode" "QI")])
1972
1973 (define_insn "*movdi_extzv_1"
1974   [(set (match_operand:DI 0 "register_operand" "=R")
1975         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1976                          (const_int 8)
1977                          (const_int 8)))]
1978   "TARGET_64BIT"
1979   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1980   [(set_attr "type" "imovx")
1981    (set_attr "mode" "DI")])
1982
1983 (define_insn "*movsi_extzv_1"
1984   [(set (match_operand:SI 0 "register_operand" "=R")
1985         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1986                          (const_int 8)
1987                          (const_int 8)))]
1988   ""
1989   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1990   [(set_attr "type" "imovx")
1991    (set_attr "mode" "SI")])
1992
1993 (define_insn "*movqi_extzv_2"
1994   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1995         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1996                                     (const_int 8)
1997                                     (const_int 8)) 0))]
1998   "!TARGET_64BIT"
1999 {
2000   switch (get_attr_type (insn))
2001     {
2002     case TYPE_IMOVX:
2003       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2004     default:
2005       return "mov{b}\t{%h1, %0|%0, %h1}";
2006     }
2007 }
2008   [(set (attr "type")
2009      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2010                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2011                              (ne (symbol_ref "TARGET_MOVX")
2012                                  (const_int 0))))
2013         (const_string "imovx")
2014         (const_string "imov")))
2015    (set (attr "mode")
2016      (if_then_else (eq_attr "type" "imovx")
2017         (const_string "SI")
2018         (const_string "QI")))])
2019
2020 (define_insn "*movqi_extzv_2_rex64"
2021   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2022         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2023                                     (const_int 8)
2024                                     (const_int 8)) 0))]
2025   "TARGET_64BIT"
2026 {
2027   switch (get_attr_type (insn))
2028     {
2029     case TYPE_IMOVX:
2030       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2031     default:
2032       return "mov{b}\t{%h1, %0|%0, %h1}";
2033     }
2034 }
2035   [(set (attr "type")
2036      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2037                         (ne (symbol_ref "TARGET_MOVX")
2038                             (const_int 0)))
2039         (const_string "imovx")
2040         (const_string "imov")))
2041    (set (attr "mode")
2042      (if_then_else (eq_attr "type" "imovx")
2043         (const_string "SI")
2044         (const_string "QI")))])
2045
2046 (define_insn "movsi_insv_1"
2047   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2048                          (const_int 8)
2049                          (const_int 8))
2050         (match_operand:SI 1 "general_operand" "Qmn"))]
2051   "!TARGET_64BIT"
2052   "mov{b}\t{%b1, %h0|%h0, %b1}"
2053   [(set_attr "type" "imov")
2054    (set_attr "mode" "QI")])
2055
2056 (define_insn "*movsi_insv_1_rex64"
2057   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2058                          (const_int 8)
2059                          (const_int 8))
2060         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2061   "TARGET_64BIT"
2062   "mov{b}\t{%b1, %h0|%h0, %b1}"
2063   [(set_attr "type" "imov")
2064    (set_attr "mode" "QI")])
2065
2066 (define_insn "movdi_insv_1_rex64"
2067   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2068                          (const_int 8)
2069                          (const_int 8))
2070         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2071   "TARGET_64BIT"
2072   "mov{b}\t{%b1, %h0|%h0, %b1}"
2073   [(set_attr "type" "imov")
2074    (set_attr "mode" "QI")])
2075
2076 (define_insn "*movqi_insv_2"
2077   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2078                          (const_int 8)
2079                          (const_int 8))
2080         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2081                      (const_int 8)))]
2082   ""
2083   "mov{b}\t{%h1, %h0|%h0, %h1}"
2084   [(set_attr "type" "imov")
2085    (set_attr "mode" "QI")])
2086
2087 (define_expand "movdi"
2088   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2089         (match_operand:DI 1 "general_operand" ""))]
2090   ""
2091   "ix86_expand_move (DImode, operands); DONE;")
2092
2093 (define_insn "*pushdi"
2094   [(set (match_operand:DI 0 "push_operand" "=<")
2095         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2096   "!TARGET_64BIT"
2097   "#")
2098
2099 (define_insn "*pushdi2_rex64"
2100   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2101         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2102   "TARGET_64BIT"
2103   "@
2104    push{q}\t%1
2105    #"
2106   [(set_attr "type" "push,multi")
2107    (set_attr "mode" "DI")])
2108
2109 ;; Convert impossible pushes of immediate to existing instructions.
2110 ;; First try to get scratch register and go through it.  In case this
2111 ;; fails, push sign extended lower part first and then overwrite
2112 ;; upper part by 32bit move.
2113 (define_peephole2
2114   [(match_scratch:DI 2 "r")
2115    (set (match_operand:DI 0 "push_operand" "")
2116         (match_operand:DI 1 "immediate_operand" ""))]
2117   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118    && !x86_64_immediate_operand (operands[1], DImode)"
2119   [(set (match_dup 2) (match_dup 1))
2120    (set (match_dup 0) (match_dup 2))]
2121   "")
2122
2123 ;; We need to define this as both peepholer and splitter for case
2124 ;; peephole2 pass is not run.
2125 ;; "&& 1" is needed to keep it from matching the previous pattern.
2126 (define_peephole2
2127   [(set (match_operand:DI 0 "push_operand" "")
2128         (match_operand:DI 1 "immediate_operand" ""))]
2129   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2131   [(set (match_dup 0) (match_dup 1))
2132    (set (match_dup 2) (match_dup 3))]
2133   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2134    operands[1] = gen_lowpart (DImode, operands[2]);
2135    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2136                                                     GEN_INT (4)));
2137   ")
2138
2139 (define_split
2140   [(set (match_operand:DI 0 "push_operand" "")
2141         (match_operand:DI 1 "immediate_operand" ""))]
2142   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2143                     ? epilogue_completed : reload_completed)
2144    && !symbolic_operand (operands[1], DImode)
2145    && !x86_64_immediate_operand (operands[1], DImode)"
2146   [(set (match_dup 0) (match_dup 1))
2147    (set (match_dup 2) (match_dup 3))]
2148   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2149    operands[1] = gen_lowpart (DImode, operands[2]);
2150    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2151                                                     GEN_INT (4)));
2152   ")
2153
2154 (define_insn "*pushdi2_prologue_rex64"
2155   [(set (match_operand:DI 0 "push_operand" "=<")
2156         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2157    (clobber (mem:BLK (scratch)))]
2158   "TARGET_64BIT"
2159   "push{q}\t%1"
2160   [(set_attr "type" "push")
2161    (set_attr "mode" "DI")])
2162
2163 (define_insn "*popdi1_epilogue_rex64"
2164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2165         (mem:DI (reg:DI SP_REG)))
2166    (set (reg:DI SP_REG)
2167         (plus:DI (reg:DI SP_REG) (const_int 8)))
2168    (clobber (mem:BLK (scratch)))]
2169   "TARGET_64BIT"
2170   "pop{q}\t%0"
2171   [(set_attr "type" "pop")
2172    (set_attr "mode" "DI")])
2173
2174 (define_insn "popdi1"
2175   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2176         (mem:DI (reg:DI SP_REG)))
2177    (set (reg:DI SP_REG)
2178         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2179   "TARGET_64BIT"
2180   "pop{q}\t%0"
2181   [(set_attr "type" "pop")
2182    (set_attr "mode" "DI")])
2183
2184 (define_insn "*movdi_xor_rex64"
2185   [(set (match_operand:DI 0 "register_operand" "=r")
2186         (match_operand:DI 1 "const0_operand" "i"))
2187    (clobber (reg:CC FLAGS_REG))]
2188   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2189    && reload_completed"
2190   "xor{l}\t%k0, %k0";
2191   [(set_attr "type" "alu1")
2192    (set_attr "mode" "SI")
2193    (set_attr "length_immediate" "0")])
2194
2195 (define_insn "*movdi_or_rex64"
2196   [(set (match_operand:DI 0 "register_operand" "=r")
2197         (match_operand:DI 1 "const_int_operand" "i"))
2198    (clobber (reg:CC FLAGS_REG))]
2199   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2200    && reload_completed
2201    && operands[1] == constm1_rtx"
2202 {
2203   operands[1] = constm1_rtx;
2204   return "or{q}\t{%1, %0|%0, %1}";
2205 }
2206   [(set_attr "type" "alu1")
2207    (set_attr "mode" "DI")
2208    (set_attr "length_immediate" "1")])
2209
2210 (define_insn "*movdi_2"
2211   [(set (match_operand:DI 0 "nonimmediate_operand"
2212                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2213         (match_operand:DI 1 "general_operand"
2214                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2215   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2216   "@
2217    #
2218    #
2219    pxor\t%0, %0
2220    movq\t{%1, %0|%0, %1}
2221    movq\t{%1, %0|%0, %1}
2222    pxor\t%0, %0
2223    movq\t{%1, %0|%0, %1}
2224    movdqa\t{%1, %0|%0, %1}
2225    movq\t{%1, %0|%0, %1}
2226    xorps\t%0, %0
2227    movlps\t{%1, %0|%0, %1}
2228    movaps\t{%1, %0|%0, %1}
2229    movlps\t{%1, %0|%0, %1}"
2230   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2231    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2232
2233 (define_split
2234   [(set (match_operand:DI 0 "push_operand" "")
2235         (match_operand:DI 1 "general_operand" ""))]
2236   "!TARGET_64BIT && reload_completed
2237    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2238   [(const_int 0)]
2239   "ix86_split_long_move (operands); DONE;")
2240
2241 ;; %%% This multiword shite has got to go.
2242 (define_split
2243   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2244         (match_operand:DI 1 "general_operand" ""))]
2245   "!TARGET_64BIT && reload_completed
2246    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2247    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2248   [(const_int 0)]
2249   "ix86_split_long_move (operands); DONE;")
2250
2251 (define_insn "*movdi_1_rex64"
2252   [(set (match_operand:DI 0 "nonimmediate_operand"
2253           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2254         (match_operand:DI 1 "general_operand"
2255           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2256   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2257 {
2258   switch (get_attr_type (insn))
2259     {
2260     case TYPE_SSECVT:
2261       if (SSE_REG_P (operands[0]))
2262         return "movq2dq\t{%1, %0|%0, %1}";
2263       else
2264         return "movdq2q\t{%1, %0|%0, %1}";
2265
2266     case TYPE_SSEMOV:
2267       if (get_attr_mode (insn) == MODE_TI)
2268         return "movdqa\t{%1, %0|%0, %1}";
2269       /* FALLTHRU */
2270
2271     case TYPE_MMXMOV:
2272       /* Moves from and into integer register is done using movd
2273          opcode with REX prefix.  */
2274       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2275         return "movd\t{%1, %0|%0, %1}";
2276       return "movq\t{%1, %0|%0, %1}";
2277
2278     case TYPE_SSELOG1:
2279     case TYPE_MMXADD:
2280       return "pxor\t%0, %0";
2281
2282     case TYPE_MULTI:
2283       return "#";
2284
2285     case TYPE_LEA:
2286       return "lea{q}\t{%a1, %0|%0, %a1}";
2287
2288     default:
2289       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2290       if (get_attr_mode (insn) == MODE_SI)
2291         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2292       else if (which_alternative == 2)
2293         return "movabs{q}\t{%1, %0|%0, %1}";
2294       else
2295         return "mov{q}\t{%1, %0|%0, %1}";
2296     }
2297 }
2298   [(set (attr "type")
2299      (cond [(eq_attr "alternative" "5")
2300               (const_string "mmxadd")
2301             (eq_attr "alternative" "6,7,8,9,10")
2302               (const_string "mmxmov")
2303             (eq_attr "alternative" "11")
2304               (const_string "sselog1")
2305             (eq_attr "alternative" "12,13,14,15,16")
2306               (const_string "ssemov")
2307             (eq_attr "alternative" "17,18")
2308               (const_string "ssecvt")
2309             (eq_attr "alternative" "4")
2310               (const_string "multi")
2311             (match_operand:DI 1 "pic_32bit_operand" "")
2312               (const_string "lea")
2313            ]
2314            (const_string "imov")))
2315    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2316    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2317    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2318
2319 ;; Stores and loads of ax to arbitrary constant address.
2320 ;; We fake an second form of instruction to force reload to load address
2321 ;; into register when rax is not available
2322 (define_insn "*movabsdi_1_rex64"
2323   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2324         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2325   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2326   "@
2327    movabs{q}\t{%1, %P0|%P0, %1}
2328    mov{q}\t{%1, %a0|%a0, %1}"
2329   [(set_attr "type" "imov")
2330    (set_attr "modrm" "0,*")
2331    (set_attr "length_address" "8,0")
2332    (set_attr "length_immediate" "0,*")
2333    (set_attr "memory" "store")
2334    (set_attr "mode" "DI")])
2335
2336 (define_insn "*movabsdi_2_rex64"
2337   [(set (match_operand:DI 0 "register_operand" "=a,r")
2338         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2339   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2340   "@
2341    movabs{q}\t{%P1, %0|%0, %P1}
2342    mov{q}\t{%a1, %0|%0, %a1}"
2343   [(set_attr "type" "imov")
2344    (set_attr "modrm" "0,*")
2345    (set_attr "length_address" "8,0")
2346    (set_attr "length_immediate" "0")
2347    (set_attr "memory" "load")
2348    (set_attr "mode" "DI")])
2349
2350 ;; Convert impossible stores of immediate to existing instructions.
2351 ;; First try to get scratch register and go through it.  In case this
2352 ;; fails, move by 32bit parts.
2353 (define_peephole2
2354   [(match_scratch:DI 2 "r")
2355    (set (match_operand:DI 0 "memory_operand" "")
2356         (match_operand:DI 1 "immediate_operand" ""))]
2357   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2358    && !x86_64_immediate_operand (operands[1], DImode)"
2359   [(set (match_dup 2) (match_dup 1))
2360    (set (match_dup 0) (match_dup 2))]
2361   "")
2362
2363 ;; We need to define this as both peepholer and splitter for case
2364 ;; peephole2 pass is not run.
2365 ;; "&& 1" is needed to keep it from matching the previous pattern.
2366 (define_peephole2
2367   [(set (match_operand:DI 0 "memory_operand" "")
2368         (match_operand:DI 1 "immediate_operand" ""))]
2369   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2370    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2371   [(set (match_dup 2) (match_dup 3))
2372    (set (match_dup 4) (match_dup 5))]
2373   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2374
2375 (define_split
2376   [(set (match_operand:DI 0 "memory_operand" "")
2377         (match_operand:DI 1 "immediate_operand" ""))]
2378   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2379                     ? epilogue_completed : reload_completed)
2380    && !symbolic_operand (operands[1], DImode)
2381    && !x86_64_immediate_operand (operands[1], DImode)"
2382   [(set (match_dup 2) (match_dup 3))
2383    (set (match_dup 4) (match_dup 5))]
2384   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2385
2386 (define_insn "*swapdi_rex64"
2387   [(set (match_operand:DI 0 "register_operand" "+r")
2388         (match_operand:DI 1 "register_operand" "+r"))
2389    (set (match_dup 1)
2390         (match_dup 0))]
2391   "TARGET_64BIT"
2392   "xchg{q}\t%1, %0"
2393   [(set_attr "type" "imov")
2394    (set_attr "mode" "DI")
2395    (set_attr "pent_pair" "np")
2396    (set_attr "athlon_decode" "vector")
2397    (set_attr "amdfam10_decode" "double")])
2398
2399 (define_expand "movti"
2400   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2401         (match_operand:TI 1 "nonimmediate_operand" ""))]
2402   "TARGET_SSE || TARGET_64BIT"
2403 {
2404   if (TARGET_64BIT)
2405     ix86_expand_move (TImode, operands);
2406   else if (push_operand (operands[0], TImode))
2407     ix86_expand_push (TImode, operands[1]);
2408   else
2409     ix86_expand_vector_move (TImode, operands);
2410   DONE;
2411 })
2412
2413 (define_insn "*movti_internal"
2414   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2415         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2416   "TARGET_SSE && !TARGET_64BIT
2417    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2418 {
2419   switch (which_alternative)
2420     {
2421     case 0:
2422       if (get_attr_mode (insn) == MODE_V4SF)
2423         return "xorps\t%0, %0";
2424       else
2425         return "pxor\t%0, %0";
2426     case 1:
2427     case 2:
2428       /* TDmode values are passed as TImode on the stack.  Moving them
2429          to stack may result in unaligned memory access.  */
2430       if (misaligned_operand (operands[0], TImode)
2431           || misaligned_operand (operands[1], TImode))
2432         { 
2433           if (get_attr_mode (insn) == MODE_V4SF)
2434             return "movups\t{%1, %0|%0, %1}";
2435          else
2436            return "movdqu\t{%1, %0|%0, %1}";
2437         }
2438       else
2439         { 
2440           if (get_attr_mode (insn) == MODE_V4SF)
2441             return "movaps\t{%1, %0|%0, %1}";
2442          else
2443            return "movdqa\t{%1, %0|%0, %1}";
2444         }
2445     default:
2446       gcc_unreachable ();
2447     }
2448 }
2449   [(set_attr "type" "sselog1,ssemov,ssemov")
2450    (set (attr "mode")
2451         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2452                     (ne (symbol_ref "optimize_size") (const_int 0)))
2453                  (const_string "V4SF")
2454                (and (eq_attr "alternative" "2")
2455                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2456                         (const_int 0)))
2457                  (const_string "V4SF")]
2458               (const_string "TI")))])
2459
2460 (define_insn "*movti_rex64"
2461   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2462         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2463   "TARGET_64BIT
2464    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2465 {
2466   switch (which_alternative)
2467     {
2468     case 0:
2469     case 1:
2470       return "#";
2471     case 2:
2472       if (get_attr_mode (insn) == MODE_V4SF)
2473         return "xorps\t%0, %0";
2474       else
2475         return "pxor\t%0, %0";
2476     case 3:
2477     case 4:
2478       /* TDmode values are passed as TImode on the stack.  Moving them
2479          to stack may result in unaligned memory access.  */
2480       if (misaligned_operand (operands[0], TImode)
2481           || misaligned_operand (operands[1], TImode))
2482         { 
2483           if (get_attr_mode (insn) == MODE_V4SF)
2484             return "movups\t{%1, %0|%0, %1}";
2485          else
2486            return "movdqu\t{%1, %0|%0, %1}";
2487         }
2488       else
2489         { 
2490           if (get_attr_mode (insn) == MODE_V4SF)
2491             return "movaps\t{%1, %0|%0, %1}";
2492          else
2493            return "movdqa\t{%1, %0|%0, %1}";
2494         }
2495     default:
2496       gcc_unreachable ();
2497     }
2498 }
2499   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2500    (set (attr "mode")
2501         (cond [(eq_attr "alternative" "2,3")
2502                  (if_then_else
2503                    (ne (symbol_ref "optimize_size")
2504                        (const_int 0))
2505                    (const_string "V4SF")
2506                    (const_string "TI"))
2507                (eq_attr "alternative" "4")
2508                  (if_then_else
2509                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2510                             (const_int 0))
2511                         (ne (symbol_ref "optimize_size")
2512                             (const_int 0)))
2513                    (const_string "V4SF")
2514                    (const_string "TI"))]
2515                (const_string "DI")))])
2516
2517 (define_split
2518   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2519         (match_operand:TI 1 "general_operand" ""))]
2520   "reload_completed && !SSE_REG_P (operands[0])
2521    && !SSE_REG_P (operands[1])"
2522   [(const_int 0)]
2523   "ix86_split_long_move (operands); DONE;")
2524
2525 ;; This expands to what emit_move_complex would generate if we didn't
2526 ;; have a movti pattern.  Having this avoids problems with reload on
2527 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2528 ;; to have around all the time.
2529 (define_expand "movcdi"
2530   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2531         (match_operand:CDI 1 "general_operand" ""))]
2532   ""
2533 {
2534   if (push_operand (operands[0], CDImode))
2535     emit_move_complex_push (CDImode, operands[0], operands[1]);
2536   else
2537     emit_move_complex_parts (operands[0], operands[1]);
2538   DONE;
2539 })
2540
2541 (define_expand "movsf"
2542   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2543         (match_operand:SF 1 "general_operand" ""))]
2544   ""
2545   "ix86_expand_move (SFmode, operands); DONE;")
2546
2547 (define_insn "*pushsf"
2548   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2549         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2550   "!TARGET_64BIT"
2551 {
2552   /* Anything else should be already split before reg-stack.  */
2553   gcc_assert (which_alternative == 1);
2554   return "push{l}\t%1";
2555 }
2556   [(set_attr "type" "multi,push,multi")
2557    (set_attr "unit" "i387,*,*")
2558    (set_attr "mode" "SF,SI,SF")])
2559
2560 (define_insn "*pushsf_rex64"
2561   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2562         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2563   "TARGET_64BIT"
2564 {
2565   /* Anything else should be already split before reg-stack.  */
2566   gcc_assert (which_alternative == 1);
2567   return "push{q}\t%q1";
2568 }
2569   [(set_attr "type" "multi,push,multi")
2570    (set_attr "unit" "i387,*,*")
2571    (set_attr "mode" "SF,DI,SF")])
2572
2573 (define_split
2574   [(set (match_operand:SF 0 "push_operand" "")
2575         (match_operand:SF 1 "memory_operand" ""))]
2576   "reload_completed
2577    && MEM_P (operands[1])
2578    && (operands[2] = find_constant_src (insn))"
2579   [(set (match_dup 0)
2580         (match_dup 2))])
2581
2582
2583 ;; %%% Kill this when call knows how to work this out.
2584 (define_split
2585   [(set (match_operand:SF 0 "push_operand" "")
2586         (match_operand:SF 1 "any_fp_register_operand" ""))]
2587   "!TARGET_64BIT"
2588   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2589    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2590
2591 (define_split
2592   [(set (match_operand:SF 0 "push_operand" "")
2593         (match_operand:SF 1 "any_fp_register_operand" ""))]
2594   "TARGET_64BIT"
2595   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2596    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2597
2598 (define_insn "*movsf_1"
2599   [(set (match_operand:SF 0 "nonimmediate_operand"
2600           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2601         (match_operand:SF 1 "general_operand"
2602           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2603   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2604    && (reload_in_progress || reload_completed
2605        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2606        || (!TARGET_SSE_MATH && optimize_size
2607            && standard_80387_constant_p (operands[1]))
2608        || GET_CODE (operands[1]) != CONST_DOUBLE
2609        || memory_operand (operands[0], SFmode))"
2610 {
2611   switch (which_alternative)
2612     {
2613     case 0:
2614     case 1:
2615       return output_387_reg_move (insn, operands);
2616
2617     case 2:
2618       return standard_80387_constant_opcode (operands[1]);
2619
2620     case 3:
2621     case 4:
2622       return "mov{l}\t{%1, %0|%0, %1}";
2623     case 5:
2624       if (get_attr_mode (insn) == MODE_TI)
2625         return "pxor\t%0, %0";
2626       else
2627         return "xorps\t%0, %0";
2628     case 6:
2629       if (get_attr_mode (insn) == MODE_V4SF)
2630         return "movaps\t{%1, %0|%0, %1}";
2631       else
2632         return "movss\t{%1, %0|%0, %1}";
2633     case 7: case 8:
2634       return "movss\t{%1, %0|%0, %1}";
2635
2636     case 9: case 10:
2637     case 12: case 13: case 14: case 15:
2638       return "movd\t{%1, %0|%0, %1}";
2639
2640     case 11:
2641       return "movq\t{%1, %0|%0, %1}";
2642
2643     default:
2644       gcc_unreachable ();
2645     }
2646 }
2647   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2648    (set (attr "mode")
2649         (cond [(eq_attr "alternative" "3,4,9,10")
2650                  (const_string "SI")
2651                (eq_attr "alternative" "5")
2652                  (if_then_else
2653                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2654                                  (const_int 0))
2655                              (ne (symbol_ref "TARGET_SSE2")
2656                                  (const_int 0)))
2657                         (eq (symbol_ref "optimize_size")
2658                             (const_int 0)))
2659                    (const_string "TI")
2660                    (const_string "V4SF"))
2661                /* For architectures resolving dependencies on
2662                   whole SSE registers use APS move to break dependency
2663                   chains, otherwise use short move to avoid extra work.
2664
2665                   Do the same for architectures resolving dependencies on
2666                   the parts.  While in DF mode it is better to always handle
2667                   just register parts, the SF mode is different due to lack
2668                   of instructions to load just part of the register.  It is
2669                   better to maintain the whole registers in single format
2670                   to avoid problems on using packed logical operations.  */
2671                (eq_attr "alternative" "6")
2672                  (if_then_else
2673                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2674                             (const_int 0))
2675                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2676                             (const_int 0)))
2677                    (const_string "V4SF")
2678                    (const_string "SF"))
2679                (eq_attr "alternative" "11")
2680                  (const_string "DI")]
2681                (const_string "SF")))])
2682
2683 (define_insn "*swapsf"
2684   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2685         (match_operand:SF 1 "fp_register_operand" "+f"))
2686    (set (match_dup 1)
2687         (match_dup 0))]
2688   "reload_completed || TARGET_80387"
2689 {
2690   if (STACK_TOP_P (operands[0]))
2691     return "fxch\t%1";
2692   else
2693     return "fxch\t%0";
2694 }
2695   [(set_attr "type" "fxch")
2696    (set_attr "mode" "SF")])
2697
2698 (define_expand "movdf"
2699   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2700         (match_operand:DF 1 "general_operand" ""))]
2701   ""
2702   "ix86_expand_move (DFmode, operands); DONE;")
2703
2704 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2705 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2706 ;; On the average, pushdf using integers can be still shorter.  Allow this
2707 ;; pattern for optimize_size too.
2708
2709 (define_insn "*pushdf_nointeger"
2710   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2711         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2712   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2713 {
2714   /* This insn should be already split before reg-stack.  */
2715   gcc_unreachable ();
2716 }
2717   [(set_attr "type" "multi")
2718    (set_attr "unit" "i387,*,*,*")
2719    (set_attr "mode" "DF,SI,SI,DF")])
2720
2721 (define_insn "*pushdf_integer"
2722   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2723         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2724   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2725 {
2726   /* This insn should be already split before reg-stack.  */
2727   gcc_unreachable ();
2728 }
2729   [(set_attr "type" "multi")
2730    (set_attr "unit" "i387,*,*")
2731    (set_attr "mode" "DF,SI,DF")])
2732
2733 ;; %%% Kill this when call knows how to work this out.
2734 (define_split
2735   [(set (match_operand:DF 0 "push_operand" "")
2736         (match_operand:DF 1 "any_fp_register_operand" ""))]
2737   "!TARGET_64BIT && reload_completed"
2738   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2739    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2740   "")
2741
2742 (define_split
2743   [(set (match_operand:DF 0 "push_operand" "")
2744         (match_operand:DF 1 "any_fp_register_operand" ""))]
2745   "TARGET_64BIT && reload_completed"
2746   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2747    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2748   "")
2749
2750 (define_split
2751   [(set (match_operand:DF 0 "push_operand" "")
2752         (match_operand:DF 1 "general_operand" ""))]
2753   "reload_completed"
2754   [(const_int 0)]
2755   "ix86_split_long_move (operands); DONE;")
2756
2757 ;; Moving is usually shorter when only FP registers are used. This separate
2758 ;; movdf pattern avoids the use of integer registers for FP operations
2759 ;; when optimizing for size.
2760
2761 (define_insn "*movdf_nointeger"
2762   [(set (match_operand:DF 0 "nonimmediate_operand"
2763                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2764         (match_operand:DF 1 "general_operand"
2765                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2766   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2767    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2768    && (reload_in_progress || reload_completed
2769        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2770        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2771            && !memory_operand (operands[0], DFmode)
2772            && standard_80387_constant_p (operands[1]))
2773        || GET_CODE (operands[1]) != CONST_DOUBLE
2774        || ((optimize_size
2775             || !TARGET_MEMORY_MISMATCH_STALL
2776             || reload_in_progress || reload_completed)
2777            && memory_operand (operands[0], DFmode)))"
2778 {
2779   switch (which_alternative)
2780     {
2781     case 0:
2782     case 1:
2783       return output_387_reg_move (insn, operands);
2784
2785     case 2:
2786       return standard_80387_constant_opcode (operands[1]);
2787
2788     case 3:
2789     case 4:
2790       return "#";
2791     case 5:
2792       switch (get_attr_mode (insn))
2793         {
2794         case MODE_V4SF:
2795           return "xorps\t%0, %0";
2796         case MODE_V2DF:
2797           return "xorpd\t%0, %0";
2798         case MODE_TI:
2799           return "pxor\t%0, %0";
2800         default:
2801           gcc_unreachable ();
2802         }
2803     case 6:
2804     case 7:
2805     case 8:
2806       switch (get_attr_mode (insn))
2807         {
2808         case MODE_V4SF:
2809           return "movaps\t{%1, %0|%0, %1}";
2810         case MODE_V2DF:
2811           return "movapd\t{%1, %0|%0, %1}";
2812         case MODE_TI:
2813           return "movdqa\t{%1, %0|%0, %1}";
2814         case MODE_DI:
2815           return "movq\t{%1, %0|%0, %1}";
2816         case MODE_DF:
2817           return "movsd\t{%1, %0|%0, %1}";
2818         case MODE_V1DF:
2819           return "movlpd\t{%1, %0|%0, %1}";
2820         case MODE_V2SF:
2821           return "movlps\t{%1, %0|%0, %1}";
2822         default:
2823           gcc_unreachable ();
2824         }
2825
2826     default:
2827       gcc_unreachable ();
2828     }
2829 }
2830   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2831    (set (attr "mode")
2832         (cond [(eq_attr "alternative" "0,1,2")
2833                  (const_string "DF")
2834                (eq_attr "alternative" "3,4")
2835                  (const_string "SI")
2836
2837                /* For SSE1, we have many fewer alternatives.  */
2838                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2839                  (cond [(eq_attr "alternative" "5,6")
2840                           (const_string "V4SF")
2841                        ]
2842                    (const_string "V2SF"))
2843
2844                /* xorps is one byte shorter.  */
2845                (eq_attr "alternative" "5")
2846                  (cond [(ne (symbol_ref "optimize_size")
2847                             (const_int 0))
2848                           (const_string "V4SF")
2849                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2850                             (const_int 0))
2851                           (const_string "TI")
2852                        ]
2853                        (const_string "V2DF"))
2854
2855                /* For architectures resolving dependencies on
2856                   whole SSE registers use APD move to break dependency
2857                   chains, otherwise use short move to avoid extra work.
2858
2859                   movaps encodes one byte shorter.  */
2860                (eq_attr "alternative" "6")
2861                  (cond
2862                    [(ne (symbol_ref "optimize_size")
2863                         (const_int 0))
2864                       (const_string "V4SF")
2865                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2866                         (const_int 0))
2867                       (const_string "V2DF")
2868                    ]
2869                    (const_string "DF"))
2870                /* For architectures resolving dependencies on register
2871                   parts we may avoid extra work to zero out upper part
2872                   of register.  */
2873                (eq_attr "alternative" "7")
2874                  (if_then_else
2875                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2876                        (const_int 0))
2877                    (const_string "V1DF")
2878                    (const_string "DF"))
2879               ]
2880               (const_string "DF")))])
2881
2882 (define_insn "*movdf_integer_rex64"
2883   [(set (match_operand:DF 0 "nonimmediate_operand"
2884                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2885         (match_operand:DF 1 "general_operand"
2886                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2887   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2888    && (reload_in_progress || reload_completed
2889        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2890        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2891            && standard_80387_constant_p (operands[1]))
2892        || GET_CODE (operands[1]) != CONST_DOUBLE
2893        || memory_operand (operands[0], DFmode))"
2894 {
2895   switch (which_alternative)
2896     {
2897     case 0:
2898     case 1:
2899       return output_387_reg_move (insn, operands);
2900
2901     case 2:
2902       return standard_80387_constant_opcode (operands[1]);
2903
2904     case 3:
2905     case 4:
2906       return "#";
2907
2908     case 5:
2909       switch (get_attr_mode (insn))
2910         {
2911         case MODE_V4SF:
2912           return "xorps\t%0, %0";
2913         case MODE_V2DF:
2914           return "xorpd\t%0, %0";
2915         case MODE_TI:
2916           return "pxor\t%0, %0";
2917         default:
2918           gcc_unreachable ();
2919         }
2920     case 6:
2921     case 7:
2922     case 8:
2923       switch (get_attr_mode (insn))
2924         {
2925         case MODE_V4SF:
2926           return "movaps\t{%1, %0|%0, %1}";
2927         case MODE_V2DF:
2928           return "movapd\t{%1, %0|%0, %1}";
2929         case MODE_TI:
2930           return "movdqa\t{%1, %0|%0, %1}";
2931         case MODE_DI:
2932           return "movq\t{%1, %0|%0, %1}";
2933         case MODE_DF:
2934           return "movsd\t{%1, %0|%0, %1}";
2935         case MODE_V1DF:
2936           return "movlpd\t{%1, %0|%0, %1}";
2937         case MODE_V2SF:
2938           return "movlps\t{%1, %0|%0, %1}";
2939         default:
2940           gcc_unreachable ();
2941         }
2942
2943     case 9:
2944     case 10:
2945       return "movd\t{%1, %0|%0, %1}";
2946
2947     default:
2948       gcc_unreachable();
2949     }
2950 }
2951   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2952    (set (attr "mode")
2953         (cond [(eq_attr "alternative" "0,1,2")
2954                  (const_string "DF")
2955                (eq_attr "alternative" "3,4,9,10")
2956                  (const_string "DI")
2957
2958                /* For SSE1, we have many fewer alternatives.  */
2959                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2960                  (cond [(eq_attr "alternative" "5,6")
2961                           (const_string "V4SF")
2962                        ]
2963                    (const_string "V2SF"))
2964
2965                /* xorps is one byte shorter.  */
2966                (eq_attr "alternative" "5")
2967                  (cond [(ne (symbol_ref "optimize_size")
2968                             (const_int 0))
2969                           (const_string "V4SF")
2970                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2971                             (const_int 0))
2972                           (const_string "TI")
2973                        ]
2974                        (const_string "V2DF"))
2975
2976                /* For architectures resolving dependencies on
2977                   whole SSE registers use APD move to break dependency
2978                   chains, otherwise use short move to avoid extra work.
2979
2980                   movaps encodes one byte shorter.  */
2981                (eq_attr "alternative" "6")
2982                  (cond
2983                    [(ne (symbol_ref "optimize_size")
2984                         (const_int 0))
2985                       (const_string "V4SF")
2986                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2987                         (const_int 0))
2988                       (const_string "V2DF")
2989                    ]
2990                    (const_string "DF"))
2991                /* For architectures resolving dependencies on register
2992                   parts we may avoid extra work to zero out upper part
2993                   of register.  */
2994                (eq_attr "alternative" "7")
2995                  (if_then_else
2996                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2997                        (const_int 0))
2998                    (const_string "V1DF")
2999                    (const_string "DF"))
3000               ]
3001               (const_string "DF")))])
3002
3003 (define_insn "*movdf_integer"
3004   [(set (match_operand:DF 0 "nonimmediate_operand"
3005                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3006         (match_operand:DF 1 "general_operand"
3007                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3008   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3009    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3010    && (reload_in_progress || reload_completed
3011        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3012        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3013            && standard_80387_constant_p (operands[1]))
3014        || GET_CODE (operands[1]) != CONST_DOUBLE
3015        || memory_operand (operands[0], DFmode))"
3016 {
3017   switch (which_alternative)
3018     {
3019     case 0:
3020     case 1:
3021       return output_387_reg_move (insn, operands);
3022
3023     case 2:
3024       return standard_80387_constant_opcode (operands[1]);
3025
3026     case 3:
3027     case 4:
3028       return "#";
3029
3030     case 5:
3031       switch (get_attr_mode (insn))
3032         {
3033         case MODE_V4SF:
3034           return "xorps\t%0, %0";
3035         case MODE_V2DF:
3036           return "xorpd\t%0, %0";
3037         case MODE_TI:
3038           return "pxor\t%0, %0";
3039         default:
3040           gcc_unreachable ();
3041         }
3042     case 6:
3043     case 7:
3044     case 8:
3045       switch (get_attr_mode (insn))
3046         {
3047         case MODE_V4SF:
3048           return "movaps\t{%1, %0|%0, %1}";
3049         case MODE_V2DF:
3050           return "movapd\t{%1, %0|%0, %1}";
3051         case MODE_TI:
3052           return "movdqa\t{%1, %0|%0, %1}";
3053         case MODE_DI:
3054           return "movq\t{%1, %0|%0, %1}";
3055         case MODE_DF:
3056           return "movsd\t{%1, %0|%0, %1}";
3057         case MODE_V1DF:
3058           return "movlpd\t{%1, %0|%0, %1}";
3059         case MODE_V2SF:
3060           return "movlps\t{%1, %0|%0, %1}";
3061         default:
3062           gcc_unreachable ();
3063         }
3064
3065     default:
3066       gcc_unreachable();
3067     }
3068 }
3069   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3070    (set (attr "mode")
3071         (cond [(eq_attr "alternative" "0,1,2")
3072                  (const_string "DF")
3073                (eq_attr "alternative" "3,4")
3074                  (const_string "SI")
3075
3076                /* For SSE1, we have many fewer alternatives.  */
3077                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3078                  (cond [(eq_attr "alternative" "5,6")
3079                           (const_string "V4SF")
3080                        ]
3081                    (const_string "V2SF"))
3082
3083                /* xorps is one byte shorter.  */
3084                (eq_attr "alternative" "5")
3085                  (cond [(ne (symbol_ref "optimize_size")
3086                             (const_int 0))
3087                           (const_string "V4SF")
3088                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3089                             (const_int 0))
3090                           (const_string "TI")
3091                        ]
3092                        (const_string "V2DF"))
3093
3094                /* For architectures resolving dependencies on
3095                   whole SSE registers use APD move to break dependency
3096                   chains, otherwise use short move to avoid extra work.
3097
3098                   movaps encodes one byte shorter.  */
3099                (eq_attr "alternative" "6")
3100                  (cond
3101                    [(ne (symbol_ref "optimize_size")
3102                         (const_int 0))
3103                       (const_string "V4SF")
3104                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3105                         (const_int 0))
3106                       (const_string "V2DF")
3107                    ]
3108                    (const_string "DF"))
3109                /* For architectures resolving dependencies on register
3110                   parts we may avoid extra work to zero out upper part
3111                   of register.  */
3112                (eq_attr "alternative" "7")
3113                  (if_then_else
3114                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3115                        (const_int 0))
3116                    (const_string "V1DF")
3117                    (const_string "DF"))
3118               ]
3119               (const_string "DF")))])
3120
3121 (define_split
3122   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3123         (match_operand:DF 1 "general_operand" ""))]
3124   "reload_completed
3125    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3126    && ! (ANY_FP_REG_P (operands[0]) ||
3127          (GET_CODE (operands[0]) == SUBREG
3128           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3129    && ! (ANY_FP_REG_P (operands[1]) ||
3130          (GET_CODE (operands[1]) == SUBREG
3131           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3132   [(const_int 0)]
3133   "ix86_split_long_move (operands); DONE;")
3134
3135 (define_insn "*swapdf"
3136   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3137         (match_operand:DF 1 "fp_register_operand" "+f"))
3138    (set (match_dup 1)
3139         (match_dup 0))]
3140   "reload_completed || TARGET_80387"
3141 {
3142   if (STACK_TOP_P (operands[0]))
3143     return "fxch\t%1";
3144   else
3145     return "fxch\t%0";
3146 }
3147   [(set_attr "type" "fxch")
3148    (set_attr "mode" "DF")])
3149
3150 (define_expand "movxf"
3151   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3152         (match_operand:XF 1 "general_operand" ""))]
3153   ""
3154   "ix86_expand_move (XFmode, operands); DONE;")
3155
3156 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3157 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3158 ;; Pushing using integer instructions is longer except for constants
3159 ;; and direct memory references.
3160 ;; (assuming that any given constant is pushed only once, but this ought to be
3161 ;;  handled elsewhere).
3162
3163 (define_insn "*pushxf_nointeger"
3164   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3165         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3166   "optimize_size"
3167 {
3168   /* This insn should be already split before reg-stack.  */
3169   gcc_unreachable ();
3170 }
3171   [(set_attr "type" "multi")
3172    (set_attr "unit" "i387,*,*")
3173    (set_attr "mode" "XF,SI,SI")])
3174
3175 (define_insn "*pushxf_integer"
3176   [(set (match_operand:XF 0 "push_operand" "=<,<")
3177         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3178   "!optimize_size"
3179 {
3180   /* This insn should be already split before reg-stack.  */
3181   gcc_unreachable ();
3182 }
3183   [(set_attr "type" "multi")
3184    (set_attr "unit" "i387,*")
3185    (set_attr "mode" "XF,SI")])
3186
3187 (define_split
3188   [(set (match_operand 0 "push_operand" "")
3189         (match_operand 1 "general_operand" ""))]
3190   "reload_completed
3191    && (GET_MODE (operands[0]) == XFmode
3192        || GET_MODE (operands[0]) == DFmode)
3193    && !ANY_FP_REG_P (operands[1])"
3194   [(const_int 0)]
3195   "ix86_split_long_move (operands); DONE;")
3196
3197 (define_split
3198   [(set (match_operand:XF 0 "push_operand" "")
3199         (match_operand:XF 1 "any_fp_register_operand" ""))]
3200   "!TARGET_64BIT"
3201   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3202    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3203   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3204
3205 (define_split
3206   [(set (match_operand:XF 0 "push_operand" "")
3207         (match_operand:XF 1 "any_fp_register_operand" ""))]
3208   "TARGET_64BIT"
3209   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3210    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3211   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3212
3213 ;; Do not use integer registers when optimizing for size
3214 (define_insn "*movxf_nointeger"
3215   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3216         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3217   "optimize_size
3218    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3219    && (reload_in_progress || reload_completed
3220        || (optimize_size && standard_80387_constant_p (operands[1]))
3221        || GET_CODE (operands[1]) != CONST_DOUBLE
3222        || memory_operand (operands[0], XFmode))"
3223 {
3224   switch (which_alternative)
3225     {
3226     case 0:
3227     case 1:
3228       return output_387_reg_move (insn, operands);
3229
3230     case 2:
3231       return standard_80387_constant_opcode (operands[1]);
3232
3233     case 3: case 4:
3234       return "#";
3235     default:
3236       gcc_unreachable ();
3237     }
3238 }
3239   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3240    (set_attr "mode" "XF,XF,XF,SI,SI")])
3241
3242 (define_insn "*movxf_integer"
3243   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3244         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3245   "!optimize_size
3246    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3247    && (reload_in_progress || reload_completed
3248        || (optimize_size && standard_80387_constant_p (operands[1]))
3249        || GET_CODE (operands[1]) != CONST_DOUBLE
3250        || memory_operand (operands[0], XFmode))"
3251 {
3252   switch (which_alternative)
3253     {
3254     case 0:
3255     case 1:
3256       return output_387_reg_move (insn, operands);
3257
3258     case 2:
3259       return standard_80387_constant_opcode (operands[1]);
3260
3261     case 3: case 4:
3262       return "#";
3263
3264     default:
3265       gcc_unreachable ();
3266     }
3267 }
3268   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3269    (set_attr "mode" "XF,XF,XF,SI,SI")])
3270
3271 (define_expand "movtf"
3272   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3273         (match_operand:TF 1 "nonimmediate_operand" ""))]
3274   "TARGET_64BIT"
3275 {
3276   ix86_expand_move (TFmode, operands);
3277   DONE;
3278 })
3279
3280 (define_insn "*movtf_internal"
3281   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3282         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3283   "TARGET_64BIT
3284    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3285 {
3286   switch (which_alternative)
3287     {
3288     case 0:
3289     case 1:
3290       if (get_attr_mode (insn) == MODE_V4SF)
3291         return "movaps\t{%1, %0|%0, %1}";
3292       else
3293         return "movdqa\t{%1, %0|%0, %1}";
3294     case 2:
3295       if (get_attr_mode (insn) == MODE_V4SF)
3296         return "xorps\t%0, %0";
3297       else
3298         return "pxor\t%0, %0";
3299     case 3:
3300     case 4:
3301         return "#";
3302     default:
3303       gcc_unreachable ();
3304     }
3305 }
3306   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3307    (set (attr "mode")
3308         (cond [(eq_attr "alternative" "0,2")
3309                  (if_then_else
3310                    (ne (symbol_ref "optimize_size")
3311                        (const_int 0))
3312                    (const_string "V4SF")
3313                    (const_string "TI"))
3314                (eq_attr "alternative" "1")
3315                  (if_then_else
3316                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3317                             (const_int 0))
3318                         (ne (symbol_ref "optimize_size")
3319                             (const_int 0)))
3320                    (const_string "V4SF")
3321                    (const_string "TI"))]
3322                (const_string "DI")))])
3323
3324 (define_split
3325   [(set (match_operand 0 "nonimmediate_operand" "")
3326         (match_operand 1 "general_operand" ""))]
3327   "reload_completed
3328    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3329    && GET_MODE (operands[0]) == XFmode
3330    && ! (ANY_FP_REG_P (operands[0]) ||
3331          (GET_CODE (operands[0]) == SUBREG
3332           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3333    && ! (ANY_FP_REG_P (operands[1]) ||
3334          (GET_CODE (operands[1]) == SUBREG
3335           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3336   [(const_int 0)]
3337   "ix86_split_long_move (operands); DONE;")
3338
3339 (define_split
3340   [(set (match_operand 0 "register_operand" "")
3341         (match_operand 1 "memory_operand" ""))]
3342   "reload_completed
3343    && MEM_P (operands[1])
3344    && (GET_MODE (operands[0]) == TFmode
3345        || GET_MODE (operands[0]) == XFmode
3346        || GET_MODE (operands[0]) == SFmode
3347        || GET_MODE (operands[0]) == DFmode)
3348    && (operands[2] = find_constant_src (insn))"
3349   [(set (match_dup 0) (match_dup 2))]
3350 {
3351   rtx c = operands[2];
3352   rtx r = operands[0];
3353
3354   if (GET_CODE (r) == SUBREG)
3355     r = SUBREG_REG (r);
3356
3357   if (SSE_REG_P (r))
3358     {
3359       if (!standard_sse_constant_p (c))
3360         FAIL;
3361     }
3362   else if (FP_REG_P (r))
3363     {
3364       if (!standard_80387_constant_p (c))
3365         FAIL;
3366     }
3367   else if (MMX_REG_P (r))
3368     FAIL;
3369 })
3370
3371 (define_split
3372   [(set (match_operand 0 "register_operand" "")
3373         (float_extend (match_operand 1 "memory_operand" "")))]
3374   "reload_completed
3375    && MEM_P (operands[1])
3376    && (GET_MODE (operands[0]) == TFmode
3377        || GET_MODE (operands[0]) == XFmode
3378        || GET_MODE (operands[0]) == SFmode
3379        || GET_MODE (operands[0]) == DFmode)
3380    && (operands[2] = find_constant_src (insn))"
3381   [(set (match_dup 0) (match_dup 2))]
3382 {
3383   rtx c = operands[2];
3384   rtx r = operands[0];
3385
3386   if (GET_CODE (r) == SUBREG)
3387     r = SUBREG_REG (r);
3388
3389   if (SSE_REG_P (r))
3390     {
3391       if (!standard_sse_constant_p (c))
3392         FAIL;
3393     }
3394   else if (FP_REG_P (r))
3395     {
3396       if (!standard_80387_constant_p (c))
3397         FAIL;
3398     }
3399   else if (MMX_REG_P (r))
3400     FAIL;
3401 })
3402
3403 (define_insn "swapxf"
3404   [(set (match_operand:XF 0 "register_operand" "+f")
3405         (match_operand:XF 1 "register_operand" "+f"))
3406    (set (match_dup 1)
3407         (match_dup 0))]
3408   "TARGET_80387"
3409 {
3410   if (STACK_TOP_P (operands[0]))
3411     return "fxch\t%1";
3412   else
3413     return "fxch\t%0";
3414 }
3415   [(set_attr "type" "fxch")
3416    (set_attr "mode" "XF")])
3417
3418 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3419 (define_split
3420   [(set (match_operand:X87MODEF 0 "register_operand" "")
3421         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3422   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3423    && (standard_80387_constant_p (operands[1]) == 8
3424        || standard_80387_constant_p (operands[1]) == 9)"
3425   [(set (match_dup 0)(match_dup 1))
3426    (set (match_dup 0)
3427         (neg:X87MODEF (match_dup 0)))]
3428 {
3429   REAL_VALUE_TYPE r;
3430
3431   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3432   if (real_isnegzero (&r))
3433     operands[1] = CONST0_RTX (<MODE>mode);
3434   else
3435     operands[1] = CONST1_RTX (<MODE>mode);
3436 })
3437
3438 (define_split
3439   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3440         (match_operand:TF 1 "general_operand" ""))]
3441   "reload_completed
3442    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3443   [(const_int 0)]
3444   "ix86_split_long_move (operands); DONE;")
3445 \f
3446 ;; Zero extension instructions
3447
3448 (define_expand "zero_extendhisi2"
3449   [(set (match_operand:SI 0 "register_operand" "")
3450      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3451   ""
3452 {
3453   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3454     {
3455       operands[1] = force_reg (HImode, operands[1]);
3456       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3457       DONE;
3458     }
3459 })
3460
3461 (define_insn "zero_extendhisi2_and"
3462   [(set (match_operand:SI 0 "register_operand" "=r")
3463      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3464    (clobber (reg:CC FLAGS_REG))]
3465   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3466   "#"
3467   [(set_attr "type" "alu1")
3468    (set_attr "mode" "SI")])
3469
3470 (define_split
3471   [(set (match_operand:SI 0 "register_operand" "")
3472         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3473    (clobber (reg:CC FLAGS_REG))]
3474   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3475   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3476               (clobber (reg:CC FLAGS_REG))])]
3477   "")
3478
3479 (define_insn "*zero_extendhisi2_movzwl"
3480   [(set (match_operand:SI 0 "register_operand" "=r")
3481      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3482   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3483   "movz{wl|x}\t{%1, %0|%0, %1}"
3484   [(set_attr "type" "imovx")
3485    (set_attr "mode" "SI")])
3486
3487 (define_expand "zero_extendqihi2"
3488   [(parallel
3489     [(set (match_operand:HI 0 "register_operand" "")
3490        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3491      (clobber (reg:CC FLAGS_REG))])]
3492   ""
3493   "")
3494
3495 (define_insn "*zero_extendqihi2_and"
3496   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3497      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3498    (clobber (reg:CC FLAGS_REG))]
3499   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3500   "#"
3501   [(set_attr "type" "alu1")
3502    (set_attr "mode" "HI")])
3503
3504 (define_insn "*zero_extendqihi2_movzbw_and"
3505   [(set (match_operand:HI 0 "register_operand" "=r,r")
3506      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3507    (clobber (reg:CC FLAGS_REG))]
3508   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3509   "#"
3510   [(set_attr "type" "imovx,alu1")
3511    (set_attr "mode" "HI")])
3512
3513 ; zero extend to SImode here to avoid partial register stalls
3514 (define_insn "*zero_extendqihi2_movzbl"
3515   [(set (match_operand:HI 0 "register_operand" "=r")
3516      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3517   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3518   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3519   [(set_attr "type" "imovx")
3520    (set_attr "mode" "SI")])
3521
3522 ;; For the movzbw case strip only the clobber
3523 (define_split
3524   [(set (match_operand:HI 0 "register_operand" "")
3525         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3526    (clobber (reg:CC FLAGS_REG))]
3527   "reload_completed
3528    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3529    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3530   [(set (match_operand:HI 0 "register_operand" "")
3531         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3532
3533 ;; When source and destination does not overlap, clear destination
3534 ;; first and then do the movb
3535 (define_split
3536   [(set (match_operand:HI 0 "register_operand" "")
3537         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3538    (clobber (reg:CC FLAGS_REG))]
3539   "reload_completed
3540    && ANY_QI_REG_P (operands[0])
3541    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3542    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3543   [(set (match_dup 0) (const_int 0))
3544    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3545   "operands[2] = gen_lowpart (QImode, operands[0]);")
3546
3547 ;; Rest is handled by single and.
3548 (define_split
3549   [(set (match_operand:HI 0 "register_operand" "")
3550         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3551    (clobber (reg:CC FLAGS_REG))]
3552   "reload_completed
3553    && true_regnum (operands[0]) == true_regnum (operands[1])"
3554   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3555               (clobber (reg:CC FLAGS_REG))])]
3556   "")
3557
3558 (define_expand "zero_extendqisi2"
3559   [(parallel
3560     [(set (match_operand:SI 0 "register_operand" "")
3561        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3562      (clobber (reg:CC FLAGS_REG))])]
3563   ""
3564   "")
3565
3566 (define_insn "*zero_extendqisi2_and"
3567   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3568      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3569    (clobber (reg:CC FLAGS_REG))]
3570   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3571   "#"
3572   [(set_attr "type" "alu1")
3573    (set_attr "mode" "SI")])
3574
3575 (define_insn "*zero_extendqisi2_movzbw_and"
3576   [(set (match_operand:SI 0 "register_operand" "=r,r")
3577      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3578    (clobber (reg:CC FLAGS_REG))]
3579   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3580   "#"
3581   [(set_attr "type" "imovx,alu1")
3582    (set_attr "mode" "SI")])
3583
3584 (define_insn "*zero_extendqisi2_movzbw"
3585   [(set (match_operand:SI 0 "register_operand" "=r")
3586      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3587   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3588   "movz{bl|x}\t{%1, %0|%0, %1}"
3589   [(set_attr "type" "imovx")
3590    (set_attr "mode" "SI")])
3591
3592 ;; For the movzbl case strip only the clobber
3593 (define_split
3594   [(set (match_operand:SI 0 "register_operand" "")
3595         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3596    (clobber (reg:CC FLAGS_REG))]
3597   "reload_completed
3598    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3599    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3600   [(set (match_dup 0)
3601         (zero_extend:SI (match_dup 1)))])
3602
3603 ;; When source and destination does not overlap, clear destination
3604 ;; first and then do the movb
3605 (define_split
3606   [(set (match_operand:SI 0 "register_operand" "")
3607         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3608    (clobber (reg:CC FLAGS_REG))]
3609   "reload_completed
3610    && ANY_QI_REG_P (operands[0])
3611    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3612    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3613    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3614   [(set (match_dup 0) (const_int 0))
3615    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3616   "operands[2] = gen_lowpart (QImode, operands[0]);")
3617
3618 ;; Rest is handled by single and.
3619 (define_split
3620   [(set (match_operand:SI 0 "register_operand" "")
3621         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3622    (clobber (reg:CC FLAGS_REG))]
3623   "reload_completed
3624    && true_regnum (operands[0]) == true_regnum (operands[1])"
3625   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3626               (clobber (reg:CC FLAGS_REG))])]
3627   "")
3628
3629 ;; %%% Kill me once multi-word ops are sane.
3630 (define_expand "zero_extendsidi2"
3631   [(set (match_operand:DI 0 "register_operand" "")
3632      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3633   ""
3634 {
3635   if (!TARGET_64BIT)
3636     {
3637       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3638       DONE;
3639     }
3640 })
3641
3642 (define_insn "zero_extendsidi2_32"
3643   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3644         (zero_extend:DI
3645          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3646    (clobber (reg:CC FLAGS_REG))]
3647   "!TARGET_64BIT"
3648   "@
3649    #
3650    #
3651    #
3652    movd\t{%1, %0|%0, %1}
3653    movd\t{%1, %0|%0, %1}
3654    movd\t{%1, %0|%0, %1}
3655    movd\t{%1, %0|%0, %1}"
3656   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3657    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3658
3659 (define_insn "zero_extendsidi2_rex64"
3660   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3661      (zero_extend:DI
3662        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3663   "TARGET_64BIT"
3664   "@
3665    mov\t{%k1, %k0|%k0, %k1}
3666    #
3667    movd\t{%1, %0|%0, %1}
3668    movd\t{%1, %0|%0, %1}
3669    movd\t{%1, %0|%0, %1}
3670    movd\t{%1, %0|%0, %1}"
3671   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3672    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3673
3674 (define_split
3675   [(set (match_operand:DI 0 "memory_operand" "")
3676      (zero_extend:DI (match_dup 0)))]
3677   "TARGET_64BIT"
3678   [(set (match_dup 4) (const_int 0))]
3679   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3680
3681 (define_split
3682   [(set (match_operand:DI 0 "register_operand" "")
3683         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3684    (clobber (reg:CC FLAGS_REG))]
3685   "!TARGET_64BIT && reload_completed
3686    && true_regnum (operands[0]) == true_regnum (operands[1])"
3687   [(set (match_dup 4) (const_int 0))]
3688   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3689
3690 (define_split
3691   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3692         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3693    (clobber (reg:CC FLAGS_REG))]
3694   "!TARGET_64BIT && reload_completed
3695    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3696   [(set (match_dup 3) (match_dup 1))
3697    (set (match_dup 4) (const_int 0))]
3698   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3699
3700 (define_insn "zero_extendhidi2"
3701   [(set (match_operand:DI 0 "register_operand" "=r")
3702      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3703   "TARGET_64BIT"
3704   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3705   [(set_attr "type" "imovx")
3706    (set_attr "mode" "DI")])
3707
3708 (define_insn "zero_extendqidi2"
3709   [(set (match_operand:DI 0 "register_operand" "=r")
3710      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3711   "TARGET_64BIT"
3712   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3713   [(set_attr "type" "imovx")
3714    (set_attr "mode" "DI")])
3715 \f
3716 ;; Sign extension instructions
3717
3718 (define_expand "extendsidi2"
3719   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3720                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3721               (clobber (reg:CC FLAGS_REG))
3722               (clobber (match_scratch:SI 2 ""))])]
3723   ""
3724 {
3725   if (TARGET_64BIT)
3726     {
3727       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3728       DONE;
3729     }
3730 })
3731
3732 (define_insn "*extendsidi2_1"
3733   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3734         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3735    (clobber (reg:CC FLAGS_REG))
3736    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3737   "!TARGET_64BIT"
3738   "#")
3739
3740 (define_insn "extendsidi2_rex64"
3741   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3742         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3743   "TARGET_64BIT"
3744   "@
3745    {cltq|cdqe}
3746    movs{lq|x}\t{%1,%0|%0, %1}"
3747   [(set_attr "type" "imovx")
3748    (set_attr "mode" "DI")
3749    (set_attr "prefix_0f" "0")
3750    (set_attr "modrm" "0,1")])
3751
3752 (define_insn "extendhidi2"
3753   [(set (match_operand:DI 0 "register_operand" "=r")
3754         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3755   "TARGET_64BIT"
3756   "movs{wq|x}\t{%1,%0|%0, %1}"
3757   [(set_attr "type" "imovx")
3758    (set_attr "mode" "DI")])
3759
3760 (define_insn "extendqidi2"
3761   [(set (match_operand:DI 0 "register_operand" "=r")
3762         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3763   "TARGET_64BIT"
3764   "movs{bq|x}\t{%1,%0|%0, %1}"
3765    [(set_attr "type" "imovx")
3766     (set_attr "mode" "DI")])
3767
3768 ;; Extend to memory case when source register does die.
3769 (define_split
3770   [(set (match_operand:DI 0 "memory_operand" "")
3771         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3772    (clobber (reg:CC FLAGS_REG))
3773    (clobber (match_operand:SI 2 "register_operand" ""))]
3774   "(reload_completed
3775     && dead_or_set_p (insn, operands[1])
3776     && !reg_mentioned_p (operands[1], operands[0]))"
3777   [(set (match_dup 3) (match_dup 1))
3778    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3779               (clobber (reg:CC FLAGS_REG))])
3780    (set (match_dup 4) (match_dup 1))]
3781   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3782
3783 ;; Extend to memory case when source register does not die.
3784 (define_split
3785   [(set (match_operand:DI 0 "memory_operand" "")
3786         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3787    (clobber (reg:CC FLAGS_REG))
3788    (clobber (match_operand:SI 2 "register_operand" ""))]
3789   "reload_completed"
3790   [(const_int 0)]
3791 {
3792   split_di (&operands[0], 1, &operands[3], &operands[4]);
3793
3794   emit_move_insn (operands[3], operands[1]);
3795
3796   /* Generate a cltd if possible and doing so it profitable.  */
3797   if ((optimize_size || TARGET_USE_CLTD)
3798       && true_regnum (operands[1]) == AX_REG
3799       && true_regnum (operands[2]) == DX_REG)
3800     {
3801       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3802     }
3803   else
3804     {
3805       emit_move_insn (operands[2], operands[1]);
3806       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3807     }
3808   emit_move_insn (operands[4], operands[2]);
3809   DONE;
3810 })
3811
3812 ;; Extend to register case.  Optimize case where source and destination
3813 ;; registers match and cases where we can use cltd.
3814 (define_split
3815   [(set (match_operand:DI 0 "register_operand" "")
3816         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3817    (clobber (reg:CC FLAGS_REG))
3818    (clobber (match_scratch:SI 2 ""))]
3819   "reload_completed"
3820   [(const_int 0)]
3821 {
3822   split_di (&operands[0], 1, &operands[3], &operands[4]);
3823
3824   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3825     emit_move_insn (operands[3], operands[1]);
3826
3827   /* Generate a cltd if possible and doing so it profitable.  */
3828   if ((optimize_size || TARGET_USE_CLTD)
3829       && true_regnum (operands[3]) == AX_REG)
3830     {
3831       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3832       DONE;
3833     }
3834
3835   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3836     emit_move_insn (operands[4], operands[1]);
3837
3838   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3839   DONE;
3840 })
3841
3842 (define_insn "extendhisi2"
3843   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3844         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3845   ""
3846 {
3847   switch (get_attr_prefix_0f (insn))
3848     {
3849     case 0:
3850       return "{cwtl|cwde}";
3851     default:
3852       return "movs{wl|x}\t{%1,%0|%0, %1}";
3853     }
3854 }
3855   [(set_attr "type" "imovx")
3856    (set_attr "mode" "SI")
3857    (set (attr "prefix_0f")
3858      ;; movsx is short decodable while cwtl is vector decoded.
3859      (if_then_else (and (eq_attr "cpu" "!k6")
3860                         (eq_attr "alternative" "0"))
3861         (const_string "0")
3862         (const_string "1")))
3863    (set (attr "modrm")
3864      (if_then_else (eq_attr "prefix_0f" "0")
3865         (const_string "0")
3866         (const_string "1")))])
3867
3868 (define_insn "*extendhisi2_zext"
3869   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3870         (zero_extend:DI
3871           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3872   "TARGET_64BIT"
3873 {
3874   switch (get_attr_prefix_0f (insn))
3875     {
3876     case 0:
3877       return "{cwtl|cwde}";
3878     default:
3879       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3880     }
3881 }
3882   [(set_attr "type" "imovx")
3883    (set_attr "mode" "SI")
3884    (set (attr "prefix_0f")
3885      ;; movsx is short decodable while cwtl is vector decoded.
3886      (if_then_else (and (eq_attr "cpu" "!k6")
3887                         (eq_attr "alternative" "0"))
3888         (const_string "0")
3889         (const_string "1")))
3890    (set (attr "modrm")
3891      (if_then_else (eq_attr "prefix_0f" "0")
3892         (const_string "0")
3893         (const_string "1")))])
3894
3895 (define_insn "extendqihi2"
3896   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3897         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3898   ""
3899 {
3900   switch (get_attr_prefix_0f (insn))
3901     {
3902     case 0:
3903       return "{cbtw|cbw}";
3904     default:
3905       return "movs{bw|x}\t{%1,%0|%0, %1}";
3906     }
3907 }
3908   [(set_attr "type" "imovx")
3909    (set_attr "mode" "HI")
3910    (set (attr "prefix_0f")
3911      ;; movsx is short decodable while cwtl is vector decoded.
3912      (if_then_else (and (eq_attr "cpu" "!k6")
3913                         (eq_attr "alternative" "0"))
3914         (const_string "0")
3915         (const_string "1")))
3916    (set (attr "modrm")
3917      (if_then_else (eq_attr "prefix_0f" "0")
3918         (const_string "0")
3919         (const_string "1")))])
3920
3921 (define_insn "extendqisi2"
3922   [(set (match_operand:SI 0 "register_operand" "=r")
3923         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3924   ""
3925   "movs{bl|x}\t{%1,%0|%0, %1}"
3926    [(set_attr "type" "imovx")
3927     (set_attr "mode" "SI")])
3928
3929 (define_insn "*extendqisi2_zext"
3930   [(set (match_operand:DI 0 "register_operand" "=r")
3931         (zero_extend:DI
3932           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3933   "TARGET_64BIT"
3934   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3935    [(set_attr "type" "imovx")
3936     (set_attr "mode" "SI")])
3937 \f
3938 ;; Conversions between float and double.
3939
3940 ;; These are all no-ops in the model used for the 80387.  So just
3941 ;; emit moves.
3942
3943 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3944 (define_insn "*dummy_extendsfdf2"
3945   [(set (match_operand:DF 0 "push_operand" "=<")
3946         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3947   "0"
3948   "#")
3949
3950 (define_split
3951   [(set (match_operand:DF 0 "push_operand" "")
3952         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3953   "!TARGET_64BIT"
3954   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3955    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3956
3957 (define_split
3958   [(set (match_operand:DF 0 "push_operand" "")
3959         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3960   "TARGET_64BIT"
3961   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3962    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3963
3964 (define_insn "*dummy_extendsfxf2"
3965   [(set (match_operand:XF 0 "push_operand" "=<")
3966         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3967   "0"
3968   "#")
3969
3970 (define_split
3971   [(set (match_operand:XF 0 "push_operand" "")
3972         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3973   ""
3974   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3975    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3976   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3977
3978 (define_split
3979   [(set (match_operand:XF 0 "push_operand" "")
3980         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3981   "TARGET_64BIT"
3982   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3983    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3984   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3985
3986 (define_split
3987   [(set (match_operand:XF 0 "push_operand" "")
3988         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3989   ""
3990   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3991    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3992   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3993
3994 (define_split
3995   [(set (match_operand:XF 0 "push_operand" "")
3996         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3997   "TARGET_64BIT"
3998   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3999    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
4000   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4001
4002 (define_expand "extendsfdf2"
4003   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4004         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4005   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4006 {
4007   /* ??? Needed for compress_float_constant since all fp constants
4008      are LEGITIMATE_CONSTANT_P.  */
4009   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4010     {
4011       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4012           && standard_80387_constant_p (operands[1]) > 0)
4013         {
4014           operands[1] = simplify_const_unary_operation
4015             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4016           emit_move_insn_1 (operands[0], operands[1]);
4017           DONE;
4018         }
4019       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4020     }
4021 })
4022
4023 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4024    cvtss2sd:
4025       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4026       cvtps2pd xmm2,xmm1
4027    We do the conversion post reload to avoid producing of 128bit spills
4028    that might lead to ICE on 32bit target.  The sequence unlikely combine
4029    anyway.  */
4030 (define_split
4031   [(set (match_operand:DF 0 "register_operand" "")
4032         (float_extend:DF
4033           (match_operand:SF 1 "nonimmediate_operand" "")))]
4034   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4035    && reload_completed && SSE_REG_P (operands[0])"
4036    [(set (match_dup 2)
4037          (float_extend:V2DF
4038            (vec_select:V2SF
4039              (match_dup 3)
4040              (parallel [(const_int 0) (const_int 1)]))))]
4041 {
4042   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4043   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4044   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4045      Try to avoid move when unpacking can be done in source.  */
4046   if (REG_P (operands[1]))
4047     {
4048       /* If it is unsafe to overwrite upper half of source, we need
4049          to move to destination and unpack there.  */
4050       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4051            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4052           && true_regnum (operands[0]) != true_regnum (operands[1]))
4053         {
4054           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4055           emit_move_insn (tmp, operands[1]);
4056         }
4057       else
4058         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4059       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4060     }
4061   else
4062     emit_insn (gen_vec_setv4sf_0 (operands[3],
4063                                   CONST0_RTX (V4SFmode), operands[1]));
4064 })
4065
4066 (define_insn "*extendsfdf2_mixed"
4067   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4068         (float_extend:DF
4069           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4070   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4071 {
4072   switch (which_alternative)
4073     {
4074     case 0:
4075     case 1:
4076       return output_387_reg_move (insn, operands);
4077
4078     case 2:
4079       return "cvtss2sd\t{%1, %0|%0, %1}";
4080
4081     default:
4082       gcc_unreachable ();
4083     }
4084 }
4085   [(set_attr "type" "fmov,fmov,ssecvt")
4086    (set_attr "mode" "SF,XF,DF")])
4087
4088 (define_insn "*extendsfdf2_sse"
4089   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4090         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4091   "TARGET_SSE2 && TARGET_SSE_MATH"
4092   "cvtss2sd\t{%1, %0|%0, %1}"
4093   [(set_attr "type" "ssecvt")
4094    (set_attr "mode" "DF")])
4095
4096 (define_insn "*extendsfdf2_i387"
4097   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4098         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4099   "TARGET_80387"
4100   "* return output_387_reg_move (insn, operands);"
4101   [(set_attr "type" "fmov")
4102    (set_attr "mode" "SF,XF")])
4103
4104 (define_expand "extend<mode>xf2"
4105   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4106         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4107   "TARGET_80387"
4108 {
4109   /* ??? Needed for compress_float_constant since all fp constants
4110      are LEGITIMATE_CONSTANT_P.  */
4111   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4112     {
4113       if (standard_80387_constant_p (operands[1]) > 0)
4114         {
4115           operands[1] = simplify_const_unary_operation
4116             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4117           emit_move_insn_1 (operands[0], operands[1]);
4118           DONE;
4119         }
4120       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4121     }
4122 })
4123
4124 (define_insn "*extend<mode>xf2_i387"
4125   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4126         (float_extend:XF
4127           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4128   "TARGET_80387"
4129   "* return output_387_reg_move (insn, operands);"
4130   [(set_attr "type" "fmov")
4131    (set_attr "mode" "<MODE>,XF")])
4132
4133 ;; %%% This seems bad bad news.
4134 ;; This cannot output into an f-reg because there is no way to be sure
4135 ;; of truncating in that case.  Otherwise this is just like a simple move
4136 ;; insn.  So we pretend we can output to a reg in order to get better
4137 ;; register preferencing, but we really use a stack slot.
4138
4139 ;; Conversion from DFmode to SFmode.
4140
4141 (define_expand "truncdfsf2"
4142   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4143         (float_truncate:SF
4144           (match_operand:DF 1 "nonimmediate_operand" "")))]
4145   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4146 {
4147   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4148     ;
4149   else if (flag_unsafe_math_optimizations)
4150     ;
4151   else
4152     {
4153       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4154       rtx temp = assign_386_stack_local (SFmode, slot);
4155       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4156       DONE;
4157     }
4158 })
4159
4160 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4161    cvtsd2ss:
4162       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4163       cvtpd2ps xmm2,xmm1
4164    We do the conversion post reload to avoid producing of 128bit spills
4165    that might lead to ICE on 32bit target.  The sequence unlikely combine
4166    anyway.  */
4167 (define_split
4168   [(set (match_operand:SF 0 "register_operand" "")
4169         (float_truncate:SF
4170           (match_operand:DF 1 "nonimmediate_operand" "")))]
4171   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4172    && reload_completed && SSE_REG_P (operands[0])"
4173    [(set (match_dup 2)
4174          (vec_concat:V4SF
4175            (float_truncate:V2SF
4176              (match_dup 4))
4177            (match_dup 3)))]
4178 {
4179   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4180   operands[3] = CONST0_RTX (V2SFmode);
4181   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4182   /* Use movsd for loading from memory, unpcklpd for registers.
4183      Try to avoid move when unpacking can be done in source, or SSE3
4184      movddup is available.  */
4185   if (REG_P (operands[1]))
4186     {
4187       if (!TARGET_SSE3
4188           && true_regnum (operands[0]) != true_regnum (operands[1])
4189           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4190               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4191         {
4192           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4193           emit_move_insn (tmp, operands[1]);
4194           operands[1] = tmp;
4195         }
4196       else if (!TARGET_SSE3)
4197         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4198       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4199     }
4200   else
4201     emit_insn (gen_sse2_loadlpd (operands[4],
4202                                  CONST0_RTX (V2DFmode), operands[1]));
4203 })
4204
4205 (define_expand "truncdfsf2_with_temp"
4206   [(parallel [(set (match_operand:SF 0 "" "")
4207                    (float_truncate:SF (match_operand:DF 1 "" "")))
4208               (clobber (match_operand:SF 2 "" ""))])]
4209   "")
4210
4211 (define_insn "*truncdfsf_fast_mixed"
4212   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4213         (float_truncate:SF
4214           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4215   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4216 {
4217   switch (which_alternative)
4218     {
4219     case 0:
4220       return output_387_reg_move (insn, operands);
4221     case 1:
4222       return "cvtsd2ss\t{%1, %0|%0, %1}";
4223     default:
4224       gcc_unreachable ();
4225     }
4226 }
4227   [(set_attr "type" "fmov,ssecvt")
4228    (set_attr "mode" "SF")])
4229
4230 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4231 ;; because nothing we do here is unsafe.
4232 (define_insn "*truncdfsf_fast_sse"
4233   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4234         (float_truncate:SF
4235           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4236   "TARGET_SSE2 && TARGET_SSE_MATH"
4237   "cvtsd2ss\t{%1, %0|%0, %1}"
4238   [(set_attr "type" "ssecvt")
4239    (set_attr "mode" "SF")])
4240
4241 (define_insn "*truncdfsf_fast_i387"
4242   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4243         (float_truncate:SF
4244           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4245   "TARGET_80387 && flag_unsafe_math_optimizations"
4246   "* return output_387_reg_move (insn, operands);"
4247   [(set_attr "type" "fmov")
4248    (set_attr "mode" "SF")])
4249
4250 (define_insn "*truncdfsf_mixed"
4251   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4252         (float_truncate:SF
4253           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4254    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4255   "TARGET_MIX_SSE_I387"
4256 {
4257   switch (which_alternative)
4258     {
4259     case 0:
4260       return output_387_reg_move (insn, operands);
4261
4262     case 1:
4263       return "#";
4264     case 2:
4265       return "cvtsd2ss\t{%1, %0|%0, %1}";
4266     default:
4267       gcc_unreachable ();
4268     }
4269 }
4270   [(set_attr "type" "fmov,multi,ssecvt")
4271    (set_attr "unit" "*,i387,*")
4272    (set_attr "mode" "SF")])
4273
4274 (define_insn "*truncdfsf_i387"
4275   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4276         (float_truncate:SF
4277           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4278    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4279   "TARGET_80387"
4280 {
4281   switch (which_alternative)
4282     {
4283     case 0:
4284       return output_387_reg_move (insn, operands);
4285
4286     case 1:
4287       return "#";
4288     default:
4289       gcc_unreachable ();
4290     }
4291 }
4292   [(set_attr "type" "fmov,multi")
4293    (set_attr "unit" "*,i387")
4294    (set_attr "mode" "SF")])
4295
4296 (define_insn "*truncdfsf2_i387_1"
4297   [(set (match_operand:SF 0 "memory_operand" "=m")
4298         (float_truncate:SF
4299           (match_operand:DF 1 "register_operand" "f")))]
4300   "TARGET_80387
4301    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4302    && !TARGET_MIX_SSE_I387"
4303   "* return output_387_reg_move (insn, operands);"
4304   [(set_attr "type" "fmov")
4305    (set_attr "mode" "SF")])
4306
4307 (define_split
4308   [(set (match_operand:SF 0 "register_operand" "")
4309         (float_truncate:SF
4310          (match_operand:DF 1 "fp_register_operand" "")))
4311    (clobber (match_operand 2 "" ""))]
4312   "reload_completed"
4313   [(set (match_dup 2) (match_dup 1))
4314    (set (match_dup 0) (match_dup 2))]
4315 {
4316   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4317 })
4318
4319 ;; Conversion from XFmode to {SF,DF}mode
4320
4321 (define_expand "truncxf<mode>2"
4322   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4323                    (float_truncate:MODEF
4324                      (match_operand:XF 1 "register_operand" "")))
4325               (clobber (match_dup 2))])]
4326   "TARGET_80387"
4327 {
4328   if (flag_unsafe_math_optimizations)
4329     {
4330       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4331       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4332       if (reg != operands[0])
4333         emit_move_insn (operands[0], reg);
4334       DONE;
4335     }
4336   else
4337     {
4338       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4339       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4340     }
4341 })
4342
4343 (define_insn "*truncxfsf2_mixed"
4344   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4345         (float_truncate:SF
4346           (match_operand:XF 1 "register_operand" "f,f")))
4347    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4348   "TARGET_80387"
4349 {
4350   gcc_assert (!which_alternative);
4351   return output_387_reg_move (insn, operands);
4352 }
4353   [(set_attr "type" "fmov,multi")
4354    (set_attr "unit" "*,i387")
4355    (set_attr "mode" "SF")])
4356
4357 (define_insn "*truncxfdf2_mixed"
4358   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4359         (float_truncate:DF
4360           (match_operand:XF 1 "register_operand" "f,f")))
4361    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4362   "TARGET_80387"
4363 {
4364   gcc_assert (!which_alternative);
4365   return output_387_reg_move (insn, operands);
4366 }
4367   [(set_attr "type" "fmov,multi")
4368    (set_attr "unit" "*,i387")
4369    (set_attr "mode" "DF")])
4370
4371 (define_insn "truncxf<mode>2_i387_noop"
4372   [(set (match_operand:MODEF 0 "register_operand" "=f")
4373         (float_truncate:MODEF
4374           (match_operand:XF 1 "register_operand" "f")))]
4375   "TARGET_80387 && flag_unsafe_math_optimizations"
4376   "* return output_387_reg_move (insn, operands);"
4377   [(set_attr "type" "fmov")
4378    (set_attr "mode" "<MODE>")])
4379
4380 (define_insn "*truncxf<mode>2_i387"
4381   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4382         (float_truncate:MODEF
4383           (match_operand:XF 1 "register_operand" "f")))]
4384   "TARGET_80387"
4385   "* return output_387_reg_move (insn, operands);"
4386   [(set_attr "type" "fmov")
4387    (set_attr "mode" "<MODE>")])
4388
4389 (define_split
4390   [(set (match_operand:MODEF 0 "register_operand" "")
4391         (float_truncate:MODEF
4392           (match_operand:XF 1 "register_operand" "")))
4393    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4394   "TARGET_80387 && reload_completed"
4395   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4396    (set (match_dup 0) (match_dup 2))]
4397   "")
4398
4399 (define_split
4400   [(set (match_operand:MODEF 0 "memory_operand" "")
4401         (float_truncate:MODEF
4402           (match_operand:XF 1 "register_operand" "")))
4403    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4404   "TARGET_80387"
4405   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4406   "")
4407 \f
4408 ;; Signed conversion to DImode.
4409
4410 (define_expand "fix_truncxfdi2"
4411   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4412                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4413               (clobber (reg:CC FLAGS_REG))])]
4414   "TARGET_80387"
4415 {
4416   if (TARGET_FISTTP)
4417    {
4418      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4419      DONE;
4420    }
4421 })
4422
4423 (define_expand "fix_trunc<mode>di2"
4424   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4425                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4426               (clobber (reg:CC FLAGS_REG))])]
4427   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4428 {
4429   if (TARGET_FISTTP
4430       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4431    {
4432      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4433      DONE;
4434    }
4435   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4436    {
4437      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4438      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4439      if (out != operands[0])
4440         emit_move_insn (operands[0], out);
4441      DONE;
4442    }
4443 })
4444
4445 ;; Signed conversion to SImode.
4446
4447 (define_expand "fix_truncxfsi2"
4448   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4449                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4450               (clobber (reg:CC FLAGS_REG))])]
4451   "TARGET_80387"
4452 {
4453   if (TARGET_FISTTP)
4454    {
4455      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4456      DONE;
4457    }
4458 })
4459
4460 (define_expand "fix_trunc<mode>si2"
4461   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4462                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4463               (clobber (reg:CC FLAGS_REG))])]
4464   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4465 {
4466   if (TARGET_FISTTP
4467       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4468    {
4469      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4470      DONE;
4471    }
4472   if (SSE_FLOAT_MODE_P (<MODE>mode))
4473    {
4474      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4475      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4476      if (out != operands[0])
4477         emit_move_insn (operands[0], out);
4478      DONE;
4479    }
4480 })
4481
4482 ;; Signed conversion to HImode.
4483
4484 (define_expand "fix_trunc<mode>hi2"
4485   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4486                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4487               (clobber (reg:CC FLAGS_REG))])]
4488   "TARGET_80387
4489    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4490 {
4491   if (TARGET_FISTTP)
4492    {
4493      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4494      DONE;
4495    }
4496 })
4497
4498 ;; Unsigned conversion to SImode.
4499
4500 (define_expand "fixuns_trunc<mode>si2"
4501   [(parallel
4502     [(set (match_operand:SI 0 "register_operand" "")
4503           (unsigned_fix:SI
4504             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4505      (use (match_dup 2))
4506      (clobber (match_scratch:<ssevecmode> 3 ""))
4507      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4508   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4509 {
4510   enum machine_mode mode = <MODE>mode;
4511   enum machine_mode vecmode = <ssevecmode>mode;
4512   REAL_VALUE_TYPE TWO31r;
4513   rtx two31;
4514
4515   real_ldexp (&TWO31r, &dconst1, 31);
4516   two31 = const_double_from_real_value (TWO31r, mode);
4517   two31 = ix86_build_const_vector (mode, true, two31);
4518   operands[2] = force_reg (vecmode, two31);
4519 })
4520
4521 (define_insn_and_split "*fixuns_trunc<mode>_1"
4522   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4523         (unsigned_fix:SI
4524           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4525    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4526    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4527    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4528   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4529   "#"
4530   "&& reload_completed"
4531   [(const_int 0)]
4532 {
4533   ix86_split_convert_uns_si_sse (operands);
4534   DONE;
4535 })
4536
4537 ;; Unsigned conversion to HImode.
4538 ;; Without these patterns, we'll try the unsigned SI conversion which
4539 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4540
4541 (define_expand "fixuns_trunc<mode>hi2"
4542   [(set (match_dup 2)
4543         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4544    (set (match_operand:HI 0 "nonimmediate_operand" "")
4545         (subreg:HI (match_dup 2) 0))]
4546   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4547   "operands[2] = gen_reg_rtx (SImode);")
4548
4549 ;; When SSE is available, it is always faster to use it!
4550 (define_insn "fix_trunc<mode>di_sse"
4551   [(set (match_operand:DI 0 "register_operand" "=r,r")
4552         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4553   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4554    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4555   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4556   [(set_attr "type" "sseicvt")
4557    (set_attr "mode" "<MODE>")
4558    (set_attr "athlon_decode" "double,vector")
4559    (set_attr "amdfam10_decode" "double,double")])
4560
4561 (define_insn "fix_trunc<mode>si_sse"
4562   [(set (match_operand:SI 0 "register_operand" "=r,r")
4563         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4564   "SSE_FLOAT_MODE_P (<MODE>mode)
4565    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4566   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4567   [(set_attr "type" "sseicvt")
4568    (set_attr "mode" "<MODE>")
4569    (set_attr "athlon_decode" "double,vector")
4570    (set_attr "amdfam10_decode" "double,double")])
4571
4572 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4573 (define_peephole2
4574   [(set (match_operand:MODEF 0 "register_operand" "")
4575         (match_operand:MODEF 1 "memory_operand" ""))
4576    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4577         (fix:SSEMODEI24 (match_dup 0)))]
4578   "TARGET_SHORTEN_X87_SSE
4579    && peep2_reg_dead_p (2, operands[0])"
4580   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4581   "")
4582
4583 ;; Avoid vector decoded forms of the instruction.
4584 (define_peephole2
4585   [(match_scratch:DF 2 "Y2")
4586    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4587         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4588   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4589   [(set (match_dup 2) (match_dup 1))
4590    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4591   "")
4592
4593 (define_peephole2
4594   [(match_scratch:SF 2 "x")
4595    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4596         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4597   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4598   [(set (match_dup 2) (match_dup 1))
4599    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4600   "")
4601
4602 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4603   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4604         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4605   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4606    && TARGET_FISTTP
4607    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4608          && (TARGET_64BIT || <MODE>mode != DImode))
4609         && TARGET_SSE_MATH)
4610    && !(reload_completed || reload_in_progress)"
4611   "#"
4612   "&& 1"
4613   [(const_int 0)]
4614 {
4615   if (memory_operand (operands[0], VOIDmode))
4616     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4617   else
4618     {
4619       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4620       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4621                                                             operands[1],
4622                                                             operands[2]));
4623     }
4624   DONE;
4625 }
4626   [(set_attr "type" "fisttp")
4627    (set_attr "mode" "<MODE>")])
4628
4629 (define_insn "fix_trunc<mode>_i387_fisttp"
4630   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4631         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4632    (clobber (match_scratch:XF 2 "=&1f"))]
4633   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4634    && TARGET_FISTTP
4635    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4636          && (TARGET_64BIT || <MODE>mode != DImode))
4637         && TARGET_SSE_MATH)"
4638   "* return output_fix_trunc (insn, operands, 1);"
4639   [(set_attr "type" "fisttp")
4640    (set_attr "mode" "<MODE>")])
4641
4642 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4643   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4644         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4645    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4646    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4647   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648    && TARGET_FISTTP
4649    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4650         && (TARGET_64BIT || <MODE>mode != DImode))
4651         && TARGET_SSE_MATH)"
4652   "#"
4653   [(set_attr "type" "fisttp")
4654    (set_attr "mode" "<MODE>")])
4655
4656 (define_split
4657   [(set (match_operand:X87MODEI 0 "register_operand" "")
4658         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4659    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4660    (clobber (match_scratch 3 ""))]
4661   "reload_completed"
4662   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4663               (clobber (match_dup 3))])
4664    (set (match_dup 0) (match_dup 2))]
4665   "")
4666
4667 (define_split
4668   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4669         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4670    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4671    (clobber (match_scratch 3 ""))]
4672   "reload_completed"
4673   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4674               (clobber (match_dup 3))])]
4675   "")
4676
4677 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4678 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4679 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4680 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4681 ;; function in i386.c.
4682 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4683   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4684         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4685    (clobber (reg:CC FLAGS_REG))]
4686   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4687    && !TARGET_FISTTP
4688    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4689          && (TARGET_64BIT || <MODE>mode != DImode))
4690    && !(reload_completed || reload_in_progress)"
4691   "#"
4692   "&& 1"
4693   [(const_int 0)]
4694 {
4695   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4696
4697   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4698   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4699   if (memory_operand (operands[0], VOIDmode))
4700     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4701                                          operands[2], operands[3]));
4702   else
4703     {
4704       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4705       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4706                                                      operands[2], operands[3],
4707                                                      operands[4]));
4708     }
4709   DONE;
4710 }
4711   [(set_attr "type" "fistp")
4712    (set_attr "i387_cw" "trunc")
4713    (set_attr "mode" "<MODE>")])
4714
4715 (define_insn "fix_truncdi_i387"
4716   [(set (match_operand:DI 0 "memory_operand" "=m")
4717         (fix:DI (match_operand 1 "register_operand" "f")))
4718    (use (match_operand:HI 2 "memory_operand" "m"))
4719    (use (match_operand:HI 3 "memory_operand" "m"))
4720    (clobber (match_scratch:XF 4 "=&1f"))]
4721   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4722    && !TARGET_FISTTP
4723    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4724   "* return output_fix_trunc (insn, operands, 0);"
4725   [(set_attr "type" "fistp")
4726    (set_attr "i387_cw" "trunc")
4727    (set_attr "mode" "DI")])
4728
4729 (define_insn "fix_truncdi_i387_with_temp"
4730   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4731         (fix:DI (match_operand 1 "register_operand" "f,f")))
4732    (use (match_operand:HI 2 "memory_operand" "m,m"))
4733    (use (match_operand:HI 3 "memory_operand" "m,m"))
4734    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4735    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4736   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4737    && !TARGET_FISTTP
4738    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4739   "#"
4740   [(set_attr "type" "fistp")
4741    (set_attr "i387_cw" "trunc")
4742    (set_attr "mode" "DI")])
4743
4744 (define_split
4745   [(set (match_operand:DI 0 "register_operand" "")
4746         (fix:DI (match_operand 1 "register_operand" "")))
4747    (use (match_operand:HI 2 "memory_operand" ""))
4748    (use (match_operand:HI 3 "memory_operand" ""))
4749    (clobber (match_operand:DI 4 "memory_operand" ""))
4750    (clobber (match_scratch 5 ""))]
4751   "reload_completed"
4752   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4753               (use (match_dup 2))
4754               (use (match_dup 3))
4755               (clobber (match_dup 5))])
4756    (set (match_dup 0) (match_dup 4))]
4757   "")
4758
4759 (define_split
4760   [(set (match_operand:DI 0 "memory_operand" "")
4761         (fix:DI (match_operand 1 "register_operand" "")))
4762    (use (match_operand:HI 2 "memory_operand" ""))
4763    (use (match_operand:HI 3 "memory_operand" ""))
4764    (clobber (match_operand:DI 4 "memory_operand" ""))
4765    (clobber (match_scratch 5 ""))]
4766   "reload_completed"
4767   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4768               (use (match_dup 2))
4769               (use (match_dup 3))
4770               (clobber (match_dup 5))])]
4771   "")
4772
4773 (define_insn "fix_trunc<mode>_i387"
4774   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4775         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4776    (use (match_operand:HI 2 "memory_operand" "m"))
4777    (use (match_operand:HI 3 "memory_operand" "m"))]
4778   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4779    && !TARGET_FISTTP
4780    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4781   "* return output_fix_trunc (insn, operands, 0);"
4782   [(set_attr "type" "fistp")
4783    (set_attr "i387_cw" "trunc")
4784    (set_attr "mode" "<MODE>")])
4785
4786 (define_insn "fix_trunc<mode>_i387_with_temp"
4787   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4788         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4789    (use (match_operand:HI 2 "memory_operand" "m,m"))
4790    (use (match_operand:HI 3 "memory_operand" "m,m"))
4791    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4792   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4793    && !TARGET_FISTTP
4794    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4795   "#"
4796   [(set_attr "type" "fistp")
4797    (set_attr "i387_cw" "trunc")
4798    (set_attr "mode" "<MODE>")])
4799
4800 (define_split
4801   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4802         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4803    (use (match_operand:HI 2 "memory_operand" ""))
4804    (use (match_operand:HI 3 "memory_operand" ""))
4805    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4806   "reload_completed"
4807   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4808               (use (match_dup 2))
4809               (use (match_dup 3))])
4810    (set (match_dup 0) (match_dup 4))]
4811   "")
4812
4813 (define_split
4814   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4815         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4816    (use (match_operand:HI 2 "memory_operand" ""))
4817    (use (match_operand:HI 3 "memory_operand" ""))
4818    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4819   "reload_completed"
4820   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4821               (use (match_dup 2))
4822               (use (match_dup 3))])]
4823   "")
4824
4825 (define_insn "x86_fnstcw_1"
4826   [(set (match_operand:HI 0 "memory_operand" "=m")
4827         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4828   "TARGET_80387"
4829   "fnstcw\t%0"
4830   [(set_attr "length" "2")
4831    (set_attr "mode" "HI")
4832    (set_attr "unit" "i387")])
4833
4834 (define_insn "x86_fldcw_1"
4835   [(set (reg:HI FPCR_REG)
4836         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4837   "TARGET_80387"
4838   "fldcw\t%0"
4839   [(set_attr "length" "2")
4840    (set_attr "mode" "HI")
4841    (set_attr "unit" "i387")
4842    (set_attr "athlon_decode" "vector")
4843    (set_attr "amdfam10_decode" "vector")])
4844 \f
4845 ;; Conversion between fixed point and floating point.
4846
4847 ;; Even though we only accept memory inputs, the backend _really_
4848 ;; wants to be able to do this between registers.
4849
4850 (define_expand "floathi<mode>2"
4851   [(set (match_operand:X87MODEF 0 "register_operand" "")
4852         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4853   "TARGET_80387
4854    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4855        || TARGET_MIX_SSE_I387)"
4856   "")
4857
4858 ;; Pre-reload splitter to add memory clobber to the pattern.
4859 (define_insn_and_split "*floathi<mode>2_1"
4860   [(set (match_operand:X87MODEF 0 "register_operand" "")
4861         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4862   "TARGET_80387
4863    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4864        || TARGET_MIX_SSE_I387)
4865    && !(reload_completed || reload_in_progress)"
4866   "#"
4867   "&& 1"
4868   [(parallel [(set (match_dup 0)
4869               (float:X87MODEF (match_dup 1)))
4870    (clobber (match_dup 2))])]
4871   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4872
4873 (define_insn "*floathi<mode>2_i387_with_temp"
4874   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4875         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4876   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4877   "TARGET_80387
4878    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4879        || TARGET_MIX_SSE_I387)"
4880   "#"
4881   [(set_attr "type" "fmov,multi")
4882    (set_attr "mode" "<MODE>")
4883    (set_attr "unit" "*,i387")
4884    (set_attr "fp_int_src" "true")])
4885
4886 (define_insn "*floathi<mode>2_i387"
4887   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4888         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4889   "TARGET_80387
4890    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4891        || TARGET_MIX_SSE_I387)"
4892   "fild%z1\t%1"
4893   [(set_attr "type" "fmov")
4894    (set_attr "mode" "<MODE>")
4895    (set_attr "fp_int_src" "true")])
4896
4897 (define_split
4898   [(set (match_operand:X87MODEF 0 "register_operand" "")
4899         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4900    (clobber (match_operand:HI 2 "memory_operand" ""))]
4901   "TARGET_80387
4902    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4903        || TARGET_MIX_SSE_I387)
4904    && reload_completed"
4905   [(set (match_dup 2) (match_dup 1))
4906    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4907   "")
4908
4909 (define_split
4910   [(set (match_operand:X87MODEF 0 "register_operand" "")
4911         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4912    (clobber (match_operand:HI 2 "memory_operand" ""))]
4913    "TARGET_80387
4914     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4915         || TARGET_MIX_SSE_I387)
4916     && reload_completed"
4917   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4918   "")
4919
4920 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4921   [(set (match_operand:X87MODEF 0 "register_operand" "")
4922         (float:X87MODEF
4923           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4924   "TARGET_80387
4925    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4926        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4927   "")
4928
4929 ;; Pre-reload splitter to add memory clobber to the pattern.
4930 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4931   [(set (match_operand:X87MODEF 0 "register_operand" "")
4932         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4933   "((TARGET_80387
4934      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4935            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4936          || TARGET_MIX_SSE_I387))
4937     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4938         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4939         && ((<SSEMODEI24:MODE>mode == SImode
4940              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4941              && flag_trapping_math)
4942             || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4943    && !(reload_completed || reload_in_progress)"
4944   "#"
4945   "&& 1"
4946   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4947               (clobber (match_dup 2))])]
4948 {
4949   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4950
4951   /* Avoid store forwarding (partial memory) stall penalty
4952      by passing DImode value through XMM registers.  */
4953   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT 
4954       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 
4955       && !optimize_size)
4956     {
4957       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4958                                                             operands[1],
4959                                                             operands[2]));
4960       DONE;
4961     }
4962 })
4963
4964 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4965   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4966         (float:MODEF
4967           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4968    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4969   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4970    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4971   "#"
4972   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4973    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4974    (set_attr "unit" "*,i387,*,*,*")
4975    (set_attr "athlon_decode" "*,*,double,direct,double")
4976    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4977    (set_attr "fp_int_src" "true")])
4978
4979 (define_insn "*floatsi<mode>2_vector_mixed"
4980   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4981         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4982   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4983    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4984   "@
4985    fild%z1\t%1
4986    #"
4987   [(set_attr "type" "fmov,sseicvt")
4988    (set_attr "mode" "<MODE>,<ssevecmode>")
4989    (set_attr "unit" "i387,*")
4990    (set_attr "athlon_decode" "*,direct")
4991    (set_attr "amdfam10_decode" "*,double")
4992    (set_attr "fp_int_src" "true")])
4993
4994 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4995   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4996         (float:MODEF
4997           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4998   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4999   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5000    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5001   "#"
5002   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5003    (set_attr "mode" "<MODEF:MODE>")
5004    (set_attr "unit" "*,i387,*,*")
5005    (set_attr "athlon_decode" "*,*,double,direct")
5006    (set_attr "amdfam10_decode" "*,*,vector,double")
5007    (set_attr "fp_int_src" "true")])
5008
5009 (define_split
5010   [(set (match_operand:MODEF 0 "register_operand" "")
5011         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5012    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5013   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5014    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5015    && TARGET_INTER_UNIT_CONVERSIONS
5016    && reload_completed
5017    && (SSE_REG_P (operands[0])
5018        || (GET_CODE (operands[0]) == SUBREG
5019            && SSE_REG_P (operands[0])))"
5020   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5021   "")
5022
5023 (define_split
5024   [(set (match_operand:MODEF 0 "register_operand" "")
5025         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5026    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5027   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5028    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5029    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5030    && reload_completed
5031    && (SSE_REG_P (operands[0])
5032        || (GET_CODE (operands[0]) == SUBREG
5033            && SSE_REG_P (operands[0])))"
5034   [(set (match_dup 2) (match_dup 1))
5035    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5036   "")
5037
5038 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5039   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5040         (float:MODEF
5041           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5042   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5043    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5044    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5045   "@
5046    fild%z1\t%1
5047    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5048    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5049   [(set_attr "type" "fmov,sseicvt,sseicvt")
5050    (set_attr "mode" "<MODEF:MODE>")
5051    (set_attr "unit" "i387,*,*")
5052    (set_attr "athlon_decode" "*,double,direct")
5053    (set_attr "amdfam10_decode" "*,vector,double")
5054    (set_attr "fp_int_src" "true")])
5055
5056 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5057   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5058         (float:MODEF
5059           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5060   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5061    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5062    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5063   "@
5064    fild%z1\t%1
5065    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5066   [(set_attr "type" "fmov,sseicvt")
5067    (set_attr "mode" "<MODEF:MODE>")
5068    (set_attr "athlon_decode" "*,direct")
5069    (set_attr "amdfam10_decode" "*,double")
5070    (set_attr "fp_int_src" "true")])
5071
5072 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5073   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5074         (float:MODEF
5075           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5076    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5077   "TARGET_SSE2 && TARGET_SSE_MATH
5078    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5079   "#"
5080   [(set_attr "type" "sseicvt")
5081    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5082    (set_attr "athlon_decode" "double,direct,double")
5083    (set_attr "amdfam10_decode" "vector,double,double")
5084    (set_attr "fp_int_src" "true")])
5085
5086 (define_insn "*floatsi<mode>2_vector_sse"
5087   [(set (match_operand:MODEF 0 "register_operand" "=x")
5088         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5089   "TARGET_SSE2 && TARGET_SSE_MATH
5090    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5091   "#"
5092   [(set_attr "type" "sseicvt")
5093    (set_attr "mode" "<MODE>")
5094    (set_attr "athlon_decode" "direct")
5095    (set_attr "amdfam10_decode" "double")
5096    (set_attr "fp_int_src" "true")])
5097
5098 (define_split
5099   [(set (match_operand:MODEF 0 "register_operand" "")
5100         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5101    (clobber (match_operand:SI 2 "memory_operand" ""))]
5102   "TARGET_SSE2 && TARGET_SSE_MATH
5103    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5104    && reload_completed
5105    && (SSE_REG_P (operands[0])
5106        || (GET_CODE (operands[0]) == SUBREG
5107            && SSE_REG_P (operands[0])))"
5108   [(const_int 0)]
5109 {
5110   rtx op1 = operands[1];
5111
5112   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5113                                      <MODE>mode, 0);
5114   if (GET_CODE (op1) == SUBREG)
5115     op1 = SUBREG_REG (op1);
5116
5117   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5118     {
5119       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5120       emit_insn (gen_sse2_loadld (operands[4],
5121                                   CONST0_RTX (V4SImode), operands[1]));
5122     }
5123   /* We can ignore possible trapping value in the
5124      high part of SSE register for non-trapping math. */
5125   else if (SSE_REG_P (op1) && !flag_trapping_math)
5126     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5127   else
5128     {
5129       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5130       emit_move_insn (operands[2], operands[1]);
5131       emit_insn (gen_sse2_loadld (operands[4],
5132                                   CONST0_RTX (V4SImode), operands[2]));
5133     }
5134   emit_insn
5135     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5136   DONE;
5137 })
5138
5139 (define_split
5140   [(set (match_operand:MODEF 0 "register_operand" "")
5141         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5142    (clobber (match_operand:SI 2 "memory_operand" ""))]
5143   "TARGET_SSE2 && TARGET_SSE_MATH
5144    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5145    && reload_completed
5146    && (SSE_REG_P (operands[0])
5147        || (GET_CODE (operands[0]) == SUBREG
5148            && SSE_REG_P (operands[0])))"
5149   [(const_int 0)]
5150 {
5151   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5152                                      <MODE>mode, 0);
5153   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5154
5155   emit_insn (gen_sse2_loadld (operands[4],
5156                               CONST0_RTX (V4SImode), operands[1]));
5157   emit_insn
5158     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5159   DONE;
5160 })
5161
5162 (define_split
5163   [(set (match_operand:MODEF 0 "register_operand" "")
5164         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5165   "TARGET_SSE2 && TARGET_SSE_MATH
5166    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5167    && reload_completed
5168    && (SSE_REG_P (operands[0])
5169        || (GET_CODE (operands[0]) == SUBREG
5170            && SSE_REG_P (operands[0])))"
5171   [(const_int 0)]
5172 {
5173   rtx op1 = operands[1];
5174
5175   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5176                                      <MODE>mode, 0);
5177   if (GET_CODE (op1) == SUBREG)
5178     op1 = SUBREG_REG (op1);
5179
5180   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5181     {
5182       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5183       emit_insn (gen_sse2_loadld (operands[4],
5184                                   CONST0_RTX (V4SImode), operands[1]));
5185     }
5186   /* We can ignore possible trapping value in the
5187      high part of SSE register for non-trapping math. */
5188   else if (SSE_REG_P (op1) && !flag_trapping_math)
5189     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5190   else
5191     gcc_unreachable ();
5192 })
5193
5194 (define_split
5195   [(set (match_operand:MODEF 0 "register_operand" "")
5196         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5197   "TARGET_SSE2 && TARGET_SSE_MATH
5198    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5199    && reload_completed
5200    && (SSE_REG_P (operands[0])
5201        || (GET_CODE (operands[0]) == SUBREG
5202            && SSE_REG_P (operands[0])))"
5203   [(const_int 0)]
5204 {
5205   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5206                                      <MODE>mode, 0);
5207   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5208
5209   emit_insn (gen_sse2_loadld (operands[4],
5210                               CONST0_RTX (V4SImode), operands[1]));
5211   emit_insn
5212     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5213   DONE;
5214 })
5215
5216 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5217   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5218         (float:MODEF
5219           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5220   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5221   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5222    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5223   "#"
5224   [(set_attr "type" "sseicvt")
5225    (set_attr "mode" "<MODEF:MODE>")
5226    (set_attr "athlon_decode" "double,direct")
5227    (set_attr "amdfam10_decode" "vector,double")
5228    (set_attr "fp_int_src" "true")])
5229
5230 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5231   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5232         (float:MODEF
5233           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5234   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5235    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5236    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5237   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5238   [(set_attr "type" "sseicvt")
5239    (set_attr "mode" "<MODEF:MODE>")
5240    (set_attr "athlon_decode" "double,direct")
5241    (set_attr "amdfam10_decode" "vector,double")
5242    (set_attr "fp_int_src" "true")])
5243
5244 (define_split
5245   [(set (match_operand:MODEF 0 "register_operand" "")
5246         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5247    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5248   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5249    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5250    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5251    && reload_completed
5252    && (SSE_REG_P (operands[0])
5253        || (GET_CODE (operands[0]) == SUBREG
5254            && SSE_REG_P (operands[0])))"
5255   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5256   "")
5257
5258 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5259   [(set (match_operand:MODEF 0 "register_operand" "=x")
5260         (float:MODEF
5261           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5262   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5263    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5264    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5265   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5266   [(set_attr "type" "sseicvt")
5267    (set_attr "mode" "<MODEF:MODE>")
5268    (set_attr "athlon_decode" "direct")
5269    (set_attr "amdfam10_decode" "double")
5270    (set_attr "fp_int_src" "true")])
5271
5272 (define_split
5273   [(set (match_operand:MODEF 0 "register_operand" "")
5274         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5275    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5276   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5277    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5278    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5279    && reload_completed
5280    && (SSE_REG_P (operands[0])
5281        || (GET_CODE (operands[0]) == SUBREG
5282            && SSE_REG_P (operands[0])))"
5283   [(set (match_dup 2) (match_dup 1))
5284    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5285   "")
5286
5287 (define_split
5288   [(set (match_operand:MODEF 0 "register_operand" "")
5289         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5290    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5291   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5292    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5293    && reload_completed
5294    && (SSE_REG_P (operands[0])
5295        || (GET_CODE (operands[0]) == SUBREG
5296            && SSE_REG_P (operands[0])))"
5297   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5298   "")
5299
5300 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5301   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5302         (float:X87MODEF
5303           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5304   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5305   "TARGET_80387"
5306   "@
5307    fild%z1\t%1
5308    #"
5309   [(set_attr "type" "fmov,multi")
5310    (set_attr "mode" "<X87MODEF:MODE>")
5311    (set_attr "unit" "*,i387")
5312    (set_attr "fp_int_src" "true")])
5313
5314 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5315   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5316         (float:X87MODEF
5317           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5318   "TARGET_80387"
5319   "fild%z1\t%1"
5320   [(set_attr "type" "fmov")
5321    (set_attr "mode" "<X87MODEF:MODE>")
5322    (set_attr "fp_int_src" "true")])
5323
5324 (define_split
5325   [(set (match_operand:X87MODEF 0 "register_operand" "")
5326         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5327    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5328   "TARGET_80387
5329    && reload_completed
5330    && FP_REG_P (operands[0])"
5331   [(set (match_dup 2) (match_dup 1))
5332    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5333   "")
5334
5335 (define_split
5336   [(set (match_operand:X87MODEF 0 "register_operand" "")
5337         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5338    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5339   "TARGET_80387
5340    && reload_completed
5341    && FP_REG_P (operands[0])"
5342   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5343   "")
5344
5345 ;; Avoid store forwarding (partial memory) stall penalty
5346 ;; by passing DImode value through XMM registers.  */
5347
5348 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5349   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5350         (float:X87MODEF
5351           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5352    (clobber (match_scratch:V4SI 3 "=X,x"))
5353    (clobber (match_scratch:V4SI 4 "=X,x"))
5354    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5355   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5356    && !TARGET_64BIT && !optimize_size"
5357   "#"
5358   [(set_attr "type" "multi")
5359    (set_attr "mode" "<X87MODEF:MODE>")
5360    (set_attr "unit" "i387")
5361    (set_attr "fp_int_src" "true")])
5362
5363 (define_split
5364   [(set (match_operand:X87MODEF 0 "register_operand" "")
5365         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5366    (clobber (match_scratch:V4SI 3 ""))
5367    (clobber (match_scratch:V4SI 4 ""))
5368    (clobber (match_operand:DI 2 "memory_operand" ""))]
5369   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5370    && !TARGET_64BIT && !optimize_size
5371    && reload_completed
5372    && FP_REG_P (operands[0])"
5373   [(set (match_dup 2) (match_dup 3))
5374    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5375 {
5376   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5377      Assemble the 64-bit DImode value in an xmm register.  */
5378   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5379                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5380   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5381                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5382   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5383
5384   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5385 })
5386
5387 (define_split
5388   [(set (match_operand:X87MODEF 0 "register_operand" "")
5389         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5390    (clobber (match_scratch:V4SI 3 ""))
5391    (clobber (match_scratch:V4SI 4 ""))
5392    (clobber (match_operand:DI 2 "memory_operand" ""))]
5393   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5394    && !TARGET_64BIT && !optimize_size
5395    && reload_completed
5396    && FP_REG_P (operands[0])"
5397   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5398   "")
5399
5400 ;; Avoid store forwarding (partial memory) stall penalty by extending
5401 ;; SImode value to DImode through XMM register instead of pushing two
5402 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5403 ;; targets benefit from this optimization. Also note that fild
5404 ;; loads from memory only.
5405
5406 (define_insn "*floatunssi<mode>2_1"
5407   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5408         (unsigned_float:X87MODEF
5409           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5410    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5411    (clobber (match_scratch:SI 3 "=X,x"))]
5412   "!TARGET_64BIT
5413    && TARGET_80387 && TARGET_SSE"
5414   "#"
5415   [(set_attr "type" "multi")
5416    (set_attr "mode" "<MODE>")])
5417
5418 (define_split
5419   [(set (match_operand:X87MODEF 0 "register_operand" "")
5420         (unsigned_float:X87MODEF
5421           (match_operand:SI 1 "register_operand" "")))
5422    (clobber (match_operand:DI 2 "memory_operand" ""))
5423    (clobber (match_scratch:SI 3 ""))]
5424   "!TARGET_64BIT
5425    && TARGET_80387 && TARGET_SSE
5426    && reload_completed"
5427   [(set (match_dup 2) (match_dup 1))
5428    (set (match_dup 0)
5429         (float:X87MODEF (match_dup 2)))]
5430   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5431
5432 (define_split
5433   [(set (match_operand:X87MODEF 0 "register_operand" "")
5434         (unsigned_float:X87MODEF
5435           (match_operand:SI 1 "memory_operand" "")))
5436    (clobber (match_operand:DI 2 "memory_operand" ""))
5437    (clobber (match_scratch:SI 3 ""))]
5438   "!TARGET_64BIT
5439    && TARGET_80387 && TARGET_SSE
5440    && reload_completed"
5441   [(set (match_dup 2) (match_dup 3))
5442    (set (match_dup 0)
5443         (float:X87MODEF (match_dup 2)))]
5444 {
5445   emit_move_insn (operands[3], operands[1]);
5446   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5447 })
5448
5449 (define_expand "floatunssi<mode>2"
5450   [(parallel
5451      [(set (match_operand:X87MODEF 0 "register_operand" "")
5452            (unsigned_float:X87MODEF
5453              (match_operand:SI 1 "nonimmediate_operand" "")))
5454       (clobber (match_dup 2))
5455       (clobber (match_scratch:SI 3 ""))])]
5456   "!TARGET_64BIT
5457    && ((TARGET_80387 && TARGET_SSE)
5458        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5459 {
5460   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5461     {
5462       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5463       DONE;
5464     }
5465   else
5466     {
5467       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5468       operands[2] = assign_386_stack_local (DImode, slot);
5469     }
5470 })
5471
5472 (define_expand "floatunsdisf2"
5473   [(use (match_operand:SF 0 "register_operand" ""))
5474    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5475   "TARGET_64BIT && TARGET_SSE_MATH"
5476   "x86_emit_floatuns (operands); DONE;")
5477
5478 (define_expand "floatunsdidf2"
5479   [(use (match_operand:DF 0 "register_operand" ""))
5480    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5481   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5482    && TARGET_SSE2 && TARGET_SSE_MATH"
5483 {
5484   if (TARGET_64BIT)
5485     x86_emit_floatuns (operands);
5486   else
5487     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5488   DONE;
5489 })
5490 \f
5491 ;; Add instructions
5492
5493 ;; %%% splits for addditi3
5494
5495 (define_expand "addti3"
5496   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5497         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5498                  (match_operand:TI 2 "x86_64_general_operand" "")))
5499    (clobber (reg:CC FLAGS_REG))]
5500   "TARGET_64BIT"
5501   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5502
5503 (define_insn "*addti3_1"
5504   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5505         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5506                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5507    (clobber (reg:CC FLAGS_REG))]
5508   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5509   "#")
5510
5511 (define_split
5512   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5513         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5514                  (match_operand:TI 2 "x86_64_general_operand" "")))
5515    (clobber (reg:CC FLAGS_REG))]
5516   "TARGET_64BIT && reload_completed"
5517   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5518                                           UNSPEC_ADD_CARRY))
5519               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5520    (parallel [(set (match_dup 3)
5521                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5522                                      (match_dup 4))
5523                             (match_dup 5)))
5524               (clobber (reg:CC FLAGS_REG))])]
5525   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5526
5527 ;; %%% splits for addsidi3
5528 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5529 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5530 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5531
5532 (define_expand "adddi3"
5533   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5534         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5535                  (match_operand:DI 2 "x86_64_general_operand" "")))
5536    (clobber (reg:CC FLAGS_REG))]
5537   ""
5538   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5539
5540 (define_insn "*adddi3_1"
5541   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5542         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5543                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5544    (clobber (reg:CC FLAGS_REG))]
5545   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5546   "#")
5547
5548 (define_split
5549   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5550         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5551                  (match_operand:DI 2 "general_operand" "")))
5552    (clobber (reg:CC FLAGS_REG))]
5553   "!TARGET_64BIT && reload_completed"
5554   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5555                                           UNSPEC_ADD_CARRY))
5556               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5557    (parallel [(set (match_dup 3)
5558                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5559                                      (match_dup 4))
5560                             (match_dup 5)))
5561               (clobber (reg:CC FLAGS_REG))])]
5562   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5563
5564 (define_insn "adddi3_carry_rex64"
5565   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5566           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5567                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5568                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5569    (clobber (reg:CC FLAGS_REG))]
5570   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5571   "adc{q}\t{%2, %0|%0, %2}"
5572   [(set_attr "type" "alu")
5573    (set_attr "pent_pair" "pu")
5574    (set_attr "mode" "DI")])
5575
5576 (define_insn "*adddi3_cc_rex64"
5577   [(set (reg:CC FLAGS_REG)
5578         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5579                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5580                    UNSPEC_ADD_CARRY))
5581    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5582         (plus:DI (match_dup 1) (match_dup 2)))]
5583   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5584   "add{q}\t{%2, %0|%0, %2}"
5585   [(set_attr "type" "alu")
5586    (set_attr "mode" "DI")])
5587
5588 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5589   [(set (reg:CCC FLAGS_REG)
5590         (compare:CCC
5591             (plusminus:SWI
5592                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5593                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5594             (match_dup 1)))
5595    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5596         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5597   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5598   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5599   [(set_attr "type" "alu")
5600    (set_attr "mode" "<MODE>")])
5601
5602 (define_insn "*add<mode>3_cconly_overflow"
5603   [(set (reg:CCC FLAGS_REG)
5604         (compare:CCC
5605                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5606                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5607                 (match_dup 1)))
5608    (clobber (match_scratch:SWI 0 "=<r>"))]
5609   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5610   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5611   [(set_attr "type" "alu")
5612    (set_attr "mode" "<MODE>")])
5613
5614 (define_insn "*sub<mode>3_cconly_overflow"
5615   [(set (reg:CCC FLAGS_REG)
5616         (compare:CCC
5617              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5618                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5619              (match_dup 0)))]
5620   ""
5621   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5622   [(set_attr "type" "icmp")
5623    (set_attr "mode" "<MODE>")])
5624
5625 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5626   [(set (reg:CCC FLAGS_REG)
5627         (compare:CCC
5628             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5629                           (match_operand:SI 2 "general_operand" "g"))
5630             (match_dup 1)))
5631    (set (match_operand:DI 0 "register_operand" "=r")
5632         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5633   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5634   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5635   [(set_attr "type" "alu")
5636    (set_attr "mode" "SI")])
5637
5638 (define_insn "addqi3_carry"
5639   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5640           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5641                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5642                    (match_operand:QI 2 "general_operand" "qi,qm")))
5643    (clobber (reg:CC FLAGS_REG))]
5644   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5645   "adc{b}\t{%2, %0|%0, %2}"
5646   [(set_attr "type" "alu")
5647    (set_attr "pent_pair" "pu")
5648    (set_attr "mode" "QI")])
5649
5650 (define_insn "addhi3_carry"
5651   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5652           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5653                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5654                    (match_operand:HI 2 "general_operand" "ri,rm")))
5655    (clobber (reg:CC FLAGS_REG))]
5656   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5657   "adc{w}\t{%2, %0|%0, %2}"
5658   [(set_attr "type" "alu")
5659    (set_attr "pent_pair" "pu")
5660    (set_attr "mode" "HI")])
5661
5662 (define_insn "addsi3_carry"
5663   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5664           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5665                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5666                    (match_operand:SI 2 "general_operand" "ri,rm")))
5667    (clobber (reg:CC FLAGS_REG))]
5668   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5669   "adc{l}\t{%2, %0|%0, %2}"
5670   [(set_attr "type" "alu")
5671    (set_attr "pent_pair" "pu")
5672    (set_attr "mode" "SI")])
5673
5674 (define_insn "*addsi3_carry_zext"
5675   [(set (match_operand:DI 0 "register_operand" "=r")
5676           (zero_extend:DI
5677             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5678                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5679                      (match_operand:SI 2 "general_operand" "g"))))
5680    (clobber (reg:CC FLAGS_REG))]
5681   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5682   "adc{l}\t{%2, %k0|%k0, %2}"
5683   [(set_attr "type" "alu")
5684    (set_attr "pent_pair" "pu")
5685    (set_attr "mode" "SI")])
5686
5687 (define_insn "*addsi3_cc"
5688   [(set (reg:CC FLAGS_REG)
5689         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5690                     (match_operand:SI 2 "general_operand" "ri,rm")]
5691                    UNSPEC_ADD_CARRY))
5692    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5693         (plus:SI (match_dup 1) (match_dup 2)))]
5694   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5695   "add{l}\t{%2, %0|%0, %2}"
5696   [(set_attr "type" "alu")
5697    (set_attr "mode" "SI")])
5698
5699 (define_insn "addqi3_cc"
5700   [(set (reg:CC FLAGS_REG)
5701         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5702                     (match_operand:QI 2 "general_operand" "qi,qm")]
5703                    UNSPEC_ADD_CARRY))
5704    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5705         (plus:QI (match_dup 1) (match_dup 2)))]
5706   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5707   "add{b}\t{%2, %0|%0, %2}"
5708   [(set_attr "type" "alu")
5709    (set_attr "mode" "QI")])
5710
5711 (define_expand "addsi3"
5712   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5713                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5714                             (match_operand:SI 2 "general_operand" "")))
5715               (clobber (reg:CC FLAGS_REG))])]
5716   ""
5717   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5718
5719 (define_insn "*lea_1"
5720   [(set (match_operand:SI 0 "register_operand" "=r")
5721         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5722   "!TARGET_64BIT"
5723   "lea{l}\t{%a1, %0|%0, %a1}"
5724   [(set_attr "type" "lea")
5725    (set_attr "mode" "SI")])
5726
5727 (define_insn "*lea_1_rex64"
5728   [(set (match_operand:SI 0 "register_operand" "=r")
5729         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5730   "TARGET_64BIT"
5731   "lea{l}\t{%a1, %0|%0, %a1}"
5732   [(set_attr "type" "lea")
5733    (set_attr "mode" "SI")])
5734
5735 (define_insn "*lea_1_zext"
5736   [(set (match_operand:DI 0 "register_operand" "=r")
5737         (zero_extend:DI
5738          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5739   "TARGET_64BIT"
5740   "lea{l}\t{%a1, %k0|%k0, %a1}"
5741   [(set_attr "type" "lea")
5742    (set_attr "mode" "SI")])
5743
5744 (define_insn "*lea_2_rex64"
5745   [(set (match_operand:DI 0 "register_operand" "=r")
5746         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5747   "TARGET_64BIT"
5748   "lea{q}\t{%a1, %0|%0, %a1}"
5749   [(set_attr "type" "lea")
5750    (set_attr "mode" "DI")])
5751
5752 ;; The lea patterns for non-Pmodes needs to be matched by several
5753 ;; insns converted to real lea by splitters.
5754
5755 (define_insn_and_split "*lea_general_1"
5756   [(set (match_operand 0 "register_operand" "=r")
5757         (plus (plus (match_operand 1 "index_register_operand" "l")
5758                     (match_operand 2 "register_operand" "r"))
5759               (match_operand 3 "immediate_operand" "i")))]
5760   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5761     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5762    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5763    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5764    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5765    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5766        || GET_MODE (operands[3]) == VOIDmode)"
5767   "#"
5768   "&& reload_completed"
5769   [(const_int 0)]
5770 {
5771   rtx pat;
5772   operands[0] = gen_lowpart (SImode, operands[0]);
5773   operands[1] = gen_lowpart (Pmode, operands[1]);
5774   operands[2] = gen_lowpart (Pmode, operands[2]);
5775   operands[3] = gen_lowpart (Pmode, operands[3]);
5776   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5777                       operands[3]);
5778   if (Pmode != SImode)
5779     pat = gen_rtx_SUBREG (SImode, pat, 0);
5780   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5781   DONE;
5782 }
5783   [(set_attr "type" "lea")
5784    (set_attr "mode" "SI")])
5785
5786 (define_insn_and_split "*lea_general_1_zext"
5787   [(set (match_operand:DI 0 "register_operand" "=r")
5788         (zero_extend:DI
5789           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5790                             (match_operand:SI 2 "register_operand" "r"))
5791                    (match_operand:SI 3 "immediate_operand" "i"))))]
5792   "TARGET_64BIT"
5793   "#"
5794   "&& reload_completed"
5795   [(set (match_dup 0)
5796         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5797                                                      (match_dup 2))
5798                                             (match_dup 3)) 0)))]
5799 {
5800   operands[1] = gen_lowpart (Pmode, operands[1]);
5801   operands[2] = gen_lowpart (Pmode, operands[2]);
5802   operands[3] = gen_lowpart (Pmode, operands[3]);
5803 }
5804   [(set_attr "type" "lea")
5805    (set_attr "mode" "SI")])
5806
5807 (define_insn_and_split "*lea_general_2"
5808   [(set (match_operand 0 "register_operand" "=r")
5809         (plus (mult (match_operand 1 "index_register_operand" "l")
5810                     (match_operand 2 "const248_operand" "i"))
5811               (match_operand 3 "nonmemory_operand" "ri")))]
5812   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5813     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5814    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5815    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5816    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5817        || GET_MODE (operands[3]) == VOIDmode)"
5818   "#"
5819   "&& reload_completed"
5820   [(const_int 0)]
5821 {
5822   rtx pat;
5823   operands[0] = gen_lowpart (SImode, operands[0]);
5824   operands[1] = gen_lowpart (Pmode, operands[1]);
5825   operands[3] = gen_lowpart (Pmode, operands[3]);
5826   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5827                       operands[3]);
5828   if (Pmode != SImode)
5829     pat = gen_rtx_SUBREG (SImode, pat, 0);
5830   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5831   DONE;
5832 }
5833   [(set_attr "type" "lea")
5834    (set_attr "mode" "SI")])
5835
5836 (define_insn_and_split "*lea_general_2_zext"
5837   [(set (match_operand:DI 0 "register_operand" "=r")
5838         (zero_extend:DI
5839           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5840                             (match_operand:SI 2 "const248_operand" "n"))
5841                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5842   "TARGET_64BIT"
5843   "#"
5844   "&& reload_completed"
5845   [(set (match_dup 0)
5846         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5847                                                      (match_dup 2))
5848                                             (match_dup 3)) 0)))]
5849 {
5850   operands[1] = gen_lowpart (Pmode, operands[1]);
5851   operands[3] = gen_lowpart (Pmode, operands[3]);
5852 }
5853   [(set_attr "type" "lea")
5854    (set_attr "mode" "SI")])
5855
5856 (define_insn_and_split "*lea_general_3"
5857   [(set (match_operand 0 "register_operand" "=r")
5858         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5859                           (match_operand 2 "const248_operand" "i"))
5860                     (match_operand 3 "register_operand" "r"))
5861               (match_operand 4 "immediate_operand" "i")))]
5862   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5863     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5864    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5865    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5866    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5867   "#"
5868   "&& reload_completed"
5869   [(const_int 0)]
5870 {
5871   rtx pat;
5872   operands[0] = gen_lowpart (SImode, operands[0]);
5873   operands[1] = gen_lowpart (Pmode, operands[1]);
5874   operands[3] = gen_lowpart (Pmode, operands[3]);
5875   operands[4] = gen_lowpart (Pmode, operands[4]);
5876   pat = gen_rtx_PLUS (Pmode,
5877                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5878                                                          operands[2]),
5879                                     operands[3]),
5880                       operands[4]);
5881   if (Pmode != SImode)
5882     pat = gen_rtx_SUBREG (SImode, pat, 0);
5883   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5884   DONE;
5885 }
5886   [(set_attr "type" "lea")
5887    (set_attr "mode" "SI")])
5888
5889 (define_insn_and_split "*lea_general_3_zext"
5890   [(set (match_operand:DI 0 "register_operand" "=r")
5891         (zero_extend:DI
5892           (plus:SI (plus:SI (mult:SI
5893                               (match_operand:SI 1 "index_register_operand" "l")
5894                               (match_operand:SI 2 "const248_operand" "n"))
5895                             (match_operand:SI 3 "register_operand" "r"))
5896                    (match_operand:SI 4 "immediate_operand" "i"))))]
5897   "TARGET_64BIT"
5898   "#"
5899   "&& reload_completed"
5900   [(set (match_dup 0)
5901         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5902                                                               (match_dup 2))
5903                                                      (match_dup 3))
5904                                             (match_dup 4)) 0)))]
5905 {
5906   operands[1] = gen_lowpart (Pmode, operands[1]);
5907   operands[3] = gen_lowpart (Pmode, operands[3]);
5908   operands[4] = gen_lowpart (Pmode, operands[4]);
5909 }
5910   [(set_attr "type" "lea")
5911    (set_attr "mode" "SI")])
5912
5913 (define_insn "*adddi_1_rex64"
5914   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5915         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5916                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5917    (clobber (reg:CC FLAGS_REG))]
5918   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5919 {
5920   switch (get_attr_type (insn))
5921     {
5922     case TYPE_LEA:
5923       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5924       return "lea{q}\t{%a2, %0|%0, %a2}";
5925
5926     case TYPE_INCDEC:
5927       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5928       if (operands[2] == const1_rtx)
5929         return "inc{q}\t%0";
5930       else
5931         {
5932           gcc_assert (operands[2] == constm1_rtx);
5933           return "dec{q}\t%0";
5934         }
5935
5936     default:
5937       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5938
5939       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5940          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5941       if (CONST_INT_P (operands[2])
5942           /* Avoid overflows.  */
5943           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5944           && (INTVAL (operands[2]) == 128
5945               || (INTVAL (operands[2]) < 0
5946                   && INTVAL (operands[2]) != -128)))
5947         {
5948           operands[2] = GEN_INT (-INTVAL (operands[2]));
5949           return "sub{q}\t{%2, %0|%0, %2}";
5950         }
5951       return "add{q}\t{%2, %0|%0, %2}";
5952     }
5953 }
5954   [(set (attr "type")
5955      (cond [(eq_attr "alternative" "2")
5956               (const_string "lea")
5957             ; Current assemblers are broken and do not allow @GOTOFF in
5958             ; ought but a memory context.
5959             (match_operand:DI 2 "pic_symbolic_operand" "")
5960               (const_string "lea")
5961             (match_operand:DI 2 "incdec_operand" "")
5962               (const_string "incdec")
5963            ]
5964            (const_string "alu")))
5965    (set_attr "mode" "DI")])
5966
5967 ;; Convert lea to the lea pattern to avoid flags dependency.
5968 (define_split
5969   [(set (match_operand:DI 0 "register_operand" "")
5970         (plus:DI (match_operand:DI 1 "register_operand" "")
5971                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5972    (clobber (reg:CC FLAGS_REG))]
5973   "TARGET_64BIT && reload_completed
5974    && true_regnum (operands[0]) != true_regnum (operands[1])"
5975   [(set (match_dup 0)
5976         (plus:DI (match_dup 1)
5977                  (match_dup 2)))]
5978   "")
5979
5980 (define_insn "*adddi_2_rex64"
5981   [(set (reg FLAGS_REG)
5982         (compare
5983           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5984                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5985           (const_int 0)))
5986    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5987         (plus:DI (match_dup 1) (match_dup 2)))]
5988   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5989    && ix86_binary_operator_ok (PLUS, DImode, operands)
5990    /* Current assemblers are broken and do not allow @GOTOFF in
5991       ought but a memory context.  */
5992    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5993 {
5994   switch (get_attr_type (insn))
5995     {
5996     case TYPE_INCDEC:
5997       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5998       if (operands[2] == const1_rtx)
5999         return "inc{q}\t%0";
6000       else
6001         {
6002           gcc_assert (operands[2] == constm1_rtx);
6003           return "dec{q}\t%0";
6004         }
6005
6006     default:
6007       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6008       /* ???? We ought to handle there the 32bit case too
6009          - do we need new constraint?  */
6010       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6012       if (CONST_INT_P (operands[2])
6013           /* Avoid overflows.  */
6014           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6015           && (INTVAL (operands[2]) == 128
6016               || (INTVAL (operands[2]) < 0
6017                   && INTVAL (operands[2]) != -128)))
6018         {
6019           operands[2] = GEN_INT (-INTVAL (operands[2]));
6020           return "sub{q}\t{%2, %0|%0, %2}";
6021         }
6022       return "add{q}\t{%2, %0|%0, %2}";
6023     }
6024 }
6025   [(set (attr "type")
6026      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6027         (const_string "incdec")
6028         (const_string "alu")))
6029    (set_attr "mode" "DI")])
6030
6031 (define_insn "*adddi_3_rex64"
6032   [(set (reg FLAGS_REG)
6033         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6034                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6035    (clobber (match_scratch:DI 0 "=r"))]
6036   "TARGET_64BIT
6037    && ix86_match_ccmode (insn, CCZmode)
6038    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6039    /* Current assemblers are broken and do not allow @GOTOFF in
6040       ought but a memory context.  */
6041    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6042 {
6043   switch (get_attr_type (insn))
6044     {
6045     case TYPE_INCDEC:
6046       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6047       if (operands[2] == const1_rtx)
6048         return "inc{q}\t%0";
6049       else
6050         {
6051           gcc_assert (operands[2] == constm1_rtx);
6052           return "dec{q}\t%0";
6053         }
6054
6055     default:
6056       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6057       /* ???? We ought to handle there the 32bit case too
6058          - do we need new constraint?  */
6059       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6060          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6061       if (CONST_INT_P (operands[2])
6062           /* Avoid overflows.  */
6063           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6064           && (INTVAL (operands[2]) == 128
6065               || (INTVAL (operands[2]) < 0
6066                   && INTVAL (operands[2]) != -128)))
6067         {
6068           operands[2] = GEN_INT (-INTVAL (operands[2]));
6069           return "sub{q}\t{%2, %0|%0, %2}";
6070         }
6071       return "add{q}\t{%2, %0|%0, %2}";
6072     }
6073 }
6074   [(set (attr "type")
6075      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6076         (const_string "incdec")
6077         (const_string "alu")))
6078    (set_attr "mode" "DI")])
6079
6080 ; For comparisons against 1, -1 and 128, we may generate better code
6081 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6082 ; is matched then.  We can't accept general immediate, because for
6083 ; case of overflows,  the result is messed up.
6084 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6085 ; when negated.
6086 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6087 ; only for comparisons not depending on it.
6088 (define_insn "*adddi_4_rex64"
6089   [(set (reg FLAGS_REG)
6090         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6091                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6092    (clobber (match_scratch:DI 0 "=rm"))]
6093   "TARGET_64BIT
6094    &&  ix86_match_ccmode (insn, CCGCmode)"
6095 {
6096   switch (get_attr_type (insn))
6097     {
6098     case TYPE_INCDEC:
6099       if (operands[2] == constm1_rtx)
6100         return "inc{q}\t%0";
6101       else
6102         {
6103           gcc_assert (operands[2] == const1_rtx);
6104           return "dec{q}\t%0";
6105         }
6106
6107     default:
6108       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6109       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6110          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6111       if ((INTVAL (operands[2]) == -128
6112            || (INTVAL (operands[2]) > 0
6113                && INTVAL (operands[2]) != 128))
6114           /* Avoid overflows.  */
6115           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6116         return "sub{q}\t{%2, %0|%0, %2}";
6117       operands[2] = GEN_INT (-INTVAL (operands[2]));
6118       return "add{q}\t{%2, %0|%0, %2}";
6119     }
6120 }
6121   [(set (attr "type")
6122      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6123         (const_string "incdec")
6124         (const_string "alu")))
6125    (set_attr "mode" "DI")])
6126
6127 (define_insn "*adddi_5_rex64"
6128   [(set (reg FLAGS_REG)
6129         (compare
6130           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6131                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6132           (const_int 0)))
6133    (clobber (match_scratch:DI 0 "=r"))]
6134   "TARGET_64BIT
6135    && ix86_match_ccmode (insn, CCGOCmode)
6136    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6137    /* Current assemblers are broken and do not allow @GOTOFF in
6138       ought but a memory context.  */
6139    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6140 {
6141   switch (get_attr_type (insn))
6142     {
6143     case TYPE_INCDEC:
6144       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6145       if (operands[2] == const1_rtx)
6146         return "inc{q}\t%0";
6147       else
6148         {
6149           gcc_assert (operands[2] == constm1_rtx);
6150           return "dec{q}\t%0";
6151         }
6152
6153     default:
6154       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6155       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6156          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6157       if (CONST_INT_P (operands[2])
6158           /* Avoid overflows.  */
6159           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6160           && (INTVAL (operands[2]) == 128
6161               || (INTVAL (operands[2]) < 0
6162                   && INTVAL (operands[2]) != -128)))
6163         {
6164           operands[2] = GEN_INT (-INTVAL (operands[2]));
6165           return "sub{q}\t{%2, %0|%0, %2}";
6166         }
6167       return "add{q}\t{%2, %0|%0, %2}";
6168     }
6169 }
6170   [(set (attr "type")
6171      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6172         (const_string "incdec")
6173         (const_string "alu")))
6174    (set_attr "mode" "DI")])
6175
6176
6177 (define_insn "*addsi_1"
6178   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6179         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6180                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6181    (clobber (reg:CC FLAGS_REG))]
6182   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6183 {
6184   switch (get_attr_type (insn))
6185     {
6186     case TYPE_LEA:
6187       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6188       return "lea{l}\t{%a2, %0|%0, %a2}";
6189
6190     case TYPE_INCDEC:
6191       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6192       if (operands[2] == const1_rtx)
6193         return "inc{l}\t%0";
6194       else
6195         {
6196           gcc_assert (operands[2] == constm1_rtx);
6197           return "dec{l}\t%0";
6198         }
6199
6200     default:
6201       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6202
6203       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6204          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6205       if (CONST_INT_P (operands[2])
6206           && (INTVAL (operands[2]) == 128
6207               || (INTVAL (operands[2]) < 0
6208                   && INTVAL (operands[2]) != -128)))
6209         {
6210           operands[2] = GEN_INT (-INTVAL (operands[2]));
6211           return "sub{l}\t{%2, %0|%0, %2}";
6212         }
6213       return "add{l}\t{%2, %0|%0, %2}";
6214     }
6215 }
6216   [(set (attr "type")
6217      (cond [(eq_attr "alternative" "2")
6218               (const_string "lea")
6219             ; Current assemblers are broken and do not allow @GOTOFF in
6220             ; ought but a memory context.
6221             (match_operand:SI 2 "pic_symbolic_operand" "")
6222               (const_string "lea")
6223             (match_operand:SI 2 "incdec_operand" "")
6224               (const_string "incdec")
6225            ]
6226            (const_string "alu")))
6227    (set_attr "mode" "SI")])
6228
6229 ;; Convert lea to the lea pattern to avoid flags dependency.
6230 (define_split
6231   [(set (match_operand 0 "register_operand" "")
6232         (plus (match_operand 1 "register_operand" "")
6233               (match_operand 2 "nonmemory_operand" "")))
6234    (clobber (reg:CC FLAGS_REG))]
6235   "reload_completed
6236    && true_regnum (operands[0]) != true_regnum (operands[1])"
6237   [(const_int 0)]
6238 {
6239   rtx pat;
6240   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6241      may confuse gen_lowpart.  */
6242   if (GET_MODE (operands[0]) != Pmode)
6243     {
6244       operands[1] = gen_lowpart (Pmode, operands[1]);
6245       operands[2] = gen_lowpart (Pmode, operands[2]);
6246     }
6247   operands[0] = gen_lowpart (SImode, operands[0]);
6248   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6249   if (Pmode != SImode)
6250     pat = gen_rtx_SUBREG (SImode, pat, 0);
6251   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6252   DONE;
6253 })
6254
6255 ;; It may seem that nonimmediate operand is proper one for operand 1.
6256 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6257 ;; we take care in ix86_binary_operator_ok to not allow two memory
6258 ;; operands so proper swapping will be done in reload.  This allow
6259 ;; patterns constructed from addsi_1 to match.
6260 (define_insn "addsi_1_zext"
6261   [(set (match_operand:DI 0 "register_operand" "=r,r")
6262         (zero_extend:DI
6263           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6264                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6265    (clobber (reg:CC FLAGS_REG))]
6266   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6267 {
6268   switch (get_attr_type (insn))
6269     {
6270     case TYPE_LEA:
6271       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6272       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6273
6274     case TYPE_INCDEC:
6275       if (operands[2] == const1_rtx)
6276         return "inc{l}\t%k0";
6277       else
6278         {
6279           gcc_assert (operands[2] == constm1_rtx);
6280           return "dec{l}\t%k0";
6281         }
6282
6283     default:
6284       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6285          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6286       if (CONST_INT_P (operands[2])
6287           && (INTVAL (operands[2]) == 128
6288               || (INTVAL (operands[2]) < 0
6289                   && INTVAL (operands[2]) != -128)))
6290         {
6291           operands[2] = GEN_INT (-INTVAL (operands[2]));
6292           return "sub{l}\t{%2, %k0|%k0, %2}";
6293         }
6294       return "add{l}\t{%2, %k0|%k0, %2}";
6295     }
6296 }
6297   [(set (attr "type")
6298      (cond [(eq_attr "alternative" "1")
6299               (const_string "lea")
6300             ; Current assemblers are broken and do not allow @GOTOFF in
6301             ; ought but a memory context.
6302             (match_operand:SI 2 "pic_symbolic_operand" "")
6303               (const_string "lea")
6304             (match_operand:SI 2 "incdec_operand" "")
6305               (const_string "incdec")
6306            ]
6307            (const_string "alu")))
6308    (set_attr "mode" "SI")])
6309
6310 ;; Convert lea to the lea pattern to avoid flags dependency.
6311 (define_split
6312   [(set (match_operand:DI 0 "register_operand" "")
6313         (zero_extend:DI
6314           (plus:SI (match_operand:SI 1 "register_operand" "")
6315                    (match_operand:SI 2 "nonmemory_operand" ""))))
6316    (clobber (reg:CC FLAGS_REG))]
6317   "TARGET_64BIT && reload_completed
6318    && true_regnum (operands[0]) != true_regnum (operands[1])"
6319   [(set (match_dup 0)
6320         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6321 {
6322   operands[1] = gen_lowpart (Pmode, operands[1]);
6323   operands[2] = gen_lowpart (Pmode, operands[2]);
6324 })
6325
6326 (define_insn "*addsi_2"
6327   [(set (reg FLAGS_REG)
6328         (compare
6329           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6330                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6331           (const_int 0)))
6332    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6333         (plus:SI (match_dup 1) (match_dup 2)))]
6334   "ix86_match_ccmode (insn, CCGOCmode)
6335    && ix86_binary_operator_ok (PLUS, SImode, operands)
6336    /* Current assemblers are broken and do not allow @GOTOFF in
6337       ought but a memory context.  */
6338    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6339 {
6340   switch (get_attr_type (insn))
6341     {
6342     case TYPE_INCDEC:
6343       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6344       if (operands[2] == const1_rtx)
6345         return "inc{l}\t%0";
6346       else
6347         {
6348           gcc_assert (operands[2] == constm1_rtx);
6349           return "dec{l}\t%0";
6350         }
6351
6352     default:
6353       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6354       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6355          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6356       if (CONST_INT_P (operands[2])
6357           && (INTVAL (operands[2]) == 128
6358               || (INTVAL (operands[2]) < 0
6359                   && INTVAL (operands[2]) != -128)))
6360         {
6361           operands[2] = GEN_INT (-INTVAL (operands[2]));
6362           return "sub{l}\t{%2, %0|%0, %2}";
6363         }
6364       return "add{l}\t{%2, %0|%0, %2}";
6365     }
6366 }
6367   [(set (attr "type")
6368      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6369         (const_string "incdec")
6370         (const_string "alu")))
6371    (set_attr "mode" "SI")])
6372
6373 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6374 (define_insn "*addsi_2_zext"
6375   [(set (reg FLAGS_REG)
6376         (compare
6377           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6378                    (match_operand:SI 2 "general_operand" "rmni"))
6379           (const_int 0)))
6380    (set (match_operand:DI 0 "register_operand" "=r")
6381         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6382   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6383    && ix86_binary_operator_ok (PLUS, SImode, operands)
6384    /* Current assemblers are broken and do not allow @GOTOFF in
6385       ought but a memory context.  */
6386    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6387 {
6388   switch (get_attr_type (insn))
6389     {
6390     case TYPE_INCDEC:
6391       if (operands[2] == const1_rtx)
6392         return "inc{l}\t%k0";
6393       else
6394         {
6395           gcc_assert (operands[2] == constm1_rtx);
6396           return "dec{l}\t%k0";
6397         }
6398
6399     default:
6400       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6401          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6402       if (CONST_INT_P (operands[2])
6403           && (INTVAL (operands[2]) == 128
6404               || (INTVAL (operands[2]) < 0
6405                   && INTVAL (operands[2]) != -128)))
6406         {
6407           operands[2] = GEN_INT (-INTVAL (operands[2]));
6408           return "sub{l}\t{%2, %k0|%k0, %2}";
6409         }
6410       return "add{l}\t{%2, %k0|%k0, %2}";
6411     }
6412 }
6413   [(set (attr "type")
6414      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6415         (const_string "incdec")
6416         (const_string "alu")))
6417    (set_attr "mode" "SI")])
6418
6419 (define_insn "*addsi_3"
6420   [(set (reg FLAGS_REG)
6421         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6422                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6423    (clobber (match_scratch:SI 0 "=r"))]
6424   "ix86_match_ccmode (insn, CCZmode)
6425    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6426    /* Current assemblers are broken and do not allow @GOTOFF in
6427       ought but a memory context.  */
6428    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6429 {
6430   switch (get_attr_type (insn))
6431     {
6432     case TYPE_INCDEC:
6433       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6434       if (operands[2] == const1_rtx)
6435         return "inc{l}\t%0";
6436       else
6437         {
6438           gcc_assert (operands[2] == constm1_rtx);
6439           return "dec{l}\t%0";
6440         }
6441
6442     default:
6443       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6444       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6445          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6446       if (CONST_INT_P (operands[2])
6447           && (INTVAL (operands[2]) == 128
6448               || (INTVAL (operands[2]) < 0
6449                   && INTVAL (operands[2]) != -128)))
6450         {
6451           operands[2] = GEN_INT (-INTVAL (operands[2]));
6452           return "sub{l}\t{%2, %0|%0, %2}";
6453         }
6454       return "add{l}\t{%2, %0|%0, %2}";
6455     }
6456 }
6457   [(set (attr "type")
6458      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6459         (const_string "incdec")
6460         (const_string "alu")))
6461    (set_attr "mode" "SI")])
6462
6463 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6464 (define_insn "*addsi_3_zext"
6465   [(set (reg FLAGS_REG)
6466         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6467                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6468    (set (match_operand:DI 0 "register_operand" "=r")
6469         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6470   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6471    && ix86_binary_operator_ok (PLUS, SImode, operands)
6472    /* Current assemblers are broken and do not allow @GOTOFF in
6473       ought but a memory context.  */
6474    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6475 {
6476   switch (get_attr_type (insn))
6477     {
6478     case TYPE_INCDEC:
6479       if (operands[2] == const1_rtx)
6480         return "inc{l}\t%k0";
6481       else
6482         {
6483           gcc_assert (operands[2] == constm1_rtx);
6484           return "dec{l}\t%k0";
6485         }
6486
6487     default:
6488       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6490       if (CONST_INT_P (operands[2])
6491           && (INTVAL (operands[2]) == 128
6492               || (INTVAL (operands[2]) < 0
6493                   && INTVAL (operands[2]) != -128)))
6494         {
6495           operands[2] = GEN_INT (-INTVAL (operands[2]));
6496           return "sub{l}\t{%2, %k0|%k0, %2}";
6497         }
6498       return "add{l}\t{%2, %k0|%k0, %2}";
6499     }
6500 }
6501   [(set (attr "type")
6502      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6503         (const_string "incdec")
6504         (const_string "alu")))
6505    (set_attr "mode" "SI")])
6506
6507 ; For comparisons against 1, -1 and 128, we may generate better code
6508 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6509 ; is matched then.  We can't accept general immediate, because for
6510 ; case of overflows,  the result is messed up.
6511 ; This pattern also don't hold of 0x80000000, since the value overflows
6512 ; when negated.
6513 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6514 ; only for comparisons not depending on it.
6515 (define_insn "*addsi_4"
6516   [(set (reg FLAGS_REG)
6517         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6518                  (match_operand:SI 2 "const_int_operand" "n")))
6519    (clobber (match_scratch:SI 0 "=rm"))]
6520   "ix86_match_ccmode (insn, CCGCmode)
6521    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6522 {
6523   switch (get_attr_type (insn))
6524     {
6525     case TYPE_INCDEC:
6526       if (operands[2] == constm1_rtx)
6527         return "inc{l}\t%0";
6528       else
6529         {
6530           gcc_assert (operands[2] == const1_rtx);
6531           return "dec{l}\t%0";
6532         }
6533
6534     default:
6535       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6536       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6537          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6538       if ((INTVAL (operands[2]) == -128
6539            || (INTVAL (operands[2]) > 0
6540                && INTVAL (operands[2]) != 128)))
6541         return "sub{l}\t{%2, %0|%0, %2}";
6542       operands[2] = GEN_INT (-INTVAL (operands[2]));
6543       return "add{l}\t{%2, %0|%0, %2}";
6544     }
6545 }
6546   [(set (attr "type")
6547      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6548         (const_string "incdec")
6549         (const_string "alu")))
6550    (set_attr "mode" "SI")])
6551
6552 (define_insn "*addsi_5"
6553   [(set (reg FLAGS_REG)
6554         (compare
6555           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6556                    (match_operand:SI 2 "general_operand" "rmni"))
6557           (const_int 0)))
6558    (clobber (match_scratch:SI 0 "=r"))]
6559   "ix86_match_ccmode (insn, CCGOCmode)
6560    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6561    /* Current assemblers are broken and do not allow @GOTOFF in
6562       ought but a memory context.  */
6563    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6564 {
6565   switch (get_attr_type (insn))
6566     {
6567     case TYPE_INCDEC:
6568       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6569       if (operands[2] == const1_rtx)
6570         return "inc{l}\t%0";
6571       else
6572         {
6573           gcc_assert (operands[2] == constm1_rtx);
6574           return "dec{l}\t%0";
6575         }
6576
6577     default:
6578       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6579       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6580          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6581       if (CONST_INT_P (operands[2])
6582           && (INTVAL (operands[2]) == 128
6583               || (INTVAL (operands[2]) < 0
6584                   && INTVAL (operands[2]) != -128)))
6585         {
6586           operands[2] = GEN_INT (-INTVAL (operands[2]));
6587           return "sub{l}\t{%2, %0|%0, %2}";
6588         }
6589       return "add{l}\t{%2, %0|%0, %2}";
6590     }
6591 }
6592   [(set (attr "type")
6593      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6594         (const_string "incdec")
6595         (const_string "alu")))
6596    (set_attr "mode" "SI")])
6597
6598 (define_expand "addhi3"
6599   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6600                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6601                             (match_operand:HI 2 "general_operand" "")))
6602               (clobber (reg:CC FLAGS_REG))])]
6603   "TARGET_HIMODE_MATH"
6604   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6605
6606 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6607 ;; type optimizations enabled by define-splits.  This is not important
6608 ;; for PII, and in fact harmful because of partial register stalls.
6609
6610 (define_insn "*addhi_1_lea"
6611   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6612         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6613                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6614    (clobber (reg:CC FLAGS_REG))]
6615   "!TARGET_PARTIAL_REG_STALL
6616    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6617 {
6618   switch (get_attr_type (insn))
6619     {
6620     case TYPE_LEA:
6621       return "#";
6622     case TYPE_INCDEC:
6623       if (operands[2] == const1_rtx)
6624         return "inc{w}\t%0";
6625       else
6626         {
6627           gcc_assert (operands[2] == constm1_rtx);
6628           return "dec{w}\t%0";
6629         }
6630
6631     default:
6632       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6633          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6634       if (CONST_INT_P (operands[2])
6635           && (INTVAL (operands[2]) == 128
6636               || (INTVAL (operands[2]) < 0
6637                   && INTVAL (operands[2]) != -128)))
6638         {
6639           operands[2] = GEN_INT (-INTVAL (operands[2]));
6640           return "sub{w}\t{%2, %0|%0, %2}";
6641         }
6642       return "add{w}\t{%2, %0|%0, %2}";
6643     }
6644 }
6645   [(set (attr "type")
6646      (if_then_else (eq_attr "alternative" "2")
6647         (const_string "lea")
6648         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6649            (const_string "incdec")
6650            (const_string "alu"))))
6651    (set_attr "mode" "HI,HI,SI")])
6652
6653 (define_insn "*addhi_1"
6654   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6655         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6656                  (match_operand:HI 2 "general_operand" "ri,rm")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "TARGET_PARTIAL_REG_STALL
6659    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6660 {
6661   switch (get_attr_type (insn))
6662     {
6663     case TYPE_INCDEC:
6664       if (operands[2] == const1_rtx)
6665         return "inc{w}\t%0";
6666       else
6667         {
6668           gcc_assert (operands[2] == constm1_rtx);
6669           return "dec{w}\t%0";
6670         }
6671
6672     default:
6673       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6674          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6675       if (CONST_INT_P (operands[2])
6676           && (INTVAL (operands[2]) == 128
6677               || (INTVAL (operands[2]) < 0
6678                   && INTVAL (operands[2]) != -128)))
6679         {
6680           operands[2] = GEN_INT (-INTVAL (operands[2]));
6681           return "sub{w}\t{%2, %0|%0, %2}";
6682         }
6683       return "add{w}\t{%2, %0|%0, %2}";
6684     }
6685 }
6686   [(set (attr "type")
6687      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6688         (const_string "incdec")
6689         (const_string "alu")))
6690    (set_attr "mode" "HI")])
6691
6692 (define_insn "*addhi_2"
6693   [(set (reg FLAGS_REG)
6694         (compare
6695           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6696                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6697           (const_int 0)))
6698    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6699         (plus:HI (match_dup 1) (match_dup 2)))]
6700   "ix86_match_ccmode (insn, CCGOCmode)
6701    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6702 {
6703   switch (get_attr_type (insn))
6704     {
6705     case TYPE_INCDEC:
6706       if (operands[2] == const1_rtx)
6707         return "inc{w}\t%0";
6708       else
6709         {
6710           gcc_assert (operands[2] == constm1_rtx);
6711           return "dec{w}\t%0";
6712         }
6713
6714     default:
6715       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6716          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6717       if (CONST_INT_P (operands[2])
6718           && (INTVAL (operands[2]) == 128
6719               || (INTVAL (operands[2]) < 0
6720                   && INTVAL (operands[2]) != -128)))
6721         {
6722           operands[2] = GEN_INT (-INTVAL (operands[2]));
6723           return "sub{w}\t{%2, %0|%0, %2}";
6724         }
6725       return "add{w}\t{%2, %0|%0, %2}";
6726     }
6727 }
6728   [(set (attr "type")
6729      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6730         (const_string "incdec")
6731         (const_string "alu")))
6732    (set_attr "mode" "HI")])
6733
6734 (define_insn "*addhi_3"
6735   [(set (reg FLAGS_REG)
6736         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6737                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6738    (clobber (match_scratch:HI 0 "=r"))]
6739   "ix86_match_ccmode (insn, CCZmode)
6740    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6741 {
6742   switch (get_attr_type (insn))
6743     {
6744     case TYPE_INCDEC:
6745       if (operands[2] == const1_rtx)
6746         return "inc{w}\t%0";
6747       else
6748         {
6749           gcc_assert (operands[2] == constm1_rtx);
6750           return "dec{w}\t%0";
6751         }
6752
6753     default:
6754       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6755          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6756       if (CONST_INT_P (operands[2])
6757           && (INTVAL (operands[2]) == 128
6758               || (INTVAL (operands[2]) < 0
6759                   && INTVAL (operands[2]) != -128)))
6760         {
6761           operands[2] = GEN_INT (-INTVAL (operands[2]));
6762           return "sub{w}\t{%2, %0|%0, %2}";
6763         }
6764       return "add{w}\t{%2, %0|%0, %2}";
6765     }
6766 }
6767   [(set (attr "type")
6768      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6769         (const_string "incdec")
6770         (const_string "alu")))
6771    (set_attr "mode" "HI")])
6772
6773 ; See comments above addsi_4 for details.
6774 (define_insn "*addhi_4"
6775   [(set (reg FLAGS_REG)
6776         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6777                  (match_operand:HI 2 "const_int_operand" "n")))
6778    (clobber (match_scratch:HI 0 "=rm"))]
6779   "ix86_match_ccmode (insn, CCGCmode)
6780    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6781 {
6782   switch (get_attr_type (insn))
6783     {
6784     case TYPE_INCDEC:
6785       if (operands[2] == constm1_rtx)
6786         return "inc{w}\t%0";
6787       else
6788         {
6789           gcc_assert (operands[2] == const1_rtx);
6790           return "dec{w}\t%0";
6791         }
6792
6793     default:
6794       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6795       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6796          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6797       if ((INTVAL (operands[2]) == -128
6798            || (INTVAL (operands[2]) > 0
6799                && INTVAL (operands[2]) != 128)))
6800         return "sub{w}\t{%2, %0|%0, %2}";
6801       operands[2] = GEN_INT (-INTVAL (operands[2]));
6802       return "add{w}\t{%2, %0|%0, %2}";
6803     }
6804 }
6805   [(set (attr "type")
6806      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6807         (const_string "incdec")
6808         (const_string "alu")))
6809    (set_attr "mode" "SI")])
6810
6811
6812 (define_insn "*addhi_5"
6813   [(set (reg FLAGS_REG)
6814         (compare
6815           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6816                    (match_operand:HI 2 "general_operand" "rmni"))
6817           (const_int 0)))
6818    (clobber (match_scratch:HI 0 "=r"))]
6819   "ix86_match_ccmode (insn, CCGOCmode)
6820    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6821 {
6822   switch (get_attr_type (insn))
6823     {
6824     case TYPE_INCDEC:
6825       if (operands[2] == const1_rtx)
6826         return "inc{w}\t%0";
6827       else
6828         {
6829           gcc_assert (operands[2] == constm1_rtx);
6830           return "dec{w}\t%0";
6831         }
6832
6833     default:
6834       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6835          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6836       if (CONST_INT_P (operands[2])
6837           && (INTVAL (operands[2]) == 128
6838               || (INTVAL (operands[2]) < 0
6839                   && INTVAL (operands[2]) != -128)))
6840         {
6841           operands[2] = GEN_INT (-INTVAL (operands[2]));
6842           return "sub{w}\t{%2, %0|%0, %2}";
6843         }
6844       return "add{w}\t{%2, %0|%0, %2}";
6845     }
6846 }
6847   [(set (attr "type")
6848      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6849         (const_string "incdec")
6850         (const_string "alu")))
6851    (set_attr "mode" "HI")])
6852
6853 (define_expand "addqi3"
6854   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6855                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6856                             (match_operand:QI 2 "general_operand" "")))
6857               (clobber (reg:CC FLAGS_REG))])]
6858   "TARGET_QIMODE_MATH"
6859   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6860
6861 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6862 (define_insn "*addqi_1_lea"
6863   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6864         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6865                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6866    (clobber (reg:CC FLAGS_REG))]
6867   "!TARGET_PARTIAL_REG_STALL
6868    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6869 {
6870   int widen = (which_alternative == 2);
6871   switch (get_attr_type (insn))
6872     {
6873     case TYPE_LEA:
6874       return "#";
6875     case TYPE_INCDEC:
6876       if (operands[2] == const1_rtx)
6877         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6878       else
6879         {
6880           gcc_assert (operands[2] == constm1_rtx);
6881           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6882         }
6883
6884     default:
6885       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6886          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6887       if (CONST_INT_P (operands[2])
6888           && (INTVAL (operands[2]) == 128
6889               || (INTVAL (operands[2]) < 0
6890                   && INTVAL (operands[2]) != -128)))
6891         {
6892           operands[2] = GEN_INT (-INTVAL (operands[2]));
6893           if (widen)
6894             return "sub{l}\t{%2, %k0|%k0, %2}";
6895           else
6896             return "sub{b}\t{%2, %0|%0, %2}";
6897         }
6898       if (widen)
6899         return "add{l}\t{%k2, %k0|%k0, %k2}";
6900       else
6901         return "add{b}\t{%2, %0|%0, %2}";
6902     }
6903 }
6904   [(set (attr "type")
6905      (if_then_else (eq_attr "alternative" "3")
6906         (const_string "lea")
6907         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6908            (const_string "incdec")
6909            (const_string "alu"))))
6910    (set_attr "mode" "QI,QI,SI,SI")])
6911
6912 (define_insn "*addqi_1"
6913   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6914         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6915                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_PARTIAL_REG_STALL
6918    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6919 {
6920   int widen = (which_alternative == 2);
6921   switch (get_attr_type (insn))
6922     {
6923     case TYPE_INCDEC:
6924       if (operands[2] == const1_rtx)
6925         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6926       else
6927         {
6928           gcc_assert (operands[2] == constm1_rtx);
6929           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6930         }
6931
6932     default:
6933       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6934          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6935       if (CONST_INT_P (operands[2])
6936           && (INTVAL (operands[2]) == 128
6937               || (INTVAL (operands[2]) < 0
6938                   && INTVAL (operands[2]) != -128)))
6939         {
6940           operands[2] = GEN_INT (-INTVAL (operands[2]));
6941           if (widen)
6942             return "sub{l}\t{%2, %k0|%k0, %2}";
6943           else
6944             return "sub{b}\t{%2, %0|%0, %2}";
6945         }
6946       if (widen)
6947         return "add{l}\t{%k2, %k0|%k0, %k2}";
6948       else
6949         return "add{b}\t{%2, %0|%0, %2}";
6950     }
6951 }
6952   [(set (attr "type")
6953      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6954         (const_string "incdec")
6955         (const_string "alu")))
6956    (set_attr "mode" "QI,QI,SI")])
6957
6958 (define_insn "*addqi_1_slp"
6959   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6960         (plus:QI (match_dup 0)
6961                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6962    (clobber (reg:CC FLAGS_REG))]
6963   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6964    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6965 {
6966   switch (get_attr_type (insn))
6967     {
6968     case TYPE_INCDEC:
6969       if (operands[1] == const1_rtx)
6970         return "inc{b}\t%0";
6971       else
6972         {
6973           gcc_assert (operands[1] == constm1_rtx);
6974           return "dec{b}\t%0";
6975         }
6976
6977     default:
6978       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6979       if (CONST_INT_P (operands[1])
6980           && INTVAL (operands[1]) < 0)
6981         {
6982           operands[1] = GEN_INT (-INTVAL (operands[1]));
6983           return "sub{b}\t{%1, %0|%0, %1}";
6984         }
6985       return "add{b}\t{%1, %0|%0, %1}";
6986     }
6987 }
6988   [(set (attr "type")
6989      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6990         (const_string "incdec")
6991         (const_string "alu1")))
6992    (set (attr "memory")
6993      (if_then_else (match_operand 1 "memory_operand" "")
6994         (const_string "load")
6995         (const_string "none")))
6996    (set_attr "mode" "QI")])
6997
6998 (define_insn "*addqi_2"
6999   [(set (reg FLAGS_REG)
7000         (compare
7001           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7002                    (match_operand:QI 2 "general_operand" "qmni,qni"))
7003           (const_int 0)))
7004    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7005         (plus:QI (match_dup 1) (match_dup 2)))]
7006   "ix86_match_ccmode (insn, CCGOCmode)
7007    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7008 {
7009   switch (get_attr_type (insn))
7010     {
7011     case TYPE_INCDEC:
7012       if (operands[2] == const1_rtx)
7013         return "inc{b}\t%0";
7014       else
7015         {
7016           gcc_assert (operands[2] == constm1_rtx
7017                       || (CONST_INT_P (operands[2])
7018                           && INTVAL (operands[2]) == 255));
7019           return "dec{b}\t%0";
7020         }
7021
7022     default:
7023       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7024       if (CONST_INT_P (operands[2])
7025           && INTVAL (operands[2]) < 0)
7026         {
7027           operands[2] = GEN_INT (-INTVAL (operands[2]));
7028           return "sub{b}\t{%2, %0|%0, %2}";
7029         }
7030       return "add{b}\t{%2, %0|%0, %2}";
7031     }
7032 }
7033   [(set (attr "type")
7034      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7035         (const_string "incdec")
7036         (const_string "alu")))
7037    (set_attr "mode" "QI")])
7038
7039 (define_insn "*addqi_3"
7040   [(set (reg FLAGS_REG)
7041         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7042                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7043    (clobber (match_scratch:QI 0 "=q"))]
7044   "ix86_match_ccmode (insn, CCZmode)
7045    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7046 {
7047   switch (get_attr_type (insn))
7048     {
7049     case TYPE_INCDEC:
7050       if (operands[2] == const1_rtx)
7051         return "inc{b}\t%0";
7052       else
7053         {
7054           gcc_assert (operands[2] == constm1_rtx
7055                       || (CONST_INT_P (operands[2])
7056                           && INTVAL (operands[2]) == 255));
7057           return "dec{b}\t%0";
7058         }
7059
7060     default:
7061       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7062       if (CONST_INT_P (operands[2])
7063           && INTVAL (operands[2]) < 0)
7064         {
7065           operands[2] = GEN_INT (-INTVAL (operands[2]));
7066           return "sub{b}\t{%2, %0|%0, %2}";
7067         }
7068       return "add{b}\t{%2, %0|%0, %2}";
7069     }
7070 }
7071   [(set (attr "type")
7072      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7073         (const_string "incdec")
7074         (const_string "alu")))
7075    (set_attr "mode" "QI")])
7076
7077 ; See comments above addsi_4 for details.
7078 (define_insn "*addqi_4"
7079   [(set (reg FLAGS_REG)
7080         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7081                  (match_operand:QI 2 "const_int_operand" "n")))
7082    (clobber (match_scratch:QI 0 "=qm"))]
7083   "ix86_match_ccmode (insn, CCGCmode)
7084    && (INTVAL (operands[2]) & 0xff) != 0x80"
7085 {
7086   switch (get_attr_type (insn))
7087     {
7088     case TYPE_INCDEC:
7089       if (operands[2] == constm1_rtx
7090           || (CONST_INT_P (operands[2])
7091               && INTVAL (operands[2]) == 255))
7092         return "inc{b}\t%0";
7093       else
7094         {
7095           gcc_assert (operands[2] == const1_rtx);
7096           return "dec{b}\t%0";
7097         }
7098
7099     default:
7100       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7101       if (INTVAL (operands[2]) < 0)
7102         {
7103           operands[2] = GEN_INT (-INTVAL (operands[2]));
7104           return "add{b}\t{%2, %0|%0, %2}";
7105         }
7106       return "sub{b}\t{%2, %0|%0, %2}";
7107     }
7108 }
7109   [(set (attr "type")
7110      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7111         (const_string "incdec")
7112         (const_string "alu")))
7113    (set_attr "mode" "QI")])
7114
7115
7116 (define_insn "*addqi_5"
7117   [(set (reg FLAGS_REG)
7118         (compare
7119           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7120                    (match_operand:QI 2 "general_operand" "qmni"))
7121           (const_int 0)))
7122    (clobber (match_scratch:QI 0 "=q"))]
7123   "ix86_match_ccmode (insn, CCGOCmode)
7124    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7125 {
7126   switch (get_attr_type (insn))
7127     {
7128     case TYPE_INCDEC:
7129       if (operands[2] == const1_rtx)
7130         return "inc{b}\t%0";
7131       else
7132         {
7133           gcc_assert (operands[2] == constm1_rtx
7134                       || (CONST_INT_P (operands[2])
7135                           && INTVAL (operands[2]) == 255));
7136           return "dec{b}\t%0";
7137         }
7138
7139     default:
7140       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7141       if (CONST_INT_P (operands[2])
7142           && INTVAL (operands[2]) < 0)
7143         {
7144           operands[2] = GEN_INT (-INTVAL (operands[2]));
7145           return "sub{b}\t{%2, %0|%0, %2}";
7146         }
7147       return "add{b}\t{%2, %0|%0, %2}";
7148     }
7149 }
7150   [(set (attr "type")
7151      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7152         (const_string "incdec")
7153         (const_string "alu")))
7154    (set_attr "mode" "QI")])
7155
7156
7157 (define_insn "addqi_ext_1"
7158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7159                          (const_int 8)
7160                          (const_int 8))
7161         (plus:SI
7162           (zero_extract:SI
7163             (match_operand 1 "ext_register_operand" "0")
7164             (const_int 8)
7165             (const_int 8))
7166           (match_operand:QI 2 "general_operand" "Qmn")))
7167    (clobber (reg:CC FLAGS_REG))]
7168   "!TARGET_64BIT"
7169 {
7170   switch (get_attr_type (insn))
7171     {
7172     case TYPE_INCDEC:
7173       if (operands[2] == const1_rtx)
7174         return "inc{b}\t%h0";
7175       else
7176         {
7177           gcc_assert (operands[2] == constm1_rtx
7178                       || (CONST_INT_P (operands[2])
7179                           && INTVAL (operands[2]) == 255));
7180           return "dec{b}\t%h0";
7181         }
7182
7183     default:
7184       return "add{b}\t{%2, %h0|%h0, %2}";
7185     }
7186 }
7187   [(set (attr "type")
7188      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7189         (const_string "incdec")
7190         (const_string "alu")))
7191    (set_attr "mode" "QI")])
7192
7193 (define_insn "*addqi_ext_1_rex64"
7194   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7195                          (const_int 8)
7196                          (const_int 8))
7197         (plus:SI
7198           (zero_extract:SI
7199             (match_operand 1 "ext_register_operand" "0")
7200             (const_int 8)
7201             (const_int 8))
7202           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7203    (clobber (reg:CC FLAGS_REG))]
7204   "TARGET_64BIT"
7205 {
7206   switch (get_attr_type (insn))
7207     {
7208     case TYPE_INCDEC:
7209       if (operands[2] == const1_rtx)
7210         return "inc{b}\t%h0";
7211       else
7212         {
7213           gcc_assert (operands[2] == constm1_rtx
7214                       || (CONST_INT_P (operands[2])
7215                           && INTVAL (operands[2]) == 255));
7216           return "dec{b}\t%h0";
7217         }
7218
7219     default:
7220       return "add{b}\t{%2, %h0|%h0, %2}";
7221     }
7222 }
7223   [(set (attr "type")
7224      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7225         (const_string "incdec")
7226         (const_string "alu")))
7227    (set_attr "mode" "QI")])
7228
7229 (define_insn "*addqi_ext_2"
7230   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7231                          (const_int 8)
7232                          (const_int 8))
7233         (plus:SI
7234           (zero_extract:SI
7235             (match_operand 1 "ext_register_operand" "%0")
7236             (const_int 8)
7237             (const_int 8))
7238           (zero_extract:SI
7239             (match_operand 2 "ext_register_operand" "Q")
7240             (const_int 8)
7241             (const_int 8))))
7242    (clobber (reg:CC FLAGS_REG))]
7243   ""
7244   "add{b}\t{%h2, %h0|%h0, %h2}"
7245   [(set_attr "type" "alu")
7246    (set_attr "mode" "QI")])
7247
7248 ;; The patterns that match these are at the end of this file.
7249
7250 (define_expand "addxf3"
7251   [(set (match_operand:XF 0 "register_operand" "")
7252         (plus:XF (match_operand:XF 1 "register_operand" "")
7253                  (match_operand:XF 2 "register_operand" "")))]
7254   "TARGET_80387"
7255   "")
7256
7257 (define_expand "add<mode>3"
7258   [(set (match_operand:MODEF 0 "register_operand" "")
7259         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7260                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7261   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7262   "")
7263 \f
7264 ;; Subtract instructions
7265
7266 ;; %%% splits for subditi3
7267
7268 (define_expand "subti3"
7269   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7270                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7271                              (match_operand:TI 2 "x86_64_general_operand" "")))
7272               (clobber (reg:CC FLAGS_REG))])]
7273   "TARGET_64BIT"
7274   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7275
7276 (define_insn "*subti3_1"
7277   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7278         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7279                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7280    (clobber (reg:CC FLAGS_REG))]
7281   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7282   "#")
7283
7284 (define_split
7285   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7286         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7287                   (match_operand:TI 2 "x86_64_general_operand" "")))
7288    (clobber (reg:CC FLAGS_REG))]
7289   "TARGET_64BIT && reload_completed"
7290   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7291               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7292    (parallel [(set (match_dup 3)
7293                    (minus:DI (match_dup 4)
7294                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7295                                       (match_dup 5))))
7296               (clobber (reg:CC FLAGS_REG))])]
7297   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7298
7299 ;; %%% splits for subsidi3
7300
7301 (define_expand "subdi3"
7302   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7303                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7304                              (match_operand:DI 2 "x86_64_general_operand" "")))
7305               (clobber (reg:CC FLAGS_REG))])]
7306   ""
7307   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7308
7309 (define_insn "*subdi3_1"
7310   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7311         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7312                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7313    (clobber (reg:CC FLAGS_REG))]
7314   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7315   "#")
7316
7317 (define_split
7318   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7319         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7320                   (match_operand:DI 2 "general_operand" "")))
7321    (clobber (reg:CC FLAGS_REG))]
7322   "!TARGET_64BIT && reload_completed"
7323   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7324               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7325    (parallel [(set (match_dup 3)
7326                    (minus:SI (match_dup 4)
7327                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7328                                       (match_dup 5))))
7329               (clobber (reg:CC FLAGS_REG))])]
7330   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7331
7332 (define_insn "subdi3_carry_rex64"
7333   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7334           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7335             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7336                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7337    (clobber (reg:CC FLAGS_REG))]
7338   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7339   "sbb{q}\t{%2, %0|%0, %2}"
7340   [(set_attr "type" "alu")
7341    (set_attr "pent_pair" "pu")
7342    (set_attr "mode" "DI")])
7343
7344 (define_insn "*subdi_1_rex64"
7345   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7346         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7347                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7348    (clobber (reg:CC FLAGS_REG))]
7349   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7350   "sub{q}\t{%2, %0|%0, %2}"
7351   [(set_attr "type" "alu")
7352    (set_attr "mode" "DI")])
7353
7354 (define_insn "*subdi_2_rex64"
7355   [(set (reg FLAGS_REG)
7356         (compare
7357           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7358                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7359           (const_int 0)))
7360    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7361         (minus:DI (match_dup 1) (match_dup 2)))]
7362   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7363    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7364   "sub{q}\t{%2, %0|%0, %2}"
7365   [(set_attr "type" "alu")
7366    (set_attr "mode" "DI")])
7367
7368 (define_insn "*subdi_3_rex63"
7369   [(set (reg FLAGS_REG)
7370         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7371                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7372    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7373         (minus:DI (match_dup 1) (match_dup 2)))]
7374   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7375    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7376   "sub{q}\t{%2, %0|%0, %2}"
7377   [(set_attr "type" "alu")
7378    (set_attr "mode" "DI")])
7379
7380 (define_insn "subqi3_carry"
7381   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7382           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7383             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7384                (match_operand:QI 2 "general_operand" "qi,qm"))))
7385    (clobber (reg:CC FLAGS_REG))]
7386   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7387   "sbb{b}\t{%2, %0|%0, %2}"
7388   [(set_attr "type" "alu")
7389    (set_attr "pent_pair" "pu")
7390    (set_attr "mode" "QI")])
7391
7392 (define_insn "subhi3_carry"
7393   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7394           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7395             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7396                (match_operand:HI 2 "general_operand" "ri,rm"))))
7397    (clobber (reg:CC FLAGS_REG))]
7398   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7399   "sbb{w}\t{%2, %0|%0, %2}"
7400   [(set_attr "type" "alu")
7401    (set_attr "pent_pair" "pu")
7402    (set_attr "mode" "HI")])
7403
7404 (define_insn "subsi3_carry"
7405   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7406           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7407             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7408                (match_operand:SI 2 "general_operand" "ri,rm"))))
7409    (clobber (reg:CC FLAGS_REG))]
7410   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7411   "sbb{l}\t{%2, %0|%0, %2}"
7412   [(set_attr "type" "alu")
7413    (set_attr "pent_pair" "pu")
7414    (set_attr "mode" "SI")])
7415
7416 (define_insn "subsi3_carry_zext"
7417   [(set (match_operand:DI 0 "register_operand" "=r")
7418           (zero_extend:DI
7419             (minus:SI (match_operand:SI 1 "register_operand" "0")
7420               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7421                  (match_operand:SI 2 "general_operand" "g")))))
7422    (clobber (reg:CC FLAGS_REG))]
7423   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7424   "sbb{l}\t{%2, %k0|%k0, %2}"
7425   [(set_attr "type" "alu")
7426    (set_attr "pent_pair" "pu")
7427    (set_attr "mode" "SI")])
7428
7429 (define_expand "subsi3"
7430   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7431                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7432                              (match_operand:SI 2 "general_operand" "")))
7433               (clobber (reg:CC FLAGS_REG))])]
7434   ""
7435   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7436
7437 (define_insn "*subsi_1"
7438   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7439         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7440                   (match_operand:SI 2 "general_operand" "ri,rm")))
7441    (clobber (reg:CC FLAGS_REG))]
7442   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7443   "sub{l}\t{%2, %0|%0, %2}"
7444   [(set_attr "type" "alu")
7445    (set_attr "mode" "SI")])
7446
7447 (define_insn "*subsi_1_zext"
7448   [(set (match_operand:DI 0 "register_operand" "=r")
7449         (zero_extend:DI
7450           (minus:SI (match_operand:SI 1 "register_operand" "0")
7451                     (match_operand:SI 2 "general_operand" "g"))))
7452    (clobber (reg:CC FLAGS_REG))]
7453   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7454   "sub{l}\t{%2, %k0|%k0, %2}"
7455   [(set_attr "type" "alu")
7456    (set_attr "mode" "SI")])
7457
7458 (define_insn "*subsi_2"
7459   [(set (reg FLAGS_REG)
7460         (compare
7461           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7462                     (match_operand:SI 2 "general_operand" "ri,rm"))
7463           (const_int 0)))
7464    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7465         (minus:SI (match_dup 1) (match_dup 2)))]
7466   "ix86_match_ccmode (insn, CCGOCmode)
7467    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7468   "sub{l}\t{%2, %0|%0, %2}"
7469   [(set_attr "type" "alu")
7470    (set_attr "mode" "SI")])
7471
7472 (define_insn "*subsi_2_zext"
7473   [(set (reg FLAGS_REG)
7474         (compare
7475           (minus:SI (match_operand:SI 1 "register_operand" "0")
7476                     (match_operand:SI 2 "general_operand" "g"))
7477           (const_int 0)))
7478    (set (match_operand:DI 0 "register_operand" "=r")
7479         (zero_extend:DI
7480           (minus:SI (match_dup 1)
7481                     (match_dup 2))))]
7482   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7483    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7484   "sub{l}\t{%2, %k0|%k0, %2}"
7485   [(set_attr "type" "alu")
7486    (set_attr "mode" "SI")])
7487
7488 (define_insn "*subsi_3"
7489   [(set (reg FLAGS_REG)
7490         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7491                  (match_operand:SI 2 "general_operand" "ri,rm")))
7492    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7493         (minus:SI (match_dup 1) (match_dup 2)))]
7494   "ix86_match_ccmode (insn, CCmode)
7495    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7496   "sub{l}\t{%2, %0|%0, %2}"
7497   [(set_attr "type" "alu")
7498    (set_attr "mode" "SI")])
7499
7500 (define_insn "*subsi_3_zext"
7501   [(set (reg FLAGS_REG)
7502         (compare (match_operand:SI 1 "register_operand" "0")
7503                  (match_operand:SI 2 "general_operand" "g")))
7504    (set (match_operand:DI 0 "register_operand" "=r")
7505         (zero_extend:DI
7506           (minus:SI (match_dup 1)
7507                     (match_dup 2))))]
7508   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7509    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7510   "sub{l}\t{%2, %1|%1, %2}"
7511   [(set_attr "type" "alu")
7512    (set_attr "mode" "DI")])
7513
7514 (define_expand "subhi3"
7515   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7516                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7517                              (match_operand:HI 2 "general_operand" "")))
7518               (clobber (reg:CC FLAGS_REG))])]
7519   "TARGET_HIMODE_MATH"
7520   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7521
7522 (define_insn "*subhi_1"
7523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7524         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7525                   (match_operand:HI 2 "general_operand" "ri,rm")))
7526    (clobber (reg:CC FLAGS_REG))]
7527   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7528   "sub{w}\t{%2, %0|%0, %2}"
7529   [(set_attr "type" "alu")
7530    (set_attr "mode" "HI")])
7531
7532 (define_insn "*subhi_2"
7533   [(set (reg FLAGS_REG)
7534         (compare
7535           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7536                     (match_operand:HI 2 "general_operand" "ri,rm"))
7537           (const_int 0)))
7538    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7539         (minus:HI (match_dup 1) (match_dup 2)))]
7540   "ix86_match_ccmode (insn, CCGOCmode)
7541    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7542   "sub{w}\t{%2, %0|%0, %2}"
7543   [(set_attr "type" "alu")
7544    (set_attr "mode" "HI")])
7545
7546 (define_insn "*subhi_3"
7547   [(set (reg FLAGS_REG)
7548         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7549                  (match_operand:HI 2 "general_operand" "ri,rm")))
7550    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7551         (minus:HI (match_dup 1) (match_dup 2)))]
7552   "ix86_match_ccmode (insn, CCmode)
7553    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7554   "sub{w}\t{%2, %0|%0, %2}"
7555   [(set_attr "type" "alu")
7556    (set_attr "mode" "HI")])
7557
7558 (define_expand "subqi3"
7559   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7560                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7561                              (match_operand:QI 2 "general_operand" "")))
7562               (clobber (reg:CC FLAGS_REG))])]
7563   "TARGET_QIMODE_MATH"
7564   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7565
7566 (define_insn "*subqi_1"
7567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7568         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7569                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7570    (clobber (reg:CC FLAGS_REG))]
7571   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7572   "sub{b}\t{%2, %0|%0, %2}"
7573   [(set_attr "type" "alu")
7574    (set_attr "mode" "QI")])
7575
7576 (define_insn "*subqi_1_slp"
7577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7578         (minus:QI (match_dup 0)
7579                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7580    (clobber (reg:CC FLAGS_REG))]
7581   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7582    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7583   "sub{b}\t{%1, %0|%0, %1}"
7584   [(set_attr "type" "alu1")
7585    (set_attr "mode" "QI")])
7586
7587 (define_insn "*subqi_2"
7588   [(set (reg FLAGS_REG)
7589         (compare
7590           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7591                     (match_operand:QI 2 "general_operand" "qi,qm"))
7592           (const_int 0)))
7593    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7594         (minus:HI (match_dup 1) (match_dup 2)))]
7595   "ix86_match_ccmode (insn, CCGOCmode)
7596    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7597   "sub{b}\t{%2, %0|%0, %2}"
7598   [(set_attr "type" "alu")
7599    (set_attr "mode" "QI")])
7600
7601 (define_insn "*subqi_3"
7602   [(set (reg FLAGS_REG)
7603         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7604                  (match_operand:QI 2 "general_operand" "qi,qm")))
7605    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7606         (minus:HI (match_dup 1) (match_dup 2)))]
7607   "ix86_match_ccmode (insn, CCmode)
7608    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7609   "sub{b}\t{%2, %0|%0, %2}"
7610   [(set_attr "type" "alu")
7611    (set_attr "mode" "QI")])
7612
7613 ;; The patterns that match these are at the end of this file.
7614
7615 (define_expand "subxf3"
7616   [(set (match_operand:XF 0 "register_operand" "")
7617         (minus:XF (match_operand:XF 1 "register_operand" "")
7618                   (match_operand:XF 2 "register_operand" "")))]
7619   "TARGET_80387"
7620   "")
7621
7622 (define_expand "sub<mode>3"
7623   [(set (match_operand:MODEF 0 "register_operand" "")
7624         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7625                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7626   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7627   "")
7628 \f
7629 ;; Multiply instructions
7630
7631 (define_expand "muldi3"
7632   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7633                    (mult:DI (match_operand:DI 1 "register_operand" "")
7634                             (match_operand:DI 2 "x86_64_general_operand" "")))
7635               (clobber (reg:CC FLAGS_REG))])]
7636   "TARGET_64BIT"
7637   "")
7638
7639 ;; On AMDFAM10
7640 ;; IMUL reg64, reg64, imm8      Direct
7641 ;; IMUL reg64, mem64, imm8      VectorPath
7642 ;; IMUL reg64, reg64, imm32     Direct
7643 ;; IMUL reg64, mem64, imm32     VectorPath
7644 ;; IMUL reg64, reg64            Direct
7645 ;; IMUL reg64, mem64            Direct
7646
7647 (define_insn "*muldi3_1_rex64"
7648   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7649         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7650                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7651    (clobber (reg:CC FLAGS_REG))]
7652   "TARGET_64BIT
7653    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7654   "@
7655    imul{q}\t{%2, %1, %0|%0, %1, %2}
7656    imul{q}\t{%2, %1, %0|%0, %1, %2}
7657    imul{q}\t{%2, %0|%0, %2}"
7658   [(set_attr "type" "imul")
7659    (set_attr "prefix_0f" "0,0,1")
7660    (set (attr "athlon_decode")
7661         (cond [(eq_attr "cpu" "athlon")
7662                   (const_string "vector")
7663                (eq_attr "alternative" "1")
7664                   (const_string "vector")
7665                (and (eq_attr "alternative" "2")
7666                     (match_operand 1 "memory_operand" ""))
7667                   (const_string "vector")]
7668               (const_string "direct")))
7669    (set (attr "amdfam10_decode")
7670         (cond [(and (eq_attr "alternative" "0,1")
7671                     (match_operand 1 "memory_operand" ""))
7672                   (const_string "vector")]
7673               (const_string "direct")))
7674    (set_attr "mode" "DI")])
7675
7676 (define_expand "mulsi3"
7677   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7678                    (mult:SI (match_operand:SI 1 "register_operand" "")
7679                             (match_operand:SI 2 "general_operand" "")))
7680               (clobber (reg:CC FLAGS_REG))])]
7681   ""
7682   "")
7683
7684 ;; On AMDFAM10
7685 ;; IMUL reg32, reg32, imm8      Direct
7686 ;; IMUL reg32, mem32, imm8      VectorPath
7687 ;; IMUL reg32, reg32, imm32     Direct
7688 ;; IMUL reg32, mem32, imm32     VectorPath
7689 ;; IMUL reg32, reg32            Direct
7690 ;; IMUL reg32, mem32            Direct
7691
7692 (define_insn "*mulsi3_1"
7693   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7694         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7695                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7696    (clobber (reg:CC FLAGS_REG))]
7697   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7698   "@
7699    imul{l}\t{%2, %1, %0|%0, %1, %2}
7700    imul{l}\t{%2, %1, %0|%0, %1, %2}
7701    imul{l}\t{%2, %0|%0, %2}"
7702   [(set_attr "type" "imul")
7703    (set_attr "prefix_0f" "0,0,1")
7704    (set (attr "athlon_decode")
7705         (cond [(eq_attr "cpu" "athlon")
7706                   (const_string "vector")
7707                (eq_attr "alternative" "1")
7708                   (const_string "vector")
7709                (and (eq_attr "alternative" "2")
7710                     (match_operand 1 "memory_operand" ""))
7711                   (const_string "vector")]
7712               (const_string "direct")))
7713    (set (attr "amdfam10_decode")
7714         (cond [(and (eq_attr "alternative" "0,1")
7715                     (match_operand 1 "memory_operand" ""))
7716                   (const_string "vector")]
7717               (const_string "direct")))
7718    (set_attr "mode" "SI")])
7719
7720 (define_insn "*mulsi3_1_zext"
7721   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7722         (zero_extend:DI
7723           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7724                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7725    (clobber (reg:CC FLAGS_REG))]
7726   "TARGET_64BIT
7727    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7728   "@
7729    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7730    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7731    imul{l}\t{%2, %k0|%k0, %2}"
7732   [(set_attr "type" "imul")
7733    (set_attr "prefix_0f" "0,0,1")
7734    (set (attr "athlon_decode")
7735         (cond [(eq_attr "cpu" "athlon")
7736                   (const_string "vector")
7737                (eq_attr "alternative" "1")
7738                   (const_string "vector")
7739                (and (eq_attr "alternative" "2")
7740                     (match_operand 1 "memory_operand" ""))
7741                   (const_string "vector")]
7742               (const_string "direct")))
7743    (set (attr "amdfam10_decode")
7744         (cond [(and (eq_attr "alternative" "0,1")
7745                     (match_operand 1 "memory_operand" ""))
7746                   (const_string "vector")]
7747               (const_string "direct")))
7748    (set_attr "mode" "SI")])
7749
7750 (define_expand "mulhi3"
7751   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7752                    (mult:HI (match_operand:HI 1 "register_operand" "")
7753                             (match_operand:HI 2 "general_operand" "")))
7754               (clobber (reg:CC FLAGS_REG))])]
7755   "TARGET_HIMODE_MATH"
7756   "")
7757
7758 ;; On AMDFAM10
7759 ;; IMUL reg16, reg16, imm8      VectorPath
7760 ;; IMUL reg16, mem16, imm8      VectorPath
7761 ;; IMUL reg16, reg16, imm16     VectorPath
7762 ;; IMUL reg16, mem16, imm16     VectorPath
7763 ;; IMUL reg16, reg16            Direct
7764 ;; IMUL reg16, mem16            Direct
7765 (define_insn "*mulhi3_1"
7766   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7767         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7768                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7769    (clobber (reg:CC FLAGS_REG))]
7770   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7771   "@
7772    imul{w}\t{%2, %1, %0|%0, %1, %2}
7773    imul{w}\t{%2, %1, %0|%0, %1, %2}
7774    imul{w}\t{%2, %0|%0, %2}"
7775   [(set_attr "type" "imul")
7776    (set_attr "prefix_0f" "0,0,1")
7777    (set (attr "athlon_decode")
7778         (cond [(eq_attr "cpu" "athlon")
7779                   (const_string "vector")
7780                (eq_attr "alternative" "1,2")
7781                   (const_string "vector")]
7782               (const_string "direct")))
7783    (set (attr "amdfam10_decode")
7784         (cond [(eq_attr "alternative" "0,1")
7785                   (const_string "vector")]
7786               (const_string "direct")))
7787    (set_attr "mode" "HI")])
7788
7789 (define_expand "mulqi3"
7790   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7791                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7792                             (match_operand:QI 2 "register_operand" "")))
7793               (clobber (reg:CC FLAGS_REG))])]
7794   "TARGET_QIMODE_MATH"
7795   "")
7796
7797 ;;On AMDFAM10
7798 ;; MUL reg8     Direct
7799 ;; MUL mem8     Direct
7800
7801 (define_insn "*mulqi3_1"
7802   [(set (match_operand:QI 0 "register_operand" "=a")
7803         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7804                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7805    (clobber (reg:CC FLAGS_REG))]
7806   "TARGET_QIMODE_MATH
7807    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7808   "mul{b}\t%2"
7809   [(set_attr "type" "imul")
7810    (set_attr "length_immediate" "0")
7811    (set (attr "athlon_decode")
7812      (if_then_else (eq_attr "cpu" "athlon")
7813         (const_string "vector")
7814         (const_string "direct")))
7815    (set_attr "amdfam10_decode" "direct")
7816    (set_attr "mode" "QI")])
7817
7818 (define_expand "umulqihi3"
7819   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7820                    (mult:HI (zero_extend:HI
7821                               (match_operand:QI 1 "nonimmediate_operand" ""))
7822                             (zero_extend:HI
7823                               (match_operand:QI 2 "register_operand" ""))))
7824               (clobber (reg:CC FLAGS_REG))])]
7825   "TARGET_QIMODE_MATH"
7826   "")
7827
7828 (define_insn "*umulqihi3_1"
7829   [(set (match_operand:HI 0 "register_operand" "=a")
7830         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7831                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7832    (clobber (reg:CC FLAGS_REG))]
7833   "TARGET_QIMODE_MATH
7834    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7835   "mul{b}\t%2"
7836   [(set_attr "type" "imul")
7837    (set_attr "length_immediate" "0")
7838    (set (attr "athlon_decode")
7839      (if_then_else (eq_attr "cpu" "athlon")
7840         (const_string "vector")
7841         (const_string "direct")))
7842    (set_attr "amdfam10_decode" "direct")
7843    (set_attr "mode" "QI")])
7844
7845 (define_expand "mulqihi3"
7846   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7847                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7848                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7849               (clobber (reg:CC FLAGS_REG))])]
7850   "TARGET_QIMODE_MATH"
7851   "")
7852
7853 (define_insn "*mulqihi3_insn"
7854   [(set (match_operand:HI 0 "register_operand" "=a")
7855         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7856                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7857    (clobber (reg:CC FLAGS_REG))]
7858   "TARGET_QIMODE_MATH
7859    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7860   "imul{b}\t%2"
7861   [(set_attr "type" "imul")
7862    (set_attr "length_immediate" "0")
7863    (set (attr "athlon_decode")
7864      (if_then_else (eq_attr "cpu" "athlon")
7865         (const_string "vector")
7866         (const_string "direct")))
7867    (set_attr "amdfam10_decode" "direct")
7868    (set_attr "mode" "QI")])
7869
7870 (define_expand "umulditi3"
7871   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7872                    (mult:TI (zero_extend:TI
7873                               (match_operand:DI 1 "nonimmediate_operand" ""))
7874                             (zero_extend:TI
7875                               (match_operand:DI 2 "register_operand" ""))))
7876               (clobber (reg:CC FLAGS_REG))])]
7877   "TARGET_64BIT"
7878   "")
7879
7880 (define_insn "*umulditi3_insn"
7881   [(set (match_operand:TI 0 "register_operand" "=A")
7882         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7883                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7884    (clobber (reg:CC FLAGS_REG))]
7885   "TARGET_64BIT
7886    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7887   "mul{q}\t%2"
7888   [(set_attr "type" "imul")
7889    (set_attr "length_immediate" "0")
7890    (set (attr "athlon_decode")
7891      (if_then_else (eq_attr "cpu" "athlon")
7892         (const_string "vector")
7893         (const_string "double")))
7894    (set_attr "amdfam10_decode" "double")
7895    (set_attr "mode" "DI")])
7896
7897 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7898 (define_expand "umulsidi3"
7899   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7900                    (mult:DI (zero_extend:DI
7901                               (match_operand:SI 1 "nonimmediate_operand" ""))
7902                             (zero_extend:DI
7903                               (match_operand:SI 2 "register_operand" ""))))
7904               (clobber (reg:CC FLAGS_REG))])]
7905   "!TARGET_64BIT"
7906   "")
7907
7908 (define_insn "*umulsidi3_insn"
7909   [(set (match_operand:DI 0 "register_operand" "=A")
7910         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7911                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7912    (clobber (reg:CC FLAGS_REG))]
7913   "!TARGET_64BIT
7914    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7915   "mul{l}\t%2"
7916   [(set_attr "type" "imul")
7917    (set_attr "length_immediate" "0")
7918    (set (attr "athlon_decode")
7919      (if_then_else (eq_attr "cpu" "athlon")
7920         (const_string "vector")
7921         (const_string "double")))
7922    (set_attr "amdfam10_decode" "double")
7923    (set_attr "mode" "SI")])
7924
7925 (define_expand "mulditi3"
7926   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7927                    (mult:TI (sign_extend:TI
7928                               (match_operand:DI 1 "nonimmediate_operand" ""))
7929                             (sign_extend:TI
7930                               (match_operand:DI 2 "register_operand" ""))))
7931               (clobber (reg:CC FLAGS_REG))])]
7932   "TARGET_64BIT"
7933   "")
7934
7935 (define_insn "*mulditi3_insn"
7936   [(set (match_operand:TI 0 "register_operand" "=A")
7937         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7938                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7939    (clobber (reg:CC FLAGS_REG))]
7940   "TARGET_64BIT
7941    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7942   "imul{q}\t%2"
7943   [(set_attr "type" "imul")
7944    (set_attr "length_immediate" "0")
7945    (set (attr "athlon_decode")
7946      (if_then_else (eq_attr "cpu" "athlon")
7947         (const_string "vector")
7948         (const_string "double")))
7949    (set_attr "amdfam10_decode" "double")
7950    (set_attr "mode" "DI")])
7951
7952 (define_expand "mulsidi3"
7953   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7954                    (mult:DI (sign_extend:DI
7955                               (match_operand:SI 1 "nonimmediate_operand" ""))
7956                             (sign_extend:DI
7957                               (match_operand:SI 2 "register_operand" ""))))
7958               (clobber (reg:CC FLAGS_REG))])]
7959   "!TARGET_64BIT"
7960   "")
7961
7962 (define_insn "*mulsidi3_insn"
7963   [(set (match_operand:DI 0 "register_operand" "=A")
7964         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7965                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7966    (clobber (reg:CC FLAGS_REG))]
7967   "!TARGET_64BIT
7968    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7969   "imul{l}\t%2"
7970   [(set_attr "type" "imul")
7971    (set_attr "length_immediate" "0")
7972    (set (attr "athlon_decode")
7973      (if_then_else (eq_attr "cpu" "athlon")
7974         (const_string "vector")
7975         (const_string "double")))
7976    (set_attr "amdfam10_decode" "double")
7977    (set_attr "mode" "SI")])
7978
7979 (define_expand "umuldi3_highpart"
7980   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7981                    (truncate:DI
7982                      (lshiftrt:TI
7983                        (mult:TI (zero_extend:TI
7984                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7985                                 (zero_extend:TI
7986                                   (match_operand:DI 2 "register_operand" "")))
7987                        (const_int 64))))
7988               (clobber (match_scratch:DI 3 ""))
7989               (clobber (reg:CC FLAGS_REG))])]
7990   "TARGET_64BIT"
7991   "")
7992
7993 (define_insn "*umuldi3_highpart_rex64"
7994   [(set (match_operand:DI 0 "register_operand" "=d")
7995         (truncate:DI
7996           (lshiftrt:TI
7997             (mult:TI (zero_extend:TI
7998                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7999                      (zero_extend:TI
8000                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8001             (const_int 64))))
8002    (clobber (match_scratch:DI 3 "=1"))
8003    (clobber (reg:CC FLAGS_REG))]
8004   "TARGET_64BIT
8005    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8006   "mul{q}\t%2"
8007   [(set_attr "type" "imul")
8008    (set_attr "length_immediate" "0")
8009    (set (attr "athlon_decode")
8010      (if_then_else (eq_attr "cpu" "athlon")
8011         (const_string "vector")
8012         (const_string "double")))
8013    (set_attr "amdfam10_decode" "double")
8014    (set_attr "mode" "DI")])
8015
8016 (define_expand "umulsi3_highpart"
8017   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8018                    (truncate:SI
8019                      (lshiftrt:DI
8020                        (mult:DI (zero_extend:DI
8021                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8022                                 (zero_extend:DI
8023                                   (match_operand:SI 2 "register_operand" "")))
8024                        (const_int 32))))
8025               (clobber (match_scratch:SI 3 ""))
8026               (clobber (reg:CC FLAGS_REG))])]
8027   ""
8028   "")
8029
8030 (define_insn "*umulsi3_highpart_insn"
8031   [(set (match_operand:SI 0 "register_operand" "=d")
8032         (truncate:SI
8033           (lshiftrt:DI
8034             (mult:DI (zero_extend:DI
8035                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8036                      (zero_extend:DI
8037                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8038             (const_int 32))))
8039    (clobber (match_scratch:SI 3 "=1"))
8040    (clobber (reg:CC FLAGS_REG))]
8041   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8042   "mul{l}\t%2"
8043   [(set_attr "type" "imul")
8044    (set_attr "length_immediate" "0")
8045    (set (attr "athlon_decode")
8046      (if_then_else (eq_attr "cpu" "athlon")
8047         (const_string "vector")
8048         (const_string "double")))
8049    (set_attr "amdfam10_decode" "double")
8050    (set_attr "mode" "SI")])
8051
8052 (define_insn "*umulsi3_highpart_zext"
8053   [(set (match_operand:DI 0 "register_operand" "=d")
8054         (zero_extend:DI (truncate:SI
8055           (lshiftrt:DI
8056             (mult:DI (zero_extend:DI
8057                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8058                      (zero_extend:DI
8059                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8060             (const_int 32)))))
8061    (clobber (match_scratch:SI 3 "=1"))
8062    (clobber (reg:CC FLAGS_REG))]
8063   "TARGET_64BIT
8064    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8065   "mul{l}\t%2"
8066   [(set_attr "type" "imul")
8067    (set_attr "length_immediate" "0")
8068    (set (attr "athlon_decode")
8069      (if_then_else (eq_attr "cpu" "athlon")
8070         (const_string "vector")
8071         (const_string "double")))
8072    (set_attr "amdfam10_decode" "double")
8073    (set_attr "mode" "SI")])
8074
8075 (define_expand "smuldi3_highpart"
8076   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8077                    (truncate:DI
8078                      (lshiftrt:TI
8079                        (mult:TI (sign_extend:TI
8080                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8081                                 (sign_extend:TI
8082                                   (match_operand:DI 2 "register_operand" "")))
8083                        (const_int 64))))
8084               (clobber (match_scratch:DI 3 ""))
8085               (clobber (reg:CC FLAGS_REG))])]
8086   "TARGET_64BIT"
8087   "")
8088
8089 (define_insn "*smuldi3_highpart_rex64"
8090   [(set (match_operand:DI 0 "register_operand" "=d")
8091         (truncate:DI
8092           (lshiftrt:TI
8093             (mult:TI (sign_extend:TI
8094                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8095                      (sign_extend:TI
8096                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8097             (const_int 64))))
8098    (clobber (match_scratch:DI 3 "=1"))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "TARGET_64BIT
8101    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8102   "imul{q}\t%2"
8103   [(set_attr "type" "imul")
8104    (set (attr "athlon_decode")
8105      (if_then_else (eq_attr "cpu" "athlon")
8106         (const_string "vector")
8107         (const_string "double")))
8108    (set_attr "amdfam10_decode" "double")
8109    (set_attr "mode" "DI")])
8110
8111 (define_expand "smulsi3_highpart"
8112   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8113                    (truncate:SI
8114                      (lshiftrt:DI
8115                        (mult:DI (sign_extend:DI
8116                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8117                                 (sign_extend:DI
8118                                   (match_operand:SI 2 "register_operand" "")))
8119                        (const_int 32))))
8120               (clobber (match_scratch:SI 3 ""))
8121               (clobber (reg:CC FLAGS_REG))])]
8122   ""
8123   "")
8124
8125 (define_insn "*smulsi3_highpart_insn"
8126   [(set (match_operand:SI 0 "register_operand" "=d")
8127         (truncate:SI
8128           (lshiftrt:DI
8129             (mult:DI (sign_extend:DI
8130                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8131                      (sign_extend:DI
8132                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8133             (const_int 32))))
8134    (clobber (match_scratch:SI 3 "=1"))
8135    (clobber (reg:CC FLAGS_REG))]
8136   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8137   "imul{l}\t%2"
8138   [(set_attr "type" "imul")
8139    (set (attr "athlon_decode")
8140      (if_then_else (eq_attr "cpu" "athlon")
8141         (const_string "vector")
8142         (const_string "double")))
8143    (set_attr "amdfam10_decode" "double")
8144    (set_attr "mode" "SI")])
8145
8146 (define_insn "*smulsi3_highpart_zext"
8147   [(set (match_operand:DI 0 "register_operand" "=d")
8148         (zero_extend:DI (truncate:SI
8149           (lshiftrt:DI
8150             (mult:DI (sign_extend:DI
8151                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8152                      (sign_extend:DI
8153                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8154             (const_int 32)))))
8155    (clobber (match_scratch:SI 3 "=1"))
8156    (clobber (reg:CC FLAGS_REG))]
8157   "TARGET_64BIT
8158    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8159   "imul{l}\t%2"
8160   [(set_attr "type" "imul")
8161    (set (attr "athlon_decode")
8162      (if_then_else (eq_attr "cpu" "athlon")
8163         (const_string "vector")
8164         (const_string "double")))
8165    (set_attr "amdfam10_decode" "double")
8166    (set_attr "mode" "SI")])
8167
8168 ;; The patterns that match these are at the end of this file.
8169
8170 (define_expand "mulxf3"
8171   [(set (match_operand:XF 0 "register_operand" "")
8172         (mult:XF (match_operand:XF 1 "register_operand" "")
8173                  (match_operand:XF 2 "register_operand" "")))]
8174   "TARGET_80387"
8175   "")
8176
8177 (define_expand "mul<mode>3"
8178   [(set (match_operand:MODEF 0 "register_operand" "")
8179         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8180                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8181   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8182   "")
8183
8184 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8185
8186 \f
8187 ;; Divide instructions
8188
8189 (define_insn "divqi3"
8190   [(set (match_operand:QI 0 "register_operand" "=a")
8191         (div:QI (match_operand:HI 1 "register_operand" "0")
8192                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8193    (clobber (reg:CC FLAGS_REG))]
8194   "TARGET_QIMODE_MATH"
8195   "idiv{b}\t%2"
8196   [(set_attr "type" "idiv")
8197    (set_attr "mode" "QI")])
8198
8199 (define_insn "udivqi3"
8200   [(set (match_operand:QI 0 "register_operand" "=a")
8201         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8202                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8203    (clobber (reg:CC FLAGS_REG))]
8204   "TARGET_QIMODE_MATH"
8205   "div{b}\t%2"
8206   [(set_attr "type" "idiv")
8207    (set_attr "mode" "QI")])
8208
8209 ;; The patterns that match these are at the end of this file.
8210
8211 (define_expand "divxf3"
8212   [(set (match_operand:XF 0 "register_operand" "")
8213         (div:XF (match_operand:XF 1 "register_operand" "")
8214                 (match_operand:XF 2 "register_operand" "")))]
8215   "TARGET_80387"
8216   "")
8217
8218 (define_expand "divdf3"
8219   [(set (match_operand:DF 0 "register_operand" "")
8220         (div:DF (match_operand:DF 1 "register_operand" "")
8221                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8222    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8223    "")
8224
8225 (define_expand "divsf3"
8226   [(set (match_operand:SF 0 "register_operand" "")
8227         (div:SF (match_operand:SF 1 "register_operand" "")
8228                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8229   "TARGET_80387 || TARGET_SSE_MATH"
8230 {
8231   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8232       && flag_finite_math_only && !flag_trapping_math
8233       && flag_unsafe_math_optimizations)
8234     {
8235       ix86_emit_swdivsf (operands[0], operands[1],
8236                          operands[2], SFmode);
8237       DONE;
8238     }
8239 })
8240 \f
8241 ;; Remainder instructions.
8242
8243 (define_expand "divmoddi4"
8244   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8245                    (div:DI (match_operand:DI 1 "register_operand" "")
8246                            (match_operand:DI 2 "nonimmediate_operand" "")))
8247               (set (match_operand:DI 3 "register_operand" "")
8248                    (mod:DI (match_dup 1) (match_dup 2)))
8249               (clobber (reg:CC FLAGS_REG))])]
8250   "TARGET_64BIT"
8251   "")
8252
8253 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8254 ;; Penalize eax case slightly because it results in worse scheduling
8255 ;; of code.
8256 (define_insn "*divmoddi4_nocltd_rex64"
8257   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8258         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8259                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8260    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8261         (mod:DI (match_dup 2) (match_dup 3)))
8262    (clobber (reg:CC FLAGS_REG))]
8263   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8264   "#"
8265   [(set_attr "type" "multi")])
8266
8267 (define_insn "*divmoddi4_cltd_rex64"
8268   [(set (match_operand:DI 0 "register_operand" "=a")
8269         (div:DI (match_operand:DI 2 "register_operand" "a")
8270                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8271    (set (match_operand:DI 1 "register_operand" "=&d")
8272         (mod:DI (match_dup 2) (match_dup 3)))
8273    (clobber (reg:CC FLAGS_REG))]
8274   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8275   "#"
8276   [(set_attr "type" "multi")])
8277
8278 (define_insn "*divmoddi_noext_rex64"
8279   [(set (match_operand:DI 0 "register_operand" "=a")
8280         (div:DI (match_operand:DI 1 "register_operand" "0")
8281                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8282    (set (match_operand:DI 3 "register_operand" "=d")
8283         (mod:DI (match_dup 1) (match_dup 2)))
8284    (use (match_operand:DI 4 "register_operand" "3"))
8285    (clobber (reg:CC FLAGS_REG))]
8286   "TARGET_64BIT"
8287   "idiv{q}\t%2"
8288   [(set_attr "type" "idiv")
8289    (set_attr "mode" "DI")])
8290
8291 (define_split
8292   [(set (match_operand:DI 0 "register_operand" "")
8293         (div:DI (match_operand:DI 1 "register_operand" "")
8294                 (match_operand:DI 2 "nonimmediate_operand" "")))
8295    (set (match_operand:DI 3 "register_operand" "")
8296         (mod:DI (match_dup 1) (match_dup 2)))
8297    (clobber (reg:CC FLAGS_REG))]
8298   "TARGET_64BIT && reload_completed"
8299   [(parallel [(set (match_dup 3)
8300                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8301               (clobber (reg:CC FLAGS_REG))])
8302    (parallel [(set (match_dup 0)
8303                    (div:DI (reg:DI 0) (match_dup 2)))
8304               (set (match_dup 3)
8305                    (mod:DI (reg:DI 0) (match_dup 2)))
8306               (use (match_dup 3))
8307               (clobber (reg:CC FLAGS_REG))])]
8308 {
8309   /* Avoid use of cltd in favor of a mov+shift.  */
8310   if (!TARGET_USE_CLTD && !optimize_size)
8311     {
8312       if (true_regnum (operands[1]))
8313         emit_move_insn (operands[0], operands[1]);
8314       else
8315         emit_move_insn (operands[3], operands[1]);
8316       operands[4] = operands[3];
8317     }
8318   else
8319     {
8320       gcc_assert (!true_regnum (operands[1]));
8321       operands[4] = operands[1];
8322     }
8323 })
8324
8325
8326 (define_expand "divmodsi4"
8327   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8328                    (div:SI (match_operand:SI 1 "register_operand" "")
8329                            (match_operand:SI 2 "nonimmediate_operand" "")))
8330               (set (match_operand:SI 3 "register_operand" "")
8331                    (mod:SI (match_dup 1) (match_dup 2)))
8332               (clobber (reg:CC FLAGS_REG))])]
8333   ""
8334   "")
8335
8336 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8337 ;; Penalize eax case slightly because it results in worse scheduling
8338 ;; of code.
8339 (define_insn "*divmodsi4_nocltd"
8340   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8341         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8342                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8343    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8344         (mod:SI (match_dup 2) (match_dup 3)))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "!optimize_size && !TARGET_USE_CLTD"
8347   "#"
8348   [(set_attr "type" "multi")])
8349
8350 (define_insn "*divmodsi4_cltd"
8351   [(set (match_operand:SI 0 "register_operand" "=a")
8352         (div:SI (match_operand:SI 2 "register_operand" "a")
8353                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8354    (set (match_operand:SI 1 "register_operand" "=&d")
8355         (mod:SI (match_dup 2) (match_dup 3)))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "optimize_size || TARGET_USE_CLTD"
8358   "#"
8359   [(set_attr "type" "multi")])
8360
8361 (define_insn "*divmodsi_noext"
8362   [(set (match_operand:SI 0 "register_operand" "=a")
8363         (div:SI (match_operand:SI 1 "register_operand" "0")
8364                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8365    (set (match_operand:SI 3 "register_operand" "=d")
8366         (mod:SI (match_dup 1) (match_dup 2)))
8367    (use (match_operand:SI 4 "register_operand" "3"))
8368    (clobber (reg:CC FLAGS_REG))]
8369   ""
8370   "idiv{l}\t%2"
8371   [(set_attr "type" "idiv")
8372    (set_attr "mode" "SI")])
8373
8374 (define_split
8375   [(set (match_operand:SI 0 "register_operand" "")
8376         (div:SI (match_operand:SI 1 "register_operand" "")
8377                 (match_operand:SI 2 "nonimmediate_operand" "")))
8378    (set (match_operand:SI 3 "register_operand" "")
8379         (mod:SI (match_dup 1) (match_dup 2)))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "reload_completed"
8382   [(parallel [(set (match_dup 3)
8383                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8384               (clobber (reg:CC FLAGS_REG))])
8385    (parallel [(set (match_dup 0)
8386                    (div:SI (reg:SI 0) (match_dup 2)))
8387               (set (match_dup 3)
8388                    (mod:SI (reg:SI 0) (match_dup 2)))
8389               (use (match_dup 3))
8390               (clobber (reg:CC FLAGS_REG))])]
8391 {
8392   /* Avoid use of cltd in favor of a mov+shift.  */
8393   if (!TARGET_USE_CLTD && !optimize_size)
8394     {
8395       if (true_regnum (operands[1]))
8396         emit_move_insn (operands[0], operands[1]);
8397       else
8398         emit_move_insn (operands[3], operands[1]);
8399       operands[4] = operands[3];
8400     }
8401   else
8402     {
8403       gcc_assert (!true_regnum (operands[1]));
8404       operands[4] = operands[1];
8405     }
8406 })
8407 ;; %%% Split me.
8408 (define_insn "divmodhi4"
8409   [(set (match_operand:HI 0 "register_operand" "=a")
8410         (div:HI (match_operand:HI 1 "register_operand" "0")
8411                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8412    (set (match_operand:HI 3 "register_operand" "=&d")
8413         (mod:HI (match_dup 1) (match_dup 2)))
8414    (clobber (reg:CC FLAGS_REG))]
8415   "TARGET_HIMODE_MATH"
8416   "cwtd\;idiv{w}\t%2"
8417   [(set_attr "type" "multi")
8418    (set_attr "length_immediate" "0")
8419    (set_attr "mode" "SI")])
8420
8421 (define_insn "udivmoddi4"
8422   [(set (match_operand:DI 0 "register_operand" "=a")
8423         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8424                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8425    (set (match_operand:DI 3 "register_operand" "=&d")
8426         (umod:DI (match_dup 1) (match_dup 2)))
8427    (clobber (reg:CC FLAGS_REG))]
8428   "TARGET_64BIT"
8429   "xor{q}\t%3, %3\;div{q}\t%2"
8430   [(set_attr "type" "multi")
8431    (set_attr "length_immediate" "0")
8432    (set_attr "mode" "DI")])
8433
8434 (define_insn "*udivmoddi4_noext"
8435   [(set (match_operand:DI 0 "register_operand" "=a")
8436         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8437                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8438    (set (match_operand:DI 3 "register_operand" "=d")
8439         (umod:DI (match_dup 1) (match_dup 2)))
8440    (use (match_dup 3))
8441    (clobber (reg:CC FLAGS_REG))]
8442   "TARGET_64BIT"
8443   "div{q}\t%2"
8444   [(set_attr "type" "idiv")
8445    (set_attr "mode" "DI")])
8446
8447 (define_split
8448   [(set (match_operand:DI 0 "register_operand" "")
8449         (udiv:DI (match_operand:DI 1 "register_operand" "")
8450                  (match_operand:DI 2 "nonimmediate_operand" "")))
8451    (set (match_operand:DI 3 "register_operand" "")
8452         (umod:DI (match_dup 1) (match_dup 2)))
8453    (clobber (reg:CC FLAGS_REG))]
8454   "TARGET_64BIT && reload_completed"
8455   [(set (match_dup 3) (const_int 0))
8456    (parallel [(set (match_dup 0)
8457                    (udiv:DI (match_dup 1) (match_dup 2)))
8458               (set (match_dup 3)
8459                    (umod:DI (match_dup 1) (match_dup 2)))
8460               (use (match_dup 3))
8461               (clobber (reg:CC FLAGS_REG))])]
8462   "")
8463
8464 (define_insn "udivmodsi4"
8465   [(set (match_operand:SI 0 "register_operand" "=a")
8466         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8467                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8468    (set (match_operand:SI 3 "register_operand" "=&d")
8469         (umod:SI (match_dup 1) (match_dup 2)))
8470    (clobber (reg:CC FLAGS_REG))]
8471   ""
8472   "xor{l}\t%3, %3\;div{l}\t%2"
8473   [(set_attr "type" "multi")
8474    (set_attr "length_immediate" "0")
8475    (set_attr "mode" "SI")])
8476
8477 (define_insn "*udivmodsi4_noext"
8478   [(set (match_operand:SI 0 "register_operand" "=a")
8479         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8480                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8481    (set (match_operand:SI 3 "register_operand" "=d")
8482         (umod:SI (match_dup 1) (match_dup 2)))
8483    (use (match_dup 3))
8484    (clobber (reg:CC FLAGS_REG))]
8485   ""
8486   "div{l}\t%2"
8487   [(set_attr "type" "idiv")
8488    (set_attr "mode" "SI")])
8489
8490 (define_split
8491   [(set (match_operand:SI 0 "register_operand" "")
8492         (udiv:SI (match_operand:SI 1 "register_operand" "")
8493                  (match_operand:SI 2 "nonimmediate_operand" "")))
8494    (set (match_operand:SI 3 "register_operand" "")
8495         (umod:SI (match_dup 1) (match_dup 2)))
8496    (clobber (reg:CC FLAGS_REG))]
8497   "reload_completed"
8498   [(set (match_dup 3) (const_int 0))
8499    (parallel [(set (match_dup 0)
8500                    (udiv:SI (match_dup 1) (match_dup 2)))
8501               (set (match_dup 3)
8502                    (umod:SI (match_dup 1) (match_dup 2)))
8503               (use (match_dup 3))
8504               (clobber (reg:CC FLAGS_REG))])]
8505   "")
8506
8507 (define_expand "udivmodhi4"
8508   [(set (match_dup 4) (const_int 0))
8509    (parallel [(set (match_operand:HI 0 "register_operand" "")
8510                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8511                             (match_operand:HI 2 "nonimmediate_operand" "")))
8512               (set (match_operand:HI 3 "register_operand" "")
8513                    (umod:HI (match_dup 1) (match_dup 2)))
8514               (use (match_dup 4))
8515               (clobber (reg:CC FLAGS_REG))])]
8516   "TARGET_HIMODE_MATH"
8517   "operands[4] = gen_reg_rtx (HImode);")
8518
8519 (define_insn "*udivmodhi_noext"
8520   [(set (match_operand:HI 0 "register_operand" "=a")
8521         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8522                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8523    (set (match_operand:HI 3 "register_operand" "=d")
8524         (umod:HI (match_dup 1) (match_dup 2)))
8525    (use (match_operand:HI 4 "register_operand" "3"))
8526    (clobber (reg:CC FLAGS_REG))]
8527   ""
8528   "div{w}\t%2"
8529   [(set_attr "type" "idiv")
8530    (set_attr "mode" "HI")])
8531
8532 ;; We cannot use div/idiv for double division, because it causes
8533 ;; "division by zero" on the overflow and that's not what we expect
8534 ;; from truncate.  Because true (non truncating) double division is
8535 ;; never generated, we can't create this insn anyway.
8536 ;
8537 ;(define_insn ""
8538 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8539 ;       (truncate:SI
8540 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8541 ;                  (zero_extend:DI
8542 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8543 ;   (set (match_operand:SI 3 "register_operand" "=d")
8544 ;       (truncate:SI
8545 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8546 ;   (clobber (reg:CC FLAGS_REG))]
8547 ;  ""
8548 ;  "div{l}\t{%2, %0|%0, %2}"
8549 ;  [(set_attr "type" "idiv")])
8550 \f
8551 ;;- Logical AND instructions
8552
8553 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8554 ;; Note that this excludes ah.
8555
8556 (define_insn "*testdi_1_rex64"
8557   [(set (reg FLAGS_REG)
8558         (compare
8559           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8560                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8561           (const_int 0)))]
8562   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8563    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8564   "@
8565    test{l}\t{%k1, %k0|%k0, %k1}
8566    test{l}\t{%k1, %k0|%k0, %k1}
8567    test{q}\t{%1, %0|%0, %1}
8568    test{q}\t{%1, %0|%0, %1}
8569    test{q}\t{%1, %0|%0, %1}"
8570   [(set_attr "type" "test")
8571    (set_attr "modrm" "0,1,0,1,1")
8572    (set_attr "mode" "SI,SI,DI,DI,DI")
8573    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8574
8575 (define_insn "testsi_1"
8576   [(set (reg FLAGS_REG)
8577         (compare
8578           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8579                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8580           (const_int 0)))]
8581   "ix86_match_ccmode (insn, CCNOmode)
8582    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8583   "test{l}\t{%1, %0|%0, %1}"
8584   [(set_attr "type" "test")
8585    (set_attr "modrm" "0,1,1")
8586    (set_attr "mode" "SI")
8587    (set_attr "pent_pair" "uv,np,uv")])
8588
8589 (define_expand "testsi_ccno_1"
8590   [(set (reg:CCNO FLAGS_REG)
8591         (compare:CCNO
8592           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8593                   (match_operand:SI 1 "nonmemory_operand" ""))
8594           (const_int 0)))]
8595   ""
8596   "")
8597
8598 (define_insn "*testhi_1"
8599   [(set (reg FLAGS_REG)
8600         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8601                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8602                  (const_int 0)))]
8603   "ix86_match_ccmode (insn, CCNOmode)
8604    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8605   "test{w}\t{%1, %0|%0, %1}"
8606   [(set_attr "type" "test")
8607    (set_attr "modrm" "0,1,1")
8608    (set_attr "mode" "HI")
8609    (set_attr "pent_pair" "uv,np,uv")])
8610
8611 (define_expand "testqi_ccz_1"
8612   [(set (reg:CCZ FLAGS_REG)
8613         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8614                              (match_operand:QI 1 "nonmemory_operand" ""))
8615                  (const_int 0)))]
8616   ""
8617   "")
8618
8619 (define_insn "*testqi_1_maybe_si"
8620   [(set (reg FLAGS_REG)
8621         (compare
8622           (and:QI
8623             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8624             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8625           (const_int 0)))]
8626    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8627     && ix86_match_ccmode (insn,
8628                          CONST_INT_P (operands[1])
8629                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8630 {
8631   if (which_alternative == 3)
8632     {
8633       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8634         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8635       return "test{l}\t{%1, %k0|%k0, %1}";
8636     }
8637   return "test{b}\t{%1, %0|%0, %1}";
8638 }
8639   [(set_attr "type" "test")
8640    (set_attr "modrm" "0,1,1,1")
8641    (set_attr "mode" "QI,QI,QI,SI")
8642    (set_attr "pent_pair" "uv,np,uv,np")])
8643
8644 (define_insn "*testqi_1"
8645   [(set (reg FLAGS_REG)
8646         (compare
8647           (and:QI
8648             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8649             (match_operand:QI 1 "general_operand" "n,n,qn"))
8650           (const_int 0)))]
8651   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8652    && ix86_match_ccmode (insn, CCNOmode)"
8653   "test{b}\t{%1, %0|%0, %1}"
8654   [(set_attr "type" "test")
8655    (set_attr "modrm" "0,1,1")
8656    (set_attr "mode" "QI")
8657    (set_attr "pent_pair" "uv,np,uv")])
8658
8659 (define_expand "testqi_ext_ccno_0"
8660   [(set (reg:CCNO FLAGS_REG)
8661         (compare:CCNO
8662           (and:SI
8663             (zero_extract:SI
8664               (match_operand 0 "ext_register_operand" "")
8665               (const_int 8)
8666               (const_int 8))
8667             (match_operand 1 "const_int_operand" ""))
8668           (const_int 0)))]
8669   ""
8670   "")
8671
8672 (define_insn "*testqi_ext_0"
8673   [(set (reg FLAGS_REG)
8674         (compare
8675           (and:SI
8676             (zero_extract:SI
8677               (match_operand 0 "ext_register_operand" "Q")
8678               (const_int 8)
8679               (const_int 8))
8680             (match_operand 1 "const_int_operand" "n"))
8681           (const_int 0)))]
8682   "ix86_match_ccmode (insn, CCNOmode)"
8683   "test{b}\t{%1, %h0|%h0, %1}"
8684   [(set_attr "type" "test")
8685    (set_attr "mode" "QI")
8686    (set_attr "length_immediate" "1")
8687    (set_attr "pent_pair" "np")])
8688
8689 (define_insn "*testqi_ext_1"
8690   [(set (reg FLAGS_REG)
8691         (compare
8692           (and:SI
8693             (zero_extract:SI
8694               (match_operand 0 "ext_register_operand" "Q")
8695               (const_int 8)
8696               (const_int 8))
8697             (zero_extend:SI
8698               (match_operand:QI 1 "general_operand" "Qm")))
8699           (const_int 0)))]
8700   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8701    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8702   "test{b}\t{%1, %h0|%h0, %1}"
8703   [(set_attr "type" "test")
8704    (set_attr "mode" "QI")])
8705
8706 (define_insn "*testqi_ext_1_rex64"
8707   [(set (reg FLAGS_REG)
8708         (compare
8709           (and:SI
8710             (zero_extract:SI
8711               (match_operand 0 "ext_register_operand" "Q")
8712               (const_int 8)
8713               (const_int 8))
8714             (zero_extend:SI
8715               (match_operand:QI 1 "register_operand" "Q")))
8716           (const_int 0)))]
8717   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8718   "test{b}\t{%1, %h0|%h0, %1}"
8719   [(set_attr "type" "test")
8720    (set_attr "mode" "QI")])
8721
8722 (define_insn "*testqi_ext_2"
8723   [(set (reg FLAGS_REG)
8724         (compare
8725           (and:SI
8726             (zero_extract:SI
8727               (match_operand 0 "ext_register_operand" "Q")
8728               (const_int 8)
8729               (const_int 8))
8730             (zero_extract:SI
8731               (match_operand 1 "ext_register_operand" "Q")
8732               (const_int 8)
8733               (const_int 8)))
8734           (const_int 0)))]
8735   "ix86_match_ccmode (insn, CCNOmode)"
8736   "test{b}\t{%h1, %h0|%h0, %h1}"
8737   [(set_attr "type" "test")
8738    (set_attr "mode" "QI")])
8739
8740 ;; Combine likes to form bit extractions for some tests.  Humor it.
8741 (define_insn "*testqi_ext_3"
8742   [(set (reg FLAGS_REG)
8743         (compare (zero_extract:SI
8744                    (match_operand 0 "nonimmediate_operand" "rm")
8745                    (match_operand:SI 1 "const_int_operand" "")
8746                    (match_operand:SI 2 "const_int_operand" ""))
8747                  (const_int 0)))]
8748   "ix86_match_ccmode (insn, CCNOmode)
8749    && INTVAL (operands[1]) > 0
8750    && INTVAL (operands[2]) >= 0
8751    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8752    && (GET_MODE (operands[0]) == SImode
8753        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8754        || GET_MODE (operands[0]) == HImode
8755        || GET_MODE (operands[0]) == QImode)"
8756   "#")
8757
8758 (define_insn "*testqi_ext_3_rex64"
8759   [(set (reg FLAGS_REG)
8760         (compare (zero_extract:DI
8761                    (match_operand 0 "nonimmediate_operand" "rm")
8762                    (match_operand:DI 1 "const_int_operand" "")
8763                    (match_operand:DI 2 "const_int_operand" ""))
8764                  (const_int 0)))]
8765   "TARGET_64BIT
8766    && ix86_match_ccmode (insn, CCNOmode)
8767    && INTVAL (operands[1]) > 0
8768    && INTVAL (operands[2]) >= 0
8769    /* Ensure that resulting mask is zero or sign extended operand.  */
8770    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8771        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8772            && INTVAL (operands[1]) > 32))
8773    && (GET_MODE (operands[0]) == SImode
8774        || GET_MODE (operands[0]) == DImode
8775        || GET_MODE (operands[0]) == HImode
8776        || GET_MODE (operands[0]) == QImode)"
8777   "#")
8778
8779 (define_split
8780   [(set (match_operand 0 "flags_reg_operand" "")
8781         (match_operator 1 "compare_operator"
8782           [(zero_extract
8783              (match_operand 2 "nonimmediate_operand" "")
8784              (match_operand 3 "const_int_operand" "")
8785              (match_operand 4 "const_int_operand" ""))
8786            (const_int 0)]))]
8787   "ix86_match_ccmode (insn, CCNOmode)"
8788   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8789 {
8790   rtx val = operands[2];
8791   HOST_WIDE_INT len = INTVAL (operands[3]);
8792   HOST_WIDE_INT pos = INTVAL (operands[4]);
8793   HOST_WIDE_INT mask;
8794   enum machine_mode mode, submode;
8795
8796   mode = GET_MODE (val);
8797   if (MEM_P (val))
8798     {
8799       /* ??? Combine likes to put non-volatile mem extractions in QImode
8800          no matter the size of the test.  So find a mode that works.  */
8801       if (! MEM_VOLATILE_P (val))
8802         {
8803           mode = smallest_mode_for_size (pos + len, MODE_INT);
8804           val = adjust_address (val, mode, 0);
8805         }
8806     }
8807   else if (GET_CODE (val) == SUBREG
8808            && (submode = GET_MODE (SUBREG_REG (val)),
8809                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8810            && pos + len <= GET_MODE_BITSIZE (submode))
8811     {
8812       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8813       mode = submode;
8814       val = SUBREG_REG (val);
8815     }
8816   else if (mode == HImode && pos + len <= 8)
8817     {
8818       /* Small HImode tests can be converted to QImode.  */
8819       mode = QImode;
8820       val = gen_lowpart (QImode, val);
8821     }
8822
8823   if (len == HOST_BITS_PER_WIDE_INT)
8824     mask = -1;
8825   else
8826     mask = ((HOST_WIDE_INT)1 << len) - 1;
8827   mask <<= pos;
8828
8829   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8830 })
8831
8832 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8833 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8834 ;; this is relatively important trick.
8835 ;; Do the conversion only post-reload to avoid limiting of the register class
8836 ;; to QI regs.
8837 (define_split
8838   [(set (match_operand 0 "flags_reg_operand" "")
8839         (match_operator 1 "compare_operator"
8840           [(and (match_operand 2 "register_operand" "")
8841                 (match_operand 3 "const_int_operand" ""))
8842            (const_int 0)]))]
8843    "reload_completed
8844     && QI_REG_P (operands[2])
8845     && GET_MODE (operands[2]) != QImode
8846     && ((ix86_match_ccmode (insn, CCZmode)
8847          && !(INTVAL (operands[3]) & ~(255 << 8)))
8848         || (ix86_match_ccmode (insn, CCNOmode)
8849             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8850   [(set (match_dup 0)
8851         (match_op_dup 1
8852           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8853                    (match_dup 3))
8854            (const_int 0)]))]
8855   "operands[2] = gen_lowpart (SImode, operands[2]);
8856    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8857
8858 (define_split
8859   [(set (match_operand 0 "flags_reg_operand" "")
8860         (match_operator 1 "compare_operator"
8861           [(and (match_operand 2 "nonimmediate_operand" "")
8862                 (match_operand 3 "const_int_operand" ""))
8863            (const_int 0)]))]
8864    "reload_completed
8865     && GET_MODE (operands[2]) != QImode
8866     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8867     && ((ix86_match_ccmode (insn, CCZmode)
8868          && !(INTVAL (operands[3]) & ~255))
8869         || (ix86_match_ccmode (insn, CCNOmode)
8870             && !(INTVAL (operands[3]) & ~127)))"
8871   [(set (match_dup 0)
8872         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8873                          (const_int 0)]))]
8874   "operands[2] = gen_lowpart (QImode, operands[2]);
8875    operands[3] = gen_lowpart (QImode, operands[3]);")
8876
8877
8878 ;; %%% This used to optimize known byte-wide and operations to memory,
8879 ;; and sometimes to QImode registers.  If this is considered useful,
8880 ;; it should be done with splitters.
8881
8882 (define_expand "anddi3"
8883   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8884         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8885                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8886    (clobber (reg:CC FLAGS_REG))]
8887   "TARGET_64BIT"
8888   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8889
8890 (define_insn "*anddi_1_rex64"
8891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8892         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8893                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8894    (clobber (reg:CC FLAGS_REG))]
8895   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8896 {
8897   switch (get_attr_type (insn))
8898     {
8899     case TYPE_IMOVX:
8900       {
8901         enum machine_mode mode;
8902
8903         gcc_assert (CONST_INT_P (operands[2]));
8904         if (INTVAL (operands[2]) == 0xff)
8905           mode = QImode;
8906         else
8907           {
8908             gcc_assert (INTVAL (operands[2]) == 0xffff);
8909             mode = HImode;
8910           }
8911
8912         operands[1] = gen_lowpart (mode, operands[1]);
8913         if (mode == QImode)
8914           return "movz{bq|x}\t{%1,%0|%0, %1}";
8915         else
8916           return "movz{wq|x}\t{%1,%0|%0, %1}";
8917       }
8918
8919     default:
8920       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8921       if (get_attr_mode (insn) == MODE_SI)
8922         return "and{l}\t{%k2, %k0|%k0, %k2}";
8923       else
8924         return "and{q}\t{%2, %0|%0, %2}";
8925     }
8926 }
8927   [(set_attr "type" "alu,alu,alu,imovx")
8928    (set_attr "length_immediate" "*,*,*,0")
8929    (set_attr "mode" "SI,DI,DI,DI")])
8930
8931 (define_insn "*anddi_2"
8932   [(set (reg FLAGS_REG)
8933         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8934                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8935                  (const_int 0)))
8936    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8937         (and:DI (match_dup 1) (match_dup 2)))]
8938   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8939    && ix86_binary_operator_ok (AND, DImode, operands)"
8940   "@
8941    and{l}\t{%k2, %k0|%k0, %k2}
8942    and{q}\t{%2, %0|%0, %2}
8943    and{q}\t{%2, %0|%0, %2}"
8944   [(set_attr "type" "alu")
8945    (set_attr "mode" "SI,DI,DI")])
8946
8947 (define_expand "andsi3"
8948   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8949         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8950                 (match_operand:SI 2 "general_operand" "")))
8951    (clobber (reg:CC FLAGS_REG))]
8952   ""
8953   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8954
8955 (define_insn "*andsi_1"
8956   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8957         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8958                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "ix86_binary_operator_ok (AND, SImode, operands)"
8961 {
8962   switch (get_attr_type (insn))
8963     {
8964     case TYPE_IMOVX:
8965       {
8966         enum machine_mode mode;
8967
8968         gcc_assert (CONST_INT_P (operands[2]));
8969         if (INTVAL (operands[2]) == 0xff)
8970           mode = QImode;
8971         else
8972           {
8973             gcc_assert (INTVAL (operands[2]) == 0xffff);
8974             mode = HImode;
8975           }
8976
8977         operands[1] = gen_lowpart (mode, operands[1]);
8978         if (mode == QImode)
8979           return "movz{bl|x}\t{%1,%0|%0, %1}";
8980         else
8981           return "movz{wl|x}\t{%1,%0|%0, %1}";
8982       }
8983
8984     default:
8985       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8986       return "and{l}\t{%2, %0|%0, %2}";
8987     }
8988 }
8989   [(set_attr "type" "alu,alu,imovx")
8990    (set_attr "length_immediate" "*,*,0")
8991    (set_attr "mode" "SI")])
8992
8993 (define_split
8994   [(set (match_operand 0 "register_operand" "")
8995         (and (match_dup 0)
8996              (const_int -65536)))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8999   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9000   "operands[1] = gen_lowpart (HImode, operands[0]);")
9001
9002 (define_split
9003   [(set (match_operand 0 "ext_register_operand" "")
9004         (and (match_dup 0)
9005              (const_int -256)))
9006    (clobber (reg:CC FLAGS_REG))]
9007   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9008   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9009   "operands[1] = gen_lowpart (QImode, operands[0]);")
9010
9011 (define_split
9012   [(set (match_operand 0 "ext_register_operand" "")
9013         (and (match_dup 0)
9014              (const_int -65281)))
9015    (clobber (reg:CC FLAGS_REG))]
9016   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9017   [(parallel [(set (zero_extract:SI (match_dup 0)
9018                                     (const_int 8)
9019                                     (const_int 8))
9020                    (xor:SI
9021                      (zero_extract:SI (match_dup 0)
9022                                       (const_int 8)
9023                                       (const_int 8))
9024                      (zero_extract:SI (match_dup 0)
9025                                       (const_int 8)
9026                                       (const_int 8))))
9027               (clobber (reg:CC FLAGS_REG))])]
9028   "operands[0] = gen_lowpart (SImode, operands[0]);")
9029
9030 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9031 (define_insn "*andsi_1_zext"
9032   [(set (match_operand:DI 0 "register_operand" "=r")
9033         (zero_extend:DI
9034           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9035                   (match_operand:SI 2 "general_operand" "g"))))
9036    (clobber (reg:CC FLAGS_REG))]
9037   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9038   "and{l}\t{%2, %k0|%k0, %2}"
9039   [(set_attr "type" "alu")
9040    (set_attr "mode" "SI")])
9041
9042 (define_insn "*andsi_2"
9043   [(set (reg FLAGS_REG)
9044         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9045                          (match_operand:SI 2 "general_operand" "g,ri"))
9046                  (const_int 0)))
9047    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9048         (and:SI (match_dup 1) (match_dup 2)))]
9049   "ix86_match_ccmode (insn, CCNOmode)
9050    && ix86_binary_operator_ok (AND, SImode, operands)"
9051   "and{l}\t{%2, %0|%0, %2}"
9052   [(set_attr "type" "alu")
9053    (set_attr "mode" "SI")])
9054
9055 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9056 (define_insn "*andsi_2_zext"
9057   [(set (reg FLAGS_REG)
9058         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059                          (match_operand:SI 2 "general_operand" "g"))
9060                  (const_int 0)))
9061    (set (match_operand:DI 0 "register_operand" "=r")
9062         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9063   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064    && ix86_binary_operator_ok (AND, SImode, operands)"
9065   "and{l}\t{%2, %k0|%k0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9068
9069 (define_expand "andhi3"
9070   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9071         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9072                 (match_operand:HI 2 "general_operand" "")))
9073    (clobber (reg:CC FLAGS_REG))]
9074   "TARGET_HIMODE_MATH"
9075   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9076
9077 (define_insn "*andhi_1"
9078   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9079         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9080                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9081    (clobber (reg:CC FLAGS_REG))]
9082   "ix86_binary_operator_ok (AND, HImode, operands)"
9083 {
9084   switch (get_attr_type (insn))
9085     {
9086     case TYPE_IMOVX:
9087       gcc_assert (CONST_INT_P (operands[2]));
9088       gcc_assert (INTVAL (operands[2]) == 0xff);
9089       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9090
9091     default:
9092       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9093
9094       return "and{w}\t{%2, %0|%0, %2}";
9095     }
9096 }
9097   [(set_attr "type" "alu,alu,imovx")
9098    (set_attr "length_immediate" "*,*,0")
9099    (set_attr "mode" "HI,HI,SI")])
9100
9101 (define_insn "*andhi_2"
9102   [(set (reg FLAGS_REG)
9103         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9104                          (match_operand:HI 2 "general_operand" "g,ri"))
9105                  (const_int 0)))
9106    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9107         (and:HI (match_dup 1) (match_dup 2)))]
9108   "ix86_match_ccmode (insn, CCNOmode)
9109    && ix86_binary_operator_ok (AND, HImode, operands)"
9110   "and{w}\t{%2, %0|%0, %2}"
9111   [(set_attr "type" "alu")
9112    (set_attr "mode" "HI")])
9113
9114 (define_expand "andqi3"
9115   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9116         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9117                 (match_operand:QI 2 "general_operand" "")))
9118    (clobber (reg:CC FLAGS_REG))]
9119   "TARGET_QIMODE_MATH"
9120   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9121
9122 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9123 (define_insn "*andqi_1"
9124   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9125         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9126                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "ix86_binary_operator_ok (AND, QImode, operands)"
9129   "@
9130    and{b}\t{%2, %0|%0, %2}
9131    and{b}\t{%2, %0|%0, %2}
9132    and{l}\t{%k2, %k0|%k0, %k2}"
9133   [(set_attr "type" "alu")
9134    (set_attr "mode" "QI,QI,SI")])
9135
9136 (define_insn "*andqi_1_slp"
9137   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9138         (and:QI (match_dup 0)
9139                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9140    (clobber (reg:CC FLAGS_REG))]
9141   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9142    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9143   "and{b}\t{%1, %0|%0, %1}"
9144   [(set_attr "type" "alu1")
9145    (set_attr "mode" "QI")])
9146
9147 (define_insn "*andqi_2_maybe_si"
9148   [(set (reg FLAGS_REG)
9149         (compare (and:QI
9150                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9151                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9152                  (const_int 0)))
9153    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9154         (and:QI (match_dup 1) (match_dup 2)))]
9155   "ix86_binary_operator_ok (AND, QImode, operands)
9156    && ix86_match_ccmode (insn,
9157                          CONST_INT_P (operands[2])
9158                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9159 {
9160   if (which_alternative == 2)
9161     {
9162       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9163         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9164       return "and{l}\t{%2, %k0|%k0, %2}";
9165     }
9166   return "and{b}\t{%2, %0|%0, %2}";
9167 }
9168   [(set_attr "type" "alu")
9169    (set_attr "mode" "QI,QI,SI")])
9170
9171 (define_insn "*andqi_2"
9172   [(set (reg FLAGS_REG)
9173         (compare (and:QI
9174                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9175                    (match_operand:QI 2 "general_operand" "qim,qi"))
9176                  (const_int 0)))
9177    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9178         (and:QI (match_dup 1) (match_dup 2)))]
9179   "ix86_match_ccmode (insn, CCNOmode)
9180    && ix86_binary_operator_ok (AND, QImode, operands)"
9181   "and{b}\t{%2, %0|%0, %2}"
9182   [(set_attr "type" "alu")
9183    (set_attr "mode" "QI")])
9184
9185 (define_insn "*andqi_2_slp"
9186   [(set (reg FLAGS_REG)
9187         (compare (and:QI
9188                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9189                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9190                  (const_int 0)))
9191    (set (strict_low_part (match_dup 0))
9192         (and:QI (match_dup 0) (match_dup 1)))]
9193   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9194    && ix86_match_ccmode (insn, CCNOmode)
9195    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9196   "and{b}\t{%1, %0|%0, %1}"
9197   [(set_attr "type" "alu1")
9198    (set_attr "mode" "QI")])
9199
9200 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9201 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9202 ;; for a QImode operand, which of course failed.
9203
9204 (define_insn "andqi_ext_0"
9205   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9206                          (const_int 8)
9207                          (const_int 8))
9208         (and:SI
9209           (zero_extract:SI
9210             (match_operand 1 "ext_register_operand" "0")
9211             (const_int 8)
9212             (const_int 8))
9213           (match_operand 2 "const_int_operand" "n")))
9214    (clobber (reg:CC FLAGS_REG))]
9215   ""
9216   "and{b}\t{%2, %h0|%h0, %2}"
9217   [(set_attr "type" "alu")
9218    (set_attr "length_immediate" "1")
9219    (set_attr "mode" "QI")])
9220
9221 ;; Generated by peephole translating test to and.  This shows up
9222 ;; often in fp comparisons.
9223
9224 (define_insn "*andqi_ext_0_cc"
9225   [(set (reg FLAGS_REG)
9226         (compare
9227           (and:SI
9228             (zero_extract:SI
9229               (match_operand 1 "ext_register_operand" "0")
9230               (const_int 8)
9231               (const_int 8))
9232             (match_operand 2 "const_int_operand" "n"))
9233           (const_int 0)))
9234    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9235                          (const_int 8)
9236                          (const_int 8))
9237         (and:SI
9238           (zero_extract:SI
9239             (match_dup 1)
9240             (const_int 8)
9241             (const_int 8))
9242           (match_dup 2)))]
9243   "ix86_match_ccmode (insn, CCNOmode)"
9244   "and{b}\t{%2, %h0|%h0, %2}"
9245   [(set_attr "type" "alu")
9246    (set_attr "length_immediate" "1")
9247    (set_attr "mode" "QI")])
9248
9249 (define_insn "*andqi_ext_1"
9250   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9251                          (const_int 8)
9252                          (const_int 8))
9253         (and:SI
9254           (zero_extract:SI
9255             (match_operand 1 "ext_register_operand" "0")
9256             (const_int 8)
9257             (const_int 8))
9258           (zero_extend:SI
9259             (match_operand:QI 2 "general_operand" "Qm"))))
9260    (clobber (reg:CC FLAGS_REG))]
9261   "!TARGET_64BIT"
9262   "and{b}\t{%2, %h0|%h0, %2}"
9263   [(set_attr "type" "alu")
9264    (set_attr "length_immediate" "0")
9265    (set_attr "mode" "QI")])
9266
9267 (define_insn "*andqi_ext_1_rex64"
9268   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9269                          (const_int 8)
9270                          (const_int 8))
9271         (and:SI
9272           (zero_extract:SI
9273             (match_operand 1 "ext_register_operand" "0")
9274             (const_int 8)
9275             (const_int 8))
9276           (zero_extend:SI
9277             (match_operand 2 "ext_register_operand" "Q"))))
9278    (clobber (reg:CC FLAGS_REG))]
9279   "TARGET_64BIT"
9280   "and{b}\t{%2, %h0|%h0, %2}"
9281   [(set_attr "type" "alu")
9282    (set_attr "length_immediate" "0")
9283    (set_attr "mode" "QI")])
9284
9285 (define_insn "*andqi_ext_2"
9286   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9287                          (const_int 8)
9288                          (const_int 8))
9289         (and:SI
9290           (zero_extract:SI
9291             (match_operand 1 "ext_register_operand" "%0")
9292             (const_int 8)
9293             (const_int 8))
9294           (zero_extract:SI
9295             (match_operand 2 "ext_register_operand" "Q")
9296             (const_int 8)
9297             (const_int 8))))
9298    (clobber (reg:CC FLAGS_REG))]
9299   ""
9300   "and{b}\t{%h2, %h0|%h0, %h2}"
9301   [(set_attr "type" "alu")
9302    (set_attr "length_immediate" "0")
9303    (set_attr "mode" "QI")])
9304
9305 ;; Convert wide AND instructions with immediate operand to shorter QImode
9306 ;; equivalents when possible.
9307 ;; Don't do the splitting with memory operands, since it introduces risk
9308 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9309 ;; for size, but that can (should?) be handled by generic code instead.
9310 (define_split
9311   [(set (match_operand 0 "register_operand" "")
9312         (and (match_operand 1 "register_operand" "")
9313              (match_operand 2 "const_int_operand" "")))
9314    (clobber (reg:CC FLAGS_REG))]
9315    "reload_completed
9316     && QI_REG_P (operands[0])
9317     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9318     && !(~INTVAL (operands[2]) & ~(255 << 8))
9319     && GET_MODE (operands[0]) != QImode"
9320   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9321                    (and:SI (zero_extract:SI (match_dup 1)
9322                                             (const_int 8) (const_int 8))
9323                            (match_dup 2)))
9324               (clobber (reg:CC FLAGS_REG))])]
9325   "operands[0] = gen_lowpart (SImode, operands[0]);
9326    operands[1] = gen_lowpart (SImode, operands[1]);
9327    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9328
9329 ;; Since AND can be encoded with sign extended immediate, this is only
9330 ;; profitable when 7th bit is not set.
9331 (define_split
9332   [(set (match_operand 0 "register_operand" "")
9333         (and (match_operand 1 "general_operand" "")
9334              (match_operand 2 "const_int_operand" "")))
9335    (clobber (reg:CC FLAGS_REG))]
9336    "reload_completed
9337     && ANY_QI_REG_P (operands[0])
9338     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9339     && !(~INTVAL (operands[2]) & ~255)
9340     && !(INTVAL (operands[2]) & 128)
9341     && GET_MODE (operands[0]) != QImode"
9342   [(parallel [(set (strict_low_part (match_dup 0))
9343                    (and:QI (match_dup 1)
9344                            (match_dup 2)))
9345               (clobber (reg:CC FLAGS_REG))])]
9346   "operands[0] = gen_lowpart (QImode, operands[0]);
9347    operands[1] = gen_lowpart (QImode, operands[1]);
9348    operands[2] = gen_lowpart (QImode, operands[2]);")
9349 \f
9350 ;; Logical inclusive OR instructions
9351
9352 ;; %%% This used to optimize known byte-wide and operations to memory.
9353 ;; If this is considered useful, it should be done with splitters.
9354
9355 (define_expand "iordi3"
9356   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9357         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9358                 (match_operand:DI 2 "x86_64_general_operand" "")))
9359    (clobber (reg:CC FLAGS_REG))]
9360   "TARGET_64BIT"
9361   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9362
9363 (define_insn "*iordi_1_rex64"
9364   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9365         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9366                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9367    (clobber (reg:CC FLAGS_REG))]
9368   "TARGET_64BIT
9369    && ix86_binary_operator_ok (IOR, DImode, operands)"
9370   "or{q}\t{%2, %0|%0, %2}"
9371   [(set_attr "type" "alu")
9372    (set_attr "mode" "DI")])
9373
9374 (define_insn "*iordi_2_rex64"
9375   [(set (reg FLAGS_REG)
9376         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9377                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9378                  (const_int 0)))
9379    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9380         (ior:DI (match_dup 1) (match_dup 2)))]
9381   "TARGET_64BIT
9382    && ix86_match_ccmode (insn, CCNOmode)
9383    && ix86_binary_operator_ok (IOR, DImode, operands)"
9384   "or{q}\t{%2, %0|%0, %2}"
9385   [(set_attr "type" "alu")
9386    (set_attr "mode" "DI")])
9387
9388 (define_insn "*iordi_3_rex64"
9389   [(set (reg FLAGS_REG)
9390         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9391                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9392                  (const_int 0)))
9393    (clobber (match_scratch:DI 0 "=r"))]
9394   "TARGET_64BIT
9395    && ix86_match_ccmode (insn, CCNOmode)
9396    && ix86_binary_operator_ok (IOR, DImode, operands)"
9397   "or{q}\t{%2, %0|%0, %2}"
9398   [(set_attr "type" "alu")
9399    (set_attr "mode" "DI")])
9400
9401
9402 (define_expand "iorsi3"
9403   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9404         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9405                 (match_operand:SI 2 "general_operand" "")))
9406    (clobber (reg:CC FLAGS_REG))]
9407   ""
9408   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9409
9410 (define_insn "*iorsi_1"
9411   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9412         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9413                 (match_operand:SI 2 "general_operand" "ri,g")))
9414    (clobber (reg:CC FLAGS_REG))]
9415   "ix86_binary_operator_ok (IOR, SImode, operands)"
9416   "or{l}\t{%2, %0|%0, %2}"
9417   [(set_attr "type" "alu")
9418    (set_attr "mode" "SI")])
9419
9420 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9421 (define_insn "*iorsi_1_zext"
9422   [(set (match_operand:DI 0 "register_operand" "=r")
9423         (zero_extend:DI
9424           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9425                   (match_operand:SI 2 "general_operand" "g"))))
9426    (clobber (reg:CC FLAGS_REG))]
9427   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9428   "or{l}\t{%2, %k0|%k0, %2}"
9429   [(set_attr "type" "alu")
9430    (set_attr "mode" "SI")])
9431
9432 (define_insn "*iorsi_1_zext_imm"
9433   [(set (match_operand:DI 0 "register_operand" "=r")
9434         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9435                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9436    (clobber (reg:CC FLAGS_REG))]
9437   "TARGET_64BIT"
9438   "or{l}\t{%2, %k0|%k0, %2}"
9439   [(set_attr "type" "alu")
9440    (set_attr "mode" "SI")])
9441
9442 (define_insn "*iorsi_2"
9443   [(set (reg FLAGS_REG)
9444         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9445                          (match_operand:SI 2 "general_operand" "g,ri"))
9446                  (const_int 0)))
9447    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9448         (ior:SI (match_dup 1) (match_dup 2)))]
9449   "ix86_match_ccmode (insn, CCNOmode)
9450    && ix86_binary_operator_ok (IOR, SImode, operands)"
9451   "or{l}\t{%2, %0|%0, %2}"
9452   [(set_attr "type" "alu")
9453    (set_attr "mode" "SI")])
9454
9455 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9456 ;; ??? Special case for immediate operand is missing - it is tricky.
9457 (define_insn "*iorsi_2_zext"
9458   [(set (reg FLAGS_REG)
9459         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9460                          (match_operand:SI 2 "general_operand" "g"))
9461                  (const_int 0)))
9462    (set (match_operand:DI 0 "register_operand" "=r")
9463         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9464   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9465    && ix86_binary_operator_ok (IOR, SImode, operands)"
9466   "or{l}\t{%2, %k0|%k0, %2}"
9467   [(set_attr "type" "alu")
9468    (set_attr "mode" "SI")])
9469
9470 (define_insn "*iorsi_2_zext_imm"
9471   [(set (reg FLAGS_REG)
9472         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9473                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9474                  (const_int 0)))
9475    (set (match_operand:DI 0 "register_operand" "=r")
9476         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9477   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9478    && ix86_binary_operator_ok (IOR, SImode, operands)"
9479   "or{l}\t{%2, %k0|%k0, %2}"
9480   [(set_attr "type" "alu")
9481    (set_attr "mode" "SI")])
9482
9483 (define_insn "*iorsi_3"
9484   [(set (reg FLAGS_REG)
9485         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9486                          (match_operand:SI 2 "general_operand" "g"))
9487                  (const_int 0)))
9488    (clobber (match_scratch:SI 0 "=r"))]
9489   "ix86_match_ccmode (insn, CCNOmode)
9490    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9491   "or{l}\t{%2, %0|%0, %2}"
9492   [(set_attr "type" "alu")
9493    (set_attr "mode" "SI")])
9494
9495 (define_expand "iorhi3"
9496   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9497         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9498                 (match_operand:HI 2 "general_operand" "")))
9499    (clobber (reg:CC FLAGS_REG))]
9500   "TARGET_HIMODE_MATH"
9501   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9502
9503 (define_insn "*iorhi_1"
9504   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9505         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9506                 (match_operand:HI 2 "general_operand" "g,ri")))
9507    (clobber (reg:CC FLAGS_REG))]
9508   "ix86_binary_operator_ok (IOR, HImode, operands)"
9509   "or{w}\t{%2, %0|%0, %2}"
9510   [(set_attr "type" "alu")
9511    (set_attr "mode" "HI")])
9512
9513 (define_insn "*iorhi_2"
9514   [(set (reg FLAGS_REG)
9515         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9516                          (match_operand:HI 2 "general_operand" "g,ri"))
9517                  (const_int 0)))
9518    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9519         (ior:HI (match_dup 1) (match_dup 2)))]
9520   "ix86_match_ccmode (insn, CCNOmode)
9521    && ix86_binary_operator_ok (IOR, HImode, operands)"
9522   "or{w}\t{%2, %0|%0, %2}"
9523   [(set_attr "type" "alu")
9524    (set_attr "mode" "HI")])
9525
9526 (define_insn "*iorhi_3"
9527   [(set (reg FLAGS_REG)
9528         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9529                          (match_operand:HI 2 "general_operand" "g"))
9530                  (const_int 0)))
9531    (clobber (match_scratch:HI 0 "=r"))]
9532   "ix86_match_ccmode (insn, CCNOmode)
9533    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9534   "or{w}\t{%2, %0|%0, %2}"
9535   [(set_attr "type" "alu")
9536    (set_attr "mode" "HI")])
9537
9538 (define_expand "iorqi3"
9539   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9540         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9541                 (match_operand:QI 2 "general_operand" "")))
9542    (clobber (reg:CC FLAGS_REG))]
9543   "TARGET_QIMODE_MATH"
9544   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9545
9546 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9547 (define_insn "*iorqi_1"
9548   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9549         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9550                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9551    (clobber (reg:CC FLAGS_REG))]
9552   "ix86_binary_operator_ok (IOR, QImode, operands)"
9553   "@
9554    or{b}\t{%2, %0|%0, %2}
9555    or{b}\t{%2, %0|%0, %2}
9556    or{l}\t{%k2, %k0|%k0, %k2}"
9557   [(set_attr "type" "alu")
9558    (set_attr "mode" "QI,QI,SI")])
9559
9560 (define_insn "*iorqi_1_slp"
9561   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9562         (ior:QI (match_dup 0)
9563                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9564    (clobber (reg:CC FLAGS_REG))]
9565   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9566    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9567   "or{b}\t{%1, %0|%0, %1}"
9568   [(set_attr "type" "alu1")
9569    (set_attr "mode" "QI")])
9570
9571 (define_insn "*iorqi_2"
9572   [(set (reg FLAGS_REG)
9573         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9574                          (match_operand:QI 2 "general_operand" "qim,qi"))
9575                  (const_int 0)))
9576    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9577         (ior:QI (match_dup 1) (match_dup 2)))]
9578   "ix86_match_ccmode (insn, CCNOmode)
9579    && ix86_binary_operator_ok (IOR, QImode, operands)"
9580   "or{b}\t{%2, %0|%0, %2}"
9581   [(set_attr "type" "alu")
9582    (set_attr "mode" "QI")])
9583
9584 (define_insn "*iorqi_2_slp"
9585   [(set (reg FLAGS_REG)
9586         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9587                          (match_operand:QI 1 "general_operand" "qim,qi"))
9588                  (const_int 0)))
9589    (set (strict_low_part (match_dup 0))
9590         (ior:QI (match_dup 0) (match_dup 1)))]
9591   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9592    && ix86_match_ccmode (insn, CCNOmode)
9593    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9594   "or{b}\t{%1, %0|%0, %1}"
9595   [(set_attr "type" "alu1")
9596    (set_attr "mode" "QI")])
9597
9598 (define_insn "*iorqi_3"
9599   [(set (reg FLAGS_REG)
9600         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9601                          (match_operand:QI 2 "general_operand" "qim"))
9602                  (const_int 0)))
9603    (clobber (match_scratch:QI 0 "=q"))]
9604   "ix86_match_ccmode (insn, CCNOmode)
9605    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9606   "or{b}\t{%2, %0|%0, %2}"
9607   [(set_attr "type" "alu")
9608    (set_attr "mode" "QI")])
9609
9610 (define_insn "iorqi_ext_0"
9611   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9612                          (const_int 8)
9613                          (const_int 8))
9614         (ior:SI
9615           (zero_extract:SI
9616             (match_operand 1 "ext_register_operand" "0")
9617             (const_int 8)
9618             (const_int 8))
9619           (match_operand 2 "const_int_operand" "n")))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9622   "or{b}\t{%2, %h0|%h0, %2}"
9623   [(set_attr "type" "alu")
9624    (set_attr "length_immediate" "1")
9625    (set_attr "mode" "QI")])
9626
9627 (define_insn "*iorqi_ext_1"
9628   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9629                          (const_int 8)
9630                          (const_int 8))
9631         (ior:SI
9632           (zero_extract:SI
9633             (match_operand 1 "ext_register_operand" "0")
9634             (const_int 8)
9635             (const_int 8))
9636           (zero_extend:SI
9637             (match_operand:QI 2 "general_operand" "Qm"))))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "!TARGET_64BIT
9640    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9641   "or{b}\t{%2, %h0|%h0, %2}"
9642   [(set_attr "type" "alu")
9643    (set_attr "length_immediate" "0")
9644    (set_attr "mode" "QI")])
9645
9646 (define_insn "*iorqi_ext_1_rex64"
9647   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9648                          (const_int 8)
9649                          (const_int 8))
9650         (ior:SI
9651           (zero_extract:SI
9652             (match_operand 1 "ext_register_operand" "0")
9653             (const_int 8)
9654             (const_int 8))
9655           (zero_extend:SI
9656             (match_operand 2 "ext_register_operand" "Q"))))
9657    (clobber (reg:CC FLAGS_REG))]
9658   "TARGET_64BIT
9659    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9660   "or{b}\t{%2, %h0|%h0, %2}"
9661   [(set_attr "type" "alu")
9662    (set_attr "length_immediate" "0")
9663    (set_attr "mode" "QI")])
9664
9665 (define_insn "*iorqi_ext_2"
9666   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9667                          (const_int 8)
9668                          (const_int 8))
9669         (ior:SI
9670           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9671                            (const_int 8)
9672                            (const_int 8))
9673           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9674                            (const_int 8)
9675                            (const_int 8))))
9676    (clobber (reg:CC FLAGS_REG))]
9677   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9678   "ior{b}\t{%h2, %h0|%h0, %h2}"
9679   [(set_attr "type" "alu")
9680    (set_attr "length_immediate" "0")
9681    (set_attr "mode" "QI")])
9682
9683 (define_split
9684   [(set (match_operand 0 "register_operand" "")
9685         (ior (match_operand 1 "register_operand" "")
9686              (match_operand 2 "const_int_operand" "")))
9687    (clobber (reg:CC FLAGS_REG))]
9688    "reload_completed
9689     && QI_REG_P (operands[0])
9690     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9691     && !(INTVAL (operands[2]) & ~(255 << 8))
9692     && GET_MODE (operands[0]) != QImode"
9693   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9694                    (ior:SI (zero_extract:SI (match_dup 1)
9695                                             (const_int 8) (const_int 8))
9696                            (match_dup 2)))
9697               (clobber (reg:CC FLAGS_REG))])]
9698   "operands[0] = gen_lowpart (SImode, operands[0]);
9699    operands[1] = gen_lowpart (SImode, operands[1]);
9700    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9701
9702 ;; Since OR can be encoded with sign extended immediate, this is only
9703 ;; profitable when 7th bit is set.
9704 (define_split
9705   [(set (match_operand 0 "register_operand" "")
9706         (ior (match_operand 1 "general_operand" "")
9707              (match_operand 2 "const_int_operand" "")))
9708    (clobber (reg:CC FLAGS_REG))]
9709    "reload_completed
9710     && ANY_QI_REG_P (operands[0])
9711     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9712     && !(INTVAL (operands[2]) & ~255)
9713     && (INTVAL (operands[2]) & 128)
9714     && GET_MODE (operands[0]) != QImode"
9715   [(parallel [(set (strict_low_part (match_dup 0))
9716                    (ior:QI (match_dup 1)
9717                            (match_dup 2)))
9718               (clobber (reg:CC FLAGS_REG))])]
9719   "operands[0] = gen_lowpart (QImode, operands[0]);
9720    operands[1] = gen_lowpart (QImode, operands[1]);
9721    operands[2] = gen_lowpart (QImode, operands[2]);")
9722 \f
9723 ;; Logical XOR instructions
9724
9725 ;; %%% This used to optimize known byte-wide and operations to memory.
9726 ;; If this is considered useful, it should be done with splitters.
9727
9728 (define_expand "xordi3"
9729   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9730         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9731                 (match_operand:DI 2 "x86_64_general_operand" "")))
9732    (clobber (reg:CC FLAGS_REG))]
9733   "TARGET_64BIT"
9734   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9735
9736 (define_insn "*xordi_1_rex64"
9737   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9738         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9739                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9740    (clobber (reg:CC FLAGS_REG))]
9741   "TARGET_64BIT
9742    && ix86_binary_operator_ok (XOR, DImode, operands)"
9743   "xor{q}\t{%2, %0|%0, %2}"
9744   [(set_attr "type" "alu")
9745    (set_attr "mode" "DI")])
9746
9747 (define_insn "*xordi_2_rex64"
9748   [(set (reg FLAGS_REG)
9749         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9750                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9751                  (const_int 0)))
9752    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9753         (xor:DI (match_dup 1) (match_dup 2)))]
9754   "TARGET_64BIT
9755    && ix86_match_ccmode (insn, CCNOmode)
9756    && ix86_binary_operator_ok (XOR, DImode, operands)"
9757   "xor{q}\t{%2, %0|%0, %2}"
9758   [(set_attr "type" "alu")
9759    (set_attr "mode" "DI")])
9760
9761 (define_insn "*xordi_3_rex64"
9762   [(set (reg FLAGS_REG)
9763         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9764                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9765                  (const_int 0)))
9766    (clobber (match_scratch:DI 0 "=r"))]
9767   "TARGET_64BIT
9768    && ix86_match_ccmode (insn, CCNOmode)
9769    && ix86_binary_operator_ok (XOR, DImode, operands)"
9770   "xor{q}\t{%2, %0|%0, %2}"
9771   [(set_attr "type" "alu")
9772    (set_attr "mode" "DI")])
9773
9774 (define_expand "xorsi3"
9775   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9776         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9777                 (match_operand:SI 2 "general_operand" "")))
9778    (clobber (reg:CC FLAGS_REG))]
9779   ""
9780   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9781
9782 (define_insn "*xorsi_1"
9783   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9784         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9785                 (match_operand:SI 2 "general_operand" "ri,rm")))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "ix86_binary_operator_ok (XOR, SImode, operands)"
9788   "xor{l}\t{%2, %0|%0, %2}"
9789   [(set_attr "type" "alu")
9790    (set_attr "mode" "SI")])
9791
9792 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9793 ;; Add speccase for immediates
9794 (define_insn "*xorsi_1_zext"
9795   [(set (match_operand:DI 0 "register_operand" "=r")
9796         (zero_extend:DI
9797           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9798                   (match_operand:SI 2 "general_operand" "g"))))
9799    (clobber (reg:CC FLAGS_REG))]
9800   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9801   "xor{l}\t{%2, %k0|%k0, %2}"
9802   [(set_attr "type" "alu")
9803    (set_attr "mode" "SI")])
9804
9805 (define_insn "*xorsi_1_zext_imm"
9806   [(set (match_operand:DI 0 "register_operand" "=r")
9807         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9808                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9809    (clobber (reg:CC FLAGS_REG))]
9810   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9811   "xor{l}\t{%2, %k0|%k0, %2}"
9812   [(set_attr "type" "alu")
9813    (set_attr "mode" "SI")])
9814
9815 (define_insn "*xorsi_2"
9816   [(set (reg FLAGS_REG)
9817         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9818                          (match_operand:SI 2 "general_operand" "g,ri"))
9819                  (const_int 0)))
9820    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9821         (xor:SI (match_dup 1) (match_dup 2)))]
9822   "ix86_match_ccmode (insn, CCNOmode)
9823    && ix86_binary_operator_ok (XOR, SImode, operands)"
9824   "xor{l}\t{%2, %0|%0, %2}"
9825   [(set_attr "type" "alu")
9826    (set_attr "mode" "SI")])
9827
9828 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9829 ;; ??? Special case for immediate operand is missing - it is tricky.
9830 (define_insn "*xorsi_2_zext"
9831   [(set (reg FLAGS_REG)
9832         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9833                          (match_operand:SI 2 "general_operand" "g"))
9834                  (const_int 0)))
9835    (set (match_operand:DI 0 "register_operand" "=r")
9836         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9837   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9838    && ix86_binary_operator_ok (XOR, SImode, operands)"
9839   "xor{l}\t{%2, %k0|%k0, %2}"
9840   [(set_attr "type" "alu")
9841    (set_attr "mode" "SI")])
9842
9843 (define_insn "*xorsi_2_zext_imm"
9844   [(set (reg FLAGS_REG)
9845         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9846                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9847                  (const_int 0)))
9848    (set (match_operand:DI 0 "register_operand" "=r")
9849         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9850   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9851    && ix86_binary_operator_ok (XOR, SImode, operands)"
9852   "xor{l}\t{%2, %k0|%k0, %2}"
9853   [(set_attr "type" "alu")
9854    (set_attr "mode" "SI")])
9855
9856 (define_insn "*xorsi_3"
9857   [(set (reg FLAGS_REG)
9858         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9859                          (match_operand:SI 2 "general_operand" "g"))
9860                  (const_int 0)))
9861    (clobber (match_scratch:SI 0 "=r"))]
9862   "ix86_match_ccmode (insn, CCNOmode)
9863    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9864   "xor{l}\t{%2, %0|%0, %2}"
9865   [(set_attr "type" "alu")
9866    (set_attr "mode" "SI")])
9867
9868 (define_expand "xorhi3"
9869   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9870         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9871                 (match_operand:HI 2 "general_operand" "")))
9872    (clobber (reg:CC FLAGS_REG))]
9873   "TARGET_HIMODE_MATH"
9874   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9875
9876 (define_insn "*xorhi_1"
9877   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9878         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9879                 (match_operand:HI 2 "general_operand" "g,ri")))
9880    (clobber (reg:CC FLAGS_REG))]
9881   "ix86_binary_operator_ok (XOR, HImode, operands)"
9882   "xor{w}\t{%2, %0|%0, %2}"
9883   [(set_attr "type" "alu")
9884    (set_attr "mode" "HI")])
9885
9886 (define_insn "*xorhi_2"
9887   [(set (reg FLAGS_REG)
9888         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9889                          (match_operand:HI 2 "general_operand" "g,ri"))
9890                  (const_int 0)))
9891    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9892         (xor:HI (match_dup 1) (match_dup 2)))]
9893   "ix86_match_ccmode (insn, CCNOmode)
9894    && ix86_binary_operator_ok (XOR, HImode, operands)"
9895   "xor{w}\t{%2, %0|%0, %2}"
9896   [(set_attr "type" "alu")
9897    (set_attr "mode" "HI")])
9898
9899 (define_insn "*xorhi_3"
9900   [(set (reg FLAGS_REG)
9901         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9902                          (match_operand:HI 2 "general_operand" "g"))
9903                  (const_int 0)))
9904    (clobber (match_scratch:HI 0 "=r"))]
9905   "ix86_match_ccmode (insn, CCNOmode)
9906    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9907   "xor{w}\t{%2, %0|%0, %2}"
9908   [(set_attr "type" "alu")
9909    (set_attr "mode" "HI")])
9910
9911 (define_expand "xorqi3"
9912   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9913         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9914                 (match_operand:QI 2 "general_operand" "")))
9915    (clobber (reg:CC FLAGS_REG))]
9916   "TARGET_QIMODE_MATH"
9917   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9918
9919 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9920 (define_insn "*xorqi_1"
9921   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9922         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9923                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9924    (clobber (reg:CC FLAGS_REG))]
9925   "ix86_binary_operator_ok (XOR, QImode, operands)"
9926   "@
9927    xor{b}\t{%2, %0|%0, %2}
9928    xor{b}\t{%2, %0|%0, %2}
9929    xor{l}\t{%k2, %k0|%k0, %k2}"
9930   [(set_attr "type" "alu")
9931    (set_attr "mode" "QI,QI,SI")])
9932
9933 (define_insn "*xorqi_1_slp"
9934   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9935         (xor:QI (match_dup 0)
9936                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9937    (clobber (reg:CC FLAGS_REG))]
9938   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9939    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9940   "xor{b}\t{%1, %0|%0, %1}"
9941   [(set_attr "type" "alu1")
9942    (set_attr "mode" "QI")])
9943
9944 (define_insn "xorqi_ext_0"
9945   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9946                          (const_int 8)
9947                          (const_int 8))
9948         (xor:SI
9949           (zero_extract:SI
9950             (match_operand 1 "ext_register_operand" "0")
9951             (const_int 8)
9952             (const_int 8))
9953           (match_operand 2 "const_int_operand" "n")))
9954    (clobber (reg:CC FLAGS_REG))]
9955   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9956   "xor{b}\t{%2, %h0|%h0, %2}"
9957   [(set_attr "type" "alu")
9958    (set_attr "length_immediate" "1")
9959    (set_attr "mode" "QI")])
9960
9961 (define_insn "*xorqi_ext_1"
9962   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9963                          (const_int 8)
9964                          (const_int 8))
9965         (xor:SI
9966           (zero_extract:SI
9967             (match_operand 1 "ext_register_operand" "0")
9968             (const_int 8)
9969             (const_int 8))
9970           (zero_extend:SI
9971             (match_operand:QI 2 "general_operand" "Qm"))))
9972    (clobber (reg:CC FLAGS_REG))]
9973   "!TARGET_64BIT
9974    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9975   "xor{b}\t{%2, %h0|%h0, %2}"
9976   [(set_attr "type" "alu")
9977    (set_attr "length_immediate" "0")
9978    (set_attr "mode" "QI")])
9979
9980 (define_insn "*xorqi_ext_1_rex64"
9981   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9982                          (const_int 8)
9983                          (const_int 8))
9984         (xor:SI
9985           (zero_extract:SI
9986             (match_operand 1 "ext_register_operand" "0")
9987             (const_int 8)
9988             (const_int 8))
9989           (zero_extend:SI
9990             (match_operand 2 "ext_register_operand" "Q"))))
9991    (clobber (reg:CC FLAGS_REG))]
9992   "TARGET_64BIT
9993    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9994   "xor{b}\t{%2, %h0|%h0, %2}"
9995   [(set_attr "type" "alu")
9996    (set_attr "length_immediate" "0")
9997    (set_attr "mode" "QI")])
9998
9999 (define_insn "*xorqi_ext_2"
10000   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10001                          (const_int 8)
10002                          (const_int 8))
10003         (xor:SI
10004           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10005                            (const_int 8)
10006                            (const_int 8))
10007           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10008                            (const_int 8)
10009                            (const_int 8))))
10010    (clobber (reg:CC FLAGS_REG))]
10011   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10012   "xor{b}\t{%h2, %h0|%h0, %h2}"
10013   [(set_attr "type" "alu")
10014    (set_attr "length_immediate" "0")
10015    (set_attr "mode" "QI")])
10016
10017 (define_insn "*xorqi_cc_1"
10018   [(set (reg FLAGS_REG)
10019         (compare
10020           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10021                   (match_operand:QI 2 "general_operand" "qim,qi"))
10022           (const_int 0)))
10023    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10024         (xor:QI (match_dup 1) (match_dup 2)))]
10025   "ix86_match_ccmode (insn, CCNOmode)
10026    && ix86_binary_operator_ok (XOR, QImode, operands)"
10027   "xor{b}\t{%2, %0|%0, %2}"
10028   [(set_attr "type" "alu")
10029    (set_attr "mode" "QI")])
10030
10031 (define_insn "*xorqi_2_slp"
10032   [(set (reg FLAGS_REG)
10033         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10034                          (match_operand:QI 1 "general_operand" "qim,qi"))
10035                  (const_int 0)))
10036    (set (strict_low_part (match_dup 0))
10037         (xor:QI (match_dup 0) (match_dup 1)))]
10038   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10039    && ix86_match_ccmode (insn, CCNOmode)
10040    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10041   "xor{b}\t{%1, %0|%0, %1}"
10042   [(set_attr "type" "alu1")
10043    (set_attr "mode" "QI")])
10044
10045 (define_insn "*xorqi_cc_2"
10046   [(set (reg FLAGS_REG)
10047         (compare
10048           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10049                   (match_operand:QI 2 "general_operand" "qim"))
10050           (const_int 0)))
10051    (clobber (match_scratch:QI 0 "=q"))]
10052   "ix86_match_ccmode (insn, CCNOmode)
10053    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10054   "xor{b}\t{%2, %0|%0, %2}"
10055   [(set_attr "type" "alu")
10056    (set_attr "mode" "QI")])
10057
10058 (define_insn "*xorqi_cc_ext_1"
10059   [(set (reg FLAGS_REG)
10060         (compare
10061           (xor:SI
10062             (zero_extract:SI
10063               (match_operand 1 "ext_register_operand" "0")
10064               (const_int 8)
10065               (const_int 8))
10066             (match_operand:QI 2 "general_operand" "qmn"))
10067           (const_int 0)))
10068    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10069                          (const_int 8)
10070                          (const_int 8))
10071         (xor:SI
10072           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10073           (match_dup 2)))]
10074   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10075   "xor{b}\t{%2, %h0|%h0, %2}"
10076   [(set_attr "type" "alu")
10077    (set_attr "mode" "QI")])
10078
10079 (define_insn "*xorqi_cc_ext_1_rex64"
10080   [(set (reg FLAGS_REG)
10081         (compare
10082           (xor:SI
10083             (zero_extract:SI
10084               (match_operand 1 "ext_register_operand" "0")
10085               (const_int 8)
10086               (const_int 8))
10087             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10088           (const_int 0)))
10089    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10090                          (const_int 8)
10091                          (const_int 8))
10092         (xor:SI
10093           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10094           (match_dup 2)))]
10095   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10096   "xor{b}\t{%2, %h0|%h0, %2}"
10097   [(set_attr "type" "alu")
10098    (set_attr "mode" "QI")])
10099
10100 (define_expand "xorqi_cc_ext_1"
10101   [(parallel [
10102      (set (reg:CCNO FLAGS_REG)
10103           (compare:CCNO
10104             (xor:SI
10105               (zero_extract:SI
10106                 (match_operand 1 "ext_register_operand" "")
10107                 (const_int 8)
10108                 (const_int 8))
10109               (match_operand:QI 2 "general_operand" ""))
10110             (const_int 0)))
10111      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10112                            (const_int 8)
10113                            (const_int 8))
10114           (xor:SI
10115             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10116             (match_dup 2)))])]
10117   ""
10118   "")
10119
10120 (define_split
10121   [(set (match_operand 0 "register_operand" "")
10122         (xor (match_operand 1 "register_operand" "")
10123              (match_operand 2 "const_int_operand" "")))
10124    (clobber (reg:CC FLAGS_REG))]
10125    "reload_completed
10126     && QI_REG_P (operands[0])
10127     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10128     && !(INTVAL (operands[2]) & ~(255 << 8))
10129     && GET_MODE (operands[0]) != QImode"
10130   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10131                    (xor:SI (zero_extract:SI (match_dup 1)
10132                                             (const_int 8) (const_int 8))
10133                            (match_dup 2)))
10134               (clobber (reg:CC FLAGS_REG))])]
10135   "operands[0] = gen_lowpart (SImode, operands[0]);
10136    operands[1] = gen_lowpart (SImode, operands[1]);
10137    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10138
10139 ;; Since XOR can be encoded with sign extended immediate, this is only
10140 ;; profitable when 7th bit is set.
10141 (define_split
10142   [(set (match_operand 0 "register_operand" "")
10143         (xor (match_operand 1 "general_operand" "")
10144              (match_operand 2 "const_int_operand" "")))
10145    (clobber (reg:CC FLAGS_REG))]
10146    "reload_completed
10147     && ANY_QI_REG_P (operands[0])
10148     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10149     && !(INTVAL (operands[2]) & ~255)
10150     && (INTVAL (operands[2]) & 128)
10151     && GET_MODE (operands[0]) != QImode"
10152   [(parallel [(set (strict_low_part (match_dup 0))
10153                    (xor:QI (match_dup 1)
10154                            (match_dup 2)))
10155               (clobber (reg:CC FLAGS_REG))])]
10156   "operands[0] = gen_lowpart (QImode, operands[0]);
10157    operands[1] = gen_lowpart (QImode, operands[1]);
10158    operands[2] = gen_lowpart (QImode, operands[2]);")
10159 \f
10160 ;; Negation instructions
10161
10162 (define_expand "negti2"
10163   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10164                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10165               (clobber (reg:CC FLAGS_REG))])]
10166   "TARGET_64BIT"
10167   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10168
10169 (define_insn "*negti2_1"
10170   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10171         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10172    (clobber (reg:CC FLAGS_REG))]
10173   "TARGET_64BIT
10174    && ix86_unary_operator_ok (NEG, TImode, operands)"
10175   "#")
10176
10177 (define_split
10178   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10179         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10180    (clobber (reg:CC FLAGS_REG))]
10181   "TARGET_64BIT && reload_completed"
10182   [(parallel
10183     [(set (reg:CCZ FLAGS_REG)
10184           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10185      (set (match_dup 0) (neg:DI (match_dup 1)))])
10186    (parallel
10187     [(set (match_dup 2)
10188           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10189                             (match_dup 3))
10190                    (const_int 0)))
10191      (clobber (reg:CC FLAGS_REG))])
10192    (parallel
10193     [(set (match_dup 2)
10194           (neg:DI (match_dup 2)))
10195      (clobber (reg:CC FLAGS_REG))])]
10196   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10197
10198 (define_expand "negdi2"
10199   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10200                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10201               (clobber (reg:CC FLAGS_REG))])]
10202   ""
10203   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10204
10205 (define_insn "*negdi2_1"
10206   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10207         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10208    (clobber (reg:CC FLAGS_REG))]
10209   "!TARGET_64BIT
10210    && ix86_unary_operator_ok (NEG, DImode, operands)"
10211   "#")
10212
10213 (define_split
10214   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10215         (neg:DI (match_operand:DI 1 "general_operand" "")))
10216    (clobber (reg:CC FLAGS_REG))]
10217   "!TARGET_64BIT && reload_completed"
10218   [(parallel
10219     [(set (reg:CCZ FLAGS_REG)
10220           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10221      (set (match_dup 0) (neg:SI (match_dup 1)))])
10222    (parallel
10223     [(set (match_dup 2)
10224           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10225                             (match_dup 3))
10226                    (const_int 0)))
10227      (clobber (reg:CC FLAGS_REG))])
10228    (parallel
10229     [(set (match_dup 2)
10230           (neg:SI (match_dup 2)))
10231      (clobber (reg:CC FLAGS_REG))])]
10232   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10233
10234 (define_insn "*negdi2_1_rex64"
10235   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10236         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10237    (clobber (reg:CC FLAGS_REG))]
10238   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10239   "neg{q}\t%0"
10240   [(set_attr "type" "negnot")
10241    (set_attr "mode" "DI")])
10242
10243 ;; The problem with neg is that it does not perform (compare x 0),
10244 ;; it really performs (compare 0 x), which leaves us with the zero
10245 ;; flag being the only useful item.
10246
10247 (define_insn "*negdi2_cmpz_rex64"
10248   [(set (reg:CCZ FLAGS_REG)
10249         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10250                      (const_int 0)))
10251    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10252         (neg:DI (match_dup 1)))]
10253   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10254   "neg{q}\t%0"
10255   [(set_attr "type" "negnot")
10256    (set_attr "mode" "DI")])
10257
10258
10259 (define_expand "negsi2"
10260   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10261                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10262               (clobber (reg:CC FLAGS_REG))])]
10263   ""
10264   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10265
10266 (define_insn "*negsi2_1"
10267   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10268         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10269    (clobber (reg:CC FLAGS_REG))]
10270   "ix86_unary_operator_ok (NEG, SImode, operands)"
10271   "neg{l}\t%0"
10272   [(set_attr "type" "negnot")
10273    (set_attr "mode" "SI")])
10274
10275 ;; Combine is quite creative about this pattern.
10276 (define_insn "*negsi2_1_zext"
10277   [(set (match_operand:DI 0 "register_operand" "=r")
10278         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10279                                         (const_int 32)))
10280                      (const_int 32)))
10281    (clobber (reg:CC FLAGS_REG))]
10282   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10283   "neg{l}\t%k0"
10284   [(set_attr "type" "negnot")
10285    (set_attr "mode" "SI")])
10286
10287 ;; The problem with neg is that it does not perform (compare x 0),
10288 ;; it really performs (compare 0 x), which leaves us with the zero
10289 ;; flag being the only useful item.
10290
10291 (define_insn "*negsi2_cmpz"
10292   [(set (reg:CCZ FLAGS_REG)
10293         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10294                      (const_int 0)))
10295    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10296         (neg:SI (match_dup 1)))]
10297   "ix86_unary_operator_ok (NEG, SImode, operands)"
10298   "neg{l}\t%0"
10299   [(set_attr "type" "negnot")
10300    (set_attr "mode" "SI")])
10301
10302 (define_insn "*negsi2_cmpz_zext"
10303   [(set (reg:CCZ FLAGS_REG)
10304         (compare:CCZ (lshiftrt:DI
10305                        (neg:DI (ashift:DI
10306                                  (match_operand:DI 1 "register_operand" "0")
10307                                  (const_int 32)))
10308                        (const_int 32))
10309                      (const_int 0)))
10310    (set (match_operand:DI 0 "register_operand" "=r")
10311         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10312                                         (const_int 32)))
10313                      (const_int 32)))]
10314   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10315   "neg{l}\t%k0"
10316   [(set_attr "type" "negnot")
10317    (set_attr "mode" "SI")])
10318
10319 (define_expand "neghi2"
10320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10321                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10322               (clobber (reg:CC FLAGS_REG))])]
10323   "TARGET_HIMODE_MATH"
10324   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10325
10326 (define_insn "*neghi2_1"
10327   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10328         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10329    (clobber (reg:CC FLAGS_REG))]
10330   "ix86_unary_operator_ok (NEG, HImode, operands)"
10331   "neg{w}\t%0"
10332   [(set_attr "type" "negnot")
10333    (set_attr "mode" "HI")])
10334
10335 (define_insn "*neghi2_cmpz"
10336   [(set (reg:CCZ FLAGS_REG)
10337         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10338                      (const_int 0)))
10339    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10340         (neg:HI (match_dup 1)))]
10341   "ix86_unary_operator_ok (NEG, HImode, operands)"
10342   "neg{w}\t%0"
10343   [(set_attr "type" "negnot")
10344    (set_attr "mode" "HI")])
10345
10346 (define_expand "negqi2"
10347   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10348                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10349               (clobber (reg:CC FLAGS_REG))])]
10350   "TARGET_QIMODE_MATH"
10351   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10352
10353 (define_insn "*negqi2_1"
10354   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10355         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10356    (clobber (reg:CC FLAGS_REG))]
10357   "ix86_unary_operator_ok (NEG, QImode, operands)"
10358   "neg{b}\t%0"
10359   [(set_attr "type" "negnot")
10360    (set_attr "mode" "QI")])
10361
10362 (define_insn "*negqi2_cmpz"
10363   [(set (reg:CCZ FLAGS_REG)
10364         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10365                      (const_int 0)))
10366    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10367         (neg:QI (match_dup 1)))]
10368   "ix86_unary_operator_ok (NEG, QImode, operands)"
10369   "neg{b}\t%0"
10370   [(set_attr "type" "negnot")
10371    (set_attr "mode" "QI")])
10372
10373 ;; Changing of sign for FP values is doable using integer unit too.
10374
10375 (define_expand "<code><mode>2"
10376   [(set (match_operand:X87MODEF 0 "register_operand" "")
10377         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10378   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10379   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10380
10381 (define_insn "*absneg<mode>2_mixed"
10382   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10383         (match_operator:MODEF 3 "absneg_operator"
10384           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10385    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10386    (clobber (reg:CC FLAGS_REG))]
10387   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10388   "#")
10389
10390 (define_insn "*absneg<mode>2_sse"
10391   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10392         (match_operator:MODEF 3 "absneg_operator"
10393           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10394    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10395    (clobber (reg:CC FLAGS_REG))]
10396   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10397   "#")
10398
10399 (define_insn "*absneg<mode>2_i387"
10400   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10401         (match_operator:X87MODEF 3 "absneg_operator"
10402           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10403    (use (match_operand 2 "" ""))
10404    (clobber (reg:CC FLAGS_REG))]
10405   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10406   "#")
10407
10408 (define_expand "<code>tf2"
10409   [(set (match_operand:TF 0 "register_operand" "")
10410         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10411   "TARGET_64BIT"
10412   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10413
10414 (define_insn "*absnegtf2_sse"
10415   [(set (match_operand:TF 0 "register_operand" "=x,x")
10416         (match_operator:TF 3 "absneg_operator"
10417           [(match_operand:TF 1 "register_operand" "0,x")]))
10418    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "TARGET_64BIT"
10421   "#")
10422
10423 ;; Splitters for fp abs and neg.
10424
10425 (define_split
10426   [(set (match_operand 0 "fp_register_operand" "")
10427         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10428    (use (match_operand 2 "" ""))
10429    (clobber (reg:CC FLAGS_REG))]
10430   "reload_completed"
10431   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10432
10433 (define_split
10434   [(set (match_operand 0 "register_operand" "")
10435         (match_operator 3 "absneg_operator"
10436           [(match_operand 1 "register_operand" "")]))
10437    (use (match_operand 2 "nonimmediate_operand" ""))
10438    (clobber (reg:CC FLAGS_REG))]
10439   "reload_completed && SSE_REG_P (operands[0])"
10440   [(set (match_dup 0) (match_dup 3))]
10441 {
10442   enum machine_mode mode = GET_MODE (operands[0]);
10443   enum machine_mode vmode = GET_MODE (operands[2]);
10444   rtx tmp;
10445
10446   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10447   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10448   if (operands_match_p (operands[0], operands[2]))
10449     {
10450       tmp = operands[1];
10451       operands[1] = operands[2];
10452       operands[2] = tmp;
10453     }
10454   if (GET_CODE (operands[3]) == ABS)
10455     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10456   else
10457     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10458   operands[3] = tmp;
10459 })
10460
10461 (define_split
10462   [(set (match_operand:SF 0 "register_operand" "")
10463         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10464    (use (match_operand:V4SF 2 "" ""))
10465    (clobber (reg:CC FLAGS_REG))]
10466   "reload_completed"
10467   [(parallel [(set (match_dup 0) (match_dup 1))
10468               (clobber (reg:CC FLAGS_REG))])]
10469 {
10470   rtx tmp;
10471   operands[0] = gen_lowpart (SImode, operands[0]);
10472   if (GET_CODE (operands[1]) == ABS)
10473     {
10474       tmp = gen_int_mode (0x7fffffff, SImode);
10475       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10476     }
10477   else
10478     {
10479       tmp = gen_int_mode (0x80000000, SImode);
10480       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10481     }
10482   operands[1] = tmp;
10483 })
10484
10485 (define_split
10486   [(set (match_operand:DF 0 "register_operand" "")
10487         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10488    (use (match_operand 2 "" ""))
10489    (clobber (reg:CC FLAGS_REG))]
10490   "reload_completed"
10491   [(parallel [(set (match_dup 0) (match_dup 1))
10492               (clobber (reg:CC FLAGS_REG))])]
10493 {
10494   rtx tmp;
10495   if (TARGET_64BIT)
10496     {
10497       tmp = gen_lowpart (DImode, operands[0]);
10498       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10499       operands[0] = tmp;
10500
10501       if (GET_CODE (operands[1]) == ABS)
10502         tmp = const0_rtx;
10503       else
10504         tmp = gen_rtx_NOT (DImode, tmp);
10505     }
10506   else
10507     {
10508       operands[0] = gen_highpart (SImode, operands[0]);
10509       if (GET_CODE (operands[1]) == ABS)
10510         {
10511           tmp = gen_int_mode (0x7fffffff, SImode);
10512           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10513         }
10514       else
10515         {
10516           tmp = gen_int_mode (0x80000000, SImode);
10517           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10518         }
10519     }
10520   operands[1] = tmp;
10521 })
10522
10523 (define_split
10524   [(set (match_operand:XF 0 "register_operand" "")
10525         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10526    (use (match_operand 2 "" ""))
10527    (clobber (reg:CC FLAGS_REG))]
10528   "reload_completed"
10529   [(parallel [(set (match_dup 0) (match_dup 1))
10530               (clobber (reg:CC FLAGS_REG))])]
10531 {
10532   rtx tmp;
10533   operands[0] = gen_rtx_REG (SImode,
10534                              true_regnum (operands[0])
10535                              + (TARGET_64BIT ? 1 : 2));
10536   if (GET_CODE (operands[1]) == ABS)
10537     {
10538       tmp = GEN_INT (0x7fff);
10539       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10540     }
10541   else
10542     {
10543       tmp = GEN_INT (0x8000);
10544       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10545     }
10546   operands[1] = tmp;
10547 })
10548
10549 ;; Conditionalize these after reload. If they match before reload, we
10550 ;; lose the clobber and ability to use integer instructions.
10551
10552 (define_insn "*<code><mode>2_1"
10553   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10554         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10555   "TARGET_80387
10556    && (reload_completed
10557        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10558   "f<absnegprefix>"
10559   [(set_attr "type" "fsgn")
10560    (set_attr "mode" "<MODE>")])
10561
10562 (define_insn "*<code>extendsfdf2"
10563   [(set (match_operand:DF 0 "register_operand" "=f")
10564         (absneg:DF (float_extend:DF
10565                      (match_operand:SF 1 "register_operand" "0"))))]
10566   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10567   "f<absnegprefix>"
10568   [(set_attr "type" "fsgn")
10569    (set_attr "mode" "DF")])
10570
10571 (define_insn "*<code>extendsfxf2"
10572   [(set (match_operand:XF 0 "register_operand" "=f")
10573         (absneg:XF (float_extend:XF
10574                      (match_operand:SF 1 "register_operand" "0"))))]
10575   "TARGET_80387"
10576   "f<absnegprefix>"
10577   [(set_attr "type" "fsgn")
10578    (set_attr "mode" "XF")])
10579
10580 (define_insn "*<code>extenddfxf2"
10581   [(set (match_operand:XF 0 "register_operand" "=f")
10582         (absneg:XF (float_extend:XF
10583                       (match_operand:DF 1 "register_operand" "0"))))]
10584   "TARGET_80387"
10585   "f<absnegprefix>"
10586   [(set_attr "type" "fsgn")
10587    (set_attr "mode" "XF")])
10588
10589 ;; Copysign instructions
10590
10591 (define_mode_iterator CSGNMODE [SF DF TF])
10592 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10593
10594 (define_expand "copysign<mode>3"
10595   [(match_operand:CSGNMODE 0 "register_operand" "")
10596    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10597    (match_operand:CSGNMODE 2 "register_operand" "")]
10598   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10599    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10600 {
10601   ix86_expand_copysign (operands);
10602   DONE;
10603 })
10604
10605 (define_insn_and_split "copysign<mode>3_const"
10606   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10607         (unspec:CSGNMODE
10608           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10609            (match_operand:CSGNMODE 2 "register_operand" "0")
10610            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10611           UNSPEC_COPYSIGN))]
10612   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10613    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10614   "#"
10615   "&& reload_completed"
10616   [(const_int 0)]
10617 {
10618   ix86_split_copysign_const (operands);
10619   DONE;
10620 })
10621
10622 (define_insn "copysign<mode>3_var"
10623   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10624         (unspec:CSGNMODE
10625           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10626            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10627            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10628            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10629           UNSPEC_COPYSIGN))
10630    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10631   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10632    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10633   "#")
10634
10635 (define_split
10636   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10637         (unspec:CSGNMODE
10638           [(match_operand:CSGNMODE 2 "register_operand" "")
10639            (match_operand:CSGNMODE 3 "register_operand" "")
10640            (match_operand:<CSGNVMODE> 4 "" "")
10641            (match_operand:<CSGNVMODE> 5 "" "")]
10642           UNSPEC_COPYSIGN))
10643    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10644   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10645     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10646    && reload_completed"
10647   [(const_int 0)]
10648 {
10649   ix86_split_copysign_var (operands);
10650   DONE;
10651 })
10652 \f
10653 ;; One complement instructions
10654
10655 (define_expand "one_cmpldi2"
10656   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10657         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10658   "TARGET_64BIT"
10659   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10660
10661 (define_insn "*one_cmpldi2_1_rex64"
10662   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10663         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10664   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10665   "not{q}\t%0"
10666   [(set_attr "type" "negnot")
10667    (set_attr "mode" "DI")])
10668
10669 (define_insn "*one_cmpldi2_2_rex64"
10670   [(set (reg FLAGS_REG)
10671         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10672                  (const_int 0)))
10673    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10674         (not:DI (match_dup 1)))]
10675   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10676    && ix86_unary_operator_ok (NOT, DImode, operands)"
10677   "#"
10678   [(set_attr "type" "alu1")
10679    (set_attr "mode" "DI")])
10680
10681 (define_split
10682   [(set (match_operand 0 "flags_reg_operand" "")
10683         (match_operator 2 "compare_operator"
10684           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10685            (const_int 0)]))
10686    (set (match_operand:DI 1 "nonimmediate_operand" "")
10687         (not:DI (match_dup 3)))]
10688   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10689   [(parallel [(set (match_dup 0)
10690                    (match_op_dup 2
10691                      [(xor:DI (match_dup 3) (const_int -1))
10692                       (const_int 0)]))
10693               (set (match_dup 1)
10694                    (xor:DI (match_dup 3) (const_int -1)))])]
10695   "")
10696
10697 (define_expand "one_cmplsi2"
10698   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10699         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10700   ""
10701   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10702
10703 (define_insn "*one_cmplsi2_1"
10704   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10705         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10706   "ix86_unary_operator_ok (NOT, SImode, operands)"
10707   "not{l}\t%0"
10708   [(set_attr "type" "negnot")
10709    (set_attr "mode" "SI")])
10710
10711 ;; ??? Currently never generated - xor is used instead.
10712 (define_insn "*one_cmplsi2_1_zext"
10713   [(set (match_operand:DI 0 "register_operand" "=r")
10714         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10715   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10716   "not{l}\t%k0"
10717   [(set_attr "type" "negnot")
10718    (set_attr "mode" "SI")])
10719
10720 (define_insn "*one_cmplsi2_2"
10721   [(set (reg FLAGS_REG)
10722         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10723                  (const_int 0)))
10724    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10725         (not:SI (match_dup 1)))]
10726   "ix86_match_ccmode (insn, CCNOmode)
10727    && ix86_unary_operator_ok (NOT, SImode, operands)"
10728   "#"
10729   [(set_attr "type" "alu1")
10730    (set_attr "mode" "SI")])
10731
10732 (define_split
10733   [(set (match_operand 0 "flags_reg_operand" "")
10734         (match_operator 2 "compare_operator"
10735           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10736            (const_int 0)]))
10737    (set (match_operand:SI 1 "nonimmediate_operand" "")
10738         (not:SI (match_dup 3)))]
10739   "ix86_match_ccmode (insn, CCNOmode)"
10740   [(parallel [(set (match_dup 0)
10741                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10742                                     (const_int 0)]))
10743               (set (match_dup 1)
10744                    (xor:SI (match_dup 3) (const_int -1)))])]
10745   "")
10746
10747 ;; ??? Currently never generated - xor is used instead.
10748 (define_insn "*one_cmplsi2_2_zext"
10749   [(set (reg FLAGS_REG)
10750         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10751                  (const_int 0)))
10752    (set (match_operand:DI 0 "register_operand" "=r")
10753         (zero_extend:DI (not:SI (match_dup 1))))]
10754   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10755    && ix86_unary_operator_ok (NOT, SImode, operands)"
10756   "#"
10757   [(set_attr "type" "alu1")
10758    (set_attr "mode" "SI")])
10759
10760 (define_split
10761   [(set (match_operand 0 "flags_reg_operand" "")
10762         (match_operator 2 "compare_operator"
10763           [(not:SI (match_operand:SI 3 "register_operand" ""))
10764            (const_int 0)]))
10765    (set (match_operand:DI 1 "register_operand" "")
10766         (zero_extend:DI (not:SI (match_dup 3))))]
10767   "ix86_match_ccmode (insn, CCNOmode)"
10768   [(parallel [(set (match_dup 0)
10769                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10770                                     (const_int 0)]))
10771               (set (match_dup 1)
10772                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10773   "")
10774
10775 (define_expand "one_cmplhi2"
10776   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10777         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10778   "TARGET_HIMODE_MATH"
10779   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10780
10781 (define_insn "*one_cmplhi2_1"
10782   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10783         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10784   "ix86_unary_operator_ok (NOT, HImode, operands)"
10785   "not{w}\t%0"
10786   [(set_attr "type" "negnot")
10787    (set_attr "mode" "HI")])
10788
10789 (define_insn "*one_cmplhi2_2"
10790   [(set (reg FLAGS_REG)
10791         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10792                  (const_int 0)))
10793    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10794         (not:HI (match_dup 1)))]
10795   "ix86_match_ccmode (insn, CCNOmode)
10796    && ix86_unary_operator_ok (NEG, HImode, operands)"
10797   "#"
10798   [(set_attr "type" "alu1")
10799    (set_attr "mode" "HI")])
10800
10801 (define_split
10802   [(set (match_operand 0 "flags_reg_operand" "")
10803         (match_operator 2 "compare_operator"
10804           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10805            (const_int 0)]))
10806    (set (match_operand:HI 1 "nonimmediate_operand" "")
10807         (not:HI (match_dup 3)))]
10808   "ix86_match_ccmode (insn, CCNOmode)"
10809   [(parallel [(set (match_dup 0)
10810                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10811                                     (const_int 0)]))
10812               (set (match_dup 1)
10813                    (xor:HI (match_dup 3) (const_int -1)))])]
10814   "")
10815
10816 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10817 (define_expand "one_cmplqi2"
10818   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10819         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10820   "TARGET_QIMODE_MATH"
10821   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10822
10823 (define_insn "*one_cmplqi2_1"
10824   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10825         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10826   "ix86_unary_operator_ok (NOT, QImode, operands)"
10827   "@
10828    not{b}\t%0
10829    not{l}\t%k0"
10830   [(set_attr "type" "negnot")
10831    (set_attr "mode" "QI,SI")])
10832
10833 (define_insn "*one_cmplqi2_2"
10834   [(set (reg FLAGS_REG)
10835         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10836                  (const_int 0)))
10837    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10838         (not:QI (match_dup 1)))]
10839   "ix86_match_ccmode (insn, CCNOmode)
10840    && ix86_unary_operator_ok (NOT, QImode, operands)"
10841   "#"
10842   [(set_attr "type" "alu1")
10843    (set_attr "mode" "QI")])
10844
10845 (define_split
10846   [(set (match_operand 0 "flags_reg_operand" "")
10847         (match_operator 2 "compare_operator"
10848           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10849            (const_int 0)]))
10850    (set (match_operand:QI 1 "nonimmediate_operand" "")
10851         (not:QI (match_dup 3)))]
10852   "ix86_match_ccmode (insn, CCNOmode)"
10853   [(parallel [(set (match_dup 0)
10854                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10855                                     (const_int 0)]))
10856               (set (match_dup 1)
10857                    (xor:QI (match_dup 3) (const_int -1)))])]
10858   "")
10859 \f
10860 ;; Arithmetic shift instructions
10861
10862 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10863 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10864 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10865 ;; from the assembler input.
10866 ;;
10867 ;; This instruction shifts the target reg/mem as usual, but instead of
10868 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10869 ;; is a left shift double, bits are taken from the high order bits of
10870 ;; reg, else if the insn is a shift right double, bits are taken from the
10871 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10872 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10873 ;;
10874 ;; Since sh[lr]d does not change the `reg' operand, that is done
10875 ;; separately, making all shifts emit pairs of shift double and normal
10876 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10877 ;; support a 63 bit shift, each shift where the count is in a reg expands
10878 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10879 ;;
10880 ;; If the shift count is a constant, we need never emit more than one
10881 ;; shift pair, instead using moves and sign extension for counts greater
10882 ;; than 31.
10883
10884 (define_expand "ashlti3"
10885   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10886                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10887                               (match_operand:QI 2 "nonmemory_operand" "")))
10888               (clobber (reg:CC FLAGS_REG))])]
10889   "TARGET_64BIT"
10890 {
10891   if (! immediate_operand (operands[2], QImode))
10892     {
10893       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10894       DONE;
10895     }
10896   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10897   DONE;
10898 })
10899
10900 (define_insn "ashlti3_1"
10901   [(set (match_operand:TI 0 "register_operand" "=r")
10902         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10903                    (match_operand:QI 2 "register_operand" "c")))
10904    (clobber (match_scratch:DI 3 "=&r"))
10905    (clobber (reg:CC FLAGS_REG))]
10906   "TARGET_64BIT"
10907   "#"
10908   [(set_attr "type" "multi")])
10909
10910 ;; This pattern must be defined before *ashlti3_2 to prevent
10911 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10912
10913 (define_insn "sse2_ashlti3"
10914   [(set (match_operand:TI 0 "register_operand" "=x")
10915         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10916                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10917   "TARGET_SSE2"
10918 {
10919   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10920   return "pslldq\t{%2, %0|%0, %2}";
10921 }
10922   [(set_attr "type" "sseishft")
10923    (set_attr "prefix_data16" "1")
10924    (set_attr "mode" "TI")])
10925
10926 (define_insn "*ashlti3_2"
10927   [(set (match_operand:TI 0 "register_operand" "=r")
10928         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10929                    (match_operand:QI 2 "immediate_operand" "O")))
10930    (clobber (reg:CC FLAGS_REG))]
10931   "TARGET_64BIT"
10932   "#"
10933   [(set_attr "type" "multi")])
10934
10935 (define_split
10936   [(set (match_operand:TI 0 "register_operand" "")
10937         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10938                    (match_operand:QI 2 "register_operand" "")))
10939    (clobber (match_scratch:DI 3 ""))
10940    (clobber (reg:CC FLAGS_REG))]
10941   "TARGET_64BIT && reload_completed"
10942   [(const_int 0)]
10943   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10944
10945 (define_split
10946   [(set (match_operand:TI 0 "register_operand" "")
10947         (ashift:TI (match_operand:TI 1 "register_operand" "")
10948                    (match_operand:QI 2 "immediate_operand" "")))
10949    (clobber (reg:CC FLAGS_REG))]
10950   "TARGET_64BIT && reload_completed"
10951   [(const_int 0)]
10952   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10953
10954 (define_insn "x86_64_shld"
10955   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10956         (ior:DI (ashift:DI (match_dup 0)
10957                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10958                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10959                   (minus:QI (const_int 64) (match_dup 2)))))
10960    (clobber (reg:CC FLAGS_REG))]
10961   "TARGET_64BIT"
10962   "@
10963    shld{q}\t{%2, %1, %0|%0, %1, %2}
10964    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10965   [(set_attr "type" "ishift")
10966    (set_attr "prefix_0f" "1")
10967    (set_attr "mode" "DI")
10968    (set_attr "athlon_decode" "vector")
10969    (set_attr "amdfam10_decode" "vector")])
10970
10971 (define_expand "x86_64_shift_adj"
10972   [(set (reg:CCZ FLAGS_REG)
10973         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10974                              (const_int 64))
10975                      (const_int 0)))
10976    (set (match_operand:DI 0 "register_operand" "")
10977         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10978                          (match_operand:DI 1 "register_operand" "")
10979                          (match_dup 0)))
10980    (set (match_dup 1)
10981         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10982                          (match_operand:DI 3 "register_operand" "r")
10983                          (match_dup 1)))]
10984   "TARGET_64BIT"
10985   "")
10986
10987 (define_expand "ashldi3"
10988   [(set (match_operand:DI 0 "shiftdi_operand" "")
10989         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10990                    (match_operand:QI 2 "nonmemory_operand" "")))]
10991   ""
10992   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10993
10994 (define_insn "*ashldi3_1_rex64"
10995   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10996         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10997                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10998    (clobber (reg:CC FLAGS_REG))]
10999   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11000 {
11001   switch (get_attr_type (insn))
11002     {
11003     case TYPE_ALU:
11004       gcc_assert (operands[2] == const1_rtx);
11005       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11006       return "add{q}\t%0, %0";
11007
11008     case TYPE_LEA:
11009       gcc_assert (CONST_INT_P (operands[2]));
11010       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11011       operands[1] = gen_rtx_MULT (DImode, operands[1],
11012                                   GEN_INT (1 << INTVAL (operands[2])));
11013       return "lea{q}\t{%a1, %0|%0, %a1}";
11014
11015     default:
11016       if (REG_P (operands[2]))
11017         return "sal{q}\t{%b2, %0|%0, %b2}";
11018       else if (operands[2] == const1_rtx
11019                && (TARGET_SHIFT1 || optimize_size))
11020         return "sal{q}\t%0";
11021       else
11022         return "sal{q}\t{%2, %0|%0, %2}";
11023     }
11024 }
11025   [(set (attr "type")
11026      (cond [(eq_attr "alternative" "1")
11027               (const_string "lea")
11028             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11029                           (const_int 0))
11030                       (match_operand 0 "register_operand" ""))
11031                  (match_operand 2 "const1_operand" ""))
11032               (const_string "alu")
11033            ]
11034            (const_string "ishift")))
11035    (set_attr "mode" "DI")])
11036
11037 ;; Convert lea to the lea pattern to avoid flags dependency.
11038 (define_split
11039   [(set (match_operand:DI 0 "register_operand" "")
11040         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11041                    (match_operand:QI 2 "immediate_operand" "")))
11042    (clobber (reg:CC FLAGS_REG))]
11043   "TARGET_64BIT && reload_completed
11044    && true_regnum (operands[0]) != true_regnum (operands[1])"
11045   [(set (match_dup 0)
11046         (mult:DI (match_dup 1)
11047                  (match_dup 2)))]
11048   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11049
11050 ;; This pattern can't accept a variable shift count, since shifts by
11051 ;; zero don't affect the flags.  We assume that shifts by constant
11052 ;; zero are optimized away.
11053 (define_insn "*ashldi3_cmp_rex64"
11054   [(set (reg FLAGS_REG)
11055         (compare
11056           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11057                      (match_operand:QI 2 "immediate_operand" "e"))
11058           (const_int 0)))
11059    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11060         (ashift:DI (match_dup 1) (match_dup 2)))]
11061   "TARGET_64BIT
11062    && (optimize_size
11063        || !TARGET_PARTIAL_FLAG_REG_STALL
11064        || (operands[2] == const1_rtx
11065            && (TARGET_SHIFT1
11066                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11067    && ix86_match_ccmode (insn, CCGOCmode)
11068    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11069 {
11070   switch (get_attr_type (insn))
11071     {
11072     case TYPE_ALU:
11073       gcc_assert (operands[2] == const1_rtx);
11074       return "add{q}\t%0, %0";
11075
11076     default:
11077       if (REG_P (operands[2]))
11078         return "sal{q}\t{%b2, %0|%0, %b2}";
11079       else if (operands[2] == const1_rtx
11080                && (TARGET_SHIFT1 || optimize_size))
11081         return "sal{q}\t%0";
11082       else
11083         return "sal{q}\t{%2, %0|%0, %2}";
11084     }
11085 }
11086   [(set (attr "type")
11087      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11088                           (const_int 0))
11089                       (match_operand 0 "register_operand" ""))
11090                  (match_operand 2 "const1_operand" ""))
11091               (const_string "alu")
11092            ]
11093            (const_string "ishift")))
11094    (set_attr "mode" "DI")])
11095
11096 (define_insn "*ashldi3_cconly_rex64"
11097   [(set (reg FLAGS_REG)
11098         (compare
11099           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11100                      (match_operand:QI 2 "immediate_operand" "e"))
11101           (const_int 0)))
11102    (clobber (match_scratch:DI 0 "=r"))]
11103   "TARGET_64BIT
11104    && (optimize_size
11105        || !TARGET_PARTIAL_FLAG_REG_STALL
11106        || (operands[2] == const1_rtx
11107            && (TARGET_SHIFT1
11108                || TARGET_DOUBLE_WITH_ADD)))
11109    && ix86_match_ccmode (insn, CCGOCmode)
11110    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11111 {
11112   switch (get_attr_type (insn))
11113     {
11114     case TYPE_ALU:
11115       gcc_assert (operands[2] == const1_rtx);
11116       return "add{q}\t%0, %0";
11117
11118     default:
11119       if (REG_P (operands[2]))
11120         return "sal{q}\t{%b2, %0|%0, %b2}";
11121       else if (operands[2] == const1_rtx
11122                && (TARGET_SHIFT1 || optimize_size))
11123         return "sal{q}\t%0";
11124       else
11125         return "sal{q}\t{%2, %0|%0, %2}";
11126     }
11127 }
11128   [(set (attr "type")
11129      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11130                           (const_int 0))
11131                       (match_operand 0 "register_operand" ""))
11132                  (match_operand 2 "const1_operand" ""))
11133               (const_string "alu")
11134            ]
11135            (const_string "ishift")))
11136    (set_attr "mode" "DI")])
11137
11138 (define_insn "*ashldi3_1"
11139   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11140         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11141                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11142    (clobber (reg:CC FLAGS_REG))]
11143   "!TARGET_64BIT"
11144   "#"
11145   [(set_attr "type" "multi")])
11146
11147 ;; By default we don't ask for a scratch register, because when DImode
11148 ;; values are manipulated, registers are already at a premium.  But if
11149 ;; we have one handy, we won't turn it away.
11150 (define_peephole2
11151   [(match_scratch:SI 3 "r")
11152    (parallel [(set (match_operand:DI 0 "register_operand" "")
11153                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11154                               (match_operand:QI 2 "nonmemory_operand" "")))
11155               (clobber (reg:CC FLAGS_REG))])
11156    (match_dup 3)]
11157   "!TARGET_64BIT && TARGET_CMOVE"
11158   [(const_int 0)]
11159   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11160
11161 (define_split
11162   [(set (match_operand:DI 0 "register_operand" "")
11163         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11164                    (match_operand:QI 2 "nonmemory_operand" "")))
11165    (clobber (reg:CC FLAGS_REG))]
11166   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11167                      ? epilogue_completed : reload_completed)"
11168   [(const_int 0)]
11169   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11170
11171 (define_insn "x86_shld_1"
11172   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11173         (ior:SI (ashift:SI (match_dup 0)
11174                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11175                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11176                   (minus:QI (const_int 32) (match_dup 2)))))
11177    (clobber (reg:CC FLAGS_REG))]
11178   ""
11179   "@
11180    shld{l}\t{%2, %1, %0|%0, %1, %2}
11181    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11182   [(set_attr "type" "ishift")
11183    (set_attr "prefix_0f" "1")
11184    (set_attr "mode" "SI")
11185    (set_attr "pent_pair" "np")
11186    (set_attr "athlon_decode" "vector")
11187    (set_attr "amdfam10_decode" "vector")])
11188
11189 (define_expand "x86_shift_adj_1"
11190   [(set (reg:CCZ FLAGS_REG)
11191         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11192                              (const_int 32))
11193                      (const_int 0)))
11194    (set (match_operand:SI 0 "register_operand" "")
11195         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11196                          (match_operand:SI 1 "register_operand" "")
11197                          (match_dup 0)))
11198    (set (match_dup 1)
11199         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11200                          (match_operand:SI 3 "register_operand" "r")
11201                          (match_dup 1)))]
11202   "TARGET_CMOVE"
11203   "")
11204
11205 (define_expand "x86_shift_adj_2"
11206   [(use (match_operand:SI 0 "register_operand" ""))
11207    (use (match_operand:SI 1 "register_operand" ""))
11208    (use (match_operand:QI 2 "register_operand" ""))]
11209   ""
11210 {
11211   rtx label = gen_label_rtx ();
11212   rtx tmp;
11213
11214   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11215
11216   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11217   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11218   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11219                               gen_rtx_LABEL_REF (VOIDmode, label),
11220                               pc_rtx);
11221   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11222   JUMP_LABEL (tmp) = label;
11223
11224   emit_move_insn (operands[0], operands[1]);
11225   ix86_expand_clear (operands[1]);
11226
11227   emit_label (label);
11228   LABEL_NUSES (label) = 1;
11229
11230   DONE;
11231 })
11232
11233 (define_expand "ashlsi3"
11234   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11235         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11236                    (match_operand:QI 2 "nonmemory_operand" "")))
11237    (clobber (reg:CC FLAGS_REG))]
11238   ""
11239   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11240
11241 (define_insn "*ashlsi3_1"
11242   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11243         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11244                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11245    (clobber (reg:CC FLAGS_REG))]
11246   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11247 {
11248   switch (get_attr_type (insn))
11249     {
11250     case TYPE_ALU:
11251       gcc_assert (operands[2] == const1_rtx);
11252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11253       return "add{l}\t%0, %0";
11254
11255     case TYPE_LEA:
11256       return "#";
11257
11258     default:
11259       if (REG_P (operands[2]))
11260         return "sal{l}\t{%b2, %0|%0, %b2}";
11261       else if (operands[2] == const1_rtx
11262                && (TARGET_SHIFT1 || optimize_size))
11263         return "sal{l}\t%0";
11264       else
11265         return "sal{l}\t{%2, %0|%0, %2}";
11266     }
11267 }
11268   [(set (attr "type")
11269      (cond [(eq_attr "alternative" "1")
11270               (const_string "lea")
11271             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11272                           (const_int 0))
11273                       (match_operand 0 "register_operand" ""))
11274                  (match_operand 2 "const1_operand" ""))
11275               (const_string "alu")
11276            ]
11277            (const_string "ishift")))
11278    (set_attr "mode" "SI")])
11279
11280 ;; Convert lea to the lea pattern to avoid flags dependency.
11281 (define_split
11282   [(set (match_operand 0 "register_operand" "")
11283         (ashift (match_operand 1 "index_register_operand" "")
11284                 (match_operand:QI 2 "const_int_operand" "")))
11285    (clobber (reg:CC FLAGS_REG))]
11286   "reload_completed
11287    && true_regnum (operands[0]) != true_regnum (operands[1])
11288    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11289   [(const_int 0)]
11290 {
11291   rtx pat;
11292   enum machine_mode mode = GET_MODE (operands[0]);
11293
11294   if (GET_MODE_SIZE (mode) < 4)
11295     operands[0] = gen_lowpart (SImode, operands[0]);
11296   if (mode != Pmode)
11297     operands[1] = gen_lowpart (Pmode, operands[1]);
11298   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11299
11300   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11301   if (Pmode != SImode)
11302     pat = gen_rtx_SUBREG (SImode, pat, 0);
11303   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11304   DONE;
11305 })
11306
11307 ;; Rare case of shifting RSP is handled by generating move and shift
11308 (define_split
11309   [(set (match_operand 0 "register_operand" "")
11310         (ashift (match_operand 1 "register_operand" "")
11311                 (match_operand:QI 2 "const_int_operand" "")))
11312    (clobber (reg:CC FLAGS_REG))]
11313   "reload_completed
11314    && true_regnum (operands[0]) != true_regnum (operands[1])"
11315   [(const_int 0)]
11316 {
11317   rtx pat, clob;
11318   emit_move_insn (operands[0], operands[1]);
11319   pat = gen_rtx_SET (VOIDmode, operands[0],
11320                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11321                                      operands[0], operands[2]));
11322   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11323   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11324   DONE;
11325 })
11326
11327 (define_insn "*ashlsi3_1_zext"
11328   [(set (match_operand:DI 0 "register_operand" "=r,r")
11329         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11330                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11333 {
11334   switch (get_attr_type (insn))
11335     {
11336     case TYPE_ALU:
11337       gcc_assert (operands[2] == const1_rtx);
11338       return "add{l}\t%k0, %k0";
11339
11340     case TYPE_LEA:
11341       return "#";
11342
11343     default:
11344       if (REG_P (operands[2]))
11345         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11346       else if (operands[2] == const1_rtx
11347                && (TARGET_SHIFT1 || optimize_size))
11348         return "sal{l}\t%k0";
11349       else
11350         return "sal{l}\t{%2, %k0|%k0, %2}";
11351     }
11352 }
11353   [(set (attr "type")
11354      (cond [(eq_attr "alternative" "1")
11355               (const_string "lea")
11356             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11357                      (const_int 0))
11358                  (match_operand 2 "const1_operand" ""))
11359               (const_string "alu")
11360            ]
11361            (const_string "ishift")))
11362    (set_attr "mode" "SI")])
11363
11364 ;; Convert lea to the lea pattern to avoid flags dependency.
11365 (define_split
11366   [(set (match_operand:DI 0 "register_operand" "")
11367         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11368                                 (match_operand:QI 2 "const_int_operand" ""))))
11369    (clobber (reg:CC FLAGS_REG))]
11370   "TARGET_64BIT && reload_completed
11371    && true_regnum (operands[0]) != true_regnum (operands[1])"
11372   [(set (match_dup 0) (zero_extend:DI
11373                         (subreg:SI (mult:SI (match_dup 1)
11374                                             (match_dup 2)) 0)))]
11375 {
11376   operands[1] = gen_lowpart (Pmode, operands[1]);
11377   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11378 })
11379
11380 ;; This pattern can't accept a variable shift count, since shifts by
11381 ;; zero don't affect the flags.  We assume that shifts by constant
11382 ;; zero are optimized away.
11383 (define_insn "*ashlsi3_cmp"
11384   [(set (reg FLAGS_REG)
11385         (compare
11386           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11387                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11388           (const_int 0)))
11389    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11390         (ashift:SI (match_dup 1) (match_dup 2)))]
11391    "(optimize_size
11392      || !TARGET_PARTIAL_FLAG_REG_STALL
11393      || (operands[2] == const1_rtx
11394          && (TARGET_SHIFT1
11395              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11396    && ix86_match_ccmode (insn, CCGOCmode)
11397    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11398 {
11399   switch (get_attr_type (insn))
11400     {
11401     case TYPE_ALU:
11402       gcc_assert (operands[2] == const1_rtx);
11403       return "add{l}\t%0, %0";
11404
11405     default:
11406       if (REG_P (operands[2]))
11407         return "sal{l}\t{%b2, %0|%0, %b2}";
11408       else if (operands[2] == const1_rtx
11409                && (TARGET_SHIFT1 || optimize_size))
11410         return "sal{l}\t%0";
11411       else
11412         return "sal{l}\t{%2, %0|%0, %2}";
11413     }
11414 }
11415   [(set (attr "type")
11416      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11417                           (const_int 0))
11418                       (match_operand 0 "register_operand" ""))
11419                  (match_operand 2 "const1_operand" ""))
11420               (const_string "alu")
11421            ]
11422            (const_string "ishift")))
11423    (set_attr "mode" "SI")])
11424
11425 (define_insn "*ashlsi3_cconly"
11426   [(set (reg FLAGS_REG)
11427         (compare
11428           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11429                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11430           (const_int 0)))
11431    (clobber (match_scratch:SI 0 "=r"))]
11432   "(optimize_size
11433     || !TARGET_PARTIAL_FLAG_REG_STALL
11434     || (operands[2] == const1_rtx
11435         && (TARGET_SHIFT1
11436             || TARGET_DOUBLE_WITH_ADD)))
11437    && ix86_match_ccmode (insn, CCGOCmode)
11438    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11439 {
11440   switch (get_attr_type (insn))
11441     {
11442     case TYPE_ALU:
11443       gcc_assert (operands[2] == const1_rtx);
11444       return "add{l}\t%0, %0";
11445
11446     default:
11447       if (REG_P (operands[2]))
11448         return "sal{l}\t{%b2, %0|%0, %b2}";
11449       else if (operands[2] == const1_rtx
11450                && (TARGET_SHIFT1 || optimize_size))
11451         return "sal{l}\t%0";
11452       else
11453         return "sal{l}\t{%2, %0|%0, %2}";
11454     }
11455 }
11456   [(set (attr "type")
11457      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11458                           (const_int 0))
11459                       (match_operand 0 "register_operand" ""))
11460                  (match_operand 2 "const1_operand" ""))
11461               (const_string "alu")
11462            ]
11463            (const_string "ishift")))
11464    (set_attr "mode" "SI")])
11465
11466 (define_insn "*ashlsi3_cmp_zext"
11467   [(set (reg FLAGS_REG)
11468         (compare
11469           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11470                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11471           (const_int 0)))
11472    (set (match_operand:DI 0 "register_operand" "=r")
11473         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11474   "TARGET_64BIT
11475    && (optimize_size
11476        || !TARGET_PARTIAL_FLAG_REG_STALL
11477        || (operands[2] == const1_rtx
11478            && (TARGET_SHIFT1
11479                || TARGET_DOUBLE_WITH_ADD)))
11480    && ix86_match_ccmode (insn, CCGOCmode)
11481    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11482 {
11483   switch (get_attr_type (insn))
11484     {
11485     case TYPE_ALU:
11486       gcc_assert (operands[2] == const1_rtx);
11487       return "add{l}\t%k0, %k0";
11488
11489     default:
11490       if (REG_P (operands[2]))
11491         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11492       else if (operands[2] == const1_rtx
11493                && (TARGET_SHIFT1 || optimize_size))
11494         return "sal{l}\t%k0";
11495       else
11496         return "sal{l}\t{%2, %k0|%k0, %2}";
11497     }
11498 }
11499   [(set (attr "type")
11500      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11501                      (const_int 0))
11502                  (match_operand 2 "const1_operand" ""))
11503               (const_string "alu")
11504            ]
11505            (const_string "ishift")))
11506    (set_attr "mode" "SI")])
11507
11508 (define_expand "ashlhi3"
11509   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11510         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11511                    (match_operand:QI 2 "nonmemory_operand" "")))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "TARGET_HIMODE_MATH"
11514   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11515
11516 (define_insn "*ashlhi3_1_lea"
11517   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11518         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11519                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11520    (clobber (reg:CC FLAGS_REG))]
11521   "!TARGET_PARTIAL_REG_STALL
11522    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11523 {
11524   switch (get_attr_type (insn))
11525     {
11526     case TYPE_LEA:
11527       return "#";
11528     case TYPE_ALU:
11529       gcc_assert (operands[2] == const1_rtx);
11530       return "add{w}\t%0, %0";
11531
11532     default:
11533       if (REG_P (operands[2]))
11534         return "sal{w}\t{%b2, %0|%0, %b2}";
11535       else if (operands[2] == const1_rtx
11536                && (TARGET_SHIFT1 || optimize_size))
11537         return "sal{w}\t%0";
11538       else
11539         return "sal{w}\t{%2, %0|%0, %2}";
11540     }
11541 }
11542   [(set (attr "type")
11543      (cond [(eq_attr "alternative" "1")
11544               (const_string "lea")
11545             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11546                           (const_int 0))
11547                       (match_operand 0 "register_operand" ""))
11548                  (match_operand 2 "const1_operand" ""))
11549               (const_string "alu")
11550            ]
11551            (const_string "ishift")))
11552    (set_attr "mode" "HI,SI")])
11553
11554 (define_insn "*ashlhi3_1"
11555   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11556         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11557                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11558    (clobber (reg:CC FLAGS_REG))]
11559   "TARGET_PARTIAL_REG_STALL
11560    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11561 {
11562   switch (get_attr_type (insn))
11563     {
11564     case TYPE_ALU:
11565       gcc_assert (operands[2] == const1_rtx);
11566       return "add{w}\t%0, %0";
11567
11568     default:
11569       if (REG_P (operands[2]))
11570         return "sal{w}\t{%b2, %0|%0, %b2}";
11571       else if (operands[2] == const1_rtx
11572                && (TARGET_SHIFT1 || optimize_size))
11573         return "sal{w}\t%0";
11574       else
11575         return "sal{w}\t{%2, %0|%0, %2}";
11576     }
11577 }
11578   [(set (attr "type")
11579      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11580                           (const_int 0))
11581                       (match_operand 0 "register_operand" ""))
11582                  (match_operand 2 "const1_operand" ""))
11583               (const_string "alu")
11584            ]
11585            (const_string "ishift")))
11586    (set_attr "mode" "HI")])
11587
11588 ;; This pattern can't accept a variable shift count, since shifts by
11589 ;; zero don't affect the flags.  We assume that shifts by constant
11590 ;; zero are optimized away.
11591 (define_insn "*ashlhi3_cmp"
11592   [(set (reg FLAGS_REG)
11593         (compare
11594           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11595                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11596           (const_int 0)))
11597    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11598         (ashift:HI (match_dup 1) (match_dup 2)))]
11599   "(optimize_size
11600     || !TARGET_PARTIAL_FLAG_REG_STALL
11601     || (operands[2] == const1_rtx
11602         && (TARGET_SHIFT1
11603             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11604    && ix86_match_ccmode (insn, CCGOCmode)
11605    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11606 {
11607   switch (get_attr_type (insn))
11608     {
11609     case TYPE_ALU:
11610       gcc_assert (operands[2] == const1_rtx);
11611       return "add{w}\t%0, %0";
11612
11613     default:
11614       if (REG_P (operands[2]))
11615         return "sal{w}\t{%b2, %0|%0, %b2}";
11616       else if (operands[2] == const1_rtx
11617                && (TARGET_SHIFT1 || optimize_size))
11618         return "sal{w}\t%0";
11619       else
11620         return "sal{w}\t{%2, %0|%0, %2}";
11621     }
11622 }
11623   [(set (attr "type")
11624      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11625                           (const_int 0))
11626                       (match_operand 0 "register_operand" ""))
11627                  (match_operand 2 "const1_operand" ""))
11628               (const_string "alu")
11629            ]
11630            (const_string "ishift")))
11631    (set_attr "mode" "HI")])
11632
11633 (define_insn "*ashlhi3_cconly"
11634   [(set (reg FLAGS_REG)
11635         (compare
11636           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11637                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11638           (const_int 0)))
11639    (clobber (match_scratch:HI 0 "=r"))]
11640   "(optimize_size
11641     || !TARGET_PARTIAL_FLAG_REG_STALL
11642     || (operands[2] == const1_rtx
11643         && (TARGET_SHIFT1
11644             || TARGET_DOUBLE_WITH_ADD)))
11645    && ix86_match_ccmode (insn, CCGOCmode)
11646    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11647 {
11648   switch (get_attr_type (insn))
11649     {
11650     case TYPE_ALU:
11651       gcc_assert (operands[2] == const1_rtx);
11652       return "add{w}\t%0, %0";
11653
11654     default:
11655       if (REG_P (operands[2]))
11656         return "sal{w}\t{%b2, %0|%0, %b2}";
11657       else if (operands[2] == const1_rtx
11658                && (TARGET_SHIFT1 || optimize_size))
11659         return "sal{w}\t%0";
11660       else
11661         return "sal{w}\t{%2, %0|%0, %2}";
11662     }
11663 }
11664   [(set (attr "type")
11665      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11666                           (const_int 0))
11667                       (match_operand 0 "register_operand" ""))
11668                  (match_operand 2 "const1_operand" ""))
11669               (const_string "alu")
11670            ]
11671            (const_string "ishift")))
11672    (set_attr "mode" "HI")])
11673
11674 (define_expand "ashlqi3"
11675   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11676         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11677                    (match_operand:QI 2 "nonmemory_operand" "")))
11678    (clobber (reg:CC FLAGS_REG))]
11679   "TARGET_QIMODE_MATH"
11680   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11681
11682 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11683
11684 (define_insn "*ashlqi3_1_lea"
11685   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11686         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11687                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "!TARGET_PARTIAL_REG_STALL
11690    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11691 {
11692   switch (get_attr_type (insn))
11693     {
11694     case TYPE_LEA:
11695       return "#";
11696     case TYPE_ALU:
11697       gcc_assert (operands[2] == const1_rtx);
11698       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11699         return "add{l}\t%k0, %k0";
11700       else
11701         return "add{b}\t%0, %0";
11702
11703     default:
11704       if (REG_P (operands[2]))
11705         {
11706           if (get_attr_mode (insn) == MODE_SI)
11707             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11708           else
11709             return "sal{b}\t{%b2, %0|%0, %b2}";
11710         }
11711       else if (operands[2] == const1_rtx
11712                && (TARGET_SHIFT1 || optimize_size))
11713         {
11714           if (get_attr_mode (insn) == MODE_SI)
11715             return "sal{l}\t%0";
11716           else
11717             return "sal{b}\t%0";
11718         }
11719       else
11720         {
11721           if (get_attr_mode (insn) == MODE_SI)
11722             return "sal{l}\t{%2, %k0|%k0, %2}";
11723           else
11724             return "sal{b}\t{%2, %0|%0, %2}";
11725         }
11726     }
11727 }
11728   [(set (attr "type")
11729      (cond [(eq_attr "alternative" "2")
11730               (const_string "lea")
11731             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11732                           (const_int 0))
11733                       (match_operand 0 "register_operand" ""))
11734                  (match_operand 2 "const1_operand" ""))
11735               (const_string "alu")
11736            ]
11737            (const_string "ishift")))
11738    (set_attr "mode" "QI,SI,SI")])
11739
11740 (define_insn "*ashlqi3_1"
11741   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11742         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11743                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "TARGET_PARTIAL_REG_STALL
11746    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11747 {
11748   switch (get_attr_type (insn))
11749     {
11750     case TYPE_ALU:
11751       gcc_assert (operands[2] == const1_rtx);
11752       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11753         return "add{l}\t%k0, %k0";
11754       else
11755         return "add{b}\t%0, %0";
11756
11757     default:
11758       if (REG_P (operands[2]))
11759         {
11760           if (get_attr_mode (insn) == MODE_SI)
11761             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11762           else
11763             return "sal{b}\t{%b2, %0|%0, %b2}";
11764         }
11765       else if (operands[2] == const1_rtx
11766                && (TARGET_SHIFT1 || optimize_size))
11767         {
11768           if (get_attr_mode (insn) == MODE_SI)
11769             return "sal{l}\t%0";
11770           else
11771             return "sal{b}\t%0";
11772         }
11773       else
11774         {
11775           if (get_attr_mode (insn) == MODE_SI)
11776             return "sal{l}\t{%2, %k0|%k0, %2}";
11777           else
11778             return "sal{b}\t{%2, %0|%0, %2}";
11779         }
11780     }
11781 }
11782   [(set (attr "type")
11783      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11784                           (const_int 0))
11785                       (match_operand 0 "register_operand" ""))
11786                  (match_operand 2 "const1_operand" ""))
11787               (const_string "alu")
11788            ]
11789            (const_string "ishift")))
11790    (set_attr "mode" "QI,SI")])
11791
11792 ;; This pattern can't accept a variable shift count, since shifts by
11793 ;; zero don't affect the flags.  We assume that shifts by constant
11794 ;; zero are optimized away.
11795 (define_insn "*ashlqi3_cmp"
11796   [(set (reg FLAGS_REG)
11797         (compare
11798           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11799                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11800           (const_int 0)))
11801    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11802         (ashift:QI (match_dup 1) (match_dup 2)))]
11803   "(optimize_size
11804     || !TARGET_PARTIAL_FLAG_REG_STALL
11805     || (operands[2] == const1_rtx
11806         && (TARGET_SHIFT1
11807             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11808    && ix86_match_ccmode (insn, CCGOCmode)
11809    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11810 {
11811   switch (get_attr_type (insn))
11812     {
11813     case TYPE_ALU:
11814       gcc_assert (operands[2] == const1_rtx);
11815       return "add{b}\t%0, %0";
11816
11817     default:
11818       if (REG_P (operands[2]))
11819         return "sal{b}\t{%b2, %0|%0, %b2}";
11820       else if (operands[2] == const1_rtx
11821                && (TARGET_SHIFT1 || optimize_size))
11822         return "sal{b}\t%0";
11823       else
11824         return "sal{b}\t{%2, %0|%0, %2}";
11825     }
11826 }
11827   [(set (attr "type")
11828      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11829                           (const_int 0))
11830                       (match_operand 0 "register_operand" ""))
11831                  (match_operand 2 "const1_operand" ""))
11832               (const_string "alu")
11833            ]
11834            (const_string "ishift")))
11835    (set_attr "mode" "QI")])
11836
11837 (define_insn "*ashlqi3_cconly"
11838   [(set (reg FLAGS_REG)
11839         (compare
11840           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11841                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11842           (const_int 0)))
11843    (clobber (match_scratch:QI 0 "=q"))]
11844   "(optimize_size
11845     || !TARGET_PARTIAL_FLAG_REG_STALL
11846     || (operands[2] == const1_rtx
11847         && (TARGET_SHIFT1
11848             || TARGET_DOUBLE_WITH_ADD)))
11849    && ix86_match_ccmode (insn, CCGOCmode)
11850    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11851 {
11852   switch (get_attr_type (insn))
11853     {
11854     case TYPE_ALU:
11855       gcc_assert (operands[2] == const1_rtx);
11856       return "add{b}\t%0, %0";
11857
11858     default:
11859       if (REG_P (operands[2]))
11860         return "sal{b}\t{%b2, %0|%0, %b2}";
11861       else if (operands[2] == const1_rtx
11862                && (TARGET_SHIFT1 || optimize_size))
11863         return "sal{b}\t%0";
11864       else
11865         return "sal{b}\t{%2, %0|%0, %2}";
11866     }
11867 }
11868   [(set (attr "type")
11869      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11870                           (const_int 0))
11871                       (match_operand 0 "register_operand" ""))
11872                  (match_operand 2 "const1_operand" ""))
11873               (const_string "alu")
11874            ]
11875            (const_string "ishift")))
11876    (set_attr "mode" "QI")])
11877
11878 ;; See comment above `ashldi3' about how this works.
11879
11880 (define_expand "ashrti3"
11881   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11882                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11883                                 (match_operand:QI 2 "nonmemory_operand" "")))
11884               (clobber (reg:CC FLAGS_REG))])]
11885   "TARGET_64BIT"
11886 {
11887   if (! immediate_operand (operands[2], QImode))
11888     {
11889       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11890       DONE;
11891     }
11892   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11893   DONE;
11894 })
11895
11896 (define_insn "ashrti3_1"
11897   [(set (match_operand:TI 0 "register_operand" "=r")
11898         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11899                      (match_operand:QI 2 "register_operand" "c")))
11900    (clobber (match_scratch:DI 3 "=&r"))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "TARGET_64BIT"
11903   "#"
11904   [(set_attr "type" "multi")])
11905
11906 (define_insn "*ashrti3_2"
11907   [(set (match_operand:TI 0 "register_operand" "=r")
11908         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11909                      (match_operand:QI 2 "immediate_operand" "O")))
11910    (clobber (reg:CC FLAGS_REG))]
11911   "TARGET_64BIT"
11912   "#"
11913   [(set_attr "type" "multi")])
11914
11915 (define_split
11916   [(set (match_operand:TI 0 "register_operand" "")
11917         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11918                      (match_operand:QI 2 "register_operand" "")))
11919    (clobber (match_scratch:DI 3 ""))
11920    (clobber (reg:CC FLAGS_REG))]
11921   "TARGET_64BIT && reload_completed"
11922   [(const_int 0)]
11923   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11924
11925 (define_split
11926   [(set (match_operand:TI 0 "register_operand" "")
11927         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11928                      (match_operand:QI 2 "immediate_operand" "")))
11929    (clobber (reg:CC FLAGS_REG))]
11930   "TARGET_64BIT && reload_completed"
11931   [(const_int 0)]
11932   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11933
11934 (define_insn "x86_64_shrd"
11935   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11936         (ior:DI (ashiftrt:DI (match_dup 0)
11937                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11938                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11939                   (minus:QI (const_int 64) (match_dup 2)))))
11940    (clobber (reg:CC FLAGS_REG))]
11941   "TARGET_64BIT"
11942   "@
11943    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11944    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11945   [(set_attr "type" "ishift")
11946    (set_attr "prefix_0f" "1")
11947    (set_attr "mode" "DI")
11948    (set_attr "athlon_decode" "vector")
11949    (set_attr "amdfam10_decode" "vector")])
11950
11951 (define_expand "ashrdi3"
11952   [(set (match_operand:DI 0 "shiftdi_operand" "")
11953         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11954                      (match_operand:QI 2 "nonmemory_operand" "")))]
11955   ""
11956   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11957
11958 (define_insn "*ashrdi3_63_rex64"
11959   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11960         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11961                      (match_operand:DI 2 "const_int_operand" "i,i")))
11962    (clobber (reg:CC FLAGS_REG))]
11963   "TARGET_64BIT && INTVAL (operands[2]) == 63
11964    && (TARGET_USE_CLTD || optimize_size)
11965    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11966   "@
11967    {cqto|cqo}
11968    sar{q}\t{%2, %0|%0, %2}"
11969   [(set_attr "type" "imovx,ishift")
11970    (set_attr "prefix_0f" "0,*")
11971    (set_attr "length_immediate" "0,*")
11972    (set_attr "modrm" "0,1")
11973    (set_attr "mode" "DI")])
11974
11975 (define_insn "*ashrdi3_1_one_bit_rex64"
11976   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11977         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11978                      (match_operand:QI 2 "const1_operand" "")))
11979    (clobber (reg:CC FLAGS_REG))]
11980   "TARGET_64BIT
11981    && (TARGET_SHIFT1 || optimize_size)
11982    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11983   "sar{q}\t%0"
11984   [(set_attr "type" "ishift")
11985    (set (attr "length")
11986      (if_then_else (match_operand:DI 0 "register_operand" "")
11987         (const_string "2")
11988         (const_string "*")))])
11989
11990 (define_insn "*ashrdi3_1_rex64"
11991   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11992         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11993                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11994    (clobber (reg:CC FLAGS_REG))]
11995   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11996   "@
11997    sar{q}\t{%2, %0|%0, %2}
11998    sar{q}\t{%b2, %0|%0, %b2}"
11999   [(set_attr "type" "ishift")
12000    (set_attr "mode" "DI")])
12001
12002 ;; This pattern can't accept a variable shift count, since shifts by
12003 ;; zero don't affect the flags.  We assume that shifts by constant
12004 ;; zero are optimized away.
12005 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12006   [(set (reg FLAGS_REG)
12007         (compare
12008           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12009                        (match_operand:QI 2 "const1_operand" ""))
12010           (const_int 0)))
12011    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12012         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12013   "TARGET_64BIT
12014    && (TARGET_SHIFT1 || optimize_size)
12015    && ix86_match_ccmode (insn, CCGOCmode)
12016    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12017   "sar{q}\t%0"
12018   [(set_attr "type" "ishift")
12019    (set (attr "length")
12020      (if_then_else (match_operand:DI 0 "register_operand" "")
12021         (const_string "2")
12022         (const_string "*")))])
12023
12024 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12025   [(set (reg FLAGS_REG)
12026         (compare
12027           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12028                        (match_operand:QI 2 "const1_operand" ""))
12029           (const_int 0)))
12030    (clobber (match_scratch:DI 0 "=r"))]
12031   "TARGET_64BIT
12032    && (TARGET_SHIFT1 || optimize_size)
12033    && ix86_match_ccmode (insn, CCGOCmode)
12034    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12035   "sar{q}\t%0"
12036   [(set_attr "type" "ishift")
12037    (set_attr "length" "2")])
12038
12039 ;; This pattern can't accept a variable shift count, since shifts by
12040 ;; zero don't affect the flags.  We assume that shifts by constant
12041 ;; zero are optimized away.
12042 (define_insn "*ashrdi3_cmp_rex64"
12043   [(set (reg FLAGS_REG)
12044         (compare
12045           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12046                        (match_operand:QI 2 "const_int_operand" "n"))
12047           (const_int 0)))
12048    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12049         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12050   "TARGET_64BIT
12051    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12052    && ix86_match_ccmode (insn, CCGOCmode)
12053    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12054   "sar{q}\t{%2, %0|%0, %2}"
12055   [(set_attr "type" "ishift")
12056    (set_attr "mode" "DI")])
12057
12058 (define_insn "*ashrdi3_cconly_rex64"
12059   [(set (reg FLAGS_REG)
12060         (compare
12061           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12062                        (match_operand:QI 2 "const_int_operand" "n"))
12063           (const_int 0)))
12064    (clobber (match_scratch:DI 0 "=r"))]
12065   "TARGET_64BIT
12066    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12067    && ix86_match_ccmode (insn, CCGOCmode)
12068    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12069   "sar{q}\t{%2, %0|%0, %2}"
12070   [(set_attr "type" "ishift")
12071    (set_attr "mode" "DI")])
12072
12073 (define_insn "*ashrdi3_1"
12074   [(set (match_operand:DI 0 "register_operand" "=r")
12075         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12076                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12077    (clobber (reg:CC FLAGS_REG))]
12078   "!TARGET_64BIT"
12079   "#"
12080   [(set_attr "type" "multi")])
12081
12082 ;; By default we don't ask for a scratch register, because when DImode
12083 ;; values are manipulated, registers are already at a premium.  But if
12084 ;; we have one handy, we won't turn it away.
12085 (define_peephole2
12086   [(match_scratch:SI 3 "r")
12087    (parallel [(set (match_operand:DI 0 "register_operand" "")
12088                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12089                                 (match_operand:QI 2 "nonmemory_operand" "")))
12090               (clobber (reg:CC FLAGS_REG))])
12091    (match_dup 3)]
12092   "!TARGET_64BIT && TARGET_CMOVE"
12093   [(const_int 0)]
12094   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12095
12096 (define_split
12097   [(set (match_operand:DI 0 "register_operand" "")
12098         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12099                      (match_operand:QI 2 "nonmemory_operand" "")))
12100    (clobber (reg:CC FLAGS_REG))]
12101   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12102                      ? epilogue_completed : reload_completed)"
12103   [(const_int 0)]
12104   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12105
12106 (define_insn "x86_shrd_1"
12107   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12108         (ior:SI (ashiftrt:SI (match_dup 0)
12109                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12110                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12111                   (minus:QI (const_int 32) (match_dup 2)))))
12112    (clobber (reg:CC FLAGS_REG))]
12113   ""
12114   "@
12115    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12116    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12117   [(set_attr "type" "ishift")
12118    (set_attr "prefix_0f" "1")
12119    (set_attr "pent_pair" "np")
12120    (set_attr "mode" "SI")])
12121
12122 (define_expand "x86_shift_adj_3"
12123   [(use (match_operand:SI 0 "register_operand" ""))
12124    (use (match_operand:SI 1 "register_operand" ""))
12125    (use (match_operand:QI 2 "register_operand" ""))]
12126   ""
12127 {
12128   rtx label = gen_label_rtx ();
12129   rtx tmp;
12130
12131   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12132
12133   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12134   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12135   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12136                               gen_rtx_LABEL_REF (VOIDmode, label),
12137                               pc_rtx);
12138   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12139   JUMP_LABEL (tmp) = label;
12140
12141   emit_move_insn (operands[0], operands[1]);
12142   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12143
12144   emit_label (label);
12145   LABEL_NUSES (label) = 1;
12146
12147   DONE;
12148 })
12149
12150 (define_insn "ashrsi3_31"
12151   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12152         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12153                      (match_operand:SI 2 "const_int_operand" "i,i")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12156    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12157   "@
12158    {cltd|cdq}
12159    sar{l}\t{%2, %0|%0, %2}"
12160   [(set_attr "type" "imovx,ishift")
12161    (set_attr "prefix_0f" "0,*")
12162    (set_attr "length_immediate" "0,*")
12163    (set_attr "modrm" "0,1")
12164    (set_attr "mode" "SI")])
12165
12166 (define_insn "*ashrsi3_31_zext"
12167   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12168         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12169                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12170    (clobber (reg:CC FLAGS_REG))]
12171   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12172    && INTVAL (operands[2]) == 31
12173    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12174   "@
12175    {cltd|cdq}
12176    sar{l}\t{%2, %k0|%k0, %2}"
12177   [(set_attr "type" "imovx,ishift")
12178    (set_attr "prefix_0f" "0,*")
12179    (set_attr "length_immediate" "0,*")
12180    (set_attr "modrm" "0,1")
12181    (set_attr "mode" "SI")])
12182
12183 (define_expand "ashrsi3"
12184   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12185         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12186                      (match_operand:QI 2 "nonmemory_operand" "")))
12187    (clobber (reg:CC FLAGS_REG))]
12188   ""
12189   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12190
12191 (define_insn "*ashrsi3_1_one_bit"
12192   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12193         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12194                      (match_operand:QI 2 "const1_operand" "")))
12195    (clobber (reg:CC FLAGS_REG))]
12196   "(TARGET_SHIFT1 || optimize_size)
12197    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12198   "sar{l}\t%0"
12199   [(set_attr "type" "ishift")
12200    (set (attr "length")
12201      (if_then_else (match_operand:SI 0 "register_operand" "")
12202         (const_string "2")
12203         (const_string "*")))])
12204
12205 (define_insn "*ashrsi3_1_one_bit_zext"
12206   [(set (match_operand:DI 0 "register_operand" "=r")
12207         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12208                                      (match_operand:QI 2 "const1_operand" ""))))
12209    (clobber (reg:CC FLAGS_REG))]
12210   "TARGET_64BIT
12211    && (TARGET_SHIFT1 || optimize_size)
12212    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12213   "sar{l}\t%k0"
12214   [(set_attr "type" "ishift")
12215    (set_attr "length" "2")])
12216
12217 (define_insn "*ashrsi3_1"
12218   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12219         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12220                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12221    (clobber (reg:CC FLAGS_REG))]
12222   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12223   "@
12224    sar{l}\t{%2, %0|%0, %2}
12225    sar{l}\t{%b2, %0|%0, %b2}"
12226   [(set_attr "type" "ishift")
12227    (set_attr "mode" "SI")])
12228
12229 (define_insn "*ashrsi3_1_zext"
12230   [(set (match_operand:DI 0 "register_operand" "=r,r")
12231         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12232                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12233    (clobber (reg:CC FLAGS_REG))]
12234   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12235   "@
12236    sar{l}\t{%2, %k0|%k0, %2}
12237    sar{l}\t{%b2, %k0|%k0, %b2}"
12238   [(set_attr "type" "ishift")
12239    (set_attr "mode" "SI")])
12240
12241 ;; This pattern can't accept a variable shift count, since shifts by
12242 ;; zero don't affect the flags.  We assume that shifts by constant
12243 ;; zero are optimized away.
12244 (define_insn "*ashrsi3_one_bit_cmp"
12245   [(set (reg FLAGS_REG)
12246         (compare
12247           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12248                        (match_operand:QI 2 "const1_operand" ""))
12249           (const_int 0)))
12250    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12251         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12252   "(TARGET_SHIFT1 || optimize_size)
12253    && ix86_match_ccmode (insn, CCGOCmode)
12254    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12255   "sar{l}\t%0"
12256   [(set_attr "type" "ishift")
12257    (set (attr "length")
12258      (if_then_else (match_operand:SI 0 "register_operand" "")
12259         (const_string "2")
12260         (const_string "*")))])
12261
12262 (define_insn "*ashrsi3_one_bit_cconly"
12263   [(set (reg FLAGS_REG)
12264         (compare
12265           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12266                        (match_operand:QI 2 "const1_operand" ""))
12267           (const_int 0)))
12268    (clobber (match_scratch:SI 0 "=r"))]
12269   "(TARGET_SHIFT1 || optimize_size)
12270    && ix86_match_ccmode (insn, CCGOCmode)
12271    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12272   "sar{l}\t%0"
12273   [(set_attr "type" "ishift")
12274    (set_attr "length" "2")])
12275
12276 (define_insn "*ashrsi3_one_bit_cmp_zext"
12277   [(set (reg FLAGS_REG)
12278         (compare
12279           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12280                        (match_operand:QI 2 "const1_operand" ""))
12281           (const_int 0)))
12282    (set (match_operand:DI 0 "register_operand" "=r")
12283         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12284   "TARGET_64BIT
12285    && (TARGET_SHIFT1 || optimize_size)
12286    && ix86_match_ccmode (insn, CCmode)
12287    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12288   "sar{l}\t%k0"
12289   [(set_attr "type" "ishift")
12290    (set_attr "length" "2")])
12291
12292 ;; This pattern can't accept a variable shift count, since shifts by
12293 ;; zero don't affect the flags.  We assume that shifts by constant
12294 ;; zero are optimized away.
12295 (define_insn "*ashrsi3_cmp"
12296   [(set (reg FLAGS_REG)
12297         (compare
12298           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12299                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12300           (const_int 0)))
12301    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12302         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12303   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12304    && ix86_match_ccmode (insn, CCGOCmode)
12305    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12306   "sar{l}\t{%2, %0|%0, %2}"
12307   [(set_attr "type" "ishift")
12308    (set_attr "mode" "SI")])
12309
12310 (define_insn "*ashrsi3_cconly"
12311   [(set (reg FLAGS_REG)
12312         (compare
12313           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12315           (const_int 0)))
12316    (clobber (match_scratch:SI 0 "=r"))]
12317   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12318    && ix86_match_ccmode (insn, CCGOCmode)
12319    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12320   "sar{l}\t{%2, %0|%0, %2}"
12321   [(set_attr "type" "ishift")
12322    (set_attr "mode" "SI")])
12323
12324 (define_insn "*ashrsi3_cmp_zext"
12325   [(set (reg FLAGS_REG)
12326         (compare
12327           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12328                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12329           (const_int 0)))
12330    (set (match_operand:DI 0 "register_operand" "=r")
12331         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12332   "TARGET_64BIT
12333    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12334    && ix86_match_ccmode (insn, CCGOCmode)
12335    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12336   "sar{l}\t{%2, %k0|%k0, %2}"
12337   [(set_attr "type" "ishift")
12338    (set_attr "mode" "SI")])
12339
12340 (define_expand "ashrhi3"
12341   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12342         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12343                      (match_operand:QI 2 "nonmemory_operand" "")))
12344    (clobber (reg:CC FLAGS_REG))]
12345   "TARGET_HIMODE_MATH"
12346   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12347
12348 (define_insn "*ashrhi3_1_one_bit"
12349   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12350         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351                      (match_operand:QI 2 "const1_operand" "")))
12352    (clobber (reg:CC FLAGS_REG))]
12353   "(TARGET_SHIFT1 || optimize_size)
12354    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12355   "sar{w}\t%0"
12356   [(set_attr "type" "ishift")
12357    (set (attr "length")
12358      (if_then_else (match_operand 0 "register_operand" "")
12359         (const_string "2")
12360         (const_string "*")))])
12361
12362 (define_insn "*ashrhi3_1"
12363   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12364         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12365                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12366    (clobber (reg:CC FLAGS_REG))]
12367   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12368   "@
12369    sar{w}\t{%2, %0|%0, %2}
12370    sar{w}\t{%b2, %0|%0, %b2}"
12371   [(set_attr "type" "ishift")
12372    (set_attr "mode" "HI")])
12373
12374 ;; This pattern can't accept a variable shift count, since shifts by
12375 ;; zero don't affect the flags.  We assume that shifts by constant
12376 ;; zero are optimized away.
12377 (define_insn "*ashrhi3_one_bit_cmp"
12378   [(set (reg FLAGS_REG)
12379         (compare
12380           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12381                        (match_operand:QI 2 "const1_operand" ""))
12382           (const_int 0)))
12383    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12384         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12385   "(TARGET_SHIFT1 || optimize_size)
12386    && ix86_match_ccmode (insn, CCGOCmode)
12387    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12388   "sar{w}\t%0"
12389   [(set_attr "type" "ishift")
12390    (set (attr "length")
12391      (if_then_else (match_operand 0 "register_operand" "")
12392         (const_string "2")
12393         (const_string "*")))])
12394
12395 (define_insn "*ashrhi3_one_bit_cconly"
12396   [(set (reg FLAGS_REG)
12397         (compare
12398           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12399                        (match_operand:QI 2 "const1_operand" ""))
12400           (const_int 0)))
12401    (clobber (match_scratch:HI 0 "=r"))]
12402   "(TARGET_SHIFT1 || optimize_size)
12403    && ix86_match_ccmode (insn, CCGOCmode)
12404    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12405   "sar{w}\t%0"
12406   [(set_attr "type" "ishift")
12407    (set_attr "length" "2")])
12408
12409 ;; This pattern can't accept a variable shift count, since shifts by
12410 ;; zero don't affect the flags.  We assume that shifts by constant
12411 ;; zero are optimized away.
12412 (define_insn "*ashrhi3_cmp"
12413   [(set (reg FLAGS_REG)
12414         (compare
12415           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12416                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12417           (const_int 0)))
12418    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12419         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12420   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12421    && ix86_match_ccmode (insn, CCGOCmode)
12422    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12423   "sar{w}\t{%2, %0|%0, %2}"
12424   [(set_attr "type" "ishift")
12425    (set_attr "mode" "HI")])
12426
12427 (define_insn "*ashrhi3_cconly"
12428   [(set (reg FLAGS_REG)
12429         (compare
12430           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12431                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12432           (const_int 0)))
12433    (clobber (match_scratch:HI 0 "=r"))]
12434   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12435    && ix86_match_ccmode (insn, CCGOCmode)
12436    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12437   "sar{w}\t{%2, %0|%0, %2}"
12438   [(set_attr "type" "ishift")
12439    (set_attr "mode" "HI")])
12440
12441 (define_expand "ashrqi3"
12442   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12443         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12444                      (match_operand:QI 2 "nonmemory_operand" "")))
12445    (clobber (reg:CC FLAGS_REG))]
12446   "TARGET_QIMODE_MATH"
12447   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12448
12449 (define_insn "*ashrqi3_1_one_bit"
12450   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12451         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12452                      (match_operand:QI 2 "const1_operand" "")))
12453    (clobber (reg:CC FLAGS_REG))]
12454   "(TARGET_SHIFT1 || optimize_size)
12455    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12456   "sar{b}\t%0"
12457   [(set_attr "type" "ishift")
12458    (set (attr "length")
12459      (if_then_else (match_operand 0 "register_operand" "")
12460         (const_string "2")
12461         (const_string "*")))])
12462
12463 (define_insn "*ashrqi3_1_one_bit_slp"
12464   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12465         (ashiftrt:QI (match_dup 0)
12466                      (match_operand:QI 1 "const1_operand" "")))
12467    (clobber (reg:CC FLAGS_REG))]
12468   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12469    && (TARGET_SHIFT1 || optimize_size)
12470    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12471   "sar{b}\t%0"
12472   [(set_attr "type" "ishift1")
12473    (set (attr "length")
12474      (if_then_else (match_operand 0 "register_operand" "")
12475         (const_string "2")
12476         (const_string "*")))])
12477
12478 (define_insn "*ashrqi3_1"
12479   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12480         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12481                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12482    (clobber (reg:CC FLAGS_REG))]
12483   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12484   "@
12485    sar{b}\t{%2, %0|%0, %2}
12486    sar{b}\t{%b2, %0|%0, %b2}"
12487   [(set_attr "type" "ishift")
12488    (set_attr "mode" "QI")])
12489
12490 (define_insn "*ashrqi3_1_slp"
12491   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12492         (ashiftrt:QI (match_dup 0)
12493                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12494    (clobber (reg:CC FLAGS_REG))]
12495   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12496    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12497   "@
12498    sar{b}\t{%1, %0|%0, %1}
12499    sar{b}\t{%b1, %0|%0, %b1}"
12500   [(set_attr "type" "ishift1")
12501    (set_attr "mode" "QI")])
12502
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags.  We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*ashrqi3_one_bit_cmp"
12507   [(set (reg FLAGS_REG)
12508         (compare
12509           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12510                        (match_operand:QI 2 "const1_operand" "I"))
12511           (const_int 0)))
12512    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12513         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12514   "(TARGET_SHIFT1 || optimize_size)
12515    && ix86_match_ccmode (insn, CCGOCmode)
12516    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12517   "sar{b}\t%0"
12518   [(set_attr "type" "ishift")
12519    (set (attr "length")
12520      (if_then_else (match_operand 0 "register_operand" "")
12521         (const_string "2")
12522         (const_string "*")))])
12523
12524 (define_insn "*ashrqi3_one_bit_cconly"
12525   [(set (reg FLAGS_REG)
12526         (compare
12527           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528                        (match_operand:QI 2 "const1_operand" "I"))
12529           (const_int 0)))
12530    (clobber (match_scratch:QI 0 "=q"))]
12531   "(TARGET_SHIFT1 || optimize_size)
12532    && ix86_match_ccmode (insn, CCGOCmode)
12533    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12534   "sar{b}\t%0"
12535   [(set_attr "type" "ishift")
12536    (set_attr "length" "2")])
12537
12538 ;; This pattern can't accept a variable shift count, since shifts by
12539 ;; zero don't affect the flags.  We assume that shifts by constant
12540 ;; zero are optimized away.
12541 (define_insn "*ashrqi3_cmp"
12542   [(set (reg FLAGS_REG)
12543         (compare
12544           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12545                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12546           (const_int 0)))
12547    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12548         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12549   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12550    && ix86_match_ccmode (insn, CCGOCmode)
12551    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12552   "sar{b}\t{%2, %0|%0, %2}"
12553   [(set_attr "type" "ishift")
12554    (set_attr "mode" "QI")])
12555
12556 (define_insn "*ashrqi3_cconly"
12557   [(set (reg FLAGS_REG)
12558         (compare
12559           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12560                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12561           (const_int 0)))
12562    (clobber (match_scratch:QI 0 "=q"))]
12563   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12564    && ix86_match_ccmode (insn, CCGOCmode)
12565    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12566   "sar{b}\t{%2, %0|%0, %2}"
12567   [(set_attr "type" "ishift")
12568    (set_attr "mode" "QI")])
12569
12570 \f
12571 ;; Logical shift instructions
12572
12573 ;; See comment above `ashldi3' about how this works.
12574
12575 (define_expand "lshrti3"
12576   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12577                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12578                                 (match_operand:QI 2 "nonmemory_operand" "")))
12579               (clobber (reg:CC FLAGS_REG))])]
12580   "TARGET_64BIT"
12581 {
12582   if (! immediate_operand (operands[2], QImode))
12583     {
12584       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12585       DONE;
12586     }
12587   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12588   DONE;
12589 })
12590
12591 (define_insn "lshrti3_1"
12592   [(set (match_operand:TI 0 "register_operand" "=r")
12593         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12594                      (match_operand:QI 2 "register_operand" "c")))
12595    (clobber (match_scratch:DI 3 "=&r"))
12596    (clobber (reg:CC FLAGS_REG))]
12597   "TARGET_64BIT"
12598   "#"
12599   [(set_attr "type" "multi")])
12600
12601 ;; This pattern must be defined before *lshrti3_2 to prevent
12602 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12603
12604 (define_insn "sse2_lshrti3"
12605   [(set (match_operand:TI 0 "register_operand" "=x")
12606         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12607                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12608   "TARGET_SSE2"
12609 {
12610   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12611   return "psrldq\t{%2, %0|%0, %2}";
12612 }
12613   [(set_attr "type" "sseishft")
12614    (set_attr "prefix_data16" "1")
12615    (set_attr "mode" "TI")])
12616
12617 (define_insn "*lshrti3_2"
12618   [(set (match_operand:TI 0 "register_operand" "=r")
12619         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12620                      (match_operand:QI 2 "immediate_operand" "O")))
12621    (clobber (reg:CC FLAGS_REG))]
12622   "TARGET_64BIT"
12623   "#"
12624   [(set_attr "type" "multi")])
12625
12626 (define_split
12627   [(set (match_operand:TI 0 "register_operand" "")
12628         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12629                      (match_operand:QI 2 "register_operand" "")))
12630    (clobber (match_scratch:DI 3 ""))
12631    (clobber (reg:CC FLAGS_REG))]
12632   "TARGET_64BIT && reload_completed"
12633   [(const_int 0)]
12634   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12635
12636 (define_split
12637   [(set (match_operand:TI 0 "register_operand" "")
12638         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12639                      (match_operand:QI 2 "immediate_operand" "")))
12640    (clobber (reg:CC FLAGS_REG))]
12641   "TARGET_64BIT && reload_completed"
12642   [(const_int 0)]
12643   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12644
12645 (define_expand "lshrdi3"
12646   [(set (match_operand:DI 0 "shiftdi_operand" "")
12647         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12648                      (match_operand:QI 2 "nonmemory_operand" "")))]
12649   ""
12650   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12651
12652 (define_insn "*lshrdi3_1_one_bit_rex64"
12653   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12654         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12655                      (match_operand:QI 2 "const1_operand" "")))
12656    (clobber (reg:CC FLAGS_REG))]
12657   "TARGET_64BIT
12658    && (TARGET_SHIFT1 || optimize_size)
12659    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12660   "shr{q}\t%0"
12661   [(set_attr "type" "ishift")
12662    (set (attr "length")
12663      (if_then_else (match_operand:DI 0 "register_operand" "")
12664         (const_string "2")
12665         (const_string "*")))])
12666
12667 (define_insn "*lshrdi3_1_rex64"
12668   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12669         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12670                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12671    (clobber (reg:CC FLAGS_REG))]
12672   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12673   "@
12674    shr{q}\t{%2, %0|%0, %2}
12675    shr{q}\t{%b2, %0|%0, %b2}"
12676   [(set_attr "type" "ishift")
12677    (set_attr "mode" "DI")])
12678
12679 ;; This pattern can't accept a variable shift count, since shifts by
12680 ;; zero don't affect the flags.  We assume that shifts by constant
12681 ;; zero are optimized away.
12682 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12683   [(set (reg FLAGS_REG)
12684         (compare
12685           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12686                        (match_operand:QI 2 "const1_operand" ""))
12687           (const_int 0)))
12688    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12689         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12690   "TARGET_64BIT
12691    && (TARGET_SHIFT1 || optimize_size)
12692    && ix86_match_ccmode (insn, CCGOCmode)
12693    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12694   "shr{q}\t%0"
12695   [(set_attr "type" "ishift")
12696    (set (attr "length")
12697      (if_then_else (match_operand:DI 0 "register_operand" "")
12698         (const_string "2")
12699         (const_string "*")))])
12700
12701 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12702   [(set (reg FLAGS_REG)
12703         (compare
12704           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12705                        (match_operand:QI 2 "const1_operand" ""))
12706           (const_int 0)))
12707    (clobber (match_scratch:DI 0 "=r"))]
12708   "TARGET_64BIT
12709    && (TARGET_SHIFT1 || optimize_size)
12710    && ix86_match_ccmode (insn, CCGOCmode)
12711    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12712   "shr{q}\t%0"
12713   [(set_attr "type" "ishift")
12714    (set_attr "length" "2")])
12715
12716 ;; This pattern can't accept a variable shift count, since shifts by
12717 ;; zero don't affect the flags.  We assume that shifts by constant
12718 ;; zero are optimized away.
12719 (define_insn "*lshrdi3_cmp_rex64"
12720   [(set (reg FLAGS_REG)
12721         (compare
12722           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12723                        (match_operand:QI 2 "const_int_operand" "e"))
12724           (const_int 0)))
12725    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12726         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12727   "TARGET_64BIT
12728    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12729    && ix86_match_ccmode (insn, CCGOCmode)
12730    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12731   "shr{q}\t{%2, %0|%0, %2}"
12732   [(set_attr "type" "ishift")
12733    (set_attr "mode" "DI")])
12734
12735 (define_insn "*lshrdi3_cconly_rex64"
12736   [(set (reg FLAGS_REG)
12737         (compare
12738           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12739                        (match_operand:QI 2 "const_int_operand" "e"))
12740           (const_int 0)))
12741    (clobber (match_scratch:DI 0 "=r"))]
12742   "TARGET_64BIT
12743    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12744    && ix86_match_ccmode (insn, CCGOCmode)
12745    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12746   "shr{q}\t{%2, %0|%0, %2}"
12747   [(set_attr "type" "ishift")
12748    (set_attr "mode" "DI")])
12749
12750 (define_insn "*lshrdi3_1"
12751   [(set (match_operand:DI 0 "register_operand" "=r")
12752         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12753                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12754    (clobber (reg:CC FLAGS_REG))]
12755   "!TARGET_64BIT"
12756   "#"
12757   [(set_attr "type" "multi")])
12758
12759 ;; By default we don't ask for a scratch register, because when DImode
12760 ;; values are manipulated, registers are already at a premium.  But if
12761 ;; we have one handy, we won't turn it away.
12762 (define_peephole2
12763   [(match_scratch:SI 3 "r")
12764    (parallel [(set (match_operand:DI 0 "register_operand" "")
12765                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12766                                 (match_operand:QI 2 "nonmemory_operand" "")))
12767               (clobber (reg:CC FLAGS_REG))])
12768    (match_dup 3)]
12769   "!TARGET_64BIT && TARGET_CMOVE"
12770   [(const_int 0)]
12771   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12772
12773 (define_split
12774   [(set (match_operand:DI 0 "register_operand" "")
12775         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12776                      (match_operand:QI 2 "nonmemory_operand" "")))
12777    (clobber (reg:CC FLAGS_REG))]
12778   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12779                      ? epilogue_completed : reload_completed)"
12780   [(const_int 0)]
12781   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12782
12783 (define_expand "lshrsi3"
12784   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12785         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12786                      (match_operand:QI 2 "nonmemory_operand" "")))
12787    (clobber (reg:CC FLAGS_REG))]
12788   ""
12789   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12790
12791 (define_insn "*lshrsi3_1_one_bit"
12792   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12793         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12794                      (match_operand:QI 2 "const1_operand" "")))
12795    (clobber (reg:CC FLAGS_REG))]
12796   "(TARGET_SHIFT1 || optimize_size)
12797    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12798   "shr{l}\t%0"
12799   [(set_attr "type" "ishift")
12800    (set (attr "length")
12801      (if_then_else (match_operand:SI 0 "register_operand" "")
12802         (const_string "2")
12803         (const_string "*")))])
12804
12805 (define_insn "*lshrsi3_1_one_bit_zext"
12806   [(set (match_operand:DI 0 "register_operand" "=r")
12807         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12808                      (match_operand:QI 2 "const1_operand" "")))
12809    (clobber (reg:CC FLAGS_REG))]
12810   "TARGET_64BIT
12811    && (TARGET_SHIFT1 || optimize_size)
12812    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12813   "shr{l}\t%k0"
12814   [(set_attr "type" "ishift")
12815    (set_attr "length" "2")])
12816
12817 (define_insn "*lshrsi3_1"
12818   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12819         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12820                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12821    (clobber (reg:CC FLAGS_REG))]
12822   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12823   "@
12824    shr{l}\t{%2, %0|%0, %2}
12825    shr{l}\t{%b2, %0|%0, %b2}"
12826   [(set_attr "type" "ishift")
12827    (set_attr "mode" "SI")])
12828
12829 (define_insn "*lshrsi3_1_zext"
12830   [(set (match_operand:DI 0 "register_operand" "=r,r")
12831         (zero_extend:DI
12832           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12833                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12834    (clobber (reg:CC FLAGS_REG))]
12835   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12836   "@
12837    shr{l}\t{%2, %k0|%k0, %2}
12838    shr{l}\t{%b2, %k0|%k0, %b2}"
12839   [(set_attr "type" "ishift")
12840    (set_attr "mode" "SI")])
12841
12842 ;; This pattern can't accept a variable shift count, since shifts by
12843 ;; zero don't affect the flags.  We assume that shifts by constant
12844 ;; zero are optimized away.
12845 (define_insn "*lshrsi3_one_bit_cmp"
12846   [(set (reg FLAGS_REG)
12847         (compare
12848           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12849                        (match_operand:QI 2 "const1_operand" ""))
12850           (const_int 0)))
12851    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12852         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12853   "(TARGET_SHIFT1 || optimize_size)
12854    && ix86_match_ccmode (insn, CCGOCmode)
12855    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12856   "shr{l}\t%0"
12857   [(set_attr "type" "ishift")
12858    (set (attr "length")
12859      (if_then_else (match_operand:SI 0 "register_operand" "")
12860         (const_string "2")
12861         (const_string "*")))])
12862
12863 (define_insn "*lshrsi3_one_bit_cconly"
12864   [(set (reg FLAGS_REG)
12865         (compare
12866           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12867                        (match_operand:QI 2 "const1_operand" ""))
12868           (const_int 0)))
12869    (clobber (match_scratch:SI 0 "=r"))]
12870   "(TARGET_SHIFT1 || optimize_size)
12871    && ix86_match_ccmode (insn, CCGOCmode)
12872    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12873   "shr{l}\t%0"
12874   [(set_attr "type" "ishift")
12875    (set_attr "length" "2")])
12876
12877 (define_insn "*lshrsi3_cmp_one_bit_zext"
12878   [(set (reg FLAGS_REG)
12879         (compare
12880           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12881                        (match_operand:QI 2 "const1_operand" ""))
12882           (const_int 0)))
12883    (set (match_operand:DI 0 "register_operand" "=r")
12884         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12885   "TARGET_64BIT
12886    && (TARGET_SHIFT1 || optimize_size)
12887    && ix86_match_ccmode (insn, CCGOCmode)
12888    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12889   "shr{l}\t%k0"
12890   [(set_attr "type" "ishift")
12891    (set_attr "length" "2")])
12892
12893 ;; This pattern can't accept a variable shift count, since shifts by
12894 ;; zero don't affect the flags.  We assume that shifts by constant
12895 ;; zero are optimized away.
12896 (define_insn "*lshrsi3_cmp"
12897   [(set (reg FLAGS_REG)
12898         (compare
12899           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12900                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12901           (const_int 0)))
12902    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12903         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12904   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12905    && ix86_match_ccmode (insn, CCGOCmode)
12906    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12907   "shr{l}\t{%2, %0|%0, %2}"
12908   [(set_attr "type" "ishift")
12909    (set_attr "mode" "SI")])
12910
12911 (define_insn "*lshrsi3_cconly"
12912   [(set (reg FLAGS_REG)
12913       (compare
12914         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12915                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12916         (const_int 0)))
12917    (clobber (match_scratch:SI 0 "=r"))]
12918   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12919    && ix86_match_ccmode (insn, CCGOCmode)
12920    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12921   "shr{l}\t{%2, %0|%0, %2}"
12922   [(set_attr "type" "ishift")
12923    (set_attr "mode" "SI")])
12924
12925 (define_insn "*lshrsi3_cmp_zext"
12926   [(set (reg FLAGS_REG)
12927         (compare
12928           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12929                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12930           (const_int 0)))
12931    (set (match_operand:DI 0 "register_operand" "=r")
12932         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12933   "TARGET_64BIT
12934    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12935    && ix86_match_ccmode (insn, CCGOCmode)
12936    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12937   "shr{l}\t{%2, %k0|%k0, %2}"
12938   [(set_attr "type" "ishift")
12939    (set_attr "mode" "SI")])
12940
12941 (define_expand "lshrhi3"
12942   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12943         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12944                      (match_operand:QI 2 "nonmemory_operand" "")))
12945    (clobber (reg:CC FLAGS_REG))]
12946   "TARGET_HIMODE_MATH"
12947   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12948
12949 (define_insn "*lshrhi3_1_one_bit"
12950   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12951         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12952                      (match_operand:QI 2 "const1_operand" "")))
12953    (clobber (reg:CC FLAGS_REG))]
12954   "(TARGET_SHIFT1 || optimize_size)
12955    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12956   "shr{w}\t%0"
12957   [(set_attr "type" "ishift")
12958    (set (attr "length")
12959      (if_then_else (match_operand 0 "register_operand" "")
12960         (const_string "2")
12961         (const_string "*")))])
12962
12963 (define_insn "*lshrhi3_1"
12964   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12965         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12966                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12967    (clobber (reg:CC FLAGS_REG))]
12968   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12969   "@
12970    shr{w}\t{%2, %0|%0, %2}
12971    shr{w}\t{%b2, %0|%0, %b2}"
12972   [(set_attr "type" "ishift")
12973    (set_attr "mode" "HI")])
12974
12975 ;; This pattern can't accept a variable shift count, since shifts by
12976 ;; zero don't affect the flags.  We assume that shifts by constant
12977 ;; zero are optimized away.
12978 (define_insn "*lshrhi3_one_bit_cmp"
12979   [(set (reg FLAGS_REG)
12980         (compare
12981           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12982                        (match_operand:QI 2 "const1_operand" ""))
12983           (const_int 0)))
12984    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12985         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12986   "(TARGET_SHIFT1 || optimize_size)
12987    && ix86_match_ccmode (insn, CCGOCmode)
12988    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12989   "shr{w}\t%0"
12990   [(set_attr "type" "ishift")
12991    (set (attr "length")
12992      (if_then_else (match_operand:SI 0 "register_operand" "")
12993         (const_string "2")
12994         (const_string "*")))])
12995
12996 (define_insn "*lshrhi3_one_bit_cconly"
12997   [(set (reg FLAGS_REG)
12998         (compare
12999           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13000                        (match_operand:QI 2 "const1_operand" ""))
13001           (const_int 0)))
13002    (clobber (match_scratch:HI 0 "=r"))]
13003   "(TARGET_SHIFT1 || optimize_size)
13004    && ix86_match_ccmode (insn, CCGOCmode)
13005    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13006   "shr{w}\t%0"
13007   [(set_attr "type" "ishift")
13008    (set_attr "length" "2")])
13009
13010 ;; This pattern can't accept a variable shift count, since shifts by
13011 ;; zero don't affect the flags.  We assume that shifts by constant
13012 ;; zero are optimized away.
13013 (define_insn "*lshrhi3_cmp"
13014   [(set (reg FLAGS_REG)
13015         (compare
13016           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13017                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13018           (const_int 0)))
13019    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13020         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13021   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13022    && ix86_match_ccmode (insn, CCGOCmode)
13023    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13024   "shr{w}\t{%2, %0|%0, %2}"
13025   [(set_attr "type" "ishift")
13026    (set_attr "mode" "HI")])
13027
13028 (define_insn "*lshrhi3_cconly"
13029   [(set (reg FLAGS_REG)
13030         (compare
13031           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13032                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13033           (const_int 0)))
13034    (clobber (match_scratch:HI 0 "=r"))]
13035   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13036    && ix86_match_ccmode (insn, CCGOCmode)
13037    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13038   "shr{w}\t{%2, %0|%0, %2}"
13039   [(set_attr "type" "ishift")
13040    (set_attr "mode" "HI")])
13041
13042 (define_expand "lshrqi3"
13043   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13044         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13045                      (match_operand:QI 2 "nonmemory_operand" "")))
13046    (clobber (reg:CC FLAGS_REG))]
13047   "TARGET_QIMODE_MATH"
13048   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13049
13050 (define_insn "*lshrqi3_1_one_bit"
13051   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13052         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13053                      (match_operand:QI 2 "const1_operand" "")))
13054    (clobber (reg:CC FLAGS_REG))]
13055   "(TARGET_SHIFT1 || optimize_size)
13056    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13057   "shr{b}\t%0"
13058   [(set_attr "type" "ishift")
13059    (set (attr "length")
13060      (if_then_else (match_operand 0 "register_operand" "")
13061         (const_string "2")
13062         (const_string "*")))])
13063
13064 (define_insn "*lshrqi3_1_one_bit_slp"
13065   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13066         (lshiftrt:QI (match_dup 0)
13067                      (match_operand:QI 1 "const1_operand" "")))
13068    (clobber (reg:CC FLAGS_REG))]
13069   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13070    && (TARGET_SHIFT1 || optimize_size)"
13071   "shr{b}\t%0"
13072   [(set_attr "type" "ishift1")
13073    (set (attr "length")
13074      (if_then_else (match_operand 0 "register_operand" "")
13075         (const_string "2")
13076         (const_string "*")))])
13077
13078 (define_insn "*lshrqi3_1"
13079   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13080         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13081                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13082    (clobber (reg:CC FLAGS_REG))]
13083   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13084   "@
13085    shr{b}\t{%2, %0|%0, %2}
13086    shr{b}\t{%b2, %0|%0, %b2}"
13087   [(set_attr "type" "ishift")
13088    (set_attr "mode" "QI")])
13089
13090 (define_insn "*lshrqi3_1_slp"
13091   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13092         (lshiftrt:QI (match_dup 0)
13093                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13094    (clobber (reg:CC FLAGS_REG))]
13095   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13096    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13097   "@
13098    shr{b}\t{%1, %0|%0, %1}
13099    shr{b}\t{%b1, %0|%0, %b1}"
13100   [(set_attr "type" "ishift1")
13101    (set_attr "mode" "QI")])
13102
13103 ;; This pattern can't accept a variable shift count, since shifts by
13104 ;; zero don't affect the flags.  We assume that shifts by constant
13105 ;; zero are optimized away.
13106 (define_insn "*lshrqi2_one_bit_cmp"
13107   [(set (reg FLAGS_REG)
13108         (compare
13109           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13110                        (match_operand:QI 2 "const1_operand" ""))
13111           (const_int 0)))
13112    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13113         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13114   "(TARGET_SHIFT1 || optimize_size)
13115    && ix86_match_ccmode (insn, CCGOCmode)
13116    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13117   "shr{b}\t%0"
13118   [(set_attr "type" "ishift")
13119    (set (attr "length")
13120      (if_then_else (match_operand:SI 0 "register_operand" "")
13121         (const_string "2")
13122         (const_string "*")))])
13123
13124 (define_insn "*lshrqi2_one_bit_cconly"
13125   [(set (reg FLAGS_REG)
13126         (compare
13127           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13128                        (match_operand:QI 2 "const1_operand" ""))
13129           (const_int 0)))
13130    (clobber (match_scratch:QI 0 "=q"))]
13131   "(TARGET_SHIFT1 || optimize_size)
13132    && ix86_match_ccmode (insn, CCGOCmode)
13133    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13134   "shr{b}\t%0"
13135   [(set_attr "type" "ishift")
13136    (set_attr "length" "2")])
13137
13138 ;; This pattern can't accept a variable shift count, since shifts by
13139 ;; zero don't affect the flags.  We assume that shifts by constant
13140 ;; zero are optimized away.
13141 (define_insn "*lshrqi2_cmp"
13142   [(set (reg FLAGS_REG)
13143         (compare
13144           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13145                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13146           (const_int 0)))
13147    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13148         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13149   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13150    && ix86_match_ccmode (insn, CCGOCmode)
13151    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13152   "shr{b}\t{%2, %0|%0, %2}"
13153   [(set_attr "type" "ishift")
13154    (set_attr "mode" "QI")])
13155
13156 (define_insn "*lshrqi2_cconly"
13157   [(set (reg FLAGS_REG)
13158         (compare
13159           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13160                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13161           (const_int 0)))
13162    (clobber (match_scratch:QI 0 "=q"))]
13163   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13164    && ix86_match_ccmode (insn, CCGOCmode)
13165    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13166   "shr{b}\t{%2, %0|%0, %2}"
13167   [(set_attr "type" "ishift")
13168    (set_attr "mode" "QI")])
13169 \f
13170 ;; Rotate instructions
13171
13172 (define_expand "rotldi3"
13173   [(set (match_operand:DI 0 "shiftdi_operand" "")
13174         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13175                    (match_operand:QI 2 "nonmemory_operand" "")))
13176    (clobber (reg:CC FLAGS_REG))]
13177  ""
13178 {
13179   if (TARGET_64BIT)
13180     {
13181       ix86_expand_binary_operator (ROTATE, DImode, operands);
13182       DONE;
13183     }
13184   if (!const_1_to_31_operand (operands[2], VOIDmode))
13185     FAIL;
13186   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13187   DONE;
13188 })
13189
13190 ;; Implement rotation using two double-precision shift instructions
13191 ;; and a scratch register.
13192 (define_insn_and_split "ix86_rotldi3"
13193  [(set (match_operand:DI 0 "register_operand" "=r")
13194        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13195                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13196   (clobber (reg:CC FLAGS_REG))
13197   (clobber (match_scratch:SI 3 "=&r"))]
13198  "!TARGET_64BIT"
13199  ""
13200  "&& reload_completed"
13201  [(set (match_dup 3) (match_dup 4))
13202   (parallel
13203    [(set (match_dup 4)
13204          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13205                  (lshiftrt:SI (match_dup 5)
13206                               (minus:QI (const_int 32) (match_dup 2)))))
13207     (clobber (reg:CC FLAGS_REG))])
13208   (parallel
13209    [(set (match_dup 5)
13210          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13211                  (lshiftrt:SI (match_dup 3)
13212                               (minus:QI (const_int 32) (match_dup 2)))))
13213     (clobber (reg:CC FLAGS_REG))])]
13214  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13215
13216 (define_insn "*rotlsi3_1_one_bit_rex64"
13217   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13218         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13219                    (match_operand:QI 2 "const1_operand" "")))
13220    (clobber (reg:CC FLAGS_REG))]
13221   "TARGET_64BIT
13222    && (TARGET_SHIFT1 || optimize_size)
13223    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13224   "rol{q}\t%0"
13225   [(set_attr "type" "rotate")
13226    (set (attr "length")
13227      (if_then_else (match_operand:DI 0 "register_operand" "")
13228         (const_string "2")
13229         (const_string "*")))])
13230
13231 (define_insn "*rotldi3_1_rex64"
13232   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13233         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13234                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13235    (clobber (reg:CC FLAGS_REG))]
13236   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13237   "@
13238    rol{q}\t{%2, %0|%0, %2}
13239    rol{q}\t{%b2, %0|%0, %b2}"
13240   [(set_attr "type" "rotate")
13241    (set_attr "mode" "DI")])
13242
13243 (define_expand "rotlsi3"
13244   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13245         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13246                    (match_operand:QI 2 "nonmemory_operand" "")))
13247    (clobber (reg:CC FLAGS_REG))]
13248   ""
13249   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13250
13251 (define_insn "*rotlsi3_1_one_bit"
13252   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13253         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13254                    (match_operand:QI 2 "const1_operand" "")))
13255    (clobber (reg:CC FLAGS_REG))]
13256   "(TARGET_SHIFT1 || optimize_size)
13257    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13258   "rol{l}\t%0"
13259   [(set_attr "type" "rotate")
13260    (set (attr "length")
13261      (if_then_else (match_operand:SI 0 "register_operand" "")
13262         (const_string "2")
13263         (const_string "*")))])
13264
13265 (define_insn "*rotlsi3_1_one_bit_zext"
13266   [(set (match_operand:DI 0 "register_operand" "=r")
13267         (zero_extend:DI
13268           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13269                      (match_operand:QI 2 "const1_operand" ""))))
13270    (clobber (reg:CC FLAGS_REG))]
13271   "TARGET_64BIT
13272    && (TARGET_SHIFT1 || optimize_size)
13273    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13274   "rol{l}\t%k0"
13275   [(set_attr "type" "rotate")
13276    (set_attr "length" "2")])
13277
13278 (define_insn "*rotlsi3_1"
13279   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13280         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13281                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13282    (clobber (reg:CC FLAGS_REG))]
13283   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13284   "@
13285    rol{l}\t{%2, %0|%0, %2}
13286    rol{l}\t{%b2, %0|%0, %b2}"
13287   [(set_attr "type" "rotate")
13288    (set_attr "mode" "SI")])
13289
13290 (define_insn "*rotlsi3_1_zext"
13291   [(set (match_operand:DI 0 "register_operand" "=r,r")
13292         (zero_extend:DI
13293           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13294                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13295    (clobber (reg:CC FLAGS_REG))]
13296   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13297   "@
13298    rol{l}\t{%2, %k0|%k0, %2}
13299    rol{l}\t{%b2, %k0|%k0, %b2}"
13300   [(set_attr "type" "rotate")
13301    (set_attr "mode" "SI")])
13302
13303 (define_expand "rotlhi3"
13304   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13305         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13306                    (match_operand:QI 2 "nonmemory_operand" "")))
13307    (clobber (reg:CC FLAGS_REG))]
13308   "TARGET_HIMODE_MATH"
13309   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13310
13311 (define_insn "*rotlhi3_1_one_bit"
13312   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13313         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13314                    (match_operand:QI 2 "const1_operand" "")))
13315    (clobber (reg:CC FLAGS_REG))]
13316   "(TARGET_SHIFT1 || optimize_size)
13317    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13318   "rol{w}\t%0"
13319   [(set_attr "type" "rotate")
13320    (set (attr "length")
13321      (if_then_else (match_operand 0 "register_operand" "")
13322         (const_string "2")
13323         (const_string "*")))])
13324
13325 (define_insn "*rotlhi3_1"
13326   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13327         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13328                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13329    (clobber (reg:CC FLAGS_REG))]
13330   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13331   "@
13332    rol{w}\t{%2, %0|%0, %2}
13333    rol{w}\t{%b2, %0|%0, %b2}"
13334   [(set_attr "type" "rotate")
13335    (set_attr "mode" "HI")])
13336
13337 (define_split
13338  [(set (match_operand:HI 0 "register_operand" "")
13339        (rotate:HI (match_dup 0) (const_int 8)))
13340   (clobber (reg:CC FLAGS_REG))]
13341  "reload_completed"
13342  [(parallel [(set (strict_low_part (match_dup 0))
13343                   (bswap:HI (match_dup 0)))
13344              (clobber (reg:CC FLAGS_REG))])]
13345  "")
13346
13347 (define_expand "rotlqi3"
13348   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13349         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13350                    (match_operand:QI 2 "nonmemory_operand" "")))
13351    (clobber (reg:CC FLAGS_REG))]
13352   "TARGET_QIMODE_MATH"
13353   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13354
13355 (define_insn "*rotlqi3_1_one_bit_slp"
13356   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13357         (rotate:QI (match_dup 0)
13358                    (match_operand:QI 1 "const1_operand" "")))
13359    (clobber (reg:CC FLAGS_REG))]
13360   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13361    && (TARGET_SHIFT1 || optimize_size)"
13362   "rol{b}\t%0"
13363   [(set_attr "type" "rotate1")
13364    (set (attr "length")
13365      (if_then_else (match_operand 0 "register_operand" "")
13366         (const_string "2")
13367         (const_string "*")))])
13368
13369 (define_insn "*rotlqi3_1_one_bit"
13370   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13371         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13372                    (match_operand:QI 2 "const1_operand" "")))
13373    (clobber (reg:CC FLAGS_REG))]
13374   "(TARGET_SHIFT1 || optimize_size)
13375    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13376   "rol{b}\t%0"
13377   [(set_attr "type" "rotate")
13378    (set (attr "length")
13379      (if_then_else (match_operand 0 "register_operand" "")
13380         (const_string "2")
13381         (const_string "*")))])
13382
13383 (define_insn "*rotlqi3_1_slp"
13384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13385         (rotate:QI (match_dup 0)
13386                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13387    (clobber (reg:CC FLAGS_REG))]
13388   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13389    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13390   "@
13391    rol{b}\t{%1, %0|%0, %1}
13392    rol{b}\t{%b1, %0|%0, %b1}"
13393   [(set_attr "type" "rotate1")
13394    (set_attr "mode" "QI")])
13395
13396 (define_insn "*rotlqi3_1"
13397   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13398         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13399                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13400    (clobber (reg:CC FLAGS_REG))]
13401   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13402   "@
13403    rol{b}\t{%2, %0|%0, %2}
13404    rol{b}\t{%b2, %0|%0, %b2}"
13405   [(set_attr "type" "rotate")
13406    (set_attr "mode" "QI")])
13407
13408 (define_expand "rotrdi3"
13409   [(set (match_operand:DI 0 "shiftdi_operand" "")
13410         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13411                    (match_operand:QI 2 "nonmemory_operand" "")))
13412    (clobber (reg:CC FLAGS_REG))]
13413  ""
13414 {
13415   if (TARGET_64BIT)
13416     {
13417       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13418       DONE;
13419     }
13420   if (!const_1_to_31_operand (operands[2], VOIDmode))
13421     FAIL;
13422   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13423   DONE;
13424 })
13425
13426 ;; Implement rotation using two double-precision shift instructions
13427 ;; and a scratch register.
13428 (define_insn_and_split "ix86_rotrdi3"
13429  [(set (match_operand:DI 0 "register_operand" "=r")
13430        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13431                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13432   (clobber (reg:CC FLAGS_REG))
13433   (clobber (match_scratch:SI 3 "=&r"))]
13434  "!TARGET_64BIT"
13435  ""
13436  "&& reload_completed"
13437  [(set (match_dup 3) (match_dup 4))
13438   (parallel
13439    [(set (match_dup 4)
13440          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13441                  (ashift:SI (match_dup 5)
13442                             (minus:QI (const_int 32) (match_dup 2)))))
13443     (clobber (reg:CC FLAGS_REG))])
13444   (parallel
13445    [(set (match_dup 5)
13446          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13447                  (ashift:SI (match_dup 3)
13448                             (minus:QI (const_int 32) (match_dup 2)))))
13449     (clobber (reg:CC FLAGS_REG))])]
13450  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13451
13452 (define_insn "*rotrdi3_1_one_bit_rex64"
13453   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13454         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13455                      (match_operand:QI 2 "const1_operand" "")))
13456    (clobber (reg:CC FLAGS_REG))]
13457   "TARGET_64BIT
13458    && (TARGET_SHIFT1 || optimize_size)
13459    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13460   "ror{q}\t%0"
13461   [(set_attr "type" "rotate")
13462    (set (attr "length")
13463      (if_then_else (match_operand:DI 0 "register_operand" "")
13464         (const_string "2")
13465         (const_string "*")))])
13466
13467 (define_insn "*rotrdi3_1_rex64"
13468   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13469         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13470                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13471    (clobber (reg:CC FLAGS_REG))]
13472   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13473   "@
13474    ror{q}\t{%2, %0|%0, %2}
13475    ror{q}\t{%b2, %0|%0, %b2}"
13476   [(set_attr "type" "rotate")
13477    (set_attr "mode" "DI")])
13478
13479 (define_expand "rotrsi3"
13480   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13481         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13482                      (match_operand:QI 2 "nonmemory_operand" "")))
13483    (clobber (reg:CC FLAGS_REG))]
13484   ""
13485   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13486
13487 (define_insn "*rotrsi3_1_one_bit"
13488   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13489         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13490                      (match_operand:QI 2 "const1_operand" "")))
13491    (clobber (reg:CC FLAGS_REG))]
13492   "(TARGET_SHIFT1 || optimize_size)
13493    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13494   "ror{l}\t%0"
13495   [(set_attr "type" "rotate")
13496    (set (attr "length")
13497      (if_then_else (match_operand:SI 0 "register_operand" "")
13498         (const_string "2")
13499         (const_string "*")))])
13500
13501 (define_insn "*rotrsi3_1_one_bit_zext"
13502   [(set (match_operand:DI 0 "register_operand" "=r")
13503         (zero_extend:DI
13504           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13505                        (match_operand:QI 2 "const1_operand" ""))))
13506    (clobber (reg:CC FLAGS_REG))]
13507   "TARGET_64BIT
13508    && (TARGET_SHIFT1 || optimize_size)
13509    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13510   "ror{l}\t%k0"
13511   [(set_attr "type" "rotate")
13512    (set (attr "length")
13513      (if_then_else (match_operand:SI 0 "register_operand" "")
13514         (const_string "2")
13515         (const_string "*")))])
13516
13517 (define_insn "*rotrsi3_1"
13518   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13519         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13520                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13521    (clobber (reg:CC FLAGS_REG))]
13522   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13523   "@
13524    ror{l}\t{%2, %0|%0, %2}
13525    ror{l}\t{%b2, %0|%0, %b2}"
13526   [(set_attr "type" "rotate")
13527    (set_attr "mode" "SI")])
13528
13529 (define_insn "*rotrsi3_1_zext"
13530   [(set (match_operand:DI 0 "register_operand" "=r,r")
13531         (zero_extend:DI
13532           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13533                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13534    (clobber (reg:CC FLAGS_REG))]
13535   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13536   "@
13537    ror{l}\t{%2, %k0|%k0, %2}
13538    ror{l}\t{%b2, %k0|%k0, %b2}"
13539   [(set_attr "type" "rotate")
13540    (set_attr "mode" "SI")])
13541
13542 (define_expand "rotrhi3"
13543   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13544         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13545                      (match_operand:QI 2 "nonmemory_operand" "")))
13546    (clobber (reg:CC FLAGS_REG))]
13547   "TARGET_HIMODE_MATH"
13548   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13549
13550 (define_insn "*rotrhi3_one_bit"
13551   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13552         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13553                      (match_operand:QI 2 "const1_operand" "")))
13554    (clobber (reg:CC FLAGS_REG))]
13555   "(TARGET_SHIFT1 || optimize_size)
13556    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13557   "ror{w}\t%0"
13558   [(set_attr "type" "rotate")
13559    (set (attr "length")
13560      (if_then_else (match_operand 0 "register_operand" "")
13561         (const_string "2")
13562         (const_string "*")))])
13563
13564 (define_insn "*rotrhi3_1"
13565   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13566         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13567                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13568    (clobber (reg:CC FLAGS_REG))]
13569   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13570   "@
13571    ror{w}\t{%2, %0|%0, %2}
13572    ror{w}\t{%b2, %0|%0, %b2}"
13573   [(set_attr "type" "rotate")
13574    (set_attr "mode" "HI")])
13575
13576 (define_split
13577  [(set (match_operand:HI 0 "register_operand" "")
13578        (rotatert:HI (match_dup 0) (const_int 8)))
13579   (clobber (reg:CC FLAGS_REG))]
13580  "reload_completed"
13581  [(parallel [(set (strict_low_part (match_dup 0))
13582                   (bswap:HI (match_dup 0)))
13583              (clobber (reg:CC FLAGS_REG))])]
13584  "")
13585
13586 (define_expand "rotrqi3"
13587   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13588         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13589                      (match_operand:QI 2 "nonmemory_operand" "")))
13590    (clobber (reg:CC FLAGS_REG))]
13591   "TARGET_QIMODE_MATH"
13592   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13593
13594 (define_insn "*rotrqi3_1_one_bit"
13595   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13596         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13597                      (match_operand:QI 2 "const1_operand" "")))
13598    (clobber (reg:CC FLAGS_REG))]
13599   "(TARGET_SHIFT1 || optimize_size)
13600    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13601   "ror{b}\t%0"
13602   [(set_attr "type" "rotate")
13603    (set (attr "length")
13604      (if_then_else (match_operand 0 "register_operand" "")
13605         (const_string "2")
13606         (const_string "*")))])
13607
13608 (define_insn "*rotrqi3_1_one_bit_slp"
13609   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13610         (rotatert:QI (match_dup 0)
13611                      (match_operand:QI 1 "const1_operand" "")))
13612    (clobber (reg:CC FLAGS_REG))]
13613   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13614    && (TARGET_SHIFT1 || optimize_size)"
13615   "ror{b}\t%0"
13616   [(set_attr "type" "rotate1")
13617    (set (attr "length")
13618      (if_then_else (match_operand 0 "register_operand" "")
13619         (const_string "2")
13620         (const_string "*")))])
13621
13622 (define_insn "*rotrqi3_1"
13623   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13624         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13625                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13626    (clobber (reg:CC FLAGS_REG))]
13627   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13628   "@
13629    ror{b}\t{%2, %0|%0, %2}
13630    ror{b}\t{%b2, %0|%0, %b2}"
13631   [(set_attr "type" "rotate")
13632    (set_attr "mode" "QI")])
13633
13634 (define_insn "*rotrqi3_1_slp"
13635   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13636         (rotatert:QI (match_dup 0)
13637                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13638    (clobber (reg:CC FLAGS_REG))]
13639   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13640    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13641   "@
13642    ror{b}\t{%1, %0|%0, %1}
13643    ror{b}\t{%b1, %0|%0, %b1}"
13644   [(set_attr "type" "rotate1")
13645    (set_attr "mode" "QI")])
13646 \f
13647 ;; Bit set / bit test instructions
13648
13649 (define_expand "extv"
13650   [(set (match_operand:SI 0 "register_operand" "")
13651         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13652                          (match_operand:SI 2 "const8_operand" "")
13653                          (match_operand:SI 3 "const8_operand" "")))]
13654   ""
13655 {
13656   /* Handle extractions from %ah et al.  */
13657   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13658     FAIL;
13659
13660   /* From mips.md: extract_bit_field doesn't verify that our source
13661      matches the predicate, so check it again here.  */
13662   if (! ext_register_operand (operands[1], VOIDmode))
13663     FAIL;
13664 })
13665
13666 (define_expand "extzv"
13667   [(set (match_operand:SI 0 "register_operand" "")
13668         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13669                          (match_operand:SI 2 "const8_operand" "")
13670                          (match_operand:SI 3 "const8_operand" "")))]
13671   ""
13672 {
13673   /* Handle extractions from %ah et al.  */
13674   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13675     FAIL;
13676
13677   /* From mips.md: extract_bit_field doesn't verify that our source
13678      matches the predicate, so check it again here.  */
13679   if (! ext_register_operand (operands[1], VOIDmode))
13680     FAIL;
13681 })
13682
13683 (define_expand "insv"
13684   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13685                       (match_operand 1 "const8_operand" "")
13686                       (match_operand 2 "const8_operand" ""))
13687         (match_operand 3 "register_operand" ""))]
13688   ""
13689 {
13690   /* Handle insertions to %ah et al.  */
13691   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13692     FAIL;
13693
13694   /* From mips.md: insert_bit_field doesn't verify that our source
13695      matches the predicate, so check it again here.  */
13696   if (! ext_register_operand (operands[0], VOIDmode))
13697     FAIL;
13698
13699   if (TARGET_64BIT)
13700     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13701   else
13702     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13703
13704   DONE;
13705 })
13706
13707 ;; %%% bts, btr, btc, bt.
13708 ;; In general these instructions are *slow* when applied to memory,
13709 ;; since they enforce atomic operation.  When applied to registers,
13710 ;; it depends on the cpu implementation.  They're never faster than
13711 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13712 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13713 ;; within the instruction itself, so operating on bits in the high
13714 ;; 32-bits of a register becomes easier.
13715 ;;
13716 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13717 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13718 ;; negdf respectively, so they can never be disabled entirely.
13719
13720 (define_insn "*btsq"
13721   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13722                          (const_int 1)
13723                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13724         (const_int 1))
13725    (clobber (reg:CC FLAGS_REG))]
13726   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13727   "bts{q} %1,%0"
13728   [(set_attr "type" "alu1")])
13729
13730 (define_insn "*btrq"
13731   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13732                          (const_int 1)
13733                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13734         (const_int 0))
13735    (clobber (reg:CC FLAGS_REG))]
13736   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13737   "btr{q} %1,%0"
13738   [(set_attr "type" "alu1")])
13739
13740 (define_insn "*btcq"
13741   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13742                          (const_int 1)
13743                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13744         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13745    (clobber (reg:CC FLAGS_REG))]
13746   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13747   "btc{q} %1,%0"
13748   [(set_attr "type" "alu1")])
13749
13750 ;; Allow Nocona to avoid these instructions if a register is available.
13751
13752 (define_peephole2
13753   [(match_scratch:DI 2 "r")
13754    (parallel [(set (zero_extract:DI
13755                      (match_operand:DI 0 "register_operand" "")
13756                      (const_int 1)
13757                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13758                    (const_int 1))
13759               (clobber (reg:CC FLAGS_REG))])]
13760   "TARGET_64BIT && !TARGET_USE_BT"
13761   [(const_int 0)]
13762 {
13763   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13764   rtx op1;
13765
13766   if (HOST_BITS_PER_WIDE_INT >= 64)
13767     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13768   else if (i < HOST_BITS_PER_WIDE_INT)
13769     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13770   else
13771     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13772
13773   op1 = immed_double_const (lo, hi, DImode);
13774   if (i >= 31)
13775     {
13776       emit_move_insn (operands[2], op1);
13777       op1 = operands[2];
13778     }
13779
13780   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13781   DONE;
13782 })
13783
13784 (define_peephole2
13785   [(match_scratch:DI 2 "r")
13786    (parallel [(set (zero_extract:DI
13787                      (match_operand:DI 0 "register_operand" "")
13788                      (const_int 1)
13789                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13790                    (const_int 0))
13791               (clobber (reg:CC FLAGS_REG))])]
13792   "TARGET_64BIT && !TARGET_USE_BT"
13793   [(const_int 0)]
13794 {
13795   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13796   rtx op1;
13797
13798   if (HOST_BITS_PER_WIDE_INT >= 64)
13799     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13800   else if (i < HOST_BITS_PER_WIDE_INT)
13801     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13802   else
13803     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13804
13805   op1 = immed_double_const (~lo, ~hi, DImode);
13806   if (i >= 32)
13807     {
13808       emit_move_insn (operands[2], op1);
13809       op1 = operands[2];
13810     }
13811
13812   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13813   DONE;
13814 })
13815
13816 (define_peephole2
13817   [(match_scratch:DI 2 "r")
13818    (parallel [(set (zero_extract:DI
13819                      (match_operand:DI 0 "register_operand" "")
13820                      (const_int 1)
13821                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13822               (not:DI (zero_extract:DI
13823                         (match_dup 0) (const_int 1) (match_dup 1))))
13824               (clobber (reg:CC FLAGS_REG))])]
13825   "TARGET_64BIT && !TARGET_USE_BT"
13826   [(const_int 0)]
13827 {
13828   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13829   rtx op1;
13830
13831   if (HOST_BITS_PER_WIDE_INT >= 64)
13832     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13833   else if (i < HOST_BITS_PER_WIDE_INT)
13834     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13835   else
13836     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13837
13838   op1 = immed_double_const (lo, hi, DImode);
13839   if (i >= 31)
13840     {
13841       emit_move_insn (operands[2], op1);
13842       op1 = operands[2];
13843     }
13844
13845   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13846   DONE;
13847 })
13848 \f
13849 ;; Store-flag instructions.
13850
13851 ;; For all sCOND expanders, also expand the compare or test insn that
13852 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13853
13854 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13855 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13856 ;; way, which can later delete the movzx if only QImode is needed.
13857
13858 (define_expand "s<code>"
13859   [(set (match_operand:QI 0 "register_operand" "")
13860         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13861   ""
13862   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13863
13864 (define_expand "s<code>"
13865   [(set (match_operand:QI 0 "register_operand" "")
13866         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13867   "TARGET_80387 || TARGET_SSE"
13868   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13869
13870 (define_insn "*setcc_1"
13871   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13872         (match_operator:QI 1 "ix86_comparison_operator"
13873           [(reg FLAGS_REG) (const_int 0)]))]
13874   ""
13875   "set%C1\t%0"
13876   [(set_attr "type" "setcc")
13877    (set_attr "mode" "QI")])
13878
13879 (define_insn "*setcc_2"
13880   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13881         (match_operator:QI 1 "ix86_comparison_operator"
13882           [(reg FLAGS_REG) (const_int 0)]))]
13883   ""
13884   "set%C1\t%0"
13885   [(set_attr "type" "setcc")
13886    (set_attr "mode" "QI")])
13887
13888 ;; In general it is not safe to assume too much about CCmode registers,
13889 ;; so simplify-rtx stops when it sees a second one.  Under certain
13890 ;; conditions this is safe on x86, so help combine not create
13891 ;;
13892 ;;      seta    %al
13893 ;;      testb   %al, %al
13894 ;;      sete    %al
13895
13896 (define_split
13897   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13898         (ne:QI (match_operator 1 "ix86_comparison_operator"
13899                  [(reg FLAGS_REG) (const_int 0)])
13900             (const_int 0)))]
13901   ""
13902   [(set (match_dup 0) (match_dup 1))]
13903 {
13904   PUT_MODE (operands[1], QImode);
13905 })
13906
13907 (define_split
13908   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13909         (ne:QI (match_operator 1 "ix86_comparison_operator"
13910                  [(reg FLAGS_REG) (const_int 0)])
13911             (const_int 0)))]
13912   ""
13913   [(set (match_dup 0) (match_dup 1))]
13914 {
13915   PUT_MODE (operands[1], QImode);
13916 })
13917
13918 (define_split
13919   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13920         (eq:QI (match_operator 1 "ix86_comparison_operator"
13921                  [(reg FLAGS_REG) (const_int 0)])
13922             (const_int 0)))]
13923   ""
13924   [(set (match_dup 0) (match_dup 1))]
13925 {
13926   rtx new_op1 = copy_rtx (operands[1]);
13927   operands[1] = new_op1;
13928   PUT_MODE (new_op1, QImode);
13929   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13930                                              GET_MODE (XEXP (new_op1, 0))));
13931
13932   /* Make sure that (a) the CCmode we have for the flags is strong
13933      enough for the reversed compare or (b) we have a valid FP compare.  */
13934   if (! ix86_comparison_operator (new_op1, VOIDmode))
13935     FAIL;
13936 })
13937
13938 (define_split
13939   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13940         (eq:QI (match_operator 1 "ix86_comparison_operator"
13941                  [(reg FLAGS_REG) (const_int 0)])
13942             (const_int 0)))]
13943   ""
13944   [(set (match_dup 0) (match_dup 1))]
13945 {
13946   rtx new_op1 = copy_rtx (operands[1]);
13947   operands[1] = new_op1;
13948   PUT_MODE (new_op1, QImode);
13949   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13950                                              GET_MODE (XEXP (new_op1, 0))));
13951
13952   /* Make sure that (a) the CCmode we have for the flags is strong
13953      enough for the reversed compare or (b) we have a valid FP compare.  */
13954   if (! ix86_comparison_operator (new_op1, VOIDmode))
13955     FAIL;
13956 })
13957
13958 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13959 ;; subsequent logical operations are used to imitate conditional moves.
13960 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13961 ;; it directly.
13962
13963 (define_insn "*sse_setcc<mode>"
13964   [(set (match_operand:MODEF 0 "register_operand" "=x")
13965         (match_operator:MODEF 1 "sse_comparison_operator"
13966           [(match_operand:MODEF 2 "register_operand" "0")
13967            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13968   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13969   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13970   [(set_attr "type" "ssecmp")
13971    (set_attr "mode" "<MODE>")])
13972
13973 (define_insn "*sse5_setcc<mode>"
13974   [(set (match_operand:MODEF 0 "register_operand" "=x")
13975         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13976           [(match_operand:MODEF 2 "register_operand" "x")
13977            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13978   "TARGET_SSE5"
13979   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13980   [(set_attr "type" "sse4arg")
13981    (set_attr "mode" "<MODE>")])
13982
13983 \f
13984 ;; Basic conditional jump instructions.
13985 ;; We ignore the overflow flag for signed branch instructions.
13986
13987 ;; For all bCOND expanders, also expand the compare or test insn that
13988 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13989
13990 (define_expand "b<code>"
13991   [(set (pc)
13992         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13993                                    (const_int 0))
13994                       (label_ref (match_operand 0 ""))
13995                       (pc)))]
13996   ""
13997   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13998
13999 (define_expand "b<code>"
14000   [(set (pc)
14001         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14002                                   (const_int 0))
14003                       (label_ref (match_operand 0 ""))
14004                       (pc)))]
14005   "TARGET_80387 || TARGET_SSE_MATH"
14006   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14007
14008 (define_insn "*jcc_1"
14009   [(set (pc)
14010         (if_then_else (match_operator 1 "ix86_comparison_operator"
14011                                       [(reg FLAGS_REG) (const_int 0)])
14012                       (label_ref (match_operand 0 "" ""))
14013                       (pc)))]
14014   ""
14015   "%+j%C1\t%l0"
14016   [(set_attr "type" "ibr")
14017    (set_attr "modrm" "0")
14018    (set (attr "length")
14019            (if_then_else (and (ge (minus (match_dup 0) (pc))
14020                                   (const_int -126))
14021                               (lt (minus (match_dup 0) (pc))
14022                                   (const_int 128)))
14023              (const_int 2)
14024              (const_int 6)))])
14025
14026 (define_insn "*jcc_2"
14027   [(set (pc)
14028         (if_then_else (match_operator 1 "ix86_comparison_operator"
14029                                       [(reg FLAGS_REG) (const_int 0)])
14030                       (pc)
14031                       (label_ref (match_operand 0 "" ""))))]
14032   ""
14033   "%+j%c1\t%l0"
14034   [(set_attr "type" "ibr")
14035    (set_attr "modrm" "0")
14036    (set (attr "length")
14037            (if_then_else (and (ge (minus (match_dup 0) (pc))
14038                                   (const_int -126))
14039                               (lt (minus (match_dup 0) (pc))
14040                                   (const_int 128)))
14041              (const_int 2)
14042              (const_int 6)))])
14043
14044 ;; In general it is not safe to assume too much about CCmode registers,
14045 ;; so simplify-rtx stops when it sees a second one.  Under certain
14046 ;; conditions this is safe on x86, so help combine not create
14047 ;;
14048 ;;      seta    %al
14049 ;;      testb   %al, %al
14050 ;;      je      Lfoo
14051
14052 (define_split
14053   [(set (pc)
14054         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14055                                       [(reg FLAGS_REG) (const_int 0)])
14056                           (const_int 0))
14057                       (label_ref (match_operand 1 "" ""))
14058                       (pc)))]
14059   ""
14060   [(set (pc)
14061         (if_then_else (match_dup 0)
14062                       (label_ref (match_dup 1))
14063                       (pc)))]
14064 {
14065   PUT_MODE (operands[0], VOIDmode);
14066 })
14067
14068 (define_split
14069   [(set (pc)
14070         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14071                                       [(reg FLAGS_REG) (const_int 0)])
14072                           (const_int 0))
14073                       (label_ref (match_operand 1 "" ""))
14074                       (pc)))]
14075   ""
14076   [(set (pc)
14077         (if_then_else (match_dup 0)
14078                       (label_ref (match_dup 1))
14079                       (pc)))]
14080 {
14081   rtx new_op0 = copy_rtx (operands[0]);
14082   operands[0] = new_op0;
14083   PUT_MODE (new_op0, VOIDmode);
14084   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14085                                              GET_MODE (XEXP (new_op0, 0))));
14086
14087   /* Make sure that (a) the CCmode we have for the flags is strong
14088      enough for the reversed compare or (b) we have a valid FP compare.  */
14089   if (! ix86_comparison_operator (new_op0, VOIDmode))
14090     FAIL;
14091 })
14092
14093 ;; Define combination compare-and-branch fp compare instructions to use
14094 ;; during early optimization.  Splitting the operation apart early makes
14095 ;; for bad code when we want to reverse the operation.
14096
14097 (define_insn "*fp_jcc_1_mixed"
14098   [(set (pc)
14099         (if_then_else (match_operator 0 "comparison_operator"
14100                         [(match_operand 1 "register_operand" "f,x")
14101                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14102           (label_ref (match_operand 3 "" ""))
14103           (pc)))
14104    (clobber (reg:CCFP FPSR_REG))
14105    (clobber (reg:CCFP FLAGS_REG))]
14106   "TARGET_MIX_SSE_I387
14107    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14108    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14109    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14110   "#")
14111
14112 (define_insn "*fp_jcc_1_sse"
14113   [(set (pc)
14114         (if_then_else (match_operator 0 "comparison_operator"
14115                         [(match_operand 1 "register_operand" "x")
14116                          (match_operand 2 "nonimmediate_operand" "xm")])
14117           (label_ref (match_operand 3 "" ""))
14118           (pc)))
14119    (clobber (reg:CCFP FPSR_REG))
14120    (clobber (reg:CCFP FLAGS_REG))]
14121   "TARGET_SSE_MATH
14122    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14123    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14124    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14125   "#")
14126
14127 (define_insn "*fp_jcc_1_387"
14128   [(set (pc)
14129         (if_then_else (match_operator 0 "comparison_operator"
14130                         [(match_operand 1 "register_operand" "f")
14131                          (match_operand 2 "register_operand" "f")])
14132           (label_ref (match_operand 3 "" ""))
14133           (pc)))
14134    (clobber (reg:CCFP FPSR_REG))
14135    (clobber (reg:CCFP FLAGS_REG))]
14136   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14137    && TARGET_CMOVE
14138    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14139    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14140   "#")
14141
14142 (define_insn "*fp_jcc_2_mixed"
14143   [(set (pc)
14144         (if_then_else (match_operator 0 "comparison_operator"
14145                         [(match_operand 1 "register_operand" "f,x")
14146                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14147           (pc)
14148           (label_ref (match_operand 3 "" ""))))
14149    (clobber (reg:CCFP FPSR_REG))
14150    (clobber (reg:CCFP FLAGS_REG))]
14151   "TARGET_MIX_SSE_I387
14152    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14153    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14154    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14155   "#")
14156
14157 (define_insn "*fp_jcc_2_sse"
14158   [(set (pc)
14159         (if_then_else (match_operator 0 "comparison_operator"
14160                         [(match_operand 1 "register_operand" "x")
14161                          (match_operand 2 "nonimmediate_operand" "xm")])
14162           (pc)
14163           (label_ref (match_operand 3 "" ""))))
14164    (clobber (reg:CCFP FPSR_REG))
14165    (clobber (reg:CCFP FLAGS_REG))]
14166   "TARGET_SSE_MATH
14167    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14168    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14169    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14170   "#")
14171
14172 (define_insn "*fp_jcc_2_387"
14173   [(set (pc)
14174         (if_then_else (match_operator 0 "comparison_operator"
14175                         [(match_operand 1 "register_operand" "f")
14176                          (match_operand 2 "register_operand" "f")])
14177           (pc)
14178           (label_ref (match_operand 3 "" ""))))
14179    (clobber (reg:CCFP FPSR_REG))
14180    (clobber (reg:CCFP FLAGS_REG))]
14181   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14182    && TARGET_CMOVE
14183    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14184    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14185   "#")
14186
14187 (define_insn "*fp_jcc_3_387"
14188   [(set (pc)
14189         (if_then_else (match_operator 0 "comparison_operator"
14190                         [(match_operand 1 "register_operand" "f")
14191                          (match_operand 2 "nonimmediate_operand" "fm")])
14192           (label_ref (match_operand 3 "" ""))
14193           (pc)))
14194    (clobber (reg:CCFP FPSR_REG))
14195    (clobber (reg:CCFP FLAGS_REG))
14196    (clobber (match_scratch:HI 4 "=a"))]
14197   "TARGET_80387
14198    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14199    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14200    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14201    && SELECT_CC_MODE (GET_CODE (operands[0]),
14202                       operands[1], operands[2]) == CCFPmode
14203    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14204   "#")
14205
14206 (define_insn "*fp_jcc_4_387"
14207   [(set (pc)
14208         (if_then_else (match_operator 0 "comparison_operator"
14209                         [(match_operand 1 "register_operand" "f")
14210                          (match_operand 2 "nonimmediate_operand" "fm")])
14211           (pc)
14212           (label_ref (match_operand 3 "" ""))))
14213    (clobber (reg:CCFP FPSR_REG))
14214    (clobber (reg:CCFP FLAGS_REG))
14215    (clobber (match_scratch:HI 4 "=a"))]
14216   "TARGET_80387
14217    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14218    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14219    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14220    && SELECT_CC_MODE (GET_CODE (operands[0]),
14221                       operands[1], operands[2]) == CCFPmode
14222    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14223   "#")
14224
14225 (define_insn "*fp_jcc_5_387"
14226   [(set (pc)
14227         (if_then_else (match_operator 0 "comparison_operator"
14228                         [(match_operand 1 "register_operand" "f")
14229                          (match_operand 2 "register_operand" "f")])
14230           (label_ref (match_operand 3 "" ""))
14231           (pc)))
14232    (clobber (reg:CCFP FPSR_REG))
14233    (clobber (reg:CCFP FLAGS_REG))
14234    (clobber (match_scratch:HI 4 "=a"))]
14235   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14236    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14237    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14238   "#")
14239
14240 (define_insn "*fp_jcc_6_387"
14241   [(set (pc)
14242         (if_then_else (match_operator 0 "comparison_operator"
14243                         [(match_operand 1 "register_operand" "f")
14244                          (match_operand 2 "register_operand" "f")])
14245           (pc)
14246           (label_ref (match_operand 3 "" ""))))
14247    (clobber (reg:CCFP FPSR_REG))
14248    (clobber (reg:CCFP FLAGS_REG))
14249    (clobber (match_scratch:HI 4 "=a"))]
14250   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14251    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14252    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14253   "#")
14254
14255 (define_insn "*fp_jcc_7_387"
14256   [(set (pc)
14257         (if_then_else (match_operator 0 "comparison_operator"
14258                         [(match_operand 1 "register_operand" "f")
14259                          (match_operand 2 "const0_operand" "X")])
14260           (label_ref (match_operand 3 "" ""))
14261           (pc)))
14262    (clobber (reg:CCFP FPSR_REG))
14263    (clobber (reg:CCFP FLAGS_REG))
14264    (clobber (match_scratch:HI 4 "=a"))]
14265   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14266    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14267    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14268    && SELECT_CC_MODE (GET_CODE (operands[0]),
14269                       operands[1], operands[2]) == CCFPmode
14270    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14271   "#")
14272
14273 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14274 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14275 ;; with a precedence over other operators and is always put in the first
14276 ;; place. Swap condition and operands to match ficom instruction.
14277
14278 (define_insn "*fp_jcc_8<mode>_387"
14279   [(set (pc)
14280         (if_then_else (match_operator 0 "comparison_operator"
14281                         [(match_operator 1 "float_operator"
14282                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14283                            (match_operand 3 "register_operand" "f,f")])
14284           (label_ref (match_operand 4 "" ""))
14285           (pc)))
14286    (clobber (reg:CCFP FPSR_REG))
14287    (clobber (reg:CCFP FLAGS_REG))
14288    (clobber (match_scratch:HI 5 "=a,a"))]
14289   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14290    && TARGET_USE_<MODE>MODE_FIOP
14291    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14292    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14293    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14294    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14295   "#")
14296
14297 (define_split
14298   [(set (pc)
14299         (if_then_else (match_operator 0 "comparison_operator"
14300                         [(match_operand 1 "register_operand" "")
14301                          (match_operand 2 "nonimmediate_operand" "")])
14302           (match_operand 3 "" "")
14303           (match_operand 4 "" "")))
14304    (clobber (reg:CCFP FPSR_REG))
14305    (clobber (reg:CCFP FLAGS_REG))]
14306   "reload_completed"
14307   [(const_int 0)]
14308 {
14309   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14310                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14311   DONE;
14312 })
14313
14314 (define_split
14315   [(set (pc)
14316         (if_then_else (match_operator 0 "comparison_operator"
14317                         [(match_operand 1 "register_operand" "")
14318                          (match_operand 2 "general_operand" "")])
14319           (match_operand 3 "" "")
14320           (match_operand 4 "" "")))
14321    (clobber (reg:CCFP FPSR_REG))
14322    (clobber (reg:CCFP FLAGS_REG))
14323    (clobber (match_scratch:HI 5 "=a"))]
14324   "reload_completed"
14325   [(const_int 0)]
14326 {
14327   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14328                         operands[3], operands[4], operands[5], NULL_RTX);
14329   DONE;
14330 })
14331
14332 (define_split
14333   [(set (pc)
14334         (if_then_else (match_operator 0 "comparison_operator"
14335                         [(match_operator 1 "float_operator"
14336                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14337                            (match_operand 3 "register_operand" "")])
14338           (match_operand 4 "" "")
14339           (match_operand 5 "" "")))
14340    (clobber (reg:CCFP FPSR_REG))
14341    (clobber (reg:CCFP FLAGS_REG))
14342    (clobber (match_scratch:HI 6 "=a"))]
14343   "reload_completed"
14344   [(const_int 0)]
14345 {
14346   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14347   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14348                         operands[3], operands[7],
14349                         operands[4], operands[5], operands[6], NULL_RTX);
14350   DONE;
14351 })
14352
14353 ;; %%% Kill this when reload knows how to do it.
14354 (define_split
14355   [(set (pc)
14356         (if_then_else (match_operator 0 "comparison_operator"
14357                         [(match_operator 1 "float_operator"
14358                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14359                            (match_operand 3 "register_operand" "")])
14360           (match_operand 4 "" "")
14361           (match_operand 5 "" "")))
14362    (clobber (reg:CCFP FPSR_REG))
14363    (clobber (reg:CCFP FLAGS_REG))
14364    (clobber (match_scratch:HI 6 "=a"))]
14365   "reload_completed"
14366   [(const_int 0)]
14367 {
14368   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14369   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14370   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14371                         operands[3], operands[7],
14372                         operands[4], operands[5], operands[6], operands[2]);
14373   DONE;
14374 })
14375 \f
14376 ;; Unconditional and other jump instructions
14377
14378 (define_insn "jump"
14379   [(set (pc)
14380         (label_ref (match_operand 0 "" "")))]
14381   ""
14382   "jmp\t%l0"
14383   [(set_attr "type" "ibr")
14384    (set (attr "length")
14385            (if_then_else (and (ge (minus (match_dup 0) (pc))
14386                                   (const_int -126))
14387                               (lt (minus (match_dup 0) (pc))
14388                                   (const_int 128)))
14389              (const_int 2)
14390              (const_int 5)))
14391    (set_attr "modrm" "0")])
14392
14393 (define_expand "indirect_jump"
14394   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14395   ""
14396   "")
14397
14398 (define_insn "*indirect_jump"
14399   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14400   "!TARGET_64BIT"
14401   "jmp\t%A0"
14402   [(set_attr "type" "ibr")
14403    (set_attr "length_immediate" "0")])
14404
14405 (define_insn "*indirect_jump_rtx64"
14406   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14407   "TARGET_64BIT"
14408   "jmp\t%A0"
14409   [(set_attr "type" "ibr")
14410    (set_attr "length_immediate" "0")])
14411
14412 (define_expand "tablejump"
14413   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14414               (use (label_ref (match_operand 1 "" "")))])]
14415   ""
14416 {
14417   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14418      relative.  Convert the relative address to an absolute address.  */
14419   if (flag_pic)
14420     {
14421       rtx op0, op1;
14422       enum rtx_code code;
14423
14424       /* We can't use @GOTOFF for text labels on VxWorks;
14425          see gotoff_operand.  */
14426       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14427         {
14428           code = PLUS;
14429           op0 = operands[0];
14430           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14431         }
14432       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14433         {
14434           code = PLUS;
14435           op0 = operands[0];
14436           op1 = pic_offset_table_rtx;
14437         }
14438       else
14439         {
14440           code = MINUS;
14441           op0 = pic_offset_table_rtx;
14442           op1 = operands[0];
14443         }
14444
14445       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14446                                          OPTAB_DIRECT);
14447     }
14448 })
14449
14450 (define_insn "*tablejump_1"
14451   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14452    (use (label_ref (match_operand 1 "" "")))]
14453   "!TARGET_64BIT"
14454   "jmp\t%A0"
14455   [(set_attr "type" "ibr")
14456    (set_attr "length_immediate" "0")])
14457
14458 (define_insn "*tablejump_1_rtx64"
14459   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14460    (use (label_ref (match_operand 1 "" "")))]
14461   "TARGET_64BIT"
14462   "jmp\t%A0"
14463   [(set_attr "type" "ibr")
14464    (set_attr "length_immediate" "0")])
14465 \f
14466 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14467
14468 (define_peephole2
14469   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14470    (set (match_operand:QI 1 "register_operand" "")
14471         (match_operator:QI 2 "ix86_comparison_operator"
14472           [(reg FLAGS_REG) (const_int 0)]))
14473    (set (match_operand 3 "q_regs_operand" "")
14474         (zero_extend (match_dup 1)))]
14475   "(peep2_reg_dead_p (3, operands[1])
14476     || operands_match_p (operands[1], operands[3]))
14477    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14478   [(set (match_dup 4) (match_dup 0))
14479    (set (strict_low_part (match_dup 5))
14480         (match_dup 2))]
14481 {
14482   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14483   operands[5] = gen_lowpart (QImode, operands[3]);
14484   ix86_expand_clear (operands[3]);
14485 })
14486
14487 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14488
14489 (define_peephole2
14490   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14491    (set (match_operand:QI 1 "register_operand" "")
14492         (match_operator:QI 2 "ix86_comparison_operator"
14493           [(reg FLAGS_REG) (const_int 0)]))
14494    (parallel [(set (match_operand 3 "q_regs_operand" "")
14495                    (zero_extend (match_dup 1)))
14496               (clobber (reg:CC FLAGS_REG))])]
14497   "(peep2_reg_dead_p (3, operands[1])
14498     || operands_match_p (operands[1], operands[3]))
14499    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14500   [(set (match_dup 4) (match_dup 0))
14501    (set (strict_low_part (match_dup 5))
14502         (match_dup 2))]
14503 {
14504   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14505   operands[5] = gen_lowpart (QImode, operands[3]);
14506   ix86_expand_clear (operands[3]);
14507 })
14508 \f
14509 ;; Call instructions.
14510
14511 ;; The predicates normally associated with named expanders are not properly
14512 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14513 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14514
14515 ;; Call subroutine returning no value.
14516
14517 (define_expand "call_pop"
14518   [(parallel [(call (match_operand:QI 0 "" "")
14519                     (match_operand:SI 1 "" ""))
14520               (set (reg:SI SP_REG)
14521                    (plus:SI (reg:SI SP_REG)
14522                             (match_operand:SI 3 "" "")))])]
14523   "!TARGET_64BIT"
14524 {
14525   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14526   DONE;
14527 })
14528
14529 (define_insn "*call_pop_0"
14530   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14531          (match_operand:SI 1 "" ""))
14532    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14533                             (match_operand:SI 2 "immediate_operand" "")))]
14534   "!TARGET_64BIT"
14535 {
14536   if (SIBLING_CALL_P (insn))
14537     return "jmp\t%P0";
14538   else
14539     return "call\t%P0";
14540 }
14541   [(set_attr "type" "call")])
14542
14543 (define_insn "*call_pop_1"
14544   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14545          (match_operand:SI 1 "" ""))
14546    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14547                             (match_operand:SI 2 "immediate_operand" "i")))]
14548   "!TARGET_64BIT"
14549 {
14550   if (constant_call_address_operand (operands[0], Pmode))
14551     {
14552       if (SIBLING_CALL_P (insn))
14553         return "jmp\t%P0";
14554       else
14555         return "call\t%P0";
14556     }
14557   if (SIBLING_CALL_P (insn))
14558     return "jmp\t%A0";
14559   else
14560     return "call\t%A0";
14561 }
14562   [(set_attr "type" "call")])
14563
14564 (define_expand "call"
14565   [(call (match_operand:QI 0 "" "")
14566          (match_operand 1 "" ""))
14567    (use (match_operand 2 "" ""))]
14568   ""
14569 {
14570   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14571   DONE;
14572 })
14573
14574 (define_expand "sibcall"
14575   [(call (match_operand:QI 0 "" "")
14576          (match_operand 1 "" ""))
14577    (use (match_operand 2 "" ""))]
14578   ""
14579 {
14580   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14581   DONE;
14582 })
14583
14584 (define_insn "*call_0"
14585   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14586          (match_operand 1 "" ""))]
14587   ""
14588 {
14589   if (SIBLING_CALL_P (insn))
14590     return "jmp\t%P0";
14591   else
14592     return "call\t%P0";
14593 }
14594   [(set_attr "type" "call")])
14595
14596 (define_insn "*call_1"
14597   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14598          (match_operand 1 "" ""))]
14599   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14600 {
14601   if (constant_call_address_operand (operands[0], Pmode))
14602     return "call\t%P0";
14603   return "call\t%A0";
14604 }
14605   [(set_attr "type" "call")])
14606
14607 (define_insn "*sibcall_1"
14608   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14609          (match_operand 1 "" ""))]
14610   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14611 {
14612   if (constant_call_address_operand (operands[0], Pmode))
14613     return "jmp\t%P0";
14614   return "jmp\t%A0";
14615 }
14616   [(set_attr "type" "call")])
14617
14618 (define_insn "*call_1_rex64"
14619   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14620          (match_operand 1 "" ""))]
14621   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14622    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14623 {
14624   if (constant_call_address_operand (operands[0], Pmode))
14625     return "call\t%P0";
14626   return "call\t%A0";
14627 }
14628   [(set_attr "type" "call")])
14629
14630 (define_insn "*call_1_rex64_large"
14631   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14632          (match_operand 1 "" ""))]
14633   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14634   "call\t%A0"
14635   [(set_attr "type" "call")])
14636
14637 (define_insn "*sibcall_1_rex64"
14638   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14639          (match_operand 1 "" ""))]
14640   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14641   "jmp\t%P0"
14642   [(set_attr "type" "call")])
14643
14644 (define_insn "*sibcall_1_rex64_v"
14645   [(call (mem:QI (reg:DI R11_REG))
14646          (match_operand 0 "" ""))]
14647   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14648   "jmp\t{*%%}r11"
14649   [(set_attr "type" "call")])
14650
14651
14652 ;; Call subroutine, returning value in operand 0
14653
14654 (define_expand "call_value_pop"
14655   [(parallel [(set (match_operand 0 "" "")
14656                    (call (match_operand:QI 1 "" "")
14657                          (match_operand:SI 2 "" "")))
14658               (set (reg:SI SP_REG)
14659                    (plus:SI (reg:SI SP_REG)
14660                             (match_operand:SI 4 "" "")))])]
14661   "!TARGET_64BIT"
14662 {
14663   ix86_expand_call (operands[0], operands[1], operands[2],
14664                     operands[3], operands[4], 0);
14665   DONE;
14666 })
14667
14668 (define_expand "call_value"
14669   [(set (match_operand 0 "" "")
14670         (call (match_operand:QI 1 "" "")
14671               (match_operand:SI 2 "" "")))
14672    (use (match_operand:SI 3 "" ""))]
14673   ;; Operand 2 not used on the i386.
14674   ""
14675 {
14676   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14677   DONE;
14678 })
14679
14680 (define_expand "sibcall_value"
14681   [(set (match_operand 0 "" "")
14682         (call (match_operand:QI 1 "" "")
14683               (match_operand:SI 2 "" "")))
14684    (use (match_operand:SI 3 "" ""))]
14685   ;; Operand 2 not used on the i386.
14686   ""
14687 {
14688   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14689   DONE;
14690 })
14691
14692 ;; Call subroutine returning any type.
14693
14694 (define_expand "untyped_call"
14695   [(parallel [(call (match_operand 0 "" "")
14696                     (const_int 0))
14697               (match_operand 1 "" "")
14698               (match_operand 2 "" "")])]
14699   ""
14700 {
14701   int i;
14702
14703   /* In order to give reg-stack an easier job in validating two
14704      coprocessor registers as containing a possible return value,
14705      simply pretend the untyped call returns a complex long double
14706      value.  */
14707
14708   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14709                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14710                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14711                     NULL, 0);
14712
14713   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14714     {
14715       rtx set = XVECEXP (operands[2], 0, i);
14716       emit_move_insn (SET_DEST (set), SET_SRC (set));
14717     }
14718
14719   /* The optimizer does not know that the call sets the function value
14720      registers we stored in the result block.  We avoid problems by
14721      claiming that all hard registers are used and clobbered at this
14722      point.  */
14723   emit_insn (gen_blockage ());
14724
14725   DONE;
14726 })
14727 \f
14728 ;; Prologue and epilogue instructions
14729
14730 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14731 ;; all of memory.  This blocks insns from being moved across this point.
14732
14733 (define_insn "blockage"
14734   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14735   ""
14736   ""
14737   [(set_attr "length" "0")])
14738
14739 ;; As USE insns aren't meaningful after reload, this is used instead
14740 ;; to prevent deleting instructions setting registers for PIC code
14741 (define_insn "prologue_use"
14742   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14743   ""
14744   ""
14745   [(set_attr "length" "0")])
14746
14747 ;; Insn emitted into the body of a function to return from a function.
14748 ;; This is only done if the function's epilogue is known to be simple.
14749 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14750
14751 (define_expand "return"
14752   [(return)]
14753   "ix86_can_use_return_insn_p ()"
14754 {
14755   if (crtl->args.pops_args)
14756     {
14757       rtx popc = GEN_INT (crtl->args.pops_args);
14758       emit_jump_insn (gen_return_pop_internal (popc));
14759       DONE;
14760     }
14761 })
14762
14763 (define_insn "return_internal"
14764   [(return)]
14765   "reload_completed"
14766   "ret"
14767   [(set_attr "length" "1")
14768    (set_attr "length_immediate" "0")
14769    (set_attr "modrm" "0")])
14770
14771 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14772 ;; instruction Athlon and K8 have.
14773
14774 (define_insn "return_internal_long"
14775   [(return)
14776    (unspec [(const_int 0)] UNSPEC_REP)]
14777   "reload_completed"
14778   "rep\;ret"
14779   [(set_attr "length" "1")
14780    (set_attr "length_immediate" "0")
14781    (set_attr "prefix_rep" "1")
14782    (set_attr "modrm" "0")])
14783
14784 (define_insn "return_pop_internal"
14785   [(return)
14786    (use (match_operand:SI 0 "const_int_operand" ""))]
14787   "reload_completed"
14788   "ret\t%0"
14789   [(set_attr "length" "3")
14790    (set_attr "length_immediate" "2")
14791    (set_attr "modrm" "0")])
14792
14793 (define_insn "return_indirect_internal"
14794   [(return)
14795    (use (match_operand:SI 0 "register_operand" "r"))]
14796   "reload_completed"
14797   "jmp\t%A0"
14798   [(set_attr "type" "ibr")
14799    (set_attr "length_immediate" "0")])
14800
14801 (define_insn "nop"
14802   [(const_int 0)]
14803   ""
14804   "nop"
14805   [(set_attr "length" "1")
14806    (set_attr "length_immediate" "0")
14807    (set_attr "modrm" "0")])
14808
14809 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14810 ;; branch prediction penalty for the third jump in a 16-byte
14811 ;; block on K8.
14812
14813 (define_insn "align"
14814   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14815   ""
14816 {
14817 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14818   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14819 #else
14820   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14821      The align insn is used to avoid 3 jump instructions in the row to improve
14822      branch prediction and the benefits hardly outweigh the cost of extra 8
14823      nops on the average inserted by full alignment pseudo operation.  */
14824 #endif
14825   return "";
14826 }
14827   [(set_attr "length" "16")])
14828
14829 (define_expand "prologue"
14830   [(const_int 0)]
14831   ""
14832   "ix86_expand_prologue (); DONE;")
14833
14834 (define_insn "set_got"
14835   [(set (match_operand:SI 0 "register_operand" "=r")
14836         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14837    (clobber (reg:CC FLAGS_REG))]
14838   "!TARGET_64BIT"
14839   { return output_set_got (operands[0], NULL_RTX); }
14840   [(set_attr "type" "multi")
14841    (set_attr "length" "12")])
14842
14843 (define_insn "set_got_labelled"
14844   [(set (match_operand:SI 0 "register_operand" "=r")
14845         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14846          UNSPEC_SET_GOT))
14847    (clobber (reg:CC FLAGS_REG))]
14848   "!TARGET_64BIT"
14849   { return output_set_got (operands[0], operands[1]); }
14850   [(set_attr "type" "multi")
14851    (set_attr "length" "12")])
14852
14853 (define_insn "set_got_rex64"
14854   [(set (match_operand:DI 0 "register_operand" "=r")
14855         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14856   "TARGET_64BIT"
14857   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14858   [(set_attr "type" "lea")
14859    (set_attr "length" "6")])
14860
14861 (define_insn "set_rip_rex64"
14862   [(set (match_operand:DI 0 "register_operand" "=r")
14863         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14864   "TARGET_64BIT"
14865   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14866   [(set_attr "type" "lea")
14867    (set_attr "length" "6")])
14868
14869 (define_insn "set_got_offset_rex64"
14870   [(set (match_operand:DI 0 "register_operand" "=r")
14871         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14872   "TARGET_64BIT"
14873   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14874   [(set_attr "type" "imov")
14875    (set_attr "length" "11")])
14876
14877 (define_expand "epilogue"
14878   [(const_int 0)]
14879   ""
14880   "ix86_expand_epilogue (1); DONE;")
14881
14882 (define_expand "sibcall_epilogue"
14883   [(const_int 0)]
14884   ""
14885   "ix86_expand_epilogue (0); DONE;")
14886
14887 (define_expand "eh_return"
14888   [(use (match_operand 0 "register_operand" ""))]
14889   ""
14890 {
14891   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14892
14893   /* Tricky bit: we write the address of the handler to which we will
14894      be returning into someone else's stack frame, one word below the
14895      stack address we wish to restore.  */
14896   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14897   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14898   tmp = gen_rtx_MEM (Pmode, tmp);
14899   emit_move_insn (tmp, ra);
14900
14901   if (Pmode == SImode)
14902     emit_jump_insn (gen_eh_return_si (sa));
14903   else
14904     emit_jump_insn (gen_eh_return_di (sa));
14905   emit_barrier ();
14906   DONE;
14907 })
14908
14909 (define_insn_and_split "eh_return_si"
14910   [(set (pc)
14911         (unspec [(match_operand:SI 0 "register_operand" "c")]
14912                  UNSPEC_EH_RETURN))]
14913   "!TARGET_64BIT"
14914   "#"
14915   "reload_completed"
14916   [(const_int 0)]
14917   "ix86_expand_epilogue (2); DONE;")
14918
14919 (define_insn_and_split "eh_return_di"
14920   [(set (pc)
14921         (unspec [(match_operand:DI 0 "register_operand" "c")]
14922                  UNSPEC_EH_RETURN))]
14923   "TARGET_64BIT"
14924   "#"
14925   "reload_completed"
14926   [(const_int 0)]
14927   "ix86_expand_epilogue (2); DONE;")
14928
14929 (define_insn "leave"
14930   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14931    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14932    (clobber (mem:BLK (scratch)))]
14933   "!TARGET_64BIT"
14934   "leave"
14935   [(set_attr "type" "leave")])
14936
14937 (define_insn "leave_rex64"
14938   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14939    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14940    (clobber (mem:BLK (scratch)))]
14941   "TARGET_64BIT"
14942   "leave"
14943   [(set_attr "type" "leave")])
14944 \f
14945 (define_expand "ffssi2"
14946   [(parallel
14947      [(set (match_operand:SI 0 "register_operand" "")
14948            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14949       (clobber (match_scratch:SI 2 ""))
14950       (clobber (reg:CC FLAGS_REG))])]
14951   ""
14952 {
14953   if (TARGET_CMOVE)
14954     {
14955       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14956       DONE;
14957     }
14958 })
14959
14960 (define_expand "ffs_cmove"
14961   [(set (match_dup 2) (const_int -1))
14962    (parallel [(set (reg:CCZ FLAGS_REG)
14963                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
14964                                 (const_int 0)))
14965               (set (match_operand:SI 0 "nonimmediate_operand" "")
14966                    (ctz:SI (match_dup 1)))])
14967    (set (match_dup 0) (if_then_else:SI
14968                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14969                         (match_dup 2)
14970                         (match_dup 0)))
14971    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14972               (clobber (reg:CC FLAGS_REG))])]
14973   "TARGET_CMOVE"
14974   "operands[2] = gen_reg_rtx (SImode);")
14975
14976 (define_insn_and_split "*ffs_no_cmove"
14977   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14978         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14979    (clobber (match_scratch:SI 2 "=&q"))
14980    (clobber (reg:CC FLAGS_REG))]
14981   "!TARGET_CMOVE"
14982   "#"
14983   "&& reload_completed"
14984   [(parallel [(set (reg:CCZ FLAGS_REG)
14985                    (compare:CCZ (match_dup 1) (const_int 0)))
14986               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14987    (set (strict_low_part (match_dup 3))
14988         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14989    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14990               (clobber (reg:CC FLAGS_REG))])
14991    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14992               (clobber (reg:CC FLAGS_REG))])
14993    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14994               (clobber (reg:CC FLAGS_REG))])]
14995 {
14996   operands[3] = gen_lowpart (QImode, operands[2]);
14997   ix86_expand_clear (operands[2]);
14998 })
14999
15000 (define_insn "*ffssi_1"
15001   [(set (reg:CCZ FLAGS_REG)
15002         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15003                      (const_int 0)))
15004    (set (match_operand:SI 0 "register_operand" "=r")
15005         (ctz:SI (match_dup 1)))]
15006   ""
15007   "bsf{l}\t{%1, %0|%0, %1}"
15008   [(set_attr "prefix_0f" "1")])
15009
15010 (define_expand "ffsdi2"
15011   [(set (match_dup 2) (const_int -1))
15012    (parallel [(set (reg:CCZ FLAGS_REG)
15013                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15014                                 (const_int 0)))
15015               (set (match_operand:DI 0 "nonimmediate_operand" "")
15016                    (ctz:DI (match_dup 1)))])
15017    (set (match_dup 0) (if_then_else:DI
15018                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15019                         (match_dup 2)
15020                         (match_dup 0)))
15021    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15022               (clobber (reg:CC FLAGS_REG))])]
15023   "TARGET_64BIT"
15024   "operands[2] = gen_reg_rtx (DImode);")
15025
15026 (define_insn "*ffsdi_1"
15027   [(set (reg:CCZ FLAGS_REG)
15028         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15029                      (const_int 0)))
15030    (set (match_operand:DI 0 "register_operand" "=r")
15031         (ctz:DI (match_dup 1)))]
15032   "TARGET_64BIT"
15033   "bsf{q}\t{%1, %0|%0, %1}"
15034   [(set_attr "prefix_0f" "1")])
15035
15036 (define_insn "ctzsi2"
15037   [(set (match_operand:SI 0 "register_operand" "=r")
15038         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15039    (clobber (reg:CC FLAGS_REG))]
15040   ""
15041   "bsf{l}\t{%1, %0|%0, %1}"
15042   [(set_attr "prefix_0f" "1")])
15043
15044 (define_insn "ctzdi2"
15045   [(set (match_operand:DI 0 "register_operand" "=r")
15046         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15047    (clobber (reg:CC FLAGS_REG))]
15048   "TARGET_64BIT"
15049   "bsf{q}\t{%1, %0|%0, %1}"
15050   [(set_attr "prefix_0f" "1")])
15051
15052 (define_expand "clzsi2"
15053   [(parallel
15054      [(set (match_operand:SI 0 "register_operand" "")
15055            (minus:SI (const_int 31)
15056                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15057       (clobber (reg:CC FLAGS_REG))])
15058    (parallel
15059      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15060       (clobber (reg:CC FLAGS_REG))])]
15061   ""
15062 {
15063   if (TARGET_ABM)
15064     {
15065       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15066       DONE;
15067     }
15068 })
15069
15070 (define_insn "clzsi2_abm"
15071   [(set (match_operand:SI 0 "register_operand" "=r")
15072         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15073    (clobber (reg:CC FLAGS_REG))]
15074   "TARGET_ABM"
15075   "lzcnt{l}\t{%1, %0|%0, %1}"
15076   [(set_attr "prefix_rep" "1")
15077    (set_attr "type" "bitmanip")
15078    (set_attr "mode" "SI")])
15079
15080 (define_insn "*bsr"
15081   [(set (match_operand:SI 0 "register_operand" "=r")
15082         (minus:SI (const_int 31)
15083                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15084    (clobber (reg:CC FLAGS_REG))]
15085   ""
15086   "bsr{l}\t{%1, %0|%0, %1}"
15087   [(set_attr "prefix_0f" "1")
15088    (set_attr "mode" "SI")])
15089
15090 (define_insn "popcountsi2"
15091   [(set (match_operand:SI 0 "register_operand" "=r")
15092         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15093    (clobber (reg:CC FLAGS_REG))]
15094   "TARGET_POPCNT"
15095   "popcnt{l}\t{%1, %0|%0, %1}"
15096   [(set_attr "prefix_rep" "1")
15097    (set_attr "type" "bitmanip")
15098    (set_attr "mode" "SI")])
15099
15100 (define_insn "*popcountsi2_cmp"
15101   [(set (reg FLAGS_REG)
15102         (compare
15103           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15104           (const_int 0)))
15105    (set (match_operand:SI 0 "register_operand" "=r")
15106         (popcount:SI (match_dup 1)))]
15107   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15108   "popcnt{l}\t{%1, %0|%0, %1}"
15109   [(set_attr "prefix_rep" "1")
15110    (set_attr "type" "bitmanip")
15111    (set_attr "mode" "SI")])
15112
15113 (define_insn "*popcountsi2_cmp_zext"
15114   [(set (reg FLAGS_REG)
15115         (compare
15116           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15117           (const_int 0)))
15118    (set (match_operand:DI 0 "register_operand" "=r")
15119         (zero_extend:DI(popcount:SI (match_dup 1))))]
15120   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15121   "popcnt{l}\t{%1, %0|%0, %1}"
15122   [(set_attr "prefix_rep" "1")
15123    (set_attr "type" "bitmanip")
15124    (set_attr "mode" "SI")])
15125
15126 (define_expand "bswapsi2"
15127   [(set (match_operand:SI 0 "register_operand" "")
15128         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15129   ""
15130 {
15131   if (!TARGET_BSWAP)
15132     {
15133       rtx x = operands[0];
15134
15135       emit_move_insn (x, operands[1]);
15136       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15137       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15138       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15139       DONE;
15140     }
15141 })
15142
15143 (define_insn "*bswapsi_1"
15144   [(set (match_operand:SI 0 "register_operand" "=r")
15145         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15146   "TARGET_BSWAP"
15147   "bswap\t%0"
15148   [(set_attr "prefix_0f" "1")
15149    (set_attr "length" "2")])
15150
15151 (define_insn "*bswaphi_lowpart_1"
15152   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15153         (bswap:HI (match_dup 0)))
15154    (clobber (reg:CC FLAGS_REG))]
15155   "TARGET_USE_XCHGB || optimize_size"
15156   "@
15157     xchg{b}\t{%h0, %b0|%b0, %h0}
15158     rol{w}\t{$8, %0|%0, 8}"
15159   [(set_attr "length" "2,4")
15160    (set_attr "mode" "QI,HI")])
15161
15162 (define_insn "bswaphi_lowpart"
15163   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15164         (bswap:HI (match_dup 0)))
15165    (clobber (reg:CC FLAGS_REG))]
15166   ""
15167   "rol{w}\t{$8, %0|%0, 8}"
15168   [(set_attr "length" "4")
15169    (set_attr "mode" "HI")])
15170
15171 (define_insn "bswapdi2"
15172   [(set (match_operand:DI 0 "register_operand" "=r")
15173         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15174   "TARGET_64BIT"
15175   "bswap\t%0"
15176   [(set_attr "prefix_0f" "1")
15177    (set_attr "length" "3")])
15178
15179 (define_expand "clzdi2"
15180   [(parallel
15181      [(set (match_operand:DI 0 "register_operand" "")
15182            (minus:DI (const_int 63)
15183                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15184       (clobber (reg:CC FLAGS_REG))])
15185    (parallel
15186      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15187       (clobber (reg:CC FLAGS_REG))])]
15188   "TARGET_64BIT"
15189 {
15190   if (TARGET_ABM)
15191     {
15192       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15193       DONE;
15194     }
15195 })
15196
15197 (define_insn "clzdi2_abm"
15198   [(set (match_operand:DI 0 "register_operand" "=r")
15199         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15200    (clobber (reg:CC FLAGS_REG))]
15201   "TARGET_64BIT && TARGET_ABM"
15202   "lzcnt{q}\t{%1, %0|%0, %1}"
15203   [(set_attr "prefix_rep" "1")
15204    (set_attr "type" "bitmanip")
15205    (set_attr "mode" "DI")])
15206
15207 (define_insn "*bsr_rex64"
15208   [(set (match_operand:DI 0 "register_operand" "=r")
15209         (minus:DI (const_int 63)
15210                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15211    (clobber (reg:CC FLAGS_REG))]
15212   "TARGET_64BIT"
15213   "bsr{q}\t{%1, %0|%0, %1}"
15214   [(set_attr "prefix_0f" "1")
15215    (set_attr "mode" "DI")])
15216
15217 (define_insn "popcountdi2"
15218   [(set (match_operand:DI 0 "register_operand" "=r")
15219         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15220    (clobber (reg:CC FLAGS_REG))]
15221   "TARGET_64BIT && TARGET_POPCNT"
15222   "popcnt{q}\t{%1, %0|%0, %1}"
15223   [(set_attr "prefix_rep" "1")
15224    (set_attr "type" "bitmanip")
15225    (set_attr "mode" "DI")])
15226
15227 (define_insn "*popcountdi2_cmp"
15228   [(set (reg FLAGS_REG)
15229         (compare
15230           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15231           (const_int 0)))
15232    (set (match_operand:DI 0 "register_operand" "=r")
15233         (popcount:DI (match_dup 1)))]
15234   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15235   "popcnt{q}\t{%1, %0|%0, %1}"
15236   [(set_attr "prefix_rep" "1")
15237    (set_attr "type" "bitmanip")
15238    (set_attr "mode" "DI")])
15239
15240 (define_expand "clzhi2"
15241   [(parallel
15242      [(set (match_operand:HI 0 "register_operand" "")
15243            (minus:HI (const_int 15)
15244                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15245       (clobber (reg:CC FLAGS_REG))])
15246    (parallel
15247      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15248       (clobber (reg:CC FLAGS_REG))])]
15249   ""
15250 {
15251   if (TARGET_ABM)
15252     {
15253       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15254       DONE;
15255     }
15256 })
15257
15258 (define_insn "clzhi2_abm"
15259   [(set (match_operand:HI 0 "register_operand" "=r")
15260         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15261    (clobber (reg:CC FLAGS_REG))]
15262   "TARGET_ABM"
15263   "lzcnt{w}\t{%1, %0|%0, %1}"
15264   [(set_attr "prefix_rep" "1")
15265    (set_attr "type" "bitmanip")
15266    (set_attr "mode" "HI")])
15267
15268 (define_insn "*bsrhi"
15269   [(set (match_operand:HI 0 "register_operand" "=r")
15270         (minus:HI (const_int 15)
15271                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15272    (clobber (reg:CC FLAGS_REG))]
15273   ""
15274   "bsr{w}\t{%1, %0|%0, %1}"
15275   [(set_attr "prefix_0f" "1")
15276    (set_attr "mode" "HI")])
15277
15278 (define_insn "popcounthi2"
15279   [(set (match_operand:HI 0 "register_operand" "=r")
15280         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15281    (clobber (reg:CC FLAGS_REG))]
15282   "TARGET_POPCNT"
15283   "popcnt{w}\t{%1, %0|%0, %1}"
15284   [(set_attr "prefix_rep" "1")
15285    (set_attr "type" "bitmanip")
15286    (set_attr "mode" "HI")])
15287
15288 (define_insn "*popcounthi2_cmp"
15289   [(set (reg FLAGS_REG)
15290         (compare
15291           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15292           (const_int 0)))
15293    (set (match_operand:HI 0 "register_operand" "=r")
15294         (popcount:HI (match_dup 1)))]
15295   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15296   "popcnt{w}\t{%1, %0|%0, %1}"
15297   [(set_attr "prefix_rep" "1")
15298    (set_attr "type" "bitmanip")
15299    (set_attr "mode" "HI")])
15300
15301 (define_expand "paritydi2"
15302   [(set (match_operand:DI 0 "register_operand" "")
15303         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15304   "! TARGET_POPCNT"
15305 {
15306   rtx scratch = gen_reg_rtx (QImode);
15307   rtx cond;
15308
15309   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15310                                 NULL_RTX, operands[1]));
15311
15312   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15313                          gen_rtx_REG (CCmode, FLAGS_REG),
15314                          const0_rtx);
15315   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15316
15317   if (TARGET_64BIT)
15318     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15319   else
15320     {
15321       rtx tmp = gen_reg_rtx (SImode);
15322
15323       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15324       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15325     }
15326   DONE;
15327 })
15328
15329 (define_insn_and_split "paritydi2_cmp"
15330   [(set (reg:CC FLAGS_REG)
15331         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15332    (clobber (match_scratch:DI 0 "=r"))
15333    (clobber (match_scratch:SI 1 "=&r"))
15334    (clobber (match_scratch:HI 2 "=Q"))]
15335   "! TARGET_POPCNT"
15336   "#"
15337   "&& reload_completed"
15338   [(parallel
15339      [(set (match_dup 1)
15340            (xor:SI (match_dup 1) (match_dup 4)))
15341       (clobber (reg:CC FLAGS_REG))])
15342    (parallel
15343      [(set (reg:CC FLAGS_REG)
15344            (parity:CC (match_dup 1)))
15345       (clobber (match_dup 1))
15346       (clobber (match_dup 2))])]
15347 {
15348   operands[4] = gen_lowpart (SImode, operands[3]);
15349
15350   if (TARGET_64BIT)
15351     {
15352       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15353       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15354     }
15355   else
15356     operands[1] = gen_highpart (SImode, operands[3]);
15357 })
15358
15359 (define_expand "paritysi2"
15360   [(set (match_operand:SI 0 "register_operand" "")
15361         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15362   "! TARGET_POPCNT"
15363 {
15364   rtx scratch = gen_reg_rtx (QImode);
15365   rtx cond;
15366
15367   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15368
15369   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15370                          gen_rtx_REG (CCmode, FLAGS_REG),
15371                          const0_rtx);
15372   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15373
15374   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15375   DONE;
15376 })
15377
15378 (define_insn_and_split "paritysi2_cmp"
15379   [(set (reg:CC FLAGS_REG)
15380         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15381    (clobber (match_scratch:SI 0 "=r"))
15382    (clobber (match_scratch:HI 1 "=&Q"))]
15383   "! TARGET_POPCNT"
15384   "#"
15385   "&& reload_completed"
15386   [(parallel
15387      [(set (match_dup 1)
15388            (xor:HI (match_dup 1) (match_dup 3)))
15389       (clobber (reg:CC FLAGS_REG))])
15390    (parallel
15391      [(set (reg:CC FLAGS_REG)
15392            (parity:CC (match_dup 1)))
15393       (clobber (match_dup 1))])]
15394 {
15395   operands[3] = gen_lowpart (HImode, operands[2]);
15396
15397   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15398   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15399 })
15400
15401 (define_insn "*parityhi2_cmp"
15402   [(set (reg:CC FLAGS_REG)
15403         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15404    (clobber (match_scratch:HI 0 "=Q"))]
15405   "! TARGET_POPCNT"
15406   "xor{b}\t{%h0, %b0|%b0, %h0}"
15407   [(set_attr "length" "2")
15408    (set_attr "mode" "HI")])
15409
15410 (define_insn "*parityqi2_cmp"
15411   [(set (reg:CC FLAGS_REG)
15412         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15413   "! TARGET_POPCNT"
15414   "test{b}\t%0, %0"
15415   [(set_attr "length" "2")
15416    (set_attr "mode" "QI")])
15417 \f
15418 ;; Thread-local storage patterns for ELF.
15419 ;;
15420 ;; Note that these code sequences must appear exactly as shown
15421 ;; in order to allow linker relaxation.
15422
15423 (define_insn "*tls_global_dynamic_32_gnu"
15424   [(set (match_operand:SI 0 "register_operand" "=a")
15425         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15426                     (match_operand:SI 2 "tls_symbolic_operand" "")
15427                     (match_operand:SI 3 "call_insn_operand" "")]
15428                     UNSPEC_TLS_GD))
15429    (clobber (match_scratch:SI 4 "=d"))
15430    (clobber (match_scratch:SI 5 "=c"))
15431    (clobber (reg:CC FLAGS_REG))]
15432   "!TARGET_64BIT && TARGET_GNU_TLS"
15433   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15434   [(set_attr "type" "multi")
15435    (set_attr "length" "12")])
15436
15437 (define_insn "*tls_global_dynamic_32_sun"
15438   [(set (match_operand:SI 0 "register_operand" "=a")
15439         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15440                     (match_operand:SI 2 "tls_symbolic_operand" "")
15441                     (match_operand:SI 3 "call_insn_operand" "")]
15442                     UNSPEC_TLS_GD))
15443    (clobber (match_scratch:SI 4 "=d"))
15444    (clobber (match_scratch:SI 5 "=c"))
15445    (clobber (reg:CC FLAGS_REG))]
15446   "!TARGET_64BIT && TARGET_SUN_TLS"
15447   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15448         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15449   [(set_attr "type" "multi")
15450    (set_attr "length" "14")])
15451
15452 (define_expand "tls_global_dynamic_32"
15453   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15454                    (unspec:SI
15455                     [(match_dup 2)
15456                      (match_operand:SI 1 "tls_symbolic_operand" "")
15457                      (match_dup 3)]
15458                     UNSPEC_TLS_GD))
15459               (clobber (match_scratch:SI 4 ""))
15460               (clobber (match_scratch:SI 5 ""))
15461               (clobber (reg:CC FLAGS_REG))])]
15462   ""
15463 {
15464   if (flag_pic)
15465     operands[2] = pic_offset_table_rtx;
15466   else
15467     {
15468       operands[2] = gen_reg_rtx (Pmode);
15469       emit_insn (gen_set_got (operands[2]));
15470     }
15471   if (TARGET_GNU2_TLS)
15472     {
15473        emit_insn (gen_tls_dynamic_gnu2_32
15474                   (operands[0], operands[1], operands[2]));
15475        DONE;
15476     }
15477   operands[3] = ix86_tls_get_addr ();
15478 })
15479
15480 (define_insn "*tls_global_dynamic_64"
15481   [(set (match_operand:DI 0 "register_operand" "=a")
15482         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15483                  (match_operand:DI 3 "" "")))
15484    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15485               UNSPEC_TLS_GD)]
15486   "TARGET_64BIT"
15487   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15488   [(set_attr "type" "multi")
15489    (set_attr "length" "16")])
15490
15491 (define_expand "tls_global_dynamic_64"
15492   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15493                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15494               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15495                          UNSPEC_TLS_GD)])]
15496   ""
15497 {
15498   if (TARGET_GNU2_TLS)
15499     {
15500        emit_insn (gen_tls_dynamic_gnu2_64
15501                   (operands[0], operands[1]));
15502        DONE;
15503     }
15504   operands[2] = ix86_tls_get_addr ();
15505 })
15506
15507 (define_insn "*tls_local_dynamic_base_32_gnu"
15508   [(set (match_operand:SI 0 "register_operand" "=a")
15509         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15510                     (match_operand:SI 2 "call_insn_operand" "")]
15511                    UNSPEC_TLS_LD_BASE))
15512    (clobber (match_scratch:SI 3 "=d"))
15513    (clobber (match_scratch:SI 4 "=c"))
15514    (clobber (reg:CC FLAGS_REG))]
15515   "!TARGET_64BIT && TARGET_GNU_TLS"
15516   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15517   [(set_attr "type" "multi")
15518    (set_attr "length" "11")])
15519
15520 (define_insn "*tls_local_dynamic_base_32_sun"
15521   [(set (match_operand:SI 0 "register_operand" "=a")
15522         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15523                     (match_operand:SI 2 "call_insn_operand" "")]
15524                    UNSPEC_TLS_LD_BASE))
15525    (clobber (match_scratch:SI 3 "=d"))
15526    (clobber (match_scratch:SI 4 "=c"))
15527    (clobber (reg:CC FLAGS_REG))]
15528   "!TARGET_64BIT && TARGET_SUN_TLS"
15529   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15530         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15531   [(set_attr "type" "multi")
15532    (set_attr "length" "13")])
15533
15534 (define_expand "tls_local_dynamic_base_32"
15535   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15536                    (unspec:SI [(match_dup 1) (match_dup 2)]
15537                               UNSPEC_TLS_LD_BASE))
15538               (clobber (match_scratch:SI 3 ""))
15539               (clobber (match_scratch:SI 4 ""))
15540               (clobber (reg:CC FLAGS_REG))])]
15541   ""
15542 {
15543   if (flag_pic)
15544     operands[1] = pic_offset_table_rtx;
15545   else
15546     {
15547       operands[1] = gen_reg_rtx (Pmode);
15548       emit_insn (gen_set_got (operands[1]));
15549     }
15550   if (TARGET_GNU2_TLS)
15551     {
15552        emit_insn (gen_tls_dynamic_gnu2_32
15553                   (operands[0], ix86_tls_module_base (), operands[1]));
15554        DONE;
15555     }
15556   operands[2] = ix86_tls_get_addr ();
15557 })
15558
15559 (define_insn "*tls_local_dynamic_base_64"
15560   [(set (match_operand:DI 0 "register_operand" "=a")
15561         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15562                  (match_operand:DI 2 "" "")))
15563    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15564   "TARGET_64BIT"
15565   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15566   [(set_attr "type" "multi")
15567    (set_attr "length" "12")])
15568
15569 (define_expand "tls_local_dynamic_base_64"
15570   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15571                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15572               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15573   ""
15574 {
15575   if (TARGET_GNU2_TLS)
15576     {
15577        emit_insn (gen_tls_dynamic_gnu2_64
15578                   (operands[0], ix86_tls_module_base ()));
15579        DONE;
15580     }
15581   operands[1] = ix86_tls_get_addr ();
15582 })
15583
15584 ;; Local dynamic of a single variable is a lose.  Show combine how
15585 ;; to convert that back to global dynamic.
15586
15587 (define_insn_and_split "*tls_local_dynamic_32_once"
15588   [(set (match_operand:SI 0 "register_operand" "=a")
15589         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15590                              (match_operand:SI 2 "call_insn_operand" "")]
15591                             UNSPEC_TLS_LD_BASE)
15592                  (const:SI (unspec:SI
15593                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15594                             UNSPEC_DTPOFF))))
15595    (clobber (match_scratch:SI 4 "=d"))
15596    (clobber (match_scratch:SI 5 "=c"))
15597    (clobber (reg:CC FLAGS_REG))]
15598   ""
15599   "#"
15600   ""
15601   [(parallel [(set (match_dup 0)
15602                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15603                               UNSPEC_TLS_GD))
15604               (clobber (match_dup 4))
15605               (clobber (match_dup 5))
15606               (clobber (reg:CC FLAGS_REG))])]
15607   "")
15608
15609 ;; Load and add the thread base pointer from %gs:0.
15610
15611 (define_insn "*load_tp_si"
15612   [(set (match_operand:SI 0 "register_operand" "=r")
15613         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15614   "!TARGET_64BIT"
15615   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15616   [(set_attr "type" "imov")
15617    (set_attr "modrm" "0")
15618    (set_attr "length" "7")
15619    (set_attr "memory" "load")
15620    (set_attr "imm_disp" "false")])
15621
15622 (define_insn "*add_tp_si"
15623   [(set (match_operand:SI 0 "register_operand" "=r")
15624         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15625                  (match_operand:SI 1 "register_operand" "0")))
15626    (clobber (reg:CC FLAGS_REG))]
15627   "!TARGET_64BIT"
15628   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15629   [(set_attr "type" "alu")
15630    (set_attr "modrm" "0")
15631    (set_attr "length" "7")
15632    (set_attr "memory" "load")
15633    (set_attr "imm_disp" "false")])
15634
15635 (define_insn "*load_tp_di"
15636   [(set (match_operand:DI 0 "register_operand" "=r")
15637         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15638   "TARGET_64BIT"
15639   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15640   [(set_attr "type" "imov")
15641    (set_attr "modrm" "0")
15642    (set_attr "length" "7")
15643    (set_attr "memory" "load")
15644    (set_attr "imm_disp" "false")])
15645
15646 (define_insn "*add_tp_di"
15647   [(set (match_operand:DI 0 "register_operand" "=r")
15648         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15649                  (match_operand:DI 1 "register_operand" "0")))
15650    (clobber (reg:CC FLAGS_REG))]
15651   "TARGET_64BIT"
15652   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15653   [(set_attr "type" "alu")
15654    (set_attr "modrm" "0")
15655    (set_attr "length" "7")
15656    (set_attr "memory" "load")
15657    (set_attr "imm_disp" "false")])
15658
15659 ;; GNU2 TLS patterns can be split.
15660
15661 (define_expand "tls_dynamic_gnu2_32"
15662   [(set (match_dup 3)
15663         (plus:SI (match_operand:SI 2 "register_operand" "")
15664                  (const:SI
15665                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15666                              UNSPEC_TLSDESC))))
15667    (parallel
15668     [(set (match_operand:SI 0 "register_operand" "")
15669           (unspec:SI [(match_dup 1) (match_dup 3)
15670                       (match_dup 2) (reg:SI SP_REG)]
15671                       UNSPEC_TLSDESC))
15672      (clobber (reg:CC FLAGS_REG))])]
15673   "!TARGET_64BIT && TARGET_GNU2_TLS"
15674 {
15675   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15676   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15677 })
15678
15679 (define_insn "*tls_dynamic_lea_32"
15680   [(set (match_operand:SI 0 "register_operand" "=r")
15681         (plus:SI (match_operand:SI 1 "register_operand" "b")
15682                  (const:SI
15683                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15684                               UNSPEC_TLSDESC))))]
15685   "!TARGET_64BIT && TARGET_GNU2_TLS"
15686   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15687   [(set_attr "type" "lea")
15688    (set_attr "mode" "SI")
15689    (set_attr "length" "6")
15690    (set_attr "length_address" "4")])
15691
15692 (define_insn "*tls_dynamic_call_32"
15693   [(set (match_operand:SI 0 "register_operand" "=a")
15694         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15695                     (match_operand:SI 2 "register_operand" "0")
15696                     ;; we have to make sure %ebx still points to the GOT
15697                     (match_operand:SI 3 "register_operand" "b")
15698                     (reg:SI SP_REG)]
15699                    UNSPEC_TLSDESC))
15700    (clobber (reg:CC FLAGS_REG))]
15701   "!TARGET_64BIT && TARGET_GNU2_TLS"
15702   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15703   [(set_attr "type" "call")
15704    (set_attr "length" "2")
15705    (set_attr "length_address" "0")])
15706
15707 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15708   [(set (match_operand:SI 0 "register_operand" "=&a")
15709         (plus:SI
15710          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15711                      (match_operand:SI 4 "" "")
15712                      (match_operand:SI 2 "register_operand" "b")
15713                      (reg:SI SP_REG)]
15714                     UNSPEC_TLSDESC)
15715          (const:SI (unspec:SI
15716                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15717                     UNSPEC_DTPOFF))))
15718    (clobber (reg:CC FLAGS_REG))]
15719   "!TARGET_64BIT && TARGET_GNU2_TLS"
15720   "#"
15721   ""
15722   [(set (match_dup 0) (match_dup 5))]
15723 {
15724   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15725   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15726 })
15727
15728 (define_expand "tls_dynamic_gnu2_64"
15729   [(set (match_dup 2)
15730         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15731                    UNSPEC_TLSDESC))
15732    (parallel
15733     [(set (match_operand:DI 0 "register_operand" "")
15734           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15735                      UNSPEC_TLSDESC))
15736      (clobber (reg:CC FLAGS_REG))])]
15737   "TARGET_64BIT && TARGET_GNU2_TLS"
15738 {
15739   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15740   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15741 })
15742
15743 (define_insn "*tls_dynamic_lea_64"
15744   [(set (match_operand:DI 0 "register_operand" "=r")
15745         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15746                    UNSPEC_TLSDESC))]
15747   "TARGET_64BIT && TARGET_GNU2_TLS"
15748   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15749   [(set_attr "type" "lea")
15750    (set_attr "mode" "DI")
15751    (set_attr "length" "7")
15752    (set_attr "length_address" "4")])
15753
15754 (define_insn "*tls_dynamic_call_64"
15755   [(set (match_operand:DI 0 "register_operand" "=a")
15756         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15757                     (match_operand:DI 2 "register_operand" "0")
15758                     (reg:DI SP_REG)]
15759                    UNSPEC_TLSDESC))
15760    (clobber (reg:CC FLAGS_REG))]
15761   "TARGET_64BIT && TARGET_GNU2_TLS"
15762   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15763   [(set_attr "type" "call")
15764    (set_attr "length" "2")
15765    (set_attr "length_address" "0")])
15766
15767 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15768   [(set (match_operand:DI 0 "register_operand" "=&a")
15769         (plus:DI
15770          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15771                      (match_operand:DI 3 "" "")
15772                      (reg:DI SP_REG)]
15773                     UNSPEC_TLSDESC)
15774          (const:DI (unspec:DI
15775                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15776                     UNSPEC_DTPOFF))))
15777    (clobber (reg:CC FLAGS_REG))]
15778   "TARGET_64BIT && TARGET_GNU2_TLS"
15779   "#"
15780   ""
15781   [(set (match_dup 0) (match_dup 4))]
15782 {
15783   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15784   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15785 })
15786
15787 ;;
15788 \f
15789 ;; These patterns match the binary 387 instructions for addM3, subM3,
15790 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15791 ;; SFmode.  The first is the normal insn, the second the same insn but
15792 ;; with one operand a conversion, and the third the same insn but with
15793 ;; the other operand a conversion.  The conversion may be SFmode or
15794 ;; SImode if the target mode DFmode, but only SImode if the target mode
15795 ;; is SFmode.
15796
15797 ;; Gcc is slightly more smart about handling normal two address instructions
15798 ;; so use special patterns for add and mull.
15799
15800 (define_insn "*fop_sf_comm_mixed"
15801   [(set (match_operand:SF 0 "register_operand" "=f,x")
15802         (match_operator:SF 3 "binary_fp_operator"
15803                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15804                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15805   "TARGET_MIX_SSE_I387
15806    && COMMUTATIVE_ARITH_P (operands[3])
15807    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15808   "* return output_387_binary_op (insn, operands);"
15809   [(set (attr "type")
15810         (if_then_else (eq_attr "alternative" "1")
15811            (if_then_else (match_operand:SF 3 "mult_operator" "")
15812               (const_string "ssemul")
15813               (const_string "sseadd"))
15814            (if_then_else (match_operand:SF 3 "mult_operator" "")
15815               (const_string "fmul")
15816               (const_string "fop"))))
15817    (set_attr "mode" "SF")])
15818
15819 (define_insn "*fop_sf_comm_sse"
15820   [(set (match_operand:SF 0 "register_operand" "=x")
15821         (match_operator:SF 3 "binary_fp_operator"
15822                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15823                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15824   "TARGET_SSE_MATH
15825    && COMMUTATIVE_ARITH_P (operands[3])
15826    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15827   "* return output_387_binary_op (insn, operands);"
15828   [(set (attr "type")
15829         (if_then_else (match_operand:SF 3 "mult_operator" "")
15830            (const_string "ssemul")
15831            (const_string "sseadd")))
15832    (set_attr "mode" "SF")])
15833
15834 (define_insn "*fop_sf_comm_i387"
15835   [(set (match_operand:SF 0 "register_operand" "=f")
15836         (match_operator:SF 3 "binary_fp_operator"
15837                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15838                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15839   "TARGET_80387
15840    && COMMUTATIVE_ARITH_P (operands[3])
15841    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15842   "* return output_387_binary_op (insn, operands);"
15843   [(set (attr "type")
15844         (if_then_else (match_operand:SF 3 "mult_operator" "")
15845            (const_string "fmul")
15846            (const_string "fop")))
15847    (set_attr "mode" "SF")])
15848
15849 (define_insn "*fop_sf_1_mixed"
15850   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15851         (match_operator:SF 3 "binary_fp_operator"
15852                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15853                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15854   "TARGET_MIX_SSE_I387
15855    && !COMMUTATIVE_ARITH_P (operands[3])
15856    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15857   "* return output_387_binary_op (insn, operands);"
15858   [(set (attr "type")
15859         (cond [(and (eq_attr "alternative" "2")
15860                     (match_operand:SF 3 "mult_operator" ""))
15861                  (const_string "ssemul")
15862                (and (eq_attr "alternative" "2")
15863                     (match_operand:SF 3 "div_operator" ""))
15864                  (const_string "ssediv")
15865                (eq_attr "alternative" "2")
15866                  (const_string "sseadd")
15867                (match_operand:SF 3 "mult_operator" "")
15868                  (const_string "fmul")
15869                (match_operand:SF 3 "div_operator" "")
15870                  (const_string "fdiv")
15871               ]
15872               (const_string "fop")))
15873    (set_attr "mode" "SF")])
15874
15875 (define_insn "*rcpsf2_sse"
15876   [(set (match_operand:SF 0 "register_operand" "=x")
15877         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15878                    UNSPEC_RCP))]
15879   "TARGET_SSE_MATH"
15880   "rcpss\t{%1, %0|%0, %1}"
15881   [(set_attr "type" "sse")
15882    (set_attr "mode" "SF")])
15883
15884 (define_insn "*fop_sf_1_sse"
15885   [(set (match_operand:SF 0 "register_operand" "=x")
15886         (match_operator:SF 3 "binary_fp_operator"
15887                         [(match_operand:SF 1 "register_operand" "0")
15888                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15889   "TARGET_SSE_MATH
15890    && !COMMUTATIVE_ARITH_P (operands[3])"
15891   "* return output_387_binary_op (insn, operands);"
15892   [(set (attr "type")
15893         (cond [(match_operand:SF 3 "mult_operator" "")
15894                  (const_string "ssemul")
15895                (match_operand:SF 3 "div_operator" "")
15896                  (const_string "ssediv")
15897               ]
15898               (const_string "sseadd")))
15899    (set_attr "mode" "SF")])
15900
15901 ;; This pattern is not fully shadowed by the pattern above.
15902 (define_insn "*fop_sf_1_i387"
15903   [(set (match_operand:SF 0 "register_operand" "=f,f")
15904         (match_operator:SF 3 "binary_fp_operator"
15905                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15906                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15907   "TARGET_80387 && !TARGET_SSE_MATH
15908    && !COMMUTATIVE_ARITH_P (operands[3])
15909    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15910   "* return output_387_binary_op (insn, operands);"
15911   [(set (attr "type")
15912         (cond [(match_operand:SF 3 "mult_operator" "")
15913                  (const_string "fmul")
15914                (match_operand:SF 3 "div_operator" "")
15915                  (const_string "fdiv")
15916               ]
15917               (const_string "fop")))
15918    (set_attr "mode" "SF")])
15919
15920 ;; ??? Add SSE splitters for these!
15921 (define_insn "*fop_sf_2<mode>_i387"
15922   [(set (match_operand:SF 0 "register_operand" "=f,f")
15923         (match_operator:SF 3 "binary_fp_operator"
15924           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15925            (match_operand:SF 2 "register_operand" "0,0")]))]
15926   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15927   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15928   [(set (attr "type")
15929         (cond [(match_operand:SF 3 "mult_operator" "")
15930                  (const_string "fmul")
15931                (match_operand:SF 3 "div_operator" "")
15932                  (const_string "fdiv")
15933               ]
15934               (const_string "fop")))
15935    (set_attr "fp_int_src" "true")
15936    (set_attr "mode" "<MODE>")])
15937
15938 (define_insn "*fop_sf_3<mode>_i387"
15939   [(set (match_operand:SF 0 "register_operand" "=f,f")
15940         (match_operator:SF 3 "binary_fp_operator"
15941           [(match_operand:SF 1 "register_operand" "0,0")
15942            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15943   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15944   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15945   [(set (attr "type")
15946         (cond [(match_operand:SF 3 "mult_operator" "")
15947                  (const_string "fmul")
15948                (match_operand:SF 3 "div_operator" "")
15949                  (const_string "fdiv")
15950               ]
15951               (const_string "fop")))
15952    (set_attr "fp_int_src" "true")
15953    (set_attr "mode" "<MODE>")])
15954
15955 (define_insn "*fop_df_comm_mixed"
15956   [(set (match_operand:DF 0 "register_operand" "=f,x")
15957         (match_operator:DF 3 "binary_fp_operator"
15958           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15959            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15960   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15961    && COMMUTATIVE_ARITH_P (operands[3])
15962    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15963   "* return output_387_binary_op (insn, operands);"
15964   [(set (attr "type")
15965         (if_then_else (eq_attr "alternative" "1")
15966            (if_then_else (match_operand:DF 3 "mult_operator" "")
15967               (const_string "ssemul")
15968               (const_string "sseadd"))
15969            (if_then_else (match_operand:DF 3 "mult_operator" "")
15970               (const_string "fmul")
15971               (const_string "fop"))))
15972    (set_attr "mode" "DF")])
15973
15974 (define_insn "*fop_df_comm_sse"
15975   [(set (match_operand:DF 0 "register_operand" "=x")
15976         (match_operator:DF 3 "binary_fp_operator"
15977           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15978            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15979   "TARGET_SSE2 && TARGET_SSE_MATH
15980    && COMMUTATIVE_ARITH_P (operands[3])
15981    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15982   "* return output_387_binary_op (insn, operands);"
15983   [(set (attr "type")
15984         (if_then_else (match_operand:DF 3 "mult_operator" "")
15985            (const_string "ssemul")
15986            (const_string "sseadd")))
15987    (set_attr "mode" "DF")])
15988
15989 (define_insn "*fop_df_comm_i387"
15990   [(set (match_operand:DF 0 "register_operand" "=f")
15991         (match_operator:DF 3 "binary_fp_operator"
15992                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15993                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15994   "TARGET_80387
15995    && COMMUTATIVE_ARITH_P (operands[3])
15996    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15997   "* return output_387_binary_op (insn, operands);"
15998   [(set (attr "type")
15999         (if_then_else (match_operand:DF 3 "mult_operator" "")
16000            (const_string "fmul")
16001            (const_string "fop")))
16002    (set_attr "mode" "DF")])
16003
16004 (define_insn "*fop_df_1_mixed"
16005   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16006         (match_operator:DF 3 "binary_fp_operator"
16007           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16008            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16009   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16010    && !COMMUTATIVE_ARITH_P (operands[3])
16011    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16012   "* return output_387_binary_op (insn, operands);"
16013   [(set (attr "type")
16014         (cond [(and (eq_attr "alternative" "2")
16015                     (match_operand:DF 3 "mult_operator" ""))
16016                  (const_string "ssemul")
16017                (and (eq_attr "alternative" "2")
16018                     (match_operand:DF 3 "div_operator" ""))
16019                  (const_string "ssediv")
16020                (eq_attr "alternative" "2")
16021                  (const_string "sseadd")
16022                (match_operand:DF 3 "mult_operator" "")
16023                  (const_string "fmul")
16024                (match_operand:DF 3 "div_operator" "")
16025                  (const_string "fdiv")
16026               ]
16027               (const_string "fop")))
16028    (set_attr "mode" "DF")])
16029
16030 (define_insn "*fop_df_1_sse"
16031   [(set (match_operand:DF 0 "register_operand" "=x")
16032         (match_operator:DF 3 "binary_fp_operator"
16033           [(match_operand:DF 1 "register_operand" "0")
16034            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16035   "TARGET_SSE2 && TARGET_SSE_MATH
16036    && !COMMUTATIVE_ARITH_P (operands[3])"
16037   "* return output_387_binary_op (insn, operands);"
16038   [(set_attr "mode" "DF")
16039    (set (attr "type")
16040         (cond [(match_operand:DF 3 "mult_operator" "")
16041                  (const_string "ssemul")
16042                (match_operand:DF 3 "div_operator" "")
16043                  (const_string "ssediv")
16044               ]
16045               (const_string "sseadd")))])
16046
16047 ;; This pattern is not fully shadowed by the pattern above.
16048 (define_insn "*fop_df_1_i387"
16049   [(set (match_operand:DF 0 "register_operand" "=f,f")
16050         (match_operator:DF 3 "binary_fp_operator"
16051                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16052                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16053   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16054    && !COMMUTATIVE_ARITH_P (operands[3])
16055    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16056   "* return output_387_binary_op (insn, operands);"
16057   [(set (attr "type")
16058         (cond [(match_operand:DF 3 "mult_operator" "")
16059                  (const_string "fmul")
16060                (match_operand:DF 3 "div_operator" "")
16061                  (const_string "fdiv")
16062               ]
16063               (const_string "fop")))
16064    (set_attr "mode" "DF")])
16065
16066 ;; ??? Add SSE splitters for these!
16067 (define_insn "*fop_df_2<mode>_i387"
16068   [(set (match_operand:DF 0 "register_operand" "=f,f")
16069         (match_operator:DF 3 "binary_fp_operator"
16070            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16071             (match_operand:DF 2 "register_operand" "0,0")]))]
16072   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16073    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16074   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16075   [(set (attr "type")
16076         (cond [(match_operand:DF 3 "mult_operator" "")
16077                  (const_string "fmul")
16078                (match_operand:DF 3 "div_operator" "")
16079                  (const_string "fdiv")
16080               ]
16081               (const_string "fop")))
16082    (set_attr "fp_int_src" "true")
16083    (set_attr "mode" "<MODE>")])
16084
16085 (define_insn "*fop_df_3<mode>_i387"
16086   [(set (match_operand:DF 0 "register_operand" "=f,f")
16087         (match_operator:DF 3 "binary_fp_operator"
16088            [(match_operand:DF 1 "register_operand" "0,0")
16089             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16090   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16091    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16092   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16093   [(set (attr "type")
16094         (cond [(match_operand:DF 3 "mult_operator" "")
16095                  (const_string "fmul")
16096                (match_operand:DF 3 "div_operator" "")
16097                  (const_string "fdiv")
16098               ]
16099               (const_string "fop")))
16100    (set_attr "fp_int_src" "true")
16101    (set_attr "mode" "<MODE>")])
16102
16103 (define_insn "*fop_df_4_i387"
16104   [(set (match_operand:DF 0 "register_operand" "=f,f")
16105         (match_operator:DF 3 "binary_fp_operator"
16106            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16107             (match_operand:DF 2 "register_operand" "0,f")]))]
16108   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16109    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16110   "* return output_387_binary_op (insn, operands);"
16111   [(set (attr "type")
16112         (cond [(match_operand:DF 3 "mult_operator" "")
16113                  (const_string "fmul")
16114                (match_operand:DF 3 "div_operator" "")
16115                  (const_string "fdiv")
16116               ]
16117               (const_string "fop")))
16118    (set_attr "mode" "SF")])
16119
16120 (define_insn "*fop_df_5_i387"
16121   [(set (match_operand:DF 0 "register_operand" "=f,f")
16122         (match_operator:DF 3 "binary_fp_operator"
16123           [(match_operand:DF 1 "register_operand" "0,f")
16124            (float_extend:DF
16125             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16126   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16127   "* return output_387_binary_op (insn, operands);"
16128   [(set (attr "type")
16129         (cond [(match_operand:DF 3 "mult_operator" "")
16130                  (const_string "fmul")
16131                (match_operand:DF 3 "div_operator" "")
16132                  (const_string "fdiv")
16133               ]
16134               (const_string "fop")))
16135    (set_attr "mode" "SF")])
16136
16137 (define_insn "*fop_df_6_i387"
16138   [(set (match_operand:DF 0 "register_operand" "=f,f")
16139         (match_operator:DF 3 "binary_fp_operator"
16140           [(float_extend:DF
16141             (match_operand:SF 1 "register_operand" "0,f"))
16142            (float_extend:DF
16143             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16144   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16145   "* return output_387_binary_op (insn, operands);"
16146   [(set (attr "type")
16147         (cond [(match_operand:DF 3 "mult_operator" "")
16148                  (const_string "fmul")
16149                (match_operand:DF 3 "div_operator" "")
16150                  (const_string "fdiv")
16151               ]
16152               (const_string "fop")))
16153    (set_attr "mode" "SF")])
16154
16155 (define_insn "*fop_xf_comm_i387"
16156   [(set (match_operand:XF 0 "register_operand" "=f")
16157         (match_operator:XF 3 "binary_fp_operator"
16158                         [(match_operand:XF 1 "register_operand" "%0")
16159                          (match_operand:XF 2 "register_operand" "f")]))]
16160   "TARGET_80387
16161    && COMMUTATIVE_ARITH_P (operands[3])"
16162   "* return output_387_binary_op (insn, operands);"
16163   [(set (attr "type")
16164         (if_then_else (match_operand:XF 3 "mult_operator" "")
16165            (const_string "fmul")
16166            (const_string "fop")))
16167    (set_attr "mode" "XF")])
16168
16169 (define_insn "*fop_xf_1_i387"
16170   [(set (match_operand:XF 0 "register_operand" "=f,f")
16171         (match_operator:XF 3 "binary_fp_operator"
16172                         [(match_operand:XF 1 "register_operand" "0,f")
16173                          (match_operand:XF 2 "register_operand" "f,0")]))]
16174   "TARGET_80387
16175    && !COMMUTATIVE_ARITH_P (operands[3])"
16176   "* return output_387_binary_op (insn, operands);"
16177   [(set (attr "type")
16178         (cond [(match_operand:XF 3 "mult_operator" "")
16179                  (const_string "fmul")
16180                (match_operand:XF 3 "div_operator" "")
16181                  (const_string "fdiv")
16182               ]
16183               (const_string "fop")))
16184    (set_attr "mode" "XF")])
16185
16186 (define_insn "*fop_xf_2<mode>_i387"
16187   [(set (match_operand:XF 0 "register_operand" "=f,f")
16188         (match_operator:XF 3 "binary_fp_operator"
16189            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16190             (match_operand:XF 2 "register_operand" "0,0")]))]
16191   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16192   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16193   [(set (attr "type")
16194         (cond [(match_operand:XF 3 "mult_operator" "")
16195                  (const_string "fmul")
16196                (match_operand:XF 3 "div_operator" "")
16197                  (const_string "fdiv")
16198               ]
16199               (const_string "fop")))
16200    (set_attr "fp_int_src" "true")
16201    (set_attr "mode" "<MODE>")])
16202
16203 (define_insn "*fop_xf_3<mode>_i387"
16204   [(set (match_operand:XF 0 "register_operand" "=f,f")
16205         (match_operator:XF 3 "binary_fp_operator"
16206           [(match_operand:XF 1 "register_operand" "0,0")
16207            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16208   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16209   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16210   [(set (attr "type")
16211         (cond [(match_operand:XF 3 "mult_operator" "")
16212                  (const_string "fmul")
16213                (match_operand:XF 3 "div_operator" "")
16214                  (const_string "fdiv")
16215               ]
16216               (const_string "fop")))
16217    (set_attr "fp_int_src" "true")
16218    (set_attr "mode" "<MODE>")])
16219
16220 (define_insn "*fop_xf_4_i387"
16221   [(set (match_operand:XF 0 "register_operand" "=f,f")
16222         (match_operator:XF 3 "binary_fp_operator"
16223            [(float_extend:XF
16224               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16225             (match_operand:XF 2 "register_operand" "0,f")]))]
16226   "TARGET_80387"
16227   "* return output_387_binary_op (insn, operands);"
16228   [(set (attr "type")
16229         (cond [(match_operand:XF 3 "mult_operator" "")
16230                  (const_string "fmul")
16231                (match_operand:XF 3 "div_operator" "")
16232                  (const_string "fdiv")
16233               ]
16234               (const_string "fop")))
16235    (set_attr "mode" "SF")])
16236
16237 (define_insn "*fop_xf_5_i387"
16238   [(set (match_operand:XF 0 "register_operand" "=f,f")
16239         (match_operator:XF 3 "binary_fp_operator"
16240           [(match_operand:XF 1 "register_operand" "0,f")
16241            (float_extend:XF
16242              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16243   "TARGET_80387"
16244   "* return output_387_binary_op (insn, operands);"
16245   [(set (attr "type")
16246         (cond [(match_operand:XF 3 "mult_operator" "")
16247                  (const_string "fmul")
16248                (match_operand:XF 3 "div_operator" "")
16249                  (const_string "fdiv")
16250               ]
16251               (const_string "fop")))
16252    (set_attr "mode" "SF")])
16253
16254 (define_insn "*fop_xf_6_i387"
16255   [(set (match_operand:XF 0 "register_operand" "=f,f")
16256         (match_operator:XF 3 "binary_fp_operator"
16257           [(float_extend:XF
16258              (match_operand:MODEF 1 "register_operand" "0,f"))
16259            (float_extend:XF
16260              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16261   "TARGET_80387"
16262   "* return output_387_binary_op (insn, operands);"
16263   [(set (attr "type")
16264         (cond [(match_operand:XF 3 "mult_operator" "")
16265                  (const_string "fmul")
16266                (match_operand:XF 3 "div_operator" "")
16267                  (const_string "fdiv")
16268               ]
16269               (const_string "fop")))
16270    (set_attr "mode" "SF")])
16271
16272 (define_split
16273   [(set (match_operand 0 "register_operand" "")
16274         (match_operator 3 "binary_fp_operator"
16275            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16276             (match_operand 2 "register_operand" "")]))]
16277   "reload_completed
16278    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16279   [(const_int 0)]
16280 {
16281   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16282   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16283   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16284                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16285                                           GET_MODE (operands[3]),
16286                                           operands[4],
16287                                           operands[2])));
16288   ix86_free_from_memory (GET_MODE (operands[1]));
16289   DONE;
16290 })
16291
16292 (define_split
16293   [(set (match_operand 0 "register_operand" "")
16294         (match_operator 3 "binary_fp_operator"
16295            [(match_operand 1 "register_operand" "")
16296             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16297   "reload_completed
16298    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16299   [(const_int 0)]
16300 {
16301   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16302   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16303   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16304                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16305                                           GET_MODE (operands[3]),
16306                                           operands[1],
16307                                           operands[4])));
16308   ix86_free_from_memory (GET_MODE (operands[2]));
16309   DONE;
16310 })
16311 \f
16312 ;; FPU special functions.
16313
16314 ;; This pattern implements a no-op XFmode truncation for
16315 ;; all fancy i386 XFmode math functions.
16316
16317 (define_insn "truncxf<mode>2_i387_noop_unspec"
16318   [(set (match_operand:MODEF 0 "register_operand" "=f")
16319         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16320         UNSPEC_TRUNC_NOOP))]
16321   "TARGET_USE_FANCY_MATH_387"
16322   "* return output_387_reg_move (insn, operands);"
16323   [(set_attr "type" "fmov")
16324    (set_attr "mode" "<MODE>")])
16325
16326 (define_insn "sqrtxf2"
16327   [(set (match_operand:XF 0 "register_operand" "=f")
16328         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16329   "TARGET_USE_FANCY_MATH_387"
16330   "fsqrt"
16331   [(set_attr "type" "fpspc")
16332    (set_attr "mode" "XF")
16333    (set_attr "athlon_decode" "direct")
16334    (set_attr "amdfam10_decode" "direct")])
16335
16336 (define_insn "sqrt_extend<mode>xf2_i387"
16337   [(set (match_operand:XF 0 "register_operand" "=f")
16338         (sqrt:XF
16339           (float_extend:XF
16340             (match_operand:MODEF 1 "register_operand" "0"))))]
16341   "TARGET_USE_FANCY_MATH_387"
16342   "fsqrt"
16343   [(set_attr "type" "fpspc")
16344    (set_attr "mode" "XF")
16345    (set_attr "athlon_decode" "direct")
16346    (set_attr "amdfam10_decode" "direct")])
16347
16348 (define_insn "*rsqrtsf2_sse"
16349   [(set (match_operand:SF 0 "register_operand" "=x")
16350         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16351                    UNSPEC_RSQRT))]
16352   "TARGET_SSE_MATH"
16353   "rsqrtss\t{%1, %0|%0, %1}"
16354   [(set_attr "type" "sse")
16355    (set_attr "mode" "SF")])
16356
16357 (define_expand "rsqrtsf2"
16358   [(set (match_operand:SF 0 "register_operand" "")
16359         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16360                    UNSPEC_RSQRT))]
16361   "TARGET_SSE_MATH"
16362 {
16363   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16364   DONE;
16365 })
16366
16367 (define_insn "*sqrt<mode>2_sse"
16368   [(set (match_operand:MODEF 0 "register_operand" "=x")
16369         (sqrt:MODEF
16370           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16371   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16372   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16373   [(set_attr "type" "sse")
16374    (set_attr "mode" "<MODE>")
16375    (set_attr "athlon_decode" "*")
16376    (set_attr "amdfam10_decode" "*")])
16377
16378 (define_expand "sqrt<mode>2"
16379   [(set (match_operand:MODEF 0 "register_operand" "")
16380         (sqrt:MODEF
16381           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16382   "TARGET_USE_FANCY_MATH_387
16383    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16384 {
16385   if (<MODE>mode == SFmode
16386       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16387       && flag_finite_math_only && !flag_trapping_math
16388       && flag_unsafe_math_optimizations)
16389     {
16390       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16391       DONE;
16392     }
16393
16394   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16395     {
16396       rtx op0 = gen_reg_rtx (XFmode);
16397       rtx op1 = force_reg (<MODE>mode, operands[1]);
16398
16399       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16400       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16401       DONE;
16402    }
16403 })
16404
16405 (define_insn "fpremxf4_i387"
16406   [(set (match_operand:XF 0 "register_operand" "=f")
16407         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16408                     (match_operand:XF 3 "register_operand" "1")]
16409                    UNSPEC_FPREM_F))
16410    (set (match_operand:XF 1 "register_operand" "=u")
16411         (unspec:XF [(match_dup 2) (match_dup 3)]
16412                    UNSPEC_FPREM_U))
16413    (set (reg:CCFP FPSR_REG)
16414         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16415                      UNSPEC_C2_FLAG))]
16416   "TARGET_USE_FANCY_MATH_387"
16417   "fprem"
16418   [(set_attr "type" "fpspc")
16419    (set_attr "mode" "XF")])
16420
16421 (define_expand "fmodxf3"
16422   [(use (match_operand:XF 0 "register_operand" ""))
16423    (use (match_operand:XF 1 "general_operand" ""))
16424    (use (match_operand:XF 2 "general_operand" ""))]
16425   "TARGET_USE_FANCY_MATH_387"
16426 {
16427   rtx label = gen_label_rtx ();
16428
16429   rtx op1 = gen_reg_rtx (XFmode);
16430   rtx op2 = gen_reg_rtx (XFmode);
16431
16432   emit_move_insn (op1, operands[1]);
16433   emit_move_insn (op2, operands[2]);
16434
16435   emit_label (label);
16436   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16437   ix86_emit_fp_unordered_jump (label);
16438   LABEL_NUSES (label) = 1;
16439
16440   emit_move_insn (operands[0], op1);
16441   DONE;
16442 })
16443
16444 (define_expand "fmod<mode>3"
16445   [(use (match_operand:MODEF 0 "register_operand" ""))
16446    (use (match_operand:MODEF 1 "general_operand" ""))
16447    (use (match_operand:MODEF 2 "general_operand" ""))]
16448   "TARGET_USE_FANCY_MATH_387"
16449 {
16450   rtx label = gen_label_rtx ();
16451
16452   rtx op1 = gen_reg_rtx (XFmode);
16453   rtx op2 = gen_reg_rtx (XFmode);
16454
16455   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16456   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16457
16458   emit_label (label);
16459   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16460   ix86_emit_fp_unordered_jump (label);
16461   LABEL_NUSES (label) = 1;
16462
16463   /* Truncate the result properly for strict SSE math.  */
16464   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16465       && !TARGET_MIX_SSE_I387)
16466     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16467   else
16468     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16469
16470   DONE;
16471 })
16472
16473 (define_insn "fprem1xf4_i387"
16474   [(set (match_operand:XF 0 "register_operand" "=f")
16475         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16476                     (match_operand:XF 3 "register_operand" "1")]
16477                    UNSPEC_FPREM1_F))
16478    (set (match_operand:XF 1 "register_operand" "=u")
16479         (unspec:XF [(match_dup 2) (match_dup 3)]
16480                    UNSPEC_FPREM1_U))
16481    (set (reg:CCFP FPSR_REG)
16482         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16483                      UNSPEC_C2_FLAG))]
16484   "TARGET_USE_FANCY_MATH_387"
16485   "fprem1"
16486   [(set_attr "type" "fpspc")
16487    (set_attr "mode" "XF")])
16488
16489 (define_expand "remainderxf3"
16490   [(use (match_operand:XF 0 "register_operand" ""))
16491    (use (match_operand:XF 1 "general_operand" ""))
16492    (use (match_operand:XF 2 "general_operand" ""))]
16493   "TARGET_USE_FANCY_MATH_387"
16494 {
16495   rtx label = gen_label_rtx ();
16496
16497   rtx op1 = gen_reg_rtx (XFmode);
16498   rtx op2 = gen_reg_rtx (XFmode);
16499
16500   emit_move_insn (op1, operands[1]);
16501   emit_move_insn (op2, operands[2]);
16502
16503   emit_label (label);
16504   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16505   ix86_emit_fp_unordered_jump (label);
16506   LABEL_NUSES (label) = 1;
16507
16508   emit_move_insn (operands[0], op1);
16509   DONE;
16510 })
16511
16512 (define_expand "remainder<mode>3"
16513   [(use (match_operand:MODEF 0 "register_operand" ""))
16514    (use (match_operand:MODEF 1 "general_operand" ""))
16515    (use (match_operand:MODEF 2 "general_operand" ""))]
16516   "TARGET_USE_FANCY_MATH_387"
16517 {
16518   rtx label = gen_label_rtx ();
16519
16520   rtx op1 = gen_reg_rtx (XFmode);
16521   rtx op2 = gen_reg_rtx (XFmode);
16522
16523   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16524   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16525
16526   emit_label (label);
16527
16528   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16529   ix86_emit_fp_unordered_jump (label);
16530   LABEL_NUSES (label) = 1;
16531
16532   /* Truncate the result properly for strict SSE math.  */
16533   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16534       && !TARGET_MIX_SSE_I387)
16535     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16536   else
16537     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16538
16539   DONE;
16540 })
16541
16542 (define_insn "*sinxf2_i387"
16543   [(set (match_operand:XF 0 "register_operand" "=f")
16544         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16545   "TARGET_USE_FANCY_MATH_387
16546    && flag_unsafe_math_optimizations"
16547   "fsin"
16548   [(set_attr "type" "fpspc")
16549    (set_attr "mode" "XF")])
16550
16551 (define_insn "*sin_extend<mode>xf2_i387"
16552   [(set (match_operand:XF 0 "register_operand" "=f")
16553         (unspec:XF [(float_extend:XF
16554                       (match_operand:MODEF 1 "register_operand" "0"))]
16555                    UNSPEC_SIN))]
16556   "TARGET_USE_FANCY_MATH_387
16557    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16558        || TARGET_MIX_SSE_I387)
16559    && flag_unsafe_math_optimizations"
16560   "fsin"
16561   [(set_attr "type" "fpspc")
16562    (set_attr "mode" "XF")])
16563
16564 (define_insn "*cosxf2_i387"
16565   [(set (match_operand:XF 0 "register_operand" "=f")
16566         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16567   "TARGET_USE_FANCY_MATH_387
16568    && flag_unsafe_math_optimizations"
16569   "fcos"
16570   [(set_attr "type" "fpspc")
16571    (set_attr "mode" "XF")])
16572
16573 (define_insn "*cos_extend<mode>xf2_i387"
16574   [(set (match_operand:XF 0 "register_operand" "=f")
16575         (unspec:XF [(float_extend:XF
16576                       (match_operand:MODEF 1 "register_operand" "0"))]
16577                    UNSPEC_COS))]
16578   "TARGET_USE_FANCY_MATH_387
16579    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16580        || TARGET_MIX_SSE_I387)
16581    && flag_unsafe_math_optimizations"
16582   "fcos"
16583   [(set_attr "type" "fpspc")
16584    (set_attr "mode" "XF")])
16585
16586 ;; When sincos pattern is defined, sin and cos builtin functions will be
16587 ;; expanded to sincos pattern with one of its outputs left unused.
16588 ;; CSE pass will figure out if two sincos patterns can be combined,
16589 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16590 ;; depending on the unused output.
16591
16592 (define_insn "sincosxf3"
16593   [(set (match_operand:XF 0 "register_operand" "=f")
16594         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16595                    UNSPEC_SINCOS_COS))
16596    (set (match_operand:XF 1 "register_operand" "=u")
16597         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16598   "TARGET_USE_FANCY_MATH_387
16599    && flag_unsafe_math_optimizations"
16600   "fsincos"
16601   [(set_attr "type" "fpspc")
16602    (set_attr "mode" "XF")])
16603
16604 (define_split
16605   [(set (match_operand:XF 0 "register_operand" "")
16606         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16607                    UNSPEC_SINCOS_COS))
16608    (set (match_operand:XF 1 "register_operand" "")
16609         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16610   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16611    && !(reload_completed || reload_in_progress)"
16612   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16613   "")
16614
16615 (define_split
16616   [(set (match_operand:XF 0 "register_operand" "")
16617         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16618                    UNSPEC_SINCOS_COS))
16619    (set (match_operand:XF 1 "register_operand" "")
16620         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16621   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16622    && !(reload_completed || reload_in_progress)"
16623   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16624   "")
16625
16626 (define_insn "sincos_extend<mode>xf3_i387"
16627   [(set (match_operand:XF 0 "register_operand" "=f")
16628         (unspec:XF [(float_extend:XF
16629                       (match_operand:MODEF 2 "register_operand" "0"))]
16630                    UNSPEC_SINCOS_COS))
16631    (set (match_operand:XF 1 "register_operand" "=u")
16632         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16635        || TARGET_MIX_SSE_I387)
16636    && flag_unsafe_math_optimizations"
16637   "fsincos"
16638   [(set_attr "type" "fpspc")
16639    (set_attr "mode" "XF")])
16640
16641 (define_split
16642   [(set (match_operand:XF 0 "register_operand" "")
16643         (unspec:XF [(float_extend:XF
16644                       (match_operand:MODEF 2 "register_operand" ""))]
16645                    UNSPEC_SINCOS_COS))
16646    (set (match_operand:XF 1 "register_operand" "")
16647         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16648   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16649    && !(reload_completed || reload_in_progress)"
16650   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16651   "")
16652
16653 (define_split
16654   [(set (match_operand:XF 0 "register_operand" "")
16655         (unspec:XF [(float_extend:XF
16656                       (match_operand:MODEF 2 "register_operand" ""))]
16657                    UNSPEC_SINCOS_COS))
16658    (set (match_operand:XF 1 "register_operand" "")
16659         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16660   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16661    && !(reload_completed || reload_in_progress)"
16662   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16663   "")
16664
16665 (define_expand "sincos<mode>3"
16666   [(use (match_operand:MODEF 0 "register_operand" ""))
16667    (use (match_operand:MODEF 1 "register_operand" ""))
16668    (use (match_operand:MODEF 2 "register_operand" ""))]
16669   "TARGET_USE_FANCY_MATH_387
16670    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671        || TARGET_MIX_SSE_I387)
16672    && flag_unsafe_math_optimizations"
16673 {
16674   rtx op0 = gen_reg_rtx (XFmode);
16675   rtx op1 = gen_reg_rtx (XFmode);
16676
16677   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16678   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16679   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16680   DONE;
16681 })
16682
16683 (define_insn "fptanxf4_i387"
16684   [(set (match_operand:XF 0 "register_operand" "=f")
16685         (match_operand:XF 3 "const_double_operand" "F"))
16686    (set (match_operand:XF 1 "register_operand" "=u")
16687         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16688                    UNSPEC_TAN))]
16689   "TARGET_USE_FANCY_MATH_387
16690    && flag_unsafe_math_optimizations
16691    && standard_80387_constant_p (operands[3]) == 2"
16692   "fptan"
16693   [(set_attr "type" "fpspc")
16694    (set_attr "mode" "XF")])
16695
16696 (define_insn "fptan_extend<mode>xf4_i387"
16697   [(set (match_operand:MODEF 0 "register_operand" "=f")
16698         (match_operand:MODEF 3 "const_double_operand" "F"))
16699    (set (match_operand:XF 1 "register_operand" "=u")
16700         (unspec:XF [(float_extend:XF
16701                       (match_operand:MODEF 2 "register_operand" "0"))]
16702                    UNSPEC_TAN))]
16703   "TARGET_USE_FANCY_MATH_387
16704    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16705        || TARGET_MIX_SSE_I387)
16706    && flag_unsafe_math_optimizations
16707    && standard_80387_constant_p (operands[3]) == 2"
16708   "fptan"
16709   [(set_attr "type" "fpspc")
16710    (set_attr "mode" "XF")])
16711
16712 (define_expand "tanxf2"
16713   [(use (match_operand:XF 0 "register_operand" ""))
16714    (use (match_operand:XF 1 "register_operand" ""))]
16715   "TARGET_USE_FANCY_MATH_387
16716    && flag_unsafe_math_optimizations"
16717 {
16718   rtx one = gen_reg_rtx (XFmode);
16719   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16720
16721   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16722   DONE;
16723 })
16724
16725 (define_expand "tan<mode>2"
16726   [(use (match_operand:MODEF 0 "register_operand" ""))
16727    (use (match_operand:MODEF 1 "register_operand" ""))]
16728   "TARGET_USE_FANCY_MATH_387
16729    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16730        || TARGET_MIX_SSE_I387)
16731    && flag_unsafe_math_optimizations"
16732 {
16733   rtx op0 = gen_reg_rtx (XFmode);
16734
16735   rtx one = gen_reg_rtx (<MODE>mode);
16736   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16737
16738   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16739                                              operands[1], op2));
16740   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16741   DONE;
16742 })
16743
16744 (define_insn "*fpatanxf3_i387"
16745   [(set (match_operand:XF 0 "register_operand" "=f")
16746         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16747                     (match_operand:XF 2 "register_operand" "u")]
16748                    UNSPEC_FPATAN))
16749    (clobber (match_scratch:XF 3 "=2"))]
16750   "TARGET_USE_FANCY_MATH_387
16751    && flag_unsafe_math_optimizations"
16752   "fpatan"
16753   [(set_attr "type" "fpspc")
16754    (set_attr "mode" "XF")])
16755
16756 (define_insn "fpatan_extend<mode>xf3_i387"
16757   [(set (match_operand:XF 0 "register_operand" "=f")
16758         (unspec:XF [(float_extend:XF
16759                       (match_operand:MODEF 1 "register_operand" "0"))
16760                     (float_extend:XF
16761                       (match_operand:MODEF 2 "register_operand" "u"))]
16762                    UNSPEC_FPATAN))
16763    (clobber (match_scratch:XF 3 "=2"))]
16764   "TARGET_USE_FANCY_MATH_387
16765    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16766        || TARGET_MIX_SSE_I387)
16767    && flag_unsafe_math_optimizations"
16768   "fpatan"
16769   [(set_attr "type" "fpspc")
16770    (set_attr "mode" "XF")])
16771
16772 (define_expand "atan2xf3"
16773   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16774                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16775                                (match_operand:XF 1 "register_operand" "")]
16776                               UNSPEC_FPATAN))
16777               (clobber (match_scratch:XF 3 ""))])]
16778   "TARGET_USE_FANCY_MATH_387
16779    && flag_unsafe_math_optimizations"
16780   "")
16781
16782 (define_expand "atan2<mode>3"
16783   [(use (match_operand:MODEF 0 "register_operand" ""))
16784    (use (match_operand:MODEF 1 "register_operand" ""))
16785    (use (match_operand:MODEF 2 "register_operand" ""))]
16786   "TARGET_USE_FANCY_MATH_387
16787    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16788        || TARGET_MIX_SSE_I387)
16789    && flag_unsafe_math_optimizations"
16790 {
16791   rtx op0 = gen_reg_rtx (XFmode);
16792
16793   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16794   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16795   DONE;
16796 })
16797
16798 (define_expand "atanxf2"
16799   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16800                    (unspec:XF [(match_dup 2)
16801                                (match_operand:XF 1 "register_operand" "")]
16802                               UNSPEC_FPATAN))
16803               (clobber (match_scratch:XF 3 ""))])]
16804   "TARGET_USE_FANCY_MATH_387
16805    && flag_unsafe_math_optimizations"
16806 {
16807   operands[2] = gen_reg_rtx (XFmode);
16808   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16809 })
16810
16811 (define_expand "atan<mode>2"
16812   [(use (match_operand:MODEF 0 "register_operand" ""))
16813    (use (match_operand:MODEF 1 "register_operand" ""))]
16814   "TARGET_USE_FANCY_MATH_387
16815    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16816        || TARGET_MIX_SSE_I387)
16817    && flag_unsafe_math_optimizations"
16818 {
16819   rtx op0 = gen_reg_rtx (XFmode);
16820
16821   rtx op2 = gen_reg_rtx (<MODE>mode);
16822   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16823
16824   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16825   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16826   DONE;
16827 })
16828
16829 (define_expand "asinxf2"
16830   [(set (match_dup 2)
16831         (mult:XF (match_operand:XF 1 "register_operand" "")
16832                  (match_dup 1)))
16833    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16834    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16835    (parallel [(set (match_operand:XF 0 "register_operand" "")
16836                    (unspec:XF [(match_dup 5) (match_dup 1)]
16837                               UNSPEC_FPATAN))
16838               (clobber (match_scratch:XF 6 ""))])]
16839   "TARGET_USE_FANCY_MATH_387
16840    && flag_unsafe_math_optimizations && !optimize_size"
16841 {
16842   int i;
16843
16844   for (i = 2; i < 6; i++)
16845     operands[i] = gen_reg_rtx (XFmode);
16846
16847   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16848 })
16849
16850 (define_expand "asin<mode>2"
16851   [(use (match_operand:MODEF 0 "register_operand" ""))
16852    (use (match_operand:MODEF 1 "general_operand" ""))]
16853  "TARGET_USE_FANCY_MATH_387
16854    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16855        || TARGET_MIX_SSE_I387)
16856    && flag_unsafe_math_optimizations && !optimize_size"
16857 {
16858   rtx op0 = gen_reg_rtx (XFmode);
16859   rtx op1 = gen_reg_rtx (XFmode);
16860
16861   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16862   emit_insn (gen_asinxf2 (op0, op1));
16863   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16864   DONE;
16865 })
16866
16867 (define_expand "acosxf2"
16868   [(set (match_dup 2)
16869         (mult:XF (match_operand:XF 1 "register_operand" "")
16870                  (match_dup 1)))
16871    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16872    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16873    (parallel [(set (match_operand:XF 0 "register_operand" "")
16874                    (unspec:XF [(match_dup 1) (match_dup 5)]
16875                               UNSPEC_FPATAN))
16876               (clobber (match_scratch:XF 6 ""))])]
16877   "TARGET_USE_FANCY_MATH_387
16878    && flag_unsafe_math_optimizations && !optimize_size"
16879 {
16880   int i;
16881
16882   for (i = 2; i < 6; i++)
16883     operands[i] = gen_reg_rtx (XFmode);
16884
16885   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16886 })
16887
16888 (define_expand "acos<mode>2"
16889   [(use (match_operand:MODEF 0 "register_operand" ""))
16890    (use (match_operand:MODEF 1 "general_operand" ""))]
16891  "TARGET_USE_FANCY_MATH_387
16892    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16893        || TARGET_MIX_SSE_I387)
16894    && flag_unsafe_math_optimizations && !optimize_size"
16895 {
16896   rtx op0 = gen_reg_rtx (XFmode);
16897   rtx op1 = gen_reg_rtx (XFmode);
16898
16899   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16900   emit_insn (gen_acosxf2 (op0, op1));
16901   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16902   DONE;
16903 })
16904
16905 (define_insn "fyl2xxf3_i387"
16906   [(set (match_operand:XF 0 "register_operand" "=f")
16907         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16908                     (match_operand:XF 2 "register_operand" "u")]
16909                    UNSPEC_FYL2X))
16910    (clobber (match_scratch:XF 3 "=2"))]
16911   "TARGET_USE_FANCY_MATH_387
16912    && flag_unsafe_math_optimizations"
16913   "fyl2x"
16914   [(set_attr "type" "fpspc")
16915    (set_attr "mode" "XF")])
16916
16917 (define_insn "fyl2x_extend<mode>xf3_i387"
16918   [(set (match_operand:XF 0 "register_operand" "=f")
16919         (unspec:XF [(float_extend:XF
16920                       (match_operand:MODEF 1 "register_operand" "0"))
16921                     (match_operand:XF 2 "register_operand" "u")]
16922                    UNSPEC_FYL2X))
16923    (clobber (match_scratch:XF 3 "=2"))]
16924   "TARGET_USE_FANCY_MATH_387
16925    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16926        || TARGET_MIX_SSE_I387)
16927    && flag_unsafe_math_optimizations"
16928   "fyl2x"
16929   [(set_attr "type" "fpspc")
16930    (set_attr "mode" "XF")])
16931
16932 (define_expand "logxf2"
16933   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16934                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16935                                (match_dup 2)] UNSPEC_FYL2X))
16936               (clobber (match_scratch:XF 3 ""))])]
16937   "TARGET_USE_FANCY_MATH_387
16938    && flag_unsafe_math_optimizations"
16939 {
16940   operands[2] = gen_reg_rtx (XFmode);
16941   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16942 })
16943
16944 (define_expand "log<mode>2"
16945   [(use (match_operand:MODEF 0 "register_operand" ""))
16946    (use (match_operand:MODEF 1 "register_operand" ""))]
16947   "TARGET_USE_FANCY_MATH_387
16948    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16949        || TARGET_MIX_SSE_I387)
16950    && flag_unsafe_math_optimizations"
16951 {
16952   rtx op0 = gen_reg_rtx (XFmode);
16953
16954   rtx op2 = gen_reg_rtx (XFmode);
16955   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16956
16957   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16958   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16959   DONE;
16960 })
16961
16962 (define_expand "log10xf2"
16963   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16964                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16965                                (match_dup 2)] UNSPEC_FYL2X))
16966               (clobber (match_scratch:XF 3 ""))])]
16967   "TARGET_USE_FANCY_MATH_387
16968    && flag_unsafe_math_optimizations"
16969 {
16970   operands[2] = gen_reg_rtx (XFmode);
16971   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16972 })
16973
16974 (define_expand "log10<mode>2"
16975   [(use (match_operand:MODEF 0 "register_operand" ""))
16976    (use (match_operand:MODEF 1 "register_operand" ""))]
16977   "TARGET_USE_FANCY_MATH_387
16978    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16979        || TARGET_MIX_SSE_I387)
16980    && flag_unsafe_math_optimizations"
16981 {
16982   rtx op0 = gen_reg_rtx (XFmode);
16983
16984   rtx op2 = gen_reg_rtx (XFmode);
16985   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16986
16987   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16988   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16989   DONE;
16990 })
16991
16992 (define_expand "log2xf2"
16993   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16994                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16995                                (match_dup 2)] UNSPEC_FYL2X))
16996               (clobber (match_scratch:XF 3 ""))])]
16997   "TARGET_USE_FANCY_MATH_387
16998    && flag_unsafe_math_optimizations"
16999 {
17000   operands[2] = gen_reg_rtx (XFmode);
17001   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17002 })
17003
17004 (define_expand "log2<mode>2"
17005   [(use (match_operand:MODEF 0 "register_operand" ""))
17006    (use (match_operand:MODEF 1 "register_operand" ""))]
17007   "TARGET_USE_FANCY_MATH_387
17008    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17009        || TARGET_MIX_SSE_I387)
17010    && flag_unsafe_math_optimizations"
17011 {
17012   rtx op0 = gen_reg_rtx (XFmode);
17013
17014   rtx op2 = gen_reg_rtx (XFmode);
17015   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17016
17017   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17018   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17019   DONE;
17020 })
17021
17022 (define_insn "fyl2xp1xf3_i387"
17023   [(set (match_operand:XF 0 "register_operand" "=f")
17024         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17025                     (match_operand:XF 2 "register_operand" "u")]
17026                    UNSPEC_FYL2XP1))
17027    (clobber (match_scratch:XF 3 "=2"))]
17028   "TARGET_USE_FANCY_MATH_387
17029    && flag_unsafe_math_optimizations"
17030   "fyl2xp1"
17031   [(set_attr "type" "fpspc")
17032    (set_attr "mode" "XF")])
17033
17034 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17035   [(set (match_operand:XF 0 "register_operand" "=f")
17036         (unspec:XF [(float_extend:XF
17037                       (match_operand:MODEF 1 "register_operand" "0"))
17038                     (match_operand:XF 2 "register_operand" "u")]
17039                    UNSPEC_FYL2XP1))
17040    (clobber (match_scratch:XF 3 "=2"))]
17041   "TARGET_USE_FANCY_MATH_387
17042    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17043        || TARGET_MIX_SSE_I387)
17044    && flag_unsafe_math_optimizations"
17045   "fyl2xp1"
17046   [(set_attr "type" "fpspc")
17047    (set_attr "mode" "XF")])
17048
17049 (define_expand "log1pxf2"
17050   [(use (match_operand:XF 0 "register_operand" ""))
17051    (use (match_operand:XF 1 "register_operand" ""))]
17052   "TARGET_USE_FANCY_MATH_387
17053    && flag_unsafe_math_optimizations && !optimize_size"
17054 {
17055   ix86_emit_i387_log1p (operands[0], operands[1]);
17056   DONE;
17057 })
17058
17059 (define_expand "log1p<mode>2"
17060   [(use (match_operand:MODEF 0 "register_operand" ""))
17061    (use (match_operand:MODEF 1 "register_operand" ""))]
17062   "TARGET_USE_FANCY_MATH_387
17063    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17064        || TARGET_MIX_SSE_I387)
17065    && flag_unsafe_math_optimizations && !optimize_size"
17066 {
17067   rtx op0 = gen_reg_rtx (XFmode);
17068
17069   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17070
17071   ix86_emit_i387_log1p (op0, operands[1]);
17072   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17073   DONE;
17074 })
17075
17076 (define_insn "fxtractxf3_i387"
17077   [(set (match_operand:XF 0 "register_operand" "=f")
17078         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17079                    UNSPEC_XTRACT_FRACT))
17080    (set (match_operand:XF 1 "register_operand" "=u")
17081         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17082   "TARGET_USE_FANCY_MATH_387
17083    && flag_unsafe_math_optimizations"
17084   "fxtract"
17085   [(set_attr "type" "fpspc")
17086    (set_attr "mode" "XF")])
17087
17088 (define_insn "fxtract_extend<mode>xf3_i387"
17089   [(set (match_operand:XF 0 "register_operand" "=f")
17090         (unspec:XF [(float_extend:XF
17091                       (match_operand:MODEF 2 "register_operand" "0"))]
17092                    UNSPEC_XTRACT_FRACT))
17093    (set (match_operand:XF 1 "register_operand" "=u")
17094         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17095   "TARGET_USE_FANCY_MATH_387
17096    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17097        || TARGET_MIX_SSE_I387)
17098    && flag_unsafe_math_optimizations"
17099   "fxtract"
17100   [(set_attr "type" "fpspc")
17101    (set_attr "mode" "XF")])
17102
17103 (define_expand "logbxf2"
17104   [(parallel [(set (match_dup 2)
17105                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17106                               UNSPEC_XTRACT_FRACT))
17107               (set (match_operand:XF 0 "register_operand" "")
17108                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17109   "TARGET_USE_FANCY_MATH_387
17110    && flag_unsafe_math_optimizations"
17111 {
17112   operands[2] = gen_reg_rtx (XFmode);
17113 })
17114
17115 (define_expand "logb<mode>2"
17116   [(use (match_operand:MODEF 0 "register_operand" ""))
17117    (use (match_operand:MODEF 1 "register_operand" ""))]
17118   "TARGET_USE_FANCY_MATH_387
17119    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17120        || TARGET_MIX_SSE_I387)
17121    && flag_unsafe_math_optimizations"
17122 {
17123   rtx op0 = gen_reg_rtx (XFmode);
17124   rtx op1 = gen_reg_rtx (XFmode);
17125
17126   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17127   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17128   DONE;
17129 })
17130
17131 (define_expand "ilogbxf2"
17132   [(use (match_operand:SI 0 "register_operand" ""))
17133    (use (match_operand:XF 1 "register_operand" ""))]
17134   "TARGET_USE_FANCY_MATH_387
17135    && flag_unsafe_math_optimizations && !optimize_size"
17136 {
17137   rtx op0 = gen_reg_rtx (XFmode);
17138   rtx op1 = gen_reg_rtx (XFmode);
17139
17140   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17141   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17142   DONE;
17143 })
17144
17145 (define_expand "ilogb<mode>2"
17146   [(use (match_operand:SI 0 "register_operand" ""))
17147    (use (match_operand:MODEF 1 "register_operand" ""))]
17148   "TARGET_USE_FANCY_MATH_387
17149    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17150        || TARGET_MIX_SSE_I387)
17151    && flag_unsafe_math_optimizations && !optimize_size"
17152 {
17153   rtx op0 = gen_reg_rtx (XFmode);
17154   rtx op1 = gen_reg_rtx (XFmode);
17155
17156   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17157   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17158   DONE;
17159 })
17160
17161 (define_insn "*f2xm1xf2_i387"
17162   [(set (match_operand:XF 0 "register_operand" "=f")
17163         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17164                    UNSPEC_F2XM1))]
17165   "TARGET_USE_FANCY_MATH_387
17166    && flag_unsafe_math_optimizations"
17167   "f2xm1"
17168   [(set_attr "type" "fpspc")
17169    (set_attr "mode" "XF")])
17170
17171 (define_insn "*fscalexf4_i387"
17172   [(set (match_operand:XF 0 "register_operand" "=f")
17173         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17174                     (match_operand:XF 3 "register_operand" "1")]
17175                    UNSPEC_FSCALE_FRACT))
17176    (set (match_operand:XF 1 "register_operand" "=u")
17177         (unspec:XF [(match_dup 2) (match_dup 3)]
17178                    UNSPEC_FSCALE_EXP))]
17179   "TARGET_USE_FANCY_MATH_387
17180    && flag_unsafe_math_optimizations"
17181   "fscale"
17182   [(set_attr "type" "fpspc")
17183    (set_attr "mode" "XF")])
17184
17185 (define_expand "expNcorexf3"
17186   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17187                                (match_operand:XF 2 "register_operand" "")))
17188    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17189    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17190    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17191    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17192    (parallel [(set (match_operand:XF 0 "register_operand" "")
17193                    (unspec:XF [(match_dup 8) (match_dup 4)]
17194                               UNSPEC_FSCALE_FRACT))
17195               (set (match_dup 9)
17196                    (unspec:XF [(match_dup 8) (match_dup 4)]
17197                               UNSPEC_FSCALE_EXP))])]
17198   "TARGET_USE_FANCY_MATH_387
17199    && flag_unsafe_math_optimizations && !optimize_size"
17200 {
17201   int i;
17202
17203   for (i = 3; i < 10; i++)
17204     operands[i] = gen_reg_rtx (XFmode);
17205
17206   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17207 })
17208
17209 (define_expand "expxf2"
17210   [(use (match_operand:XF 0 "register_operand" ""))
17211    (use (match_operand:XF 1 "register_operand" ""))]
17212   "TARGET_USE_FANCY_MATH_387
17213    && flag_unsafe_math_optimizations && !optimize_size"
17214 {
17215   rtx op2 = gen_reg_rtx (XFmode);
17216   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17217
17218   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17219   DONE;
17220 })
17221
17222 (define_expand "exp<mode>2"
17223   [(use (match_operand:MODEF 0 "register_operand" ""))
17224    (use (match_operand:MODEF 1 "general_operand" ""))]
17225  "TARGET_USE_FANCY_MATH_387
17226    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17227        || TARGET_MIX_SSE_I387)
17228    && flag_unsafe_math_optimizations && !optimize_size"
17229 {
17230   rtx op0 = gen_reg_rtx (XFmode);
17231   rtx op1 = gen_reg_rtx (XFmode);
17232
17233   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17234   emit_insn (gen_expxf2 (op0, op1));
17235   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17236   DONE;
17237 })
17238
17239 (define_expand "exp10xf2"
17240   [(use (match_operand:XF 0 "register_operand" ""))
17241    (use (match_operand:XF 1 "register_operand" ""))]
17242   "TARGET_USE_FANCY_MATH_387
17243    && flag_unsafe_math_optimizations && !optimize_size"
17244 {
17245   rtx op2 = gen_reg_rtx (XFmode);
17246   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17247
17248   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17249   DONE;
17250 })
17251
17252 (define_expand "exp10<mode>2"
17253   [(use (match_operand:MODEF 0 "register_operand" ""))
17254    (use (match_operand:MODEF 1 "general_operand" ""))]
17255  "TARGET_USE_FANCY_MATH_387
17256    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17257        || TARGET_MIX_SSE_I387)
17258    && flag_unsafe_math_optimizations && !optimize_size"
17259 {
17260   rtx op0 = gen_reg_rtx (XFmode);
17261   rtx op1 = gen_reg_rtx (XFmode);
17262
17263   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17264   emit_insn (gen_exp10xf2 (op0, op1));
17265   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17266   DONE;
17267 })
17268
17269 (define_expand "exp2xf2"
17270   [(use (match_operand:XF 0 "register_operand" ""))
17271    (use (match_operand:XF 1 "register_operand" ""))]
17272   "TARGET_USE_FANCY_MATH_387
17273    && flag_unsafe_math_optimizations && !optimize_size"
17274 {
17275   rtx op2 = gen_reg_rtx (XFmode);
17276   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17277
17278   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17279   DONE;
17280 })
17281
17282 (define_expand "exp2<mode>2"
17283   [(use (match_operand:MODEF 0 "register_operand" ""))
17284    (use (match_operand:MODEF 1 "general_operand" ""))]
17285  "TARGET_USE_FANCY_MATH_387
17286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17287        || TARGET_MIX_SSE_I387)
17288    && flag_unsafe_math_optimizations && !optimize_size"
17289 {
17290   rtx op0 = gen_reg_rtx (XFmode);
17291   rtx op1 = gen_reg_rtx (XFmode);
17292
17293   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17294   emit_insn (gen_exp2xf2 (op0, op1));
17295   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17296   DONE;
17297 })
17298
17299 (define_expand "expm1xf2"
17300   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17301                                (match_dup 2)))
17302    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17303    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17304    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17305    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17306    (parallel [(set (match_dup 7)
17307                    (unspec:XF [(match_dup 6) (match_dup 4)]
17308                               UNSPEC_FSCALE_FRACT))
17309               (set (match_dup 8)
17310                    (unspec:XF [(match_dup 6) (match_dup 4)]
17311                               UNSPEC_FSCALE_EXP))])
17312    (parallel [(set (match_dup 10)
17313                    (unspec:XF [(match_dup 9) (match_dup 8)]
17314                               UNSPEC_FSCALE_FRACT))
17315               (set (match_dup 11)
17316                    (unspec:XF [(match_dup 9) (match_dup 8)]
17317                               UNSPEC_FSCALE_EXP))])
17318    (set (match_dup 12) (minus:XF (match_dup 10)
17319                                  (float_extend:XF (match_dup 13))))
17320    (set (match_operand:XF 0 "register_operand" "")
17321         (plus:XF (match_dup 12) (match_dup 7)))]
17322   "TARGET_USE_FANCY_MATH_387
17323    && flag_unsafe_math_optimizations && !optimize_size"
17324 {
17325   int i;
17326
17327   for (i = 2; i < 13; i++)
17328     operands[i] = gen_reg_rtx (XFmode);
17329
17330   operands[13]
17331     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17332
17333   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17334 })
17335
17336 (define_expand "expm1<mode>2"
17337   [(use (match_operand:MODEF 0 "register_operand" ""))
17338    (use (match_operand:MODEF 1 "general_operand" ""))]
17339  "TARGET_USE_FANCY_MATH_387
17340    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17341        || TARGET_MIX_SSE_I387)
17342    && flag_unsafe_math_optimizations && !optimize_size"
17343 {
17344   rtx op0 = gen_reg_rtx (XFmode);
17345   rtx op1 = gen_reg_rtx (XFmode);
17346
17347   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17348   emit_insn (gen_expm1xf2 (op0, op1));
17349   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17350   DONE;
17351 })
17352
17353 (define_expand "ldexpxf3"
17354   [(set (match_dup 3)
17355         (float:XF (match_operand:SI 2 "register_operand" "")))
17356    (parallel [(set (match_operand:XF 0 " register_operand" "")
17357                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17358                                (match_dup 3)]
17359                               UNSPEC_FSCALE_FRACT))
17360               (set (match_dup 4)
17361                    (unspec:XF [(match_dup 1) (match_dup 3)]
17362                               UNSPEC_FSCALE_EXP))])]
17363   "TARGET_USE_FANCY_MATH_387
17364    && flag_unsafe_math_optimizations && !optimize_size"
17365 {
17366   operands[3] = gen_reg_rtx (XFmode);
17367   operands[4] = gen_reg_rtx (XFmode);
17368 })
17369
17370 (define_expand "ldexp<mode>3"
17371   [(use (match_operand:MODEF 0 "register_operand" ""))
17372    (use (match_operand:MODEF 1 "general_operand" ""))
17373    (use (match_operand:SI 2 "register_operand" ""))]
17374  "TARGET_USE_FANCY_MATH_387
17375    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17376        || TARGET_MIX_SSE_I387)
17377    && flag_unsafe_math_optimizations && !optimize_size"
17378 {
17379   rtx op0 = gen_reg_rtx (XFmode);
17380   rtx op1 = gen_reg_rtx (XFmode);
17381
17382   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17383   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17384   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17385   DONE;
17386 })
17387
17388 (define_expand "scalbxf3"
17389   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17390                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17391                                (match_operand:XF 2 "register_operand" "")]
17392                               UNSPEC_FSCALE_FRACT))
17393               (set (match_dup 3)
17394                    (unspec:XF [(match_dup 1) (match_dup 2)]
17395                               UNSPEC_FSCALE_EXP))])]
17396   "TARGET_USE_FANCY_MATH_387
17397    && flag_unsafe_math_optimizations && !optimize_size"
17398 {
17399   operands[3] = gen_reg_rtx (XFmode);
17400 })
17401
17402 (define_expand "scalb<mode>3"
17403   [(use (match_operand:MODEF 0 "register_operand" ""))
17404    (use (match_operand:MODEF 1 "general_operand" ""))
17405    (use (match_operand:MODEF 2 "register_operand" ""))]
17406  "TARGET_USE_FANCY_MATH_387
17407    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17408        || TARGET_MIX_SSE_I387)
17409    && flag_unsafe_math_optimizations && !optimize_size"
17410 {
17411   rtx op0 = gen_reg_rtx (XFmode);
17412   rtx op1 = gen_reg_rtx (XFmode);
17413   rtx op2 = gen_reg_rtx (XFmode);
17414
17415   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17416   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17417   emit_insn (gen_scalbxf3 (op0, op1, op2));
17418   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17419   DONE;
17420 })
17421 \f
17422
17423 (define_insn "sse4_1_round<mode>2"
17424   [(set (match_operand:MODEF 0 "register_operand" "=x")
17425         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17426                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17427                       UNSPEC_ROUND))]
17428   "TARGET_ROUND"
17429   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17430   [(set_attr "type" "ssecvt")
17431    (set_attr "prefix_extra" "1")
17432    (set_attr "mode" "<MODE>")])
17433
17434 (define_insn "rintxf2"
17435   [(set (match_operand:XF 0 "register_operand" "=f")
17436         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17437                    UNSPEC_FRNDINT))]
17438   "TARGET_USE_FANCY_MATH_387
17439    && flag_unsafe_math_optimizations"
17440   "frndint"
17441   [(set_attr "type" "fpspc")
17442    (set_attr "mode" "XF")])
17443
17444 (define_expand "rint<mode>2"
17445   [(use (match_operand:MODEF 0 "register_operand" ""))
17446    (use (match_operand:MODEF 1 "register_operand" ""))]
17447   "(TARGET_USE_FANCY_MATH_387
17448     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17449         || TARGET_MIX_SSE_I387)
17450     && flag_unsafe_math_optimizations)
17451    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17452        && !flag_trapping_math
17453        && (TARGET_ROUND || !optimize_size))"
17454 {
17455   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17456       && !flag_trapping_math
17457       && (TARGET_ROUND || !optimize_size))
17458     {
17459       if (TARGET_ROUND)
17460         emit_insn (gen_sse4_1_round<mode>2
17461                    (operands[0], operands[1], GEN_INT (0x04)));
17462       else
17463         ix86_expand_rint (operand0, operand1);
17464     }
17465   else
17466     {
17467       rtx op0 = gen_reg_rtx (XFmode);
17468       rtx op1 = gen_reg_rtx (XFmode);
17469
17470       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17471       emit_insn (gen_rintxf2 (op0, op1));
17472
17473       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17474     }
17475   DONE;
17476 })
17477
17478 (define_expand "round<mode>2"
17479   [(match_operand:MODEF 0 "register_operand" "")
17480    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17481   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17482    && !flag_trapping_math && !flag_rounding_math
17483    && !optimize_size"
17484 {
17485   if (TARGET_64BIT || (<MODE>mode != DFmode))
17486     ix86_expand_round (operand0, operand1);
17487   else
17488     ix86_expand_rounddf_32 (operand0, operand1);
17489   DONE;
17490 })
17491
17492 (define_insn_and_split "*fistdi2_1"
17493   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17494         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17495                    UNSPEC_FIST))]
17496   "TARGET_USE_FANCY_MATH_387
17497    && !(reload_completed || reload_in_progress)"
17498   "#"
17499   "&& 1"
17500   [(const_int 0)]
17501 {
17502   if (memory_operand (operands[0], VOIDmode))
17503     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17504   else
17505     {
17506       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17507       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17508                                          operands[2]));
17509     }
17510   DONE;
17511 }
17512   [(set_attr "type" "fpspc")
17513    (set_attr "mode" "DI")])
17514
17515 (define_insn "fistdi2"
17516   [(set (match_operand:DI 0 "memory_operand" "=m")
17517         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17518                    UNSPEC_FIST))
17519    (clobber (match_scratch:XF 2 "=&1f"))]
17520   "TARGET_USE_FANCY_MATH_387"
17521   "* return output_fix_trunc (insn, operands, 0);"
17522   [(set_attr "type" "fpspc")
17523    (set_attr "mode" "DI")])
17524
17525 (define_insn "fistdi2_with_temp"
17526   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17527         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17528                    UNSPEC_FIST))
17529    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17530    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17531   "TARGET_USE_FANCY_MATH_387"
17532   "#"
17533   [(set_attr "type" "fpspc")
17534    (set_attr "mode" "DI")])
17535
17536 (define_split
17537   [(set (match_operand:DI 0 "register_operand" "")
17538         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17539                    UNSPEC_FIST))
17540    (clobber (match_operand:DI 2 "memory_operand" ""))
17541    (clobber (match_scratch 3 ""))]
17542   "reload_completed"
17543   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17544               (clobber (match_dup 3))])
17545    (set (match_dup 0) (match_dup 2))]
17546   "")
17547
17548 (define_split
17549   [(set (match_operand:DI 0 "memory_operand" "")
17550         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17551                    UNSPEC_FIST))
17552    (clobber (match_operand:DI 2 "memory_operand" ""))
17553    (clobber (match_scratch 3 ""))]
17554   "reload_completed"
17555   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17556               (clobber (match_dup 3))])]
17557   "")
17558
17559 (define_insn_and_split "*fist<mode>2_1"
17560   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17561         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17562                            UNSPEC_FIST))]
17563   "TARGET_USE_FANCY_MATH_387
17564    && !(reload_completed || reload_in_progress)"
17565   "#"
17566   "&& 1"
17567   [(const_int 0)]
17568 {
17569   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17570   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17571                                         operands[2]));
17572   DONE;
17573 }
17574   [(set_attr "type" "fpspc")
17575    (set_attr "mode" "<MODE>")])
17576
17577 (define_insn "fist<mode>2"
17578   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17579         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17580                            UNSPEC_FIST))]
17581   "TARGET_USE_FANCY_MATH_387"
17582   "* return output_fix_trunc (insn, operands, 0);"
17583   [(set_attr "type" "fpspc")
17584    (set_attr "mode" "<MODE>")])
17585
17586 (define_insn "fist<mode>2_with_temp"
17587   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17588         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17589                            UNSPEC_FIST))
17590    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17591   "TARGET_USE_FANCY_MATH_387"
17592   "#"
17593   [(set_attr "type" "fpspc")
17594    (set_attr "mode" "<MODE>")])
17595
17596 (define_split
17597   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17598         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17599                            UNSPEC_FIST))
17600    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17601   "reload_completed"
17602   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17603    (set (match_dup 0) (match_dup 2))]
17604   "")
17605
17606 (define_split
17607   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17608         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17609                            UNSPEC_FIST))
17610    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17611   "reload_completed"
17612   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17613   "")
17614
17615 (define_expand "lrintxf<mode>2"
17616   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17617      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17618                       UNSPEC_FIST))]
17619   "TARGET_USE_FANCY_MATH_387"
17620   "")
17621
17622 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17623   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17624      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17625                         UNSPEC_FIX_NOTRUNC))]
17626   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17627    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17628   "")
17629
17630 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17631   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17632    (match_operand:MODEF 1 "register_operand" "")]
17633   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17634    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17635    && !flag_trapping_math && !flag_rounding_math
17636    && !optimize_size"
17637 {
17638   ix86_expand_lround (operand0, operand1);
17639   DONE;
17640 })
17641
17642 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17643 (define_insn_and_split "frndintxf2_floor"
17644   [(set (match_operand:XF 0 "register_operand" "")
17645         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17646          UNSPEC_FRNDINT_FLOOR))
17647    (clobber (reg:CC FLAGS_REG))]
17648   "TARGET_USE_FANCY_MATH_387
17649    && flag_unsafe_math_optimizations
17650    && !(reload_completed || reload_in_progress)"
17651   "#"
17652   "&& 1"
17653   [(const_int 0)]
17654 {
17655   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17656
17657   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17658   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17659
17660   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17661                                         operands[2], operands[3]));
17662   DONE;
17663 }
17664   [(set_attr "type" "frndint")
17665    (set_attr "i387_cw" "floor")
17666    (set_attr "mode" "XF")])
17667
17668 (define_insn "frndintxf2_floor_i387"
17669   [(set (match_operand:XF 0 "register_operand" "=f")
17670         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17671          UNSPEC_FRNDINT_FLOOR))
17672    (use (match_operand:HI 2 "memory_operand" "m"))
17673    (use (match_operand:HI 3 "memory_operand" "m"))]
17674   "TARGET_USE_FANCY_MATH_387
17675    && flag_unsafe_math_optimizations"
17676   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17677   [(set_attr "type" "frndint")
17678    (set_attr "i387_cw" "floor")
17679    (set_attr "mode" "XF")])
17680
17681 (define_expand "floorxf2"
17682   [(use (match_operand:XF 0 "register_operand" ""))
17683    (use (match_operand:XF 1 "register_operand" ""))]
17684   "TARGET_USE_FANCY_MATH_387
17685    && flag_unsafe_math_optimizations && !optimize_size"
17686 {
17687   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17688   DONE;
17689 })
17690
17691 (define_expand "floor<mode>2"
17692   [(use (match_operand:MODEF 0 "register_operand" ""))
17693    (use (match_operand:MODEF 1 "register_operand" ""))]
17694   "(TARGET_USE_FANCY_MATH_387
17695     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17696         || TARGET_MIX_SSE_I387)
17697     && flag_unsafe_math_optimizations && !optimize_size)
17698    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17699        && !flag_trapping_math
17700        && (TARGET_ROUND || !optimize_size))"
17701 {
17702   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17703       && !flag_trapping_math
17704       && (TARGET_ROUND || !optimize_size))
17705     {
17706       if (TARGET_ROUND)
17707         emit_insn (gen_sse4_1_round<mode>2
17708                    (operands[0], operands[1], GEN_INT (0x01)));
17709       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17710         ix86_expand_floorceil (operand0, operand1, true);
17711       else
17712         ix86_expand_floorceildf_32 (operand0, operand1, true);
17713     }
17714   else
17715     {
17716       rtx op0 = gen_reg_rtx (XFmode);
17717       rtx op1 = gen_reg_rtx (XFmode);
17718
17719       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17720       emit_insn (gen_frndintxf2_floor (op0, op1));
17721
17722       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17723     }
17724   DONE;
17725 })
17726
17727 (define_insn_and_split "*fist<mode>2_floor_1"
17728   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17729         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17730          UNSPEC_FIST_FLOOR))
17731    (clobber (reg:CC FLAGS_REG))]
17732   "TARGET_USE_FANCY_MATH_387
17733    && flag_unsafe_math_optimizations
17734    && !(reload_completed || reload_in_progress)"
17735   "#"
17736   "&& 1"
17737   [(const_int 0)]
17738 {
17739   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17740
17741   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17742   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17743   if (memory_operand (operands[0], VOIDmode))
17744     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17745                                       operands[2], operands[3]));
17746   else
17747     {
17748       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17749       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17750                                                   operands[2], operands[3],
17751                                                   operands[4]));
17752     }
17753   DONE;
17754 }
17755   [(set_attr "type" "fistp")
17756    (set_attr "i387_cw" "floor")
17757    (set_attr "mode" "<MODE>")])
17758
17759 (define_insn "fistdi2_floor"
17760   [(set (match_operand:DI 0 "memory_operand" "=m")
17761         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17762          UNSPEC_FIST_FLOOR))
17763    (use (match_operand:HI 2 "memory_operand" "m"))
17764    (use (match_operand:HI 3 "memory_operand" "m"))
17765    (clobber (match_scratch:XF 4 "=&1f"))]
17766   "TARGET_USE_FANCY_MATH_387
17767    && flag_unsafe_math_optimizations"
17768   "* return output_fix_trunc (insn, operands, 0);"
17769   [(set_attr "type" "fistp")
17770    (set_attr "i387_cw" "floor")
17771    (set_attr "mode" "DI")])
17772
17773 (define_insn "fistdi2_floor_with_temp"
17774   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17775         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17776          UNSPEC_FIST_FLOOR))
17777    (use (match_operand:HI 2 "memory_operand" "m,m"))
17778    (use (match_operand:HI 3 "memory_operand" "m,m"))
17779    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17780    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17781   "TARGET_USE_FANCY_MATH_387
17782    && flag_unsafe_math_optimizations"
17783   "#"
17784   [(set_attr "type" "fistp")
17785    (set_attr "i387_cw" "floor")
17786    (set_attr "mode" "DI")])
17787
17788 (define_split
17789   [(set (match_operand:DI 0 "register_operand" "")
17790         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17791          UNSPEC_FIST_FLOOR))
17792    (use (match_operand:HI 2 "memory_operand" ""))
17793    (use (match_operand:HI 3 "memory_operand" ""))
17794    (clobber (match_operand:DI 4 "memory_operand" ""))
17795    (clobber (match_scratch 5 ""))]
17796   "reload_completed"
17797   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17798               (use (match_dup 2))
17799               (use (match_dup 3))
17800               (clobber (match_dup 5))])
17801    (set (match_dup 0) (match_dup 4))]
17802   "")
17803
17804 (define_split
17805   [(set (match_operand:DI 0 "memory_operand" "")
17806         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17807          UNSPEC_FIST_FLOOR))
17808    (use (match_operand:HI 2 "memory_operand" ""))
17809    (use (match_operand:HI 3 "memory_operand" ""))
17810    (clobber (match_operand:DI 4 "memory_operand" ""))
17811    (clobber (match_scratch 5 ""))]
17812   "reload_completed"
17813   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17814               (use (match_dup 2))
17815               (use (match_dup 3))
17816               (clobber (match_dup 5))])]
17817   "")
17818
17819 (define_insn "fist<mode>2_floor"
17820   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17821         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17822          UNSPEC_FIST_FLOOR))
17823    (use (match_operand:HI 2 "memory_operand" "m"))
17824    (use (match_operand:HI 3 "memory_operand" "m"))]
17825   "TARGET_USE_FANCY_MATH_387
17826    && flag_unsafe_math_optimizations"
17827   "* return output_fix_trunc (insn, operands, 0);"
17828   [(set_attr "type" "fistp")
17829    (set_attr "i387_cw" "floor")
17830    (set_attr "mode" "<MODE>")])
17831
17832 (define_insn "fist<mode>2_floor_with_temp"
17833   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17834         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17835          UNSPEC_FIST_FLOOR))
17836    (use (match_operand:HI 2 "memory_operand" "m,m"))
17837    (use (match_operand:HI 3 "memory_operand" "m,m"))
17838    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17839   "TARGET_USE_FANCY_MATH_387
17840    && flag_unsafe_math_optimizations"
17841   "#"
17842   [(set_attr "type" "fistp")
17843    (set_attr "i387_cw" "floor")
17844    (set_attr "mode" "<MODE>")])
17845
17846 (define_split
17847   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17848         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17849          UNSPEC_FIST_FLOOR))
17850    (use (match_operand:HI 2 "memory_operand" ""))
17851    (use (match_operand:HI 3 "memory_operand" ""))
17852    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17853   "reload_completed"
17854   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17855                                   UNSPEC_FIST_FLOOR))
17856               (use (match_dup 2))
17857               (use (match_dup 3))])
17858    (set (match_dup 0) (match_dup 4))]
17859   "")
17860
17861 (define_split
17862   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17863         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17864          UNSPEC_FIST_FLOOR))
17865    (use (match_operand:HI 2 "memory_operand" ""))
17866    (use (match_operand:HI 3 "memory_operand" ""))
17867    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17868   "reload_completed"
17869   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17870                                   UNSPEC_FIST_FLOOR))
17871               (use (match_dup 2))
17872               (use (match_dup 3))])]
17873   "")
17874
17875 (define_expand "lfloorxf<mode>2"
17876   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17877                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17878                     UNSPEC_FIST_FLOOR))
17879               (clobber (reg:CC FLAGS_REG))])]
17880   "TARGET_USE_FANCY_MATH_387
17881    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17882    && flag_unsafe_math_optimizations"
17883   "")
17884
17885 (define_expand "lfloor<mode>di2"
17886   [(match_operand:DI 0 "nonimmediate_operand" "")
17887    (match_operand:MODEF 1 "register_operand" "")]
17888   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17889    && !flag_trapping_math
17890    && !optimize_size"
17891 {
17892   ix86_expand_lfloorceil (operand0, operand1, true);
17893   DONE;
17894 })
17895
17896 (define_expand "lfloor<mode>si2"
17897   [(match_operand:SI 0 "nonimmediate_operand" "")
17898    (match_operand:MODEF 1 "register_operand" "")]
17899   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17900    && !flag_trapping_math
17901    && (!optimize_size || !TARGET_64BIT)"
17902 {
17903   ix86_expand_lfloorceil (operand0, operand1, true);
17904   DONE;
17905 })
17906
17907 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17908 (define_insn_and_split "frndintxf2_ceil"
17909   [(set (match_operand:XF 0 "register_operand" "")
17910         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17911          UNSPEC_FRNDINT_CEIL))
17912    (clobber (reg:CC FLAGS_REG))]
17913   "TARGET_USE_FANCY_MATH_387
17914    && flag_unsafe_math_optimizations
17915    && !(reload_completed || reload_in_progress)"
17916   "#"
17917   "&& 1"
17918   [(const_int 0)]
17919 {
17920   ix86_optimize_mode_switching[I387_CEIL] = 1;
17921
17922   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17923   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17924
17925   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17926                                        operands[2], operands[3]));
17927   DONE;
17928 }
17929   [(set_attr "type" "frndint")
17930    (set_attr "i387_cw" "ceil")
17931    (set_attr "mode" "XF")])
17932
17933 (define_insn "frndintxf2_ceil_i387"
17934   [(set (match_operand:XF 0 "register_operand" "=f")
17935         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17936          UNSPEC_FRNDINT_CEIL))
17937    (use (match_operand:HI 2 "memory_operand" "m"))
17938    (use (match_operand:HI 3 "memory_operand" "m"))]
17939   "TARGET_USE_FANCY_MATH_387
17940    && flag_unsafe_math_optimizations"
17941   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17942   [(set_attr "type" "frndint")
17943    (set_attr "i387_cw" "ceil")
17944    (set_attr "mode" "XF")])
17945
17946 (define_expand "ceilxf2"
17947   [(use (match_operand:XF 0 "register_operand" ""))
17948    (use (match_operand:XF 1 "register_operand" ""))]
17949   "TARGET_USE_FANCY_MATH_387
17950    && flag_unsafe_math_optimizations && !optimize_size"
17951 {
17952   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17953   DONE;
17954 })
17955
17956 (define_expand "ceil<mode>2"
17957   [(use (match_operand:MODEF 0 "register_operand" ""))
17958    (use (match_operand:MODEF 1 "register_operand" ""))]
17959   "(TARGET_USE_FANCY_MATH_387
17960     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17961         || TARGET_MIX_SSE_I387)
17962     && flag_unsafe_math_optimizations && !optimize_size)
17963    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17964        && !flag_trapping_math
17965        && (TARGET_ROUND || !optimize_size))"
17966 {
17967   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17968       && !flag_trapping_math
17969       && (TARGET_ROUND || !optimize_size))
17970     {
17971       if (TARGET_ROUND)
17972         emit_insn (gen_sse4_1_round<mode>2
17973                    (operands[0], operands[1], GEN_INT (0x02)));
17974       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17975         ix86_expand_floorceil (operand0, operand1, false);
17976       else
17977         ix86_expand_floorceildf_32 (operand0, operand1, false);
17978     }
17979   else
17980     {
17981       rtx op0 = gen_reg_rtx (XFmode);
17982       rtx op1 = gen_reg_rtx (XFmode);
17983
17984       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17985       emit_insn (gen_frndintxf2_ceil (op0, op1));
17986
17987       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17988     }
17989   DONE;
17990 })
17991
17992 (define_insn_and_split "*fist<mode>2_ceil_1"
17993   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17994         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17995          UNSPEC_FIST_CEIL))
17996    (clobber (reg:CC FLAGS_REG))]
17997   "TARGET_USE_FANCY_MATH_387
17998    && flag_unsafe_math_optimizations
17999    && !(reload_completed || reload_in_progress)"
18000   "#"
18001   "&& 1"
18002   [(const_int 0)]
18003 {
18004   ix86_optimize_mode_switching[I387_CEIL] = 1;
18005
18006   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18007   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18008   if (memory_operand (operands[0], VOIDmode))
18009     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18010                                      operands[2], operands[3]));
18011   else
18012     {
18013       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18014       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18015                                                  operands[2], operands[3],
18016                                                  operands[4]));
18017     }
18018   DONE;
18019 }
18020   [(set_attr "type" "fistp")
18021    (set_attr "i387_cw" "ceil")
18022    (set_attr "mode" "<MODE>")])
18023
18024 (define_insn "fistdi2_ceil"
18025   [(set (match_operand:DI 0 "memory_operand" "=m")
18026         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18027          UNSPEC_FIST_CEIL))
18028    (use (match_operand:HI 2 "memory_operand" "m"))
18029    (use (match_operand:HI 3 "memory_operand" "m"))
18030    (clobber (match_scratch:XF 4 "=&1f"))]
18031   "TARGET_USE_FANCY_MATH_387
18032    && flag_unsafe_math_optimizations"
18033   "* return output_fix_trunc (insn, operands, 0);"
18034   [(set_attr "type" "fistp")
18035    (set_attr "i387_cw" "ceil")
18036    (set_attr "mode" "DI")])
18037
18038 (define_insn "fistdi2_ceil_with_temp"
18039   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18040         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18041          UNSPEC_FIST_CEIL))
18042    (use (match_operand:HI 2 "memory_operand" "m,m"))
18043    (use (match_operand:HI 3 "memory_operand" "m,m"))
18044    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18045    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18046   "TARGET_USE_FANCY_MATH_387
18047    && flag_unsafe_math_optimizations"
18048   "#"
18049   [(set_attr "type" "fistp")
18050    (set_attr "i387_cw" "ceil")
18051    (set_attr "mode" "DI")])
18052
18053 (define_split
18054   [(set (match_operand:DI 0 "register_operand" "")
18055         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18056          UNSPEC_FIST_CEIL))
18057    (use (match_operand:HI 2 "memory_operand" ""))
18058    (use (match_operand:HI 3 "memory_operand" ""))
18059    (clobber (match_operand:DI 4 "memory_operand" ""))
18060    (clobber (match_scratch 5 ""))]
18061   "reload_completed"
18062   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18063               (use (match_dup 2))
18064               (use (match_dup 3))
18065               (clobber (match_dup 5))])
18066    (set (match_dup 0) (match_dup 4))]
18067   "")
18068
18069 (define_split
18070   [(set (match_operand:DI 0 "memory_operand" "")
18071         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18072          UNSPEC_FIST_CEIL))
18073    (use (match_operand:HI 2 "memory_operand" ""))
18074    (use (match_operand:HI 3 "memory_operand" ""))
18075    (clobber (match_operand:DI 4 "memory_operand" ""))
18076    (clobber (match_scratch 5 ""))]
18077   "reload_completed"
18078   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18079               (use (match_dup 2))
18080               (use (match_dup 3))
18081               (clobber (match_dup 5))])]
18082   "")
18083
18084 (define_insn "fist<mode>2_ceil"
18085   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18086         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18087          UNSPEC_FIST_CEIL))
18088    (use (match_operand:HI 2 "memory_operand" "m"))
18089    (use (match_operand:HI 3 "memory_operand" "m"))]
18090   "TARGET_USE_FANCY_MATH_387
18091    && flag_unsafe_math_optimizations"
18092   "* return output_fix_trunc (insn, operands, 0);"
18093   [(set_attr "type" "fistp")
18094    (set_attr "i387_cw" "ceil")
18095    (set_attr "mode" "<MODE>")])
18096
18097 (define_insn "fist<mode>2_ceil_with_temp"
18098   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18099         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18100          UNSPEC_FIST_CEIL))
18101    (use (match_operand:HI 2 "memory_operand" "m,m"))
18102    (use (match_operand:HI 3 "memory_operand" "m,m"))
18103    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18104   "TARGET_USE_FANCY_MATH_387
18105    && flag_unsafe_math_optimizations"
18106   "#"
18107   [(set_attr "type" "fistp")
18108    (set_attr "i387_cw" "ceil")
18109    (set_attr "mode" "<MODE>")])
18110
18111 (define_split
18112   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18113         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18114          UNSPEC_FIST_CEIL))
18115    (use (match_operand:HI 2 "memory_operand" ""))
18116    (use (match_operand:HI 3 "memory_operand" ""))
18117    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18118   "reload_completed"
18119   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18120                                   UNSPEC_FIST_CEIL))
18121               (use (match_dup 2))
18122               (use (match_dup 3))])
18123    (set (match_dup 0) (match_dup 4))]
18124   "")
18125
18126 (define_split
18127   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18128         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18129          UNSPEC_FIST_CEIL))
18130    (use (match_operand:HI 2 "memory_operand" ""))
18131    (use (match_operand:HI 3 "memory_operand" ""))
18132    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18133   "reload_completed"
18134   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18135                                   UNSPEC_FIST_CEIL))
18136               (use (match_dup 2))
18137               (use (match_dup 3))])]
18138   "")
18139
18140 (define_expand "lceilxf<mode>2"
18141   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18142                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18143                     UNSPEC_FIST_CEIL))
18144               (clobber (reg:CC FLAGS_REG))])]
18145   "TARGET_USE_FANCY_MATH_387
18146    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18147    && flag_unsafe_math_optimizations"
18148   "")
18149
18150 (define_expand "lceil<mode>di2"
18151   [(match_operand:DI 0 "nonimmediate_operand" "")
18152    (match_operand:MODEF 1 "register_operand" "")]
18153   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18154    && !flag_trapping_math"
18155 {
18156   ix86_expand_lfloorceil (operand0, operand1, false);
18157   DONE;
18158 })
18159
18160 (define_expand "lceil<mode>si2"
18161   [(match_operand:SI 0 "nonimmediate_operand" "")
18162    (match_operand:MODEF 1 "register_operand" "")]
18163   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18164    && !flag_trapping_math"
18165 {
18166   ix86_expand_lfloorceil (operand0, operand1, false);
18167   DONE;
18168 })
18169
18170 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18171 (define_insn_and_split "frndintxf2_trunc"
18172   [(set (match_operand:XF 0 "register_operand" "")
18173         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18174          UNSPEC_FRNDINT_TRUNC))
18175    (clobber (reg:CC FLAGS_REG))]
18176   "TARGET_USE_FANCY_MATH_387
18177    && flag_unsafe_math_optimizations
18178    && !(reload_completed || reload_in_progress)"
18179   "#"
18180   "&& 1"
18181   [(const_int 0)]
18182 {
18183   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18184
18185   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18186   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18187
18188   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18189                                         operands[2], operands[3]));
18190   DONE;
18191 }
18192   [(set_attr "type" "frndint")
18193    (set_attr "i387_cw" "trunc")
18194    (set_attr "mode" "XF")])
18195
18196 (define_insn "frndintxf2_trunc_i387"
18197   [(set (match_operand:XF 0 "register_operand" "=f")
18198         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18199          UNSPEC_FRNDINT_TRUNC))
18200    (use (match_operand:HI 2 "memory_operand" "m"))
18201    (use (match_operand:HI 3 "memory_operand" "m"))]
18202   "TARGET_USE_FANCY_MATH_387
18203    && flag_unsafe_math_optimizations"
18204   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18205   [(set_attr "type" "frndint")
18206    (set_attr "i387_cw" "trunc")
18207    (set_attr "mode" "XF")])
18208
18209 (define_expand "btruncxf2"
18210   [(use (match_operand:XF 0 "register_operand" ""))
18211    (use (match_operand:XF 1 "register_operand" ""))]
18212   "TARGET_USE_FANCY_MATH_387
18213    && flag_unsafe_math_optimizations && !optimize_size"
18214 {
18215   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18216   DONE;
18217 })
18218
18219 (define_expand "btrunc<mode>2"
18220   [(use (match_operand:MODEF 0 "register_operand" ""))
18221    (use (match_operand:MODEF 1 "register_operand" ""))]
18222   "(TARGET_USE_FANCY_MATH_387
18223     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18224         || TARGET_MIX_SSE_I387)
18225     && flag_unsafe_math_optimizations && !optimize_size)
18226    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18227        && !flag_trapping_math
18228        && (TARGET_ROUND || !optimize_size))"
18229 {
18230   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18231       && !flag_trapping_math
18232       && (TARGET_ROUND || !optimize_size))
18233     {
18234       if (TARGET_ROUND)
18235         emit_insn (gen_sse4_1_round<mode>2
18236                    (operands[0], operands[1], GEN_INT (0x03)));
18237       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18238         ix86_expand_trunc (operand0, operand1);
18239       else
18240         ix86_expand_truncdf_32 (operand0, operand1);
18241     }
18242   else
18243     {
18244       rtx op0 = gen_reg_rtx (XFmode);
18245       rtx op1 = gen_reg_rtx (XFmode);
18246
18247       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18248       emit_insn (gen_frndintxf2_trunc (op0, op1));
18249
18250       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18251     }
18252   DONE;
18253 })
18254
18255 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18256 (define_insn_and_split "frndintxf2_mask_pm"
18257   [(set (match_operand:XF 0 "register_operand" "")
18258         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18259          UNSPEC_FRNDINT_MASK_PM))
18260    (clobber (reg:CC FLAGS_REG))]
18261   "TARGET_USE_FANCY_MATH_387
18262    && flag_unsafe_math_optimizations
18263    && !(reload_completed || reload_in_progress)"
18264   "#"
18265   "&& 1"
18266   [(const_int 0)]
18267 {
18268   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18269
18270   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18271   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18272
18273   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18274                                           operands[2], operands[3]));
18275   DONE;
18276 }
18277   [(set_attr "type" "frndint")
18278    (set_attr "i387_cw" "mask_pm")
18279    (set_attr "mode" "XF")])
18280
18281 (define_insn "frndintxf2_mask_pm_i387"
18282   [(set (match_operand:XF 0 "register_operand" "=f")
18283         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18284          UNSPEC_FRNDINT_MASK_PM))
18285    (use (match_operand:HI 2 "memory_operand" "m"))
18286    (use (match_operand:HI 3 "memory_operand" "m"))]
18287   "TARGET_USE_FANCY_MATH_387
18288    && flag_unsafe_math_optimizations"
18289   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18290   [(set_attr "type" "frndint")
18291    (set_attr "i387_cw" "mask_pm")
18292    (set_attr "mode" "XF")])
18293
18294 (define_expand "nearbyintxf2"
18295   [(use (match_operand:XF 0 "register_operand" ""))
18296    (use (match_operand:XF 1 "register_operand" ""))]
18297   "TARGET_USE_FANCY_MATH_387
18298    && flag_unsafe_math_optimizations"
18299 {
18300   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18301
18302   DONE;
18303 })
18304
18305 (define_expand "nearbyint<mode>2"
18306   [(use (match_operand:MODEF 0 "register_operand" ""))
18307    (use (match_operand:MODEF 1 "register_operand" ""))]
18308   "TARGET_USE_FANCY_MATH_387
18309    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18310        || TARGET_MIX_SSE_I387)
18311    && flag_unsafe_math_optimizations"
18312 {
18313   rtx op0 = gen_reg_rtx (XFmode);
18314   rtx op1 = gen_reg_rtx (XFmode);
18315
18316   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18317   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18318
18319   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18320   DONE;
18321 })
18322
18323 (define_insn "fxam<mode>2_i387"
18324   [(set (match_operand:HI 0 "register_operand" "=a")
18325         (unspec:HI
18326           [(match_operand:X87MODEF 1 "register_operand" "f")]
18327           UNSPEC_FXAM))]
18328   "TARGET_USE_FANCY_MATH_387"
18329   "fxam\n\tfnstsw\t%0"
18330   [(set_attr "type" "multi")
18331    (set_attr "unit" "i387")
18332    (set_attr "mode" "<MODE>")])
18333
18334 (define_expand "isinf<mode>2"
18335   [(use (match_operand:SI 0 "register_operand" ""))
18336    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18337   "TARGET_USE_FANCY_MATH_387
18338    && TARGET_C99_FUNCTIONS
18339    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18340 {
18341   rtx mask = GEN_INT (0x45);
18342   rtx val = GEN_INT (0x05);
18343
18344   rtx cond;
18345
18346   rtx scratch = gen_reg_rtx (HImode);
18347   rtx res = gen_reg_rtx (QImode);
18348
18349   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18350   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18351   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18352   cond = gen_rtx_fmt_ee (EQ, QImode,
18353                          gen_rtx_REG (CCmode, FLAGS_REG),
18354                          const0_rtx);
18355   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18356   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18357   DONE;
18358 })
18359
18360 (define_expand "signbit<mode>2"
18361   [(use (match_operand:SI 0 "register_operand" ""))
18362    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18363   "TARGET_USE_FANCY_MATH_387
18364    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18365 {
18366   rtx mask = GEN_INT (0x0200);
18367
18368   rtx scratch = gen_reg_rtx (HImode);
18369
18370   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18371   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18372   DONE;
18373 })
18374 \f
18375 ;; Block operation instructions
18376
18377 (define_expand "movmemsi"
18378   [(use (match_operand:BLK 0 "memory_operand" ""))
18379    (use (match_operand:BLK 1 "memory_operand" ""))
18380    (use (match_operand:SI 2 "nonmemory_operand" ""))
18381    (use (match_operand:SI 3 "const_int_operand" ""))
18382    (use (match_operand:SI 4 "const_int_operand" ""))
18383    (use (match_operand:SI 5 "const_int_operand" ""))]
18384   ""
18385 {
18386  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18387                          operands[4], operands[5]))
18388    DONE;
18389  else
18390    FAIL;
18391 })
18392
18393 (define_expand "movmemdi"
18394   [(use (match_operand:BLK 0 "memory_operand" ""))
18395    (use (match_operand:BLK 1 "memory_operand" ""))
18396    (use (match_operand:DI 2 "nonmemory_operand" ""))
18397    (use (match_operand:DI 3 "const_int_operand" ""))
18398    (use (match_operand:SI 4 "const_int_operand" ""))
18399    (use (match_operand:SI 5 "const_int_operand" ""))]
18400   "TARGET_64BIT"
18401 {
18402  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18403                          operands[4], operands[5]))
18404    DONE;
18405  else
18406    FAIL;
18407 })
18408
18409 ;; Most CPUs don't like single string operations
18410 ;; Handle this case here to simplify previous expander.
18411
18412 (define_expand "strmov"
18413   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18414    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18415    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18416               (clobber (reg:CC FLAGS_REG))])
18417    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18418               (clobber (reg:CC FLAGS_REG))])]
18419   ""
18420 {
18421   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18422
18423   /* If .md ever supports :P for Pmode, these can be directly
18424      in the pattern above.  */
18425   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18426   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18427
18428   /* Can't use this if the user has appropriated esi or edi.  */
18429   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18430       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18431     {
18432       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18433                                       operands[2], operands[3],
18434                                       operands[5], operands[6]));
18435       DONE;
18436     }
18437
18438   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18439 })
18440
18441 (define_expand "strmov_singleop"
18442   [(parallel [(set (match_operand 1 "memory_operand" "")
18443                    (match_operand 3 "memory_operand" ""))
18444               (set (match_operand 0 "register_operand" "")
18445                    (match_operand 4 "" ""))
18446               (set (match_operand 2 "register_operand" "")
18447                    (match_operand 5 "" ""))])]
18448   "TARGET_SINGLE_STRINGOP || optimize_size"
18449   "")
18450
18451 (define_insn "*strmovdi_rex_1"
18452   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18453         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18454    (set (match_operand:DI 0 "register_operand" "=D")
18455         (plus:DI (match_dup 2)
18456                  (const_int 8)))
18457    (set (match_operand:DI 1 "register_operand" "=S")
18458         (plus:DI (match_dup 3)
18459                  (const_int 8)))]
18460   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18461   "movsq"
18462   [(set_attr "type" "str")
18463    (set_attr "mode" "DI")
18464    (set_attr "memory" "both")])
18465
18466 (define_insn "*strmovsi_1"
18467   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18468         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18469    (set (match_operand:SI 0 "register_operand" "=D")
18470         (plus:SI (match_dup 2)
18471                  (const_int 4)))
18472    (set (match_operand:SI 1 "register_operand" "=S")
18473         (plus:SI (match_dup 3)
18474                  (const_int 4)))]
18475   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18476   "movs{l|d}"
18477   [(set_attr "type" "str")
18478    (set_attr "mode" "SI")
18479    (set_attr "memory" "both")])
18480
18481 (define_insn "*strmovsi_rex_1"
18482   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18483         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18484    (set (match_operand:DI 0 "register_operand" "=D")
18485         (plus:DI (match_dup 2)
18486                  (const_int 4)))
18487    (set (match_operand:DI 1 "register_operand" "=S")
18488         (plus:DI (match_dup 3)
18489                  (const_int 4)))]
18490   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18491   "movs{l|d}"
18492   [(set_attr "type" "str")
18493    (set_attr "mode" "SI")
18494    (set_attr "memory" "both")])
18495
18496 (define_insn "*strmovhi_1"
18497   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18498         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18499    (set (match_operand:SI 0 "register_operand" "=D")
18500         (plus:SI (match_dup 2)
18501                  (const_int 2)))
18502    (set (match_operand:SI 1 "register_operand" "=S")
18503         (plus:SI (match_dup 3)
18504                  (const_int 2)))]
18505   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18506   "movsw"
18507   [(set_attr "type" "str")
18508    (set_attr "memory" "both")
18509    (set_attr "mode" "HI")])
18510
18511 (define_insn "*strmovhi_rex_1"
18512   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18513         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18514    (set (match_operand:DI 0 "register_operand" "=D")
18515         (plus:DI (match_dup 2)
18516                  (const_int 2)))
18517    (set (match_operand:DI 1 "register_operand" "=S")
18518         (plus:DI (match_dup 3)
18519                  (const_int 2)))]
18520   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18521   "movsw"
18522   [(set_attr "type" "str")
18523    (set_attr "memory" "both")
18524    (set_attr "mode" "HI")])
18525
18526 (define_insn "*strmovqi_1"
18527   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18528         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18529    (set (match_operand:SI 0 "register_operand" "=D")
18530         (plus:SI (match_dup 2)
18531                  (const_int 1)))
18532    (set (match_operand:SI 1 "register_operand" "=S")
18533         (plus:SI (match_dup 3)
18534                  (const_int 1)))]
18535   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18536   "movsb"
18537   [(set_attr "type" "str")
18538    (set_attr "memory" "both")
18539    (set_attr "mode" "QI")])
18540
18541 (define_insn "*strmovqi_rex_1"
18542   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18543         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18544    (set (match_operand:DI 0 "register_operand" "=D")
18545         (plus:DI (match_dup 2)
18546                  (const_int 1)))
18547    (set (match_operand:DI 1 "register_operand" "=S")
18548         (plus:DI (match_dup 3)
18549                  (const_int 1)))]
18550   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18551   "movsb"
18552   [(set_attr "type" "str")
18553    (set_attr "memory" "both")
18554    (set_attr "mode" "QI")])
18555
18556 (define_expand "rep_mov"
18557   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18558               (set (match_operand 0 "register_operand" "")
18559                    (match_operand 5 "" ""))
18560               (set (match_operand 2 "register_operand" "")
18561                    (match_operand 6 "" ""))
18562               (set (match_operand 1 "memory_operand" "")
18563                    (match_operand 3 "memory_operand" ""))
18564               (use (match_dup 4))])]
18565   ""
18566   "")
18567
18568 (define_insn "*rep_movdi_rex64"
18569   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18570    (set (match_operand:DI 0 "register_operand" "=D")
18571         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18572                             (const_int 3))
18573                  (match_operand:DI 3 "register_operand" "0")))
18574    (set (match_operand:DI 1 "register_operand" "=S")
18575         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18576                  (match_operand:DI 4 "register_operand" "1")))
18577    (set (mem:BLK (match_dup 3))
18578         (mem:BLK (match_dup 4)))
18579    (use (match_dup 5))]
18580   "TARGET_64BIT"
18581   "rep movsq"
18582   [(set_attr "type" "str")
18583    (set_attr "prefix_rep" "1")
18584    (set_attr "memory" "both")
18585    (set_attr "mode" "DI")])
18586
18587 (define_insn "*rep_movsi"
18588   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18589    (set (match_operand:SI 0 "register_operand" "=D")
18590         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18591                             (const_int 2))
18592                  (match_operand:SI 3 "register_operand" "0")))
18593    (set (match_operand:SI 1 "register_operand" "=S")
18594         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18595                  (match_operand:SI 4 "register_operand" "1")))
18596    (set (mem:BLK (match_dup 3))
18597         (mem:BLK (match_dup 4)))
18598    (use (match_dup 5))]
18599   "!TARGET_64BIT"
18600   "rep movs{l|d}"
18601   [(set_attr "type" "str")
18602    (set_attr "prefix_rep" "1")
18603    (set_attr "memory" "both")
18604    (set_attr "mode" "SI")])
18605
18606 (define_insn "*rep_movsi_rex64"
18607   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18608    (set (match_operand:DI 0 "register_operand" "=D")
18609         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18610                             (const_int 2))
18611                  (match_operand:DI 3 "register_operand" "0")))
18612    (set (match_operand:DI 1 "register_operand" "=S")
18613         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18614                  (match_operand:DI 4 "register_operand" "1")))
18615    (set (mem:BLK (match_dup 3))
18616         (mem:BLK (match_dup 4)))
18617    (use (match_dup 5))]
18618   "TARGET_64BIT"
18619   "rep movs{l|d}"
18620   [(set_attr "type" "str")
18621    (set_attr "prefix_rep" "1")
18622    (set_attr "memory" "both")
18623    (set_attr "mode" "SI")])
18624
18625 (define_insn "*rep_movqi"
18626   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18627    (set (match_operand:SI 0 "register_operand" "=D")
18628         (plus:SI (match_operand:SI 3 "register_operand" "0")
18629                  (match_operand:SI 5 "register_operand" "2")))
18630    (set (match_operand:SI 1 "register_operand" "=S")
18631         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18632    (set (mem:BLK (match_dup 3))
18633         (mem:BLK (match_dup 4)))
18634    (use (match_dup 5))]
18635   "!TARGET_64BIT"
18636   "rep movsb"
18637   [(set_attr "type" "str")
18638    (set_attr "prefix_rep" "1")
18639    (set_attr "memory" "both")
18640    (set_attr "mode" "SI")])
18641
18642 (define_insn "*rep_movqi_rex64"
18643   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18644    (set (match_operand:DI 0 "register_operand" "=D")
18645         (plus:DI (match_operand:DI 3 "register_operand" "0")
18646                  (match_operand:DI 5 "register_operand" "2")))
18647    (set (match_operand:DI 1 "register_operand" "=S")
18648         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18649    (set (mem:BLK (match_dup 3))
18650         (mem:BLK (match_dup 4)))
18651    (use (match_dup 5))]
18652   "TARGET_64BIT"
18653   "rep movsb"
18654   [(set_attr "type" "str")
18655    (set_attr "prefix_rep" "1")
18656    (set_attr "memory" "both")
18657    (set_attr "mode" "SI")])
18658
18659 (define_expand "setmemsi"
18660    [(use (match_operand:BLK 0 "memory_operand" ""))
18661     (use (match_operand:SI 1 "nonmemory_operand" ""))
18662     (use (match_operand 2 "const_int_operand" ""))
18663     (use (match_operand 3 "const_int_operand" ""))
18664     (use (match_operand:SI 4 "const_int_operand" ""))
18665     (use (match_operand:SI 5 "const_int_operand" ""))]
18666   ""
18667 {
18668  if (ix86_expand_setmem (operands[0], operands[1],
18669                          operands[2], operands[3],
18670                          operands[4], operands[5]))
18671    DONE;
18672  else
18673    FAIL;
18674 })
18675
18676 (define_expand "setmemdi"
18677    [(use (match_operand:BLK 0 "memory_operand" ""))
18678     (use (match_operand:DI 1 "nonmemory_operand" ""))
18679     (use (match_operand 2 "const_int_operand" ""))
18680     (use (match_operand 3 "const_int_operand" ""))
18681     (use (match_operand 4 "const_int_operand" ""))
18682     (use (match_operand 5 "const_int_operand" ""))]
18683   "TARGET_64BIT"
18684 {
18685  if (ix86_expand_setmem (operands[0], operands[1],
18686                          operands[2], operands[3],
18687                          operands[4], operands[5]))
18688    DONE;
18689  else
18690    FAIL;
18691 })
18692
18693 ;; Most CPUs don't like single string operations
18694 ;; Handle this case here to simplify previous expander.
18695
18696 (define_expand "strset"
18697   [(set (match_operand 1 "memory_operand" "")
18698         (match_operand 2 "register_operand" ""))
18699    (parallel [(set (match_operand 0 "register_operand" "")
18700                    (match_dup 3))
18701               (clobber (reg:CC FLAGS_REG))])]
18702   ""
18703 {
18704   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18705     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18706
18707   /* If .md ever supports :P for Pmode, this can be directly
18708      in the pattern above.  */
18709   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18710                               GEN_INT (GET_MODE_SIZE (GET_MODE
18711                                                       (operands[2]))));
18712   if (TARGET_SINGLE_STRINGOP || optimize_size)
18713     {
18714       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18715                                       operands[3]));
18716       DONE;
18717     }
18718 })
18719
18720 (define_expand "strset_singleop"
18721   [(parallel [(set (match_operand 1 "memory_operand" "")
18722                    (match_operand 2 "register_operand" ""))
18723               (set (match_operand 0 "register_operand" "")
18724                    (match_operand 3 "" ""))])]
18725   "TARGET_SINGLE_STRINGOP || optimize_size"
18726   "")
18727
18728 (define_insn "*strsetdi_rex_1"
18729   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18730         (match_operand:DI 2 "register_operand" "a"))
18731    (set (match_operand:DI 0 "register_operand" "=D")
18732         (plus:DI (match_dup 1)
18733                  (const_int 8)))]
18734   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18735   "stosq"
18736   [(set_attr "type" "str")
18737    (set_attr "memory" "store")
18738    (set_attr "mode" "DI")])
18739
18740 (define_insn "*strsetsi_1"
18741   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18742         (match_operand:SI 2 "register_operand" "a"))
18743    (set (match_operand:SI 0 "register_operand" "=D")
18744         (plus:SI (match_dup 1)
18745                  (const_int 4)))]
18746   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18747   "stos{l|d}"
18748   [(set_attr "type" "str")
18749    (set_attr "memory" "store")
18750    (set_attr "mode" "SI")])
18751
18752 (define_insn "*strsetsi_rex_1"
18753   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18754         (match_operand:SI 2 "register_operand" "a"))
18755    (set (match_operand:DI 0 "register_operand" "=D")
18756         (plus:DI (match_dup 1)
18757                  (const_int 4)))]
18758   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18759   "stos{l|d}"
18760   [(set_attr "type" "str")
18761    (set_attr "memory" "store")
18762    (set_attr "mode" "SI")])
18763
18764 (define_insn "*strsethi_1"
18765   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18766         (match_operand:HI 2 "register_operand" "a"))
18767    (set (match_operand:SI 0 "register_operand" "=D")
18768         (plus:SI (match_dup 1)
18769                  (const_int 2)))]
18770   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18771   "stosw"
18772   [(set_attr "type" "str")
18773    (set_attr "memory" "store")
18774    (set_attr "mode" "HI")])
18775
18776 (define_insn "*strsethi_rex_1"
18777   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18778         (match_operand:HI 2 "register_operand" "a"))
18779    (set (match_operand:DI 0 "register_operand" "=D")
18780         (plus:DI (match_dup 1)
18781                  (const_int 2)))]
18782   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18783   "stosw"
18784   [(set_attr "type" "str")
18785    (set_attr "memory" "store")
18786    (set_attr "mode" "HI")])
18787
18788 (define_insn "*strsetqi_1"
18789   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18790         (match_operand:QI 2 "register_operand" "a"))
18791    (set (match_operand:SI 0 "register_operand" "=D")
18792         (plus:SI (match_dup 1)
18793                  (const_int 1)))]
18794   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18795   "stosb"
18796   [(set_attr "type" "str")
18797    (set_attr "memory" "store")
18798    (set_attr "mode" "QI")])
18799
18800 (define_insn "*strsetqi_rex_1"
18801   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18802         (match_operand:QI 2 "register_operand" "a"))
18803    (set (match_operand:DI 0 "register_operand" "=D")
18804         (plus:DI (match_dup 1)
18805                  (const_int 1)))]
18806   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18807   "stosb"
18808   [(set_attr "type" "str")
18809    (set_attr "memory" "store")
18810    (set_attr "mode" "QI")])
18811
18812 (define_expand "rep_stos"
18813   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18814               (set (match_operand 0 "register_operand" "")
18815                    (match_operand 4 "" ""))
18816               (set (match_operand 2 "memory_operand" "") (const_int 0))
18817               (use (match_operand 3 "register_operand" ""))
18818               (use (match_dup 1))])]
18819   ""
18820   "")
18821
18822 (define_insn "*rep_stosdi_rex64"
18823   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18824    (set (match_operand:DI 0 "register_operand" "=D")
18825         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18826                             (const_int 3))
18827                  (match_operand:DI 3 "register_operand" "0")))
18828    (set (mem:BLK (match_dup 3))
18829         (const_int 0))
18830    (use (match_operand:DI 2 "register_operand" "a"))
18831    (use (match_dup 4))]
18832   "TARGET_64BIT"
18833   "rep stosq"
18834   [(set_attr "type" "str")
18835    (set_attr "prefix_rep" "1")
18836    (set_attr "memory" "store")
18837    (set_attr "mode" "DI")])
18838
18839 (define_insn "*rep_stossi"
18840   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18841    (set (match_operand:SI 0 "register_operand" "=D")
18842         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18843                             (const_int 2))
18844                  (match_operand:SI 3 "register_operand" "0")))
18845    (set (mem:BLK (match_dup 3))
18846         (const_int 0))
18847    (use (match_operand:SI 2 "register_operand" "a"))
18848    (use (match_dup 4))]
18849   "!TARGET_64BIT"
18850   "rep stos{l|d}"
18851   [(set_attr "type" "str")
18852    (set_attr "prefix_rep" "1")
18853    (set_attr "memory" "store")
18854    (set_attr "mode" "SI")])
18855
18856 (define_insn "*rep_stossi_rex64"
18857   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18858    (set (match_operand:DI 0 "register_operand" "=D")
18859         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18860                             (const_int 2))
18861                  (match_operand:DI 3 "register_operand" "0")))
18862    (set (mem:BLK (match_dup 3))
18863         (const_int 0))
18864    (use (match_operand:SI 2 "register_operand" "a"))
18865    (use (match_dup 4))]
18866   "TARGET_64BIT"
18867   "rep stos{l|d}"
18868   [(set_attr "type" "str")
18869    (set_attr "prefix_rep" "1")
18870    (set_attr "memory" "store")
18871    (set_attr "mode" "SI")])
18872
18873 (define_insn "*rep_stosqi"
18874   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18875    (set (match_operand:SI 0 "register_operand" "=D")
18876         (plus:SI (match_operand:SI 3 "register_operand" "0")
18877                  (match_operand:SI 4 "register_operand" "1")))
18878    (set (mem:BLK (match_dup 3))
18879         (const_int 0))
18880    (use (match_operand:QI 2 "register_operand" "a"))
18881    (use (match_dup 4))]
18882   "!TARGET_64BIT"
18883   "rep stosb"
18884   [(set_attr "type" "str")
18885    (set_attr "prefix_rep" "1")
18886    (set_attr "memory" "store")
18887    (set_attr "mode" "QI")])
18888
18889 (define_insn "*rep_stosqi_rex64"
18890   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18891    (set (match_operand:DI 0 "register_operand" "=D")
18892         (plus:DI (match_operand:DI 3 "register_operand" "0")
18893                  (match_operand:DI 4 "register_operand" "1")))
18894    (set (mem:BLK (match_dup 3))
18895         (const_int 0))
18896    (use (match_operand:QI 2 "register_operand" "a"))
18897    (use (match_dup 4))]
18898   "TARGET_64BIT"
18899   "rep stosb"
18900   [(set_attr "type" "str")
18901    (set_attr "prefix_rep" "1")
18902    (set_attr "memory" "store")
18903    (set_attr "mode" "QI")])
18904
18905 (define_expand "cmpstrnsi"
18906   [(set (match_operand:SI 0 "register_operand" "")
18907         (compare:SI (match_operand:BLK 1 "general_operand" "")
18908                     (match_operand:BLK 2 "general_operand" "")))
18909    (use (match_operand 3 "general_operand" ""))
18910    (use (match_operand 4 "immediate_operand" ""))]
18911   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18912 {
18913   rtx addr1, addr2, out, outlow, count, countreg, align;
18914
18915   /* Can't use this if the user has appropriated esi or edi.  */
18916   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18917     FAIL;
18918
18919   out = operands[0];
18920   if (!REG_P (out))
18921     out = gen_reg_rtx (SImode);
18922
18923   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18924   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18925   if (addr1 != XEXP (operands[1], 0))
18926     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18927   if (addr2 != XEXP (operands[2], 0))
18928     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18929
18930   count = operands[3];
18931   countreg = ix86_zero_extend_to_Pmode (count);
18932
18933   /* %%% Iff we are testing strict equality, we can use known alignment
18934      to good advantage.  This may be possible with combine, particularly
18935      once cc0 is dead.  */
18936   align = operands[4];
18937
18938   if (CONST_INT_P (count))
18939     {
18940       if (INTVAL (count) == 0)
18941         {
18942           emit_move_insn (operands[0], const0_rtx);
18943           DONE;
18944         }
18945       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18946                                      operands[1], operands[2]));
18947     }
18948   else
18949     {
18950       if (TARGET_64BIT)
18951         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18952       else
18953         emit_insn (gen_cmpsi_1 (countreg, countreg));
18954       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18955                                   operands[1], operands[2]));
18956     }
18957
18958   outlow = gen_lowpart (QImode, out);
18959   emit_insn (gen_cmpintqi (outlow));
18960   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18961
18962   if (operands[0] != out)
18963     emit_move_insn (operands[0], out);
18964
18965   DONE;
18966 })
18967
18968 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18969
18970 (define_expand "cmpintqi"
18971   [(set (match_dup 1)
18972         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18973    (set (match_dup 2)
18974         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18975    (parallel [(set (match_operand:QI 0 "register_operand" "")
18976                    (minus:QI (match_dup 1)
18977                              (match_dup 2)))
18978               (clobber (reg:CC FLAGS_REG))])]
18979   ""
18980   "operands[1] = gen_reg_rtx (QImode);
18981    operands[2] = gen_reg_rtx (QImode);")
18982
18983 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18984 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18985
18986 (define_expand "cmpstrnqi_nz_1"
18987   [(parallel [(set (reg:CC FLAGS_REG)
18988                    (compare:CC (match_operand 4 "memory_operand" "")
18989                                (match_operand 5 "memory_operand" "")))
18990               (use (match_operand 2 "register_operand" ""))
18991               (use (match_operand:SI 3 "immediate_operand" ""))
18992               (clobber (match_operand 0 "register_operand" ""))
18993               (clobber (match_operand 1 "register_operand" ""))
18994               (clobber (match_dup 2))])]
18995   ""
18996   "")
18997
18998 (define_insn "*cmpstrnqi_nz_1"
18999   [(set (reg:CC FLAGS_REG)
19000         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19001                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19002    (use (match_operand:SI 6 "register_operand" "2"))
19003    (use (match_operand:SI 3 "immediate_operand" "i"))
19004    (clobber (match_operand:SI 0 "register_operand" "=S"))
19005    (clobber (match_operand:SI 1 "register_operand" "=D"))
19006    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19007   "!TARGET_64BIT"
19008   "repz cmpsb"
19009   [(set_attr "type" "str")
19010    (set_attr "mode" "QI")
19011    (set_attr "prefix_rep" "1")])
19012
19013 (define_insn "*cmpstrnqi_nz_rex_1"
19014   [(set (reg:CC FLAGS_REG)
19015         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19016                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19017    (use (match_operand:DI 6 "register_operand" "2"))
19018    (use (match_operand:SI 3 "immediate_operand" "i"))
19019    (clobber (match_operand:DI 0 "register_operand" "=S"))
19020    (clobber (match_operand:DI 1 "register_operand" "=D"))
19021    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19022   "TARGET_64BIT"
19023   "repz cmpsb"
19024   [(set_attr "type" "str")
19025    (set_attr "mode" "QI")
19026    (set_attr "prefix_rep" "1")])
19027
19028 ;; The same, but the count is not known to not be zero.
19029
19030 (define_expand "cmpstrnqi_1"
19031   [(parallel [(set (reg:CC FLAGS_REG)
19032                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19033                                      (const_int 0))
19034                   (compare:CC (match_operand 4 "memory_operand" "")
19035                               (match_operand 5 "memory_operand" ""))
19036                   (const_int 0)))
19037               (use (match_operand:SI 3 "immediate_operand" ""))
19038               (use (reg:CC FLAGS_REG))
19039               (clobber (match_operand 0 "register_operand" ""))
19040               (clobber (match_operand 1 "register_operand" ""))
19041               (clobber (match_dup 2))])]
19042   ""
19043   "")
19044
19045 (define_insn "*cmpstrnqi_1"
19046   [(set (reg:CC FLAGS_REG)
19047         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19048                              (const_int 0))
19049           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19050                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19051           (const_int 0)))
19052    (use (match_operand:SI 3 "immediate_operand" "i"))
19053    (use (reg:CC FLAGS_REG))
19054    (clobber (match_operand:SI 0 "register_operand" "=S"))
19055    (clobber (match_operand:SI 1 "register_operand" "=D"))
19056    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19057   "!TARGET_64BIT"
19058   "repz cmpsb"
19059   [(set_attr "type" "str")
19060    (set_attr "mode" "QI")
19061    (set_attr "prefix_rep" "1")])
19062
19063 (define_insn "*cmpstrnqi_rex_1"
19064   [(set (reg:CC FLAGS_REG)
19065         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19066                              (const_int 0))
19067           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19068                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19069           (const_int 0)))
19070    (use (match_operand:SI 3 "immediate_operand" "i"))
19071    (use (reg:CC FLAGS_REG))
19072    (clobber (match_operand:DI 0 "register_operand" "=S"))
19073    (clobber (match_operand:DI 1 "register_operand" "=D"))
19074    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19075   "TARGET_64BIT"
19076   "repz cmpsb"
19077   [(set_attr "type" "str")
19078    (set_attr "mode" "QI")
19079    (set_attr "prefix_rep" "1")])
19080
19081 (define_expand "strlensi"
19082   [(set (match_operand:SI 0 "register_operand" "")
19083         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19084                     (match_operand:QI 2 "immediate_operand" "")
19085                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19086   ""
19087 {
19088  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19089    DONE;
19090  else
19091    FAIL;
19092 })
19093
19094 (define_expand "strlendi"
19095   [(set (match_operand:DI 0 "register_operand" "")
19096         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19097                     (match_operand:QI 2 "immediate_operand" "")
19098                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19099   ""
19100 {
19101  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19102    DONE;
19103  else
19104    FAIL;
19105 })
19106
19107 (define_expand "strlenqi_1"
19108   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19109               (clobber (match_operand 1 "register_operand" ""))
19110               (clobber (reg:CC FLAGS_REG))])]
19111   ""
19112   "")
19113
19114 (define_insn "*strlenqi_1"
19115   [(set (match_operand:SI 0 "register_operand" "=&c")
19116         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19117                     (match_operand:QI 2 "register_operand" "a")
19118                     (match_operand:SI 3 "immediate_operand" "i")
19119                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19120    (clobber (match_operand:SI 1 "register_operand" "=D"))
19121    (clobber (reg:CC FLAGS_REG))]
19122   "!TARGET_64BIT"
19123   "repnz scasb"
19124   [(set_attr "type" "str")
19125    (set_attr "mode" "QI")
19126    (set_attr "prefix_rep" "1")])
19127
19128 (define_insn "*strlenqi_rex_1"
19129   [(set (match_operand:DI 0 "register_operand" "=&c")
19130         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19131                     (match_operand:QI 2 "register_operand" "a")
19132                     (match_operand:DI 3 "immediate_operand" "i")
19133                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19134    (clobber (match_operand:DI 1 "register_operand" "=D"))
19135    (clobber (reg:CC FLAGS_REG))]
19136   "TARGET_64BIT"
19137   "repnz scasb"
19138   [(set_attr "type" "str")
19139    (set_attr "mode" "QI")
19140    (set_attr "prefix_rep" "1")])
19141
19142 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19143 ;; handled in combine, but it is not currently up to the task.
19144 ;; When used for their truth value, the cmpstrn* expanders generate
19145 ;; code like this:
19146 ;;
19147 ;;   repz cmpsb
19148 ;;   seta       %al
19149 ;;   setb       %dl
19150 ;;   cmpb       %al, %dl
19151 ;;   jcc        label
19152 ;;
19153 ;; The intermediate three instructions are unnecessary.
19154
19155 ;; This one handles cmpstrn*_nz_1...
19156 (define_peephole2
19157   [(parallel[
19158      (set (reg:CC FLAGS_REG)
19159           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19160                       (mem:BLK (match_operand 5 "register_operand" ""))))
19161      (use (match_operand 6 "register_operand" ""))
19162      (use (match_operand:SI 3 "immediate_operand" ""))
19163      (clobber (match_operand 0 "register_operand" ""))
19164      (clobber (match_operand 1 "register_operand" ""))
19165      (clobber (match_operand 2 "register_operand" ""))])
19166    (set (match_operand:QI 7 "register_operand" "")
19167         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19168    (set (match_operand:QI 8 "register_operand" "")
19169         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19170    (set (reg FLAGS_REG)
19171         (compare (match_dup 7) (match_dup 8)))
19172   ]
19173   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19174   [(parallel[
19175      (set (reg:CC FLAGS_REG)
19176           (compare:CC (mem:BLK (match_dup 4))
19177                       (mem:BLK (match_dup 5))))
19178      (use (match_dup 6))
19179      (use (match_dup 3))
19180      (clobber (match_dup 0))
19181      (clobber (match_dup 1))
19182      (clobber (match_dup 2))])]
19183   "")
19184
19185 ;; ...and this one handles cmpstrn*_1.
19186 (define_peephole2
19187   [(parallel[
19188      (set (reg:CC FLAGS_REG)
19189           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19190                                (const_int 0))
19191             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19192                         (mem:BLK (match_operand 5 "register_operand" "")))
19193             (const_int 0)))
19194      (use (match_operand:SI 3 "immediate_operand" ""))
19195      (use (reg:CC FLAGS_REG))
19196      (clobber (match_operand 0 "register_operand" ""))
19197      (clobber (match_operand 1 "register_operand" ""))
19198      (clobber (match_operand 2 "register_operand" ""))])
19199    (set (match_operand:QI 7 "register_operand" "")
19200         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19201    (set (match_operand:QI 8 "register_operand" "")
19202         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19203    (set (reg FLAGS_REG)
19204         (compare (match_dup 7) (match_dup 8)))
19205   ]
19206   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19207   [(parallel[
19208      (set (reg:CC FLAGS_REG)
19209           (if_then_else:CC (ne (match_dup 6)
19210                                (const_int 0))
19211             (compare:CC (mem:BLK (match_dup 4))
19212                         (mem:BLK (match_dup 5)))
19213             (const_int 0)))
19214      (use (match_dup 3))
19215      (use (reg:CC FLAGS_REG))
19216      (clobber (match_dup 0))
19217      (clobber (match_dup 1))
19218      (clobber (match_dup 2))])]
19219   "")
19220
19221
19222 \f
19223 ;; Conditional move instructions.
19224
19225 (define_expand "movdicc"
19226   [(set (match_operand:DI 0 "register_operand" "")
19227         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19228                          (match_operand:DI 2 "general_operand" "")
19229                          (match_operand:DI 3 "general_operand" "")))]
19230   "TARGET_64BIT"
19231   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19232
19233 (define_insn "x86_movdicc_0_m1_rex64"
19234   [(set (match_operand:DI 0 "register_operand" "=r")
19235         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19236           (const_int -1)
19237           (const_int 0)))
19238    (clobber (reg:CC FLAGS_REG))]
19239   "TARGET_64BIT"
19240   "sbb{q}\t%0, %0"
19241   ; Since we don't have the proper number of operands for an alu insn,
19242   ; fill in all the blanks.
19243   [(set_attr "type" "alu")
19244    (set_attr "pent_pair" "pu")
19245    (set_attr "memory" "none")
19246    (set_attr "imm_disp" "false")
19247    (set_attr "mode" "DI")
19248    (set_attr "length_immediate" "0")])
19249
19250 (define_insn "*x86_movdicc_0_m1_se"
19251   [(set (match_operand:DI 0 "register_operand" "=r")
19252         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19253                          (const_int 1)
19254                          (const_int 0)))
19255    (clobber (reg:CC FLAGS_REG))]
19256   ""
19257   "sbb{q}\t%0, %0"
19258   [(set_attr "type" "alu")
19259    (set_attr "pent_pair" "pu")
19260    (set_attr "memory" "none")
19261    (set_attr "imm_disp" "false")
19262    (set_attr "mode" "DI")
19263    (set_attr "length_immediate" "0")])
19264
19265 (define_insn "*movdicc_c_rex64"
19266   [(set (match_operand:DI 0 "register_operand" "=r,r")
19267         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19268                                 [(reg FLAGS_REG) (const_int 0)])
19269                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19270                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19271   "TARGET_64BIT && TARGET_CMOVE
19272    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19273   "@
19274    cmov%O2%C1\t{%2, %0|%0, %2}
19275    cmov%O2%c1\t{%3, %0|%0, %3}"
19276   [(set_attr "type" "icmov")
19277    (set_attr "mode" "DI")])
19278
19279 (define_expand "movsicc"
19280   [(set (match_operand:SI 0 "register_operand" "")
19281         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19282                          (match_operand:SI 2 "general_operand" "")
19283                          (match_operand:SI 3 "general_operand" "")))]
19284   ""
19285   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19286
19287 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19288 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19289 ;; So just document what we're doing explicitly.
19290
19291 (define_insn "x86_movsicc_0_m1"
19292   [(set (match_operand:SI 0 "register_operand" "=r")
19293         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19294           (const_int -1)
19295           (const_int 0)))
19296    (clobber (reg:CC FLAGS_REG))]
19297   ""
19298   "sbb{l}\t%0, %0"
19299   ; Since we don't have the proper number of operands for an alu insn,
19300   ; fill in all the blanks.
19301   [(set_attr "type" "alu")
19302    (set_attr "pent_pair" "pu")
19303    (set_attr "memory" "none")
19304    (set_attr "imm_disp" "false")
19305    (set_attr "mode" "SI")
19306    (set_attr "length_immediate" "0")])
19307
19308 (define_insn "*x86_movsicc_0_m1_se"
19309   [(set (match_operand:SI 0 "register_operand" "=r")
19310         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19311                          (const_int 1)
19312                          (const_int 0)))
19313    (clobber (reg:CC FLAGS_REG))]
19314   ""
19315   "sbb{l}\t%0, %0"
19316   [(set_attr "type" "alu")
19317    (set_attr "pent_pair" "pu")
19318    (set_attr "memory" "none")
19319    (set_attr "imm_disp" "false")
19320    (set_attr "mode" "SI")
19321    (set_attr "length_immediate" "0")])
19322
19323 (define_insn "*movsicc_noc"
19324   [(set (match_operand:SI 0 "register_operand" "=r,r")
19325         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19326                                 [(reg FLAGS_REG) (const_int 0)])
19327                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19328                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19329   "TARGET_CMOVE
19330    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19331   "@
19332    cmov%O2%C1\t{%2, %0|%0, %2}
19333    cmov%O2%c1\t{%3, %0|%0, %3}"
19334   [(set_attr "type" "icmov")
19335    (set_attr "mode" "SI")])
19336
19337 (define_expand "movhicc"
19338   [(set (match_operand:HI 0 "register_operand" "")
19339         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19340                          (match_operand:HI 2 "general_operand" "")
19341                          (match_operand:HI 3 "general_operand" "")))]
19342   "TARGET_HIMODE_MATH"
19343   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19344
19345 (define_insn "*movhicc_noc"
19346   [(set (match_operand:HI 0 "register_operand" "=r,r")
19347         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19348                                 [(reg FLAGS_REG) (const_int 0)])
19349                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19350                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19351   "TARGET_CMOVE
19352    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19353   "@
19354    cmov%O2%C1\t{%2, %0|%0, %2}
19355    cmov%O2%c1\t{%3, %0|%0, %3}"
19356   [(set_attr "type" "icmov")
19357    (set_attr "mode" "HI")])
19358
19359 (define_expand "movqicc"
19360   [(set (match_operand:QI 0 "register_operand" "")
19361         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19362                          (match_operand:QI 2 "general_operand" "")
19363                          (match_operand:QI 3 "general_operand" "")))]
19364   "TARGET_QIMODE_MATH"
19365   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19366
19367 (define_insn_and_split "*movqicc_noc"
19368   [(set (match_operand:QI 0 "register_operand" "=r,r")
19369         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19370                                 [(match_operand 4 "flags_reg_operand" "")
19371                                  (const_int 0)])
19372                       (match_operand:QI 2 "register_operand" "r,0")
19373                       (match_operand:QI 3 "register_operand" "0,r")))]
19374   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19375   "#"
19376   "&& reload_completed"
19377   [(set (match_dup 0)
19378         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19379                       (match_dup 2)
19380                       (match_dup 3)))]
19381   "operands[0] = gen_lowpart (SImode, operands[0]);
19382    operands[2] = gen_lowpart (SImode, operands[2]);
19383    operands[3] = gen_lowpart (SImode, operands[3]);"
19384   [(set_attr "type" "icmov")
19385    (set_attr "mode" "SI")])
19386
19387 (define_expand "mov<mode>cc"
19388   [(set (match_operand:X87MODEF 0 "register_operand" "")
19389         (if_then_else:X87MODEF
19390           (match_operand 1 "comparison_operator" "")
19391           (match_operand:X87MODEF 2 "register_operand" "")
19392           (match_operand:X87MODEF 3 "register_operand" "")))]
19393   "(TARGET_80387 && TARGET_CMOVE)
19394    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19395   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19396
19397 (define_insn "*movsfcc_1_387"
19398   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19399         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19400                                 [(reg FLAGS_REG) (const_int 0)])
19401                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19402                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19403   "TARGET_80387 && TARGET_CMOVE
19404    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19405   "@
19406    fcmov%F1\t{%2, %0|%0, %2}
19407    fcmov%f1\t{%3, %0|%0, %3}
19408    cmov%O2%C1\t{%2, %0|%0, %2}
19409    cmov%O2%c1\t{%3, %0|%0, %3}"
19410   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19411    (set_attr "mode" "SF,SF,SI,SI")])
19412
19413 (define_insn "*movdfcc_1"
19414   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19415         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19416                                 [(reg FLAGS_REG) (const_int 0)])
19417                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19418                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19419   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19420    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19421   "@
19422    fcmov%F1\t{%2, %0|%0, %2}
19423    fcmov%f1\t{%3, %0|%0, %3}
19424    #
19425    #"
19426   [(set_attr "type" "fcmov,fcmov,multi,multi")
19427    (set_attr "mode" "DF")])
19428
19429 (define_insn "*movdfcc_1_rex64"
19430   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19431         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19432                                 [(reg FLAGS_REG) (const_int 0)])
19433                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19434                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19435   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19436    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19437   "@
19438    fcmov%F1\t{%2, %0|%0, %2}
19439    fcmov%f1\t{%3, %0|%0, %3}
19440    cmov%O2%C1\t{%2, %0|%0, %2}
19441    cmov%O2%c1\t{%3, %0|%0, %3}"
19442   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19443    (set_attr "mode" "DF")])
19444
19445 (define_split
19446   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19447         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19448                                 [(match_operand 4 "flags_reg_operand" "")
19449                                  (const_int 0)])
19450                       (match_operand:DF 2 "nonimmediate_operand" "")
19451                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19452   "!TARGET_64BIT && reload_completed"
19453   [(set (match_dup 2)
19454         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19455                       (match_dup 5)
19456                       (match_dup 6)))
19457    (set (match_dup 3)
19458         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19459                       (match_dup 7)
19460                       (match_dup 8)))]
19461   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19462    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19463
19464 (define_insn "*movxfcc_1"
19465   [(set (match_operand:XF 0 "register_operand" "=f,f")
19466         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19467                                 [(reg FLAGS_REG) (const_int 0)])
19468                       (match_operand:XF 2 "register_operand" "f,0")
19469                       (match_operand:XF 3 "register_operand" "0,f")))]
19470   "TARGET_80387 && TARGET_CMOVE"
19471   "@
19472    fcmov%F1\t{%2, %0|%0, %2}
19473    fcmov%f1\t{%3, %0|%0, %3}"
19474   [(set_attr "type" "fcmov")
19475    (set_attr "mode" "XF")])
19476
19477 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19478 ;; the scalar versions to have only XMM registers as operands.
19479
19480 ;; SSE5 conditional move
19481 (define_insn "*sse5_pcmov_<mode>"
19482   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19483         (if_then_else:MODEF
19484           (match_operand:MODEF 1 "register_operand" "x,0")
19485           (match_operand:MODEF 2 "register_operand" "0,x")
19486           (match_operand:MODEF 3 "register_operand" "x,x")))]
19487   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19488   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19489   [(set_attr "type" "sse4arg")])
19490
19491 ;; These versions of the min/max patterns are intentionally ignorant of
19492 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19493 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19494 ;; are undefined in this condition, we're certain this is correct.
19495
19496 (define_insn "<code><mode>3"
19497   [(set (match_operand:MODEF 0 "register_operand" "=x")
19498         (smaxmin:MODEF
19499           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19500           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19501   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19502   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19503   [(set_attr "type" "sseadd")
19504    (set_attr "mode" "<MODE>")])
19505
19506 ;; These versions of the min/max patterns implement exactly the operations
19507 ;;   min = (op1 < op2 ? op1 : op2)
19508 ;;   max = (!(op1 < op2) ? op1 : op2)
19509 ;; Their operands are not commutative, and thus they may be used in the
19510 ;; presence of -0.0 and NaN.
19511
19512 (define_insn "*ieee_smin<mode>3"
19513   [(set (match_operand:MODEF 0 "register_operand" "=x")
19514         (unspec:MODEF
19515           [(match_operand:MODEF 1 "register_operand" "0")
19516            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19517          UNSPEC_IEEE_MIN))]
19518   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19519   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19520   [(set_attr "type" "sseadd")
19521    (set_attr "mode" "<MODE>")])
19522
19523 (define_insn "*ieee_smax<mode>3"
19524   [(set (match_operand:MODEF 0 "register_operand" "=x")
19525         (unspec:MODEF
19526           [(match_operand:MODEF 1 "register_operand" "0")
19527            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19528          UNSPEC_IEEE_MAX))]
19529   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19530   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19531   [(set_attr "type" "sseadd")
19532    (set_attr "mode" "<MODE>")])
19533
19534 ;; Make two stack loads independent:
19535 ;;   fld aa              fld aa
19536 ;;   fld %st(0)     ->   fld bb
19537 ;;   fmul bb             fmul %st(1), %st
19538 ;;
19539 ;; Actually we only match the last two instructions for simplicity.
19540 (define_peephole2
19541   [(set (match_operand 0 "fp_register_operand" "")
19542         (match_operand 1 "fp_register_operand" ""))
19543    (set (match_dup 0)
19544         (match_operator 2 "binary_fp_operator"
19545            [(match_dup 0)
19546             (match_operand 3 "memory_operand" "")]))]
19547   "REGNO (operands[0]) != REGNO (operands[1])"
19548   [(set (match_dup 0) (match_dup 3))
19549    (set (match_dup 0) (match_dup 4))]
19550
19551   ;; The % modifier is not operational anymore in peephole2's, so we have to
19552   ;; swap the operands manually in the case of addition and multiplication.
19553   "if (COMMUTATIVE_ARITH_P (operands[2]))
19554      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19555                                  operands[0], operands[1]);
19556    else
19557      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19558                                  operands[1], operands[0]);")
19559
19560 ;; Conditional addition patterns
19561 (define_expand "add<mode>cc"
19562   [(match_operand:SWI 0 "register_operand" "")
19563    (match_operand 1 "comparison_operator" "")
19564    (match_operand:SWI 2 "register_operand" "")
19565    (match_operand:SWI 3 "const_int_operand" "")]
19566   ""
19567   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19568
19569 \f
19570 ;; Misc patterns (?)
19571
19572 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19573 ;; Otherwise there will be nothing to keep
19574 ;;
19575 ;; [(set (reg ebp) (reg esp))]
19576 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19577 ;;  (clobber (eflags)]
19578 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19579 ;;
19580 ;; in proper program order.
19581 (define_insn "pro_epilogue_adjust_stack_1"
19582   [(set (match_operand:SI 0 "register_operand" "=r,r")
19583         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19584                  (match_operand:SI 2 "immediate_operand" "i,i")))
19585    (clobber (reg:CC FLAGS_REG))
19586    (clobber (mem:BLK (scratch)))]
19587   "!TARGET_64BIT"
19588 {
19589   switch (get_attr_type (insn))
19590     {
19591     case TYPE_IMOV:
19592       return "mov{l}\t{%1, %0|%0, %1}";
19593
19594     case TYPE_ALU:
19595       if (CONST_INT_P (operands[2])
19596           && (INTVAL (operands[2]) == 128
19597               || (INTVAL (operands[2]) < 0
19598                   && INTVAL (operands[2]) != -128)))
19599         {
19600           operands[2] = GEN_INT (-INTVAL (operands[2]));
19601           return "sub{l}\t{%2, %0|%0, %2}";
19602         }
19603       return "add{l}\t{%2, %0|%0, %2}";
19604
19605     case TYPE_LEA:
19606       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19607       return "lea{l}\t{%a2, %0|%0, %a2}";
19608
19609     default:
19610       gcc_unreachable ();
19611     }
19612 }
19613   [(set (attr "type")
19614         (cond [(eq_attr "alternative" "0")
19615                  (const_string "alu")
19616                (match_operand:SI 2 "const0_operand" "")
19617                  (const_string "imov")
19618               ]
19619               (const_string "lea")))
19620    (set_attr "mode" "SI")])
19621
19622 (define_insn "pro_epilogue_adjust_stack_rex64"
19623   [(set (match_operand:DI 0 "register_operand" "=r,r")
19624         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19625                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19626    (clobber (reg:CC FLAGS_REG))
19627    (clobber (mem:BLK (scratch)))]
19628   "TARGET_64BIT"
19629 {
19630   switch (get_attr_type (insn))
19631     {
19632     case TYPE_IMOV:
19633       return "mov{q}\t{%1, %0|%0, %1}";
19634
19635     case TYPE_ALU:
19636       if (CONST_INT_P (operands[2])
19637           /* Avoid overflows.  */
19638           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19639           && (INTVAL (operands[2]) == 128
19640               || (INTVAL (operands[2]) < 0
19641                   && INTVAL (operands[2]) != -128)))
19642         {
19643           operands[2] = GEN_INT (-INTVAL (operands[2]));
19644           return "sub{q}\t{%2, %0|%0, %2}";
19645         }
19646       return "add{q}\t{%2, %0|%0, %2}";
19647
19648     case TYPE_LEA:
19649       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19650       return "lea{q}\t{%a2, %0|%0, %a2}";
19651
19652     default:
19653       gcc_unreachable ();
19654     }
19655 }
19656   [(set (attr "type")
19657         (cond [(eq_attr "alternative" "0")
19658                  (const_string "alu")
19659                (match_operand:DI 2 "const0_operand" "")
19660                  (const_string "imov")
19661               ]
19662               (const_string "lea")))
19663    (set_attr "mode" "DI")])
19664
19665 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19666   [(set (match_operand:DI 0 "register_operand" "=r,r")
19667         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19668                  (match_operand:DI 3 "immediate_operand" "i,i")))
19669    (use (match_operand:DI 2 "register_operand" "r,r"))
19670    (clobber (reg:CC FLAGS_REG))
19671    (clobber (mem:BLK (scratch)))]
19672   "TARGET_64BIT"
19673 {
19674   switch (get_attr_type (insn))
19675     {
19676     case TYPE_ALU:
19677       return "add{q}\t{%2, %0|%0, %2}";
19678
19679     case TYPE_LEA:
19680       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19681       return "lea{q}\t{%a2, %0|%0, %a2}";
19682
19683     default:
19684       gcc_unreachable ();
19685     }
19686 }
19687   [(set_attr "type" "alu,lea")
19688    (set_attr "mode" "DI")])
19689
19690 (define_insn "allocate_stack_worker_32"
19691   [(set (match_operand:SI 0 "register_operand" "+a")
19692         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19693    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19694    (clobber (reg:CC FLAGS_REG))]
19695   "!TARGET_64BIT && TARGET_STACK_PROBE"
19696   "call\t___chkstk"
19697   [(set_attr "type" "multi")
19698    (set_attr "length" "5")])
19699
19700 (define_insn "allocate_stack_worker_64"
19701   [(set (match_operand:DI 0 "register_operand" "=a")
19702         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19703    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19704    (clobber (reg:DI R10_REG))
19705    (clobber (reg:DI R11_REG))
19706    (clobber (reg:CC FLAGS_REG))]
19707   "TARGET_64BIT && TARGET_STACK_PROBE"
19708   "call\t___chkstk"
19709   [(set_attr "type" "multi")
19710    (set_attr "length" "5")])
19711
19712 (define_expand "allocate_stack"
19713   [(match_operand 0 "register_operand" "")
19714    (match_operand 1 "general_operand" "")]
19715   "TARGET_STACK_PROBE"
19716 {
19717   rtx x;
19718
19719 #ifndef CHECK_STACK_LIMIT
19720 #define CHECK_STACK_LIMIT 0
19721 #endif
19722
19723   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19724       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19725     {
19726       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19727                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19728       if (x != stack_pointer_rtx)
19729         emit_move_insn (stack_pointer_rtx, x);
19730     }
19731   else
19732     {
19733       x = copy_to_mode_reg (Pmode, operands[1]);
19734       if (TARGET_64BIT)
19735         x = gen_allocate_stack_worker_64 (x);
19736       else
19737         x = gen_allocate_stack_worker_32 (x);
19738       emit_insn (x);
19739     }
19740
19741   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19742   DONE;
19743 })
19744
19745 (define_expand "builtin_setjmp_receiver"
19746   [(label_ref (match_operand 0 "" ""))]
19747   "!TARGET_64BIT && flag_pic"
19748 {
19749   if (TARGET_MACHO)
19750     {
19751       rtx xops[3];
19752       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19753       rtx label_rtx = gen_label_rtx ();
19754       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19755       xops[0] = xops[1] = picreg;
19756       xops[2] = gen_rtx_CONST (SImode,
19757                   gen_rtx_MINUS (SImode,
19758                     gen_rtx_LABEL_REF (SImode, label_rtx),
19759                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19760       ix86_expand_binary_operator (MINUS, SImode, xops);
19761     }
19762   else
19763     emit_insn (gen_set_got (pic_offset_table_rtx));
19764   DONE;
19765 })
19766 \f
19767 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19768
19769 (define_split
19770   [(set (match_operand 0 "register_operand" "")
19771         (match_operator 3 "promotable_binary_operator"
19772            [(match_operand 1 "register_operand" "")
19773             (match_operand 2 "aligned_operand" "")]))
19774    (clobber (reg:CC FLAGS_REG))]
19775   "! TARGET_PARTIAL_REG_STALL && reload_completed
19776    && ((GET_MODE (operands[0]) == HImode
19777         && ((!optimize_size && !TARGET_FAST_PREFIX)
19778             /* ??? next two lines just !satisfies_constraint_K (...) */
19779             || !CONST_INT_P (operands[2])
19780             || satisfies_constraint_K (operands[2])))
19781        || (GET_MODE (operands[0]) == QImode
19782            && (TARGET_PROMOTE_QImode || optimize_size)))"
19783   [(parallel [(set (match_dup 0)
19784                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19785               (clobber (reg:CC FLAGS_REG))])]
19786   "operands[0] = gen_lowpart (SImode, operands[0]);
19787    operands[1] = gen_lowpart (SImode, operands[1]);
19788    if (GET_CODE (operands[3]) != ASHIFT)
19789      operands[2] = gen_lowpart (SImode, operands[2]);
19790    PUT_MODE (operands[3], SImode);")
19791
19792 ; Promote the QImode tests, as i386 has encoding of the AND
19793 ; instruction with 32-bit sign-extended immediate and thus the
19794 ; instruction size is unchanged, except in the %eax case for
19795 ; which it is increased by one byte, hence the ! optimize_size.
19796 (define_split
19797   [(set (match_operand 0 "flags_reg_operand" "")
19798         (match_operator 2 "compare_operator"
19799           [(and (match_operand 3 "aligned_operand" "")
19800                 (match_operand 4 "const_int_operand" ""))
19801            (const_int 0)]))
19802    (set (match_operand 1 "register_operand" "")
19803         (and (match_dup 3) (match_dup 4)))]
19804   "! TARGET_PARTIAL_REG_STALL && reload_completed
19805    && ! optimize_size
19806    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19807        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19808    /* Ensure that the operand will remain sign-extended immediate.  */
19809    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19810   [(parallel [(set (match_dup 0)
19811                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19812                                     (const_int 0)]))
19813               (set (match_dup 1)
19814                    (and:SI (match_dup 3) (match_dup 4)))])]
19815 {
19816   operands[4]
19817     = gen_int_mode (INTVAL (operands[4])
19818                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19819   operands[1] = gen_lowpart (SImode, operands[1]);
19820   operands[3] = gen_lowpart (SImode, operands[3]);
19821 })
19822
19823 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19824 ; the TEST instruction with 32-bit sign-extended immediate and thus
19825 ; the instruction size would at least double, which is not what we
19826 ; want even with ! optimize_size.
19827 (define_split
19828   [(set (match_operand 0 "flags_reg_operand" "")
19829         (match_operator 1 "compare_operator"
19830           [(and (match_operand:HI 2 "aligned_operand" "")
19831                 (match_operand:HI 3 "const_int_operand" ""))
19832            (const_int 0)]))]
19833   "! TARGET_PARTIAL_REG_STALL && reload_completed
19834    && ! TARGET_FAST_PREFIX
19835    && ! optimize_size
19836    /* Ensure that the operand will remain sign-extended immediate.  */
19837    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19838   [(set (match_dup 0)
19839         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19840                          (const_int 0)]))]
19841 {
19842   operands[3]
19843     = gen_int_mode (INTVAL (operands[3])
19844                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19845   operands[2] = gen_lowpart (SImode, operands[2]);
19846 })
19847
19848 (define_split
19849   [(set (match_operand 0 "register_operand" "")
19850         (neg (match_operand 1 "register_operand" "")))
19851    (clobber (reg:CC FLAGS_REG))]
19852   "! TARGET_PARTIAL_REG_STALL && reload_completed
19853    && (GET_MODE (operands[0]) == HImode
19854        || (GET_MODE (operands[0]) == QImode
19855            && (TARGET_PROMOTE_QImode || optimize_size)))"
19856   [(parallel [(set (match_dup 0)
19857                    (neg:SI (match_dup 1)))
19858               (clobber (reg:CC FLAGS_REG))])]
19859   "operands[0] = gen_lowpart (SImode, operands[0]);
19860    operands[1] = gen_lowpart (SImode, operands[1]);")
19861
19862 (define_split
19863   [(set (match_operand 0 "register_operand" "")
19864         (not (match_operand 1 "register_operand" "")))]
19865   "! TARGET_PARTIAL_REG_STALL && reload_completed
19866    && (GET_MODE (operands[0]) == HImode
19867        || (GET_MODE (operands[0]) == QImode
19868            && (TARGET_PROMOTE_QImode || optimize_size)))"
19869   [(set (match_dup 0)
19870         (not:SI (match_dup 1)))]
19871   "operands[0] = gen_lowpart (SImode, operands[0]);
19872    operands[1] = gen_lowpart (SImode, operands[1]);")
19873
19874 (define_split
19875   [(set (match_operand 0 "register_operand" "")
19876         (if_then_else (match_operator 1 "comparison_operator"
19877                                 [(reg FLAGS_REG) (const_int 0)])
19878                       (match_operand 2 "register_operand" "")
19879                       (match_operand 3 "register_operand" "")))]
19880   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19881    && (GET_MODE (operands[0]) == HImode
19882        || (GET_MODE (operands[0]) == QImode
19883            && (TARGET_PROMOTE_QImode || optimize_size)))"
19884   [(set (match_dup 0)
19885         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19886   "operands[0] = gen_lowpart (SImode, operands[0]);
19887    operands[2] = gen_lowpart (SImode, operands[2]);
19888    operands[3] = gen_lowpart (SImode, operands[3]);")
19889
19890 \f
19891 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19892 ;; transform a complex memory operation into two memory to register operations.
19893
19894 ;; Don't push memory operands
19895 (define_peephole2
19896   [(set (match_operand:SI 0 "push_operand" "")
19897         (match_operand:SI 1 "memory_operand" ""))
19898    (match_scratch:SI 2 "r")]
19899   "!optimize_size && !TARGET_PUSH_MEMORY
19900    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19901   [(set (match_dup 2) (match_dup 1))
19902    (set (match_dup 0) (match_dup 2))]
19903   "")
19904
19905 (define_peephole2
19906   [(set (match_operand:DI 0 "push_operand" "")
19907         (match_operand:DI 1 "memory_operand" ""))
19908    (match_scratch:DI 2 "r")]
19909   "!optimize_size && !TARGET_PUSH_MEMORY
19910    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19911   [(set (match_dup 2) (match_dup 1))
19912    (set (match_dup 0) (match_dup 2))]
19913   "")
19914
19915 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19916 ;; SImode pushes.
19917 (define_peephole2
19918   [(set (match_operand:SF 0 "push_operand" "")
19919         (match_operand:SF 1 "memory_operand" ""))
19920    (match_scratch:SF 2 "r")]
19921   "!optimize_size && !TARGET_PUSH_MEMORY
19922    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19923   [(set (match_dup 2) (match_dup 1))
19924    (set (match_dup 0) (match_dup 2))]
19925   "")
19926
19927 (define_peephole2
19928   [(set (match_operand:HI 0 "push_operand" "")
19929         (match_operand:HI 1 "memory_operand" ""))
19930    (match_scratch:HI 2 "r")]
19931   "!optimize_size && !TARGET_PUSH_MEMORY
19932    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19933   [(set (match_dup 2) (match_dup 1))
19934    (set (match_dup 0) (match_dup 2))]
19935   "")
19936
19937 (define_peephole2
19938   [(set (match_operand:QI 0 "push_operand" "")
19939         (match_operand:QI 1 "memory_operand" ""))
19940    (match_scratch:QI 2 "q")]
19941   "!optimize_size && !TARGET_PUSH_MEMORY
19942    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19943   [(set (match_dup 2) (match_dup 1))
19944    (set (match_dup 0) (match_dup 2))]
19945   "")
19946
19947 ;; Don't move an immediate directly to memory when the instruction
19948 ;; gets too big.
19949 (define_peephole2
19950   [(match_scratch:SI 1 "r")
19951    (set (match_operand:SI 0 "memory_operand" "")
19952         (const_int 0))]
19953   "! optimize_size
19954    && ! TARGET_USE_MOV0
19955    && TARGET_SPLIT_LONG_MOVES
19956    && get_attr_length (insn) >= ix86_cost->large_insn
19957    && peep2_regno_dead_p (0, FLAGS_REG)"
19958   [(parallel [(set (match_dup 1) (const_int 0))
19959               (clobber (reg:CC FLAGS_REG))])
19960    (set (match_dup 0) (match_dup 1))]
19961   "")
19962
19963 (define_peephole2
19964   [(match_scratch:HI 1 "r")
19965    (set (match_operand:HI 0 "memory_operand" "")
19966         (const_int 0))]
19967   "! optimize_size
19968    && ! TARGET_USE_MOV0
19969    && TARGET_SPLIT_LONG_MOVES
19970    && get_attr_length (insn) >= ix86_cost->large_insn
19971    && peep2_regno_dead_p (0, FLAGS_REG)"
19972   [(parallel [(set (match_dup 2) (const_int 0))
19973               (clobber (reg:CC FLAGS_REG))])
19974    (set (match_dup 0) (match_dup 1))]
19975   "operands[2] = gen_lowpart (SImode, operands[1]);")
19976
19977 (define_peephole2
19978   [(match_scratch:QI 1 "q")
19979    (set (match_operand:QI 0 "memory_operand" "")
19980         (const_int 0))]
19981   "! optimize_size
19982    && ! TARGET_USE_MOV0
19983    && TARGET_SPLIT_LONG_MOVES
19984    && get_attr_length (insn) >= ix86_cost->large_insn
19985    && peep2_regno_dead_p (0, FLAGS_REG)"
19986   [(parallel [(set (match_dup 2) (const_int 0))
19987               (clobber (reg:CC FLAGS_REG))])
19988    (set (match_dup 0) (match_dup 1))]
19989   "operands[2] = gen_lowpart (SImode, operands[1]);")
19990
19991 (define_peephole2
19992   [(match_scratch:SI 2 "r")
19993    (set (match_operand:SI 0 "memory_operand" "")
19994         (match_operand:SI 1 "immediate_operand" ""))]
19995   "! optimize_size
19996    && TARGET_SPLIT_LONG_MOVES
19997    && get_attr_length (insn) >= ix86_cost->large_insn"
19998   [(set (match_dup 2) (match_dup 1))
19999    (set (match_dup 0) (match_dup 2))]
20000   "")
20001
20002 (define_peephole2
20003   [(match_scratch:HI 2 "r")
20004    (set (match_operand:HI 0 "memory_operand" "")
20005         (match_operand:HI 1 "immediate_operand" ""))]
20006   "! optimize_size
20007    && TARGET_SPLIT_LONG_MOVES
20008    && get_attr_length (insn) >= ix86_cost->large_insn"
20009   [(set (match_dup 2) (match_dup 1))
20010    (set (match_dup 0) (match_dup 2))]
20011   "")
20012
20013 (define_peephole2
20014   [(match_scratch:QI 2 "q")
20015    (set (match_operand:QI 0 "memory_operand" "")
20016         (match_operand:QI 1 "immediate_operand" ""))]
20017   "! optimize_size
20018    && TARGET_SPLIT_LONG_MOVES
20019    && get_attr_length (insn) >= ix86_cost->large_insn"
20020   [(set (match_dup 2) (match_dup 1))
20021    (set (match_dup 0) (match_dup 2))]
20022   "")
20023
20024 ;; Don't compare memory with zero, load and use a test instead.
20025 (define_peephole2
20026   [(set (match_operand 0 "flags_reg_operand" "")
20027         (match_operator 1 "compare_operator"
20028           [(match_operand:SI 2 "memory_operand" "")
20029            (const_int 0)]))
20030    (match_scratch:SI 3 "r")]
20031   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20032   [(set (match_dup 3) (match_dup 2))
20033    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20034   "")
20035
20036 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20037 ;; Don't split NOTs with a displacement operand, because resulting XOR
20038 ;; will not be pairable anyway.
20039 ;;
20040 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20041 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20042 ;; so this split helps here as well.
20043 ;;
20044 ;; Note: Can't do this as a regular split because we can't get proper
20045 ;; lifetime information then.
20046
20047 (define_peephole2
20048   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20049         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20050   "!optimize_size
20051    && ((TARGET_NOT_UNPAIRABLE
20052         && (!MEM_P (operands[0])
20053             || !memory_displacement_operand (operands[0], SImode)))
20054        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20055    && peep2_regno_dead_p (0, FLAGS_REG)"
20056   [(parallel [(set (match_dup 0)
20057                    (xor:SI (match_dup 1) (const_int -1)))
20058               (clobber (reg:CC FLAGS_REG))])]
20059   "")
20060
20061 (define_peephole2
20062   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20063         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20064   "!optimize_size
20065    && ((TARGET_NOT_UNPAIRABLE
20066         && (!MEM_P (operands[0])
20067             || !memory_displacement_operand (operands[0], HImode)))
20068        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20069    && peep2_regno_dead_p (0, FLAGS_REG)"
20070   [(parallel [(set (match_dup 0)
20071                    (xor:HI (match_dup 1) (const_int -1)))
20072               (clobber (reg:CC FLAGS_REG))])]
20073   "")
20074
20075 (define_peephole2
20076   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20077         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20078   "!optimize_size
20079    && ((TARGET_NOT_UNPAIRABLE
20080         && (!MEM_P (operands[0])
20081             || !memory_displacement_operand (operands[0], QImode)))
20082        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20083    && peep2_regno_dead_p (0, FLAGS_REG)"
20084   [(parallel [(set (match_dup 0)
20085                    (xor:QI (match_dup 1) (const_int -1)))
20086               (clobber (reg:CC FLAGS_REG))])]
20087   "")
20088
20089 ;; Non pairable "test imm, reg" instructions can be translated to
20090 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20091 ;; byte opcode instead of two, have a short form for byte operands),
20092 ;; so do it for other CPUs as well.  Given that the value was dead,
20093 ;; this should not create any new dependencies.  Pass on the sub-word
20094 ;; versions if we're concerned about partial register stalls.
20095
20096 (define_peephole2
20097   [(set (match_operand 0 "flags_reg_operand" "")
20098         (match_operator 1 "compare_operator"
20099           [(and:SI (match_operand:SI 2 "register_operand" "")
20100                    (match_operand:SI 3 "immediate_operand" ""))
20101            (const_int 0)]))]
20102   "ix86_match_ccmode (insn, CCNOmode)
20103    && (true_regnum (operands[2]) != AX_REG
20104        || satisfies_constraint_K (operands[3]))
20105    && peep2_reg_dead_p (1, operands[2])"
20106   [(parallel
20107      [(set (match_dup 0)
20108            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20109                             (const_int 0)]))
20110       (set (match_dup 2)
20111            (and:SI (match_dup 2) (match_dup 3)))])]
20112   "")
20113
20114 ;; We don't need to handle HImode case, because it will be promoted to SImode
20115 ;; on ! TARGET_PARTIAL_REG_STALL
20116
20117 (define_peephole2
20118   [(set (match_operand 0 "flags_reg_operand" "")
20119         (match_operator 1 "compare_operator"
20120           [(and:QI (match_operand:QI 2 "register_operand" "")
20121                    (match_operand:QI 3 "immediate_operand" ""))
20122            (const_int 0)]))]
20123   "! TARGET_PARTIAL_REG_STALL
20124    && ix86_match_ccmode (insn, CCNOmode)
20125    && true_regnum (operands[2]) != AX_REG
20126    && peep2_reg_dead_p (1, operands[2])"
20127   [(parallel
20128      [(set (match_dup 0)
20129            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20130                             (const_int 0)]))
20131       (set (match_dup 2)
20132            (and:QI (match_dup 2) (match_dup 3)))])]
20133   "")
20134
20135 (define_peephole2
20136   [(set (match_operand 0 "flags_reg_operand" "")
20137         (match_operator 1 "compare_operator"
20138           [(and:SI
20139              (zero_extract:SI
20140                (match_operand 2 "ext_register_operand" "")
20141                (const_int 8)
20142                (const_int 8))
20143              (match_operand 3 "const_int_operand" ""))
20144            (const_int 0)]))]
20145   "! TARGET_PARTIAL_REG_STALL
20146    && ix86_match_ccmode (insn, CCNOmode)
20147    && true_regnum (operands[2]) != AX_REG
20148    && peep2_reg_dead_p (1, operands[2])"
20149   [(parallel [(set (match_dup 0)
20150                    (match_op_dup 1
20151                      [(and:SI
20152                         (zero_extract:SI
20153                           (match_dup 2)
20154                           (const_int 8)
20155                           (const_int 8))
20156                         (match_dup 3))
20157                       (const_int 0)]))
20158               (set (zero_extract:SI (match_dup 2)
20159                                     (const_int 8)
20160                                     (const_int 8))
20161                    (and:SI
20162                      (zero_extract:SI
20163                        (match_dup 2)
20164                        (const_int 8)
20165                        (const_int 8))
20166                      (match_dup 3)))])]
20167   "")
20168
20169 ;; Don't do logical operations with memory inputs.
20170 (define_peephole2
20171   [(match_scratch:SI 2 "r")
20172    (parallel [(set (match_operand:SI 0 "register_operand" "")
20173                    (match_operator:SI 3 "arith_or_logical_operator"
20174                      [(match_dup 0)
20175                       (match_operand:SI 1 "memory_operand" "")]))
20176               (clobber (reg:CC FLAGS_REG))])]
20177   "! optimize_size && ! TARGET_READ_MODIFY"
20178   [(set (match_dup 2) (match_dup 1))
20179    (parallel [(set (match_dup 0)
20180                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20181               (clobber (reg:CC FLAGS_REG))])]
20182   "")
20183
20184 (define_peephole2
20185   [(match_scratch:SI 2 "r")
20186    (parallel [(set (match_operand:SI 0 "register_operand" "")
20187                    (match_operator:SI 3 "arith_or_logical_operator"
20188                      [(match_operand:SI 1 "memory_operand" "")
20189                       (match_dup 0)]))
20190               (clobber (reg:CC FLAGS_REG))])]
20191   "! optimize_size && ! TARGET_READ_MODIFY"
20192   [(set (match_dup 2) (match_dup 1))
20193    (parallel [(set (match_dup 0)
20194                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20195               (clobber (reg:CC FLAGS_REG))])]
20196   "")
20197
20198 ; Don't do logical operations with memory outputs
20199 ;
20200 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20201 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20202 ; the same decoder scheduling characteristics as the original.
20203
20204 (define_peephole2
20205   [(match_scratch:SI 2 "r")
20206    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20207                    (match_operator:SI 3 "arith_or_logical_operator"
20208                      [(match_dup 0)
20209                       (match_operand:SI 1 "nonmemory_operand" "")]))
20210               (clobber (reg:CC FLAGS_REG))])]
20211   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20212   [(set (match_dup 2) (match_dup 0))
20213    (parallel [(set (match_dup 2)
20214                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20215               (clobber (reg:CC FLAGS_REG))])
20216    (set (match_dup 0) (match_dup 2))]
20217   "")
20218
20219 (define_peephole2
20220   [(match_scratch:SI 2 "r")
20221    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20222                    (match_operator:SI 3 "arith_or_logical_operator"
20223                      [(match_operand:SI 1 "nonmemory_operand" "")
20224                       (match_dup 0)]))
20225               (clobber (reg:CC FLAGS_REG))])]
20226   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20227   [(set (match_dup 2) (match_dup 0))
20228    (parallel [(set (match_dup 2)
20229                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20230               (clobber (reg:CC FLAGS_REG))])
20231    (set (match_dup 0) (match_dup 2))]
20232   "")
20233
20234 ;; Attempt to always use XOR for zeroing registers.
20235 (define_peephole2
20236   [(set (match_operand 0 "register_operand" "")
20237         (match_operand 1 "const0_operand" ""))]
20238   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20239    && (! TARGET_USE_MOV0 || optimize_size)
20240    && GENERAL_REG_P (operands[0])
20241    && peep2_regno_dead_p (0, FLAGS_REG)"
20242   [(parallel [(set (match_dup 0) (const_int 0))
20243               (clobber (reg:CC FLAGS_REG))])]
20244 {
20245   operands[0] = gen_lowpart (word_mode, operands[0]);
20246 })
20247
20248 (define_peephole2
20249   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20250         (const_int 0))]
20251   "(GET_MODE (operands[0]) == QImode
20252     || GET_MODE (operands[0]) == HImode)
20253    && (! TARGET_USE_MOV0 || optimize_size)
20254    && peep2_regno_dead_p (0, FLAGS_REG)"
20255   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20256               (clobber (reg:CC FLAGS_REG))])])
20257
20258 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20259 (define_peephole2
20260   [(set (match_operand 0 "register_operand" "")
20261         (const_int -1))]
20262   "(GET_MODE (operands[0]) == HImode
20263     || GET_MODE (operands[0]) == SImode
20264     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20265    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20266    && peep2_regno_dead_p (0, FLAGS_REG)"
20267   [(parallel [(set (match_dup 0) (const_int -1))
20268               (clobber (reg:CC FLAGS_REG))])]
20269   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20270                               operands[0]);")
20271
20272 ;; Attempt to convert simple leas to adds. These can be created by
20273 ;; move expanders.
20274 (define_peephole2
20275   [(set (match_operand:SI 0 "register_operand" "")
20276         (plus:SI (match_dup 0)
20277                  (match_operand:SI 1 "nonmemory_operand" "")))]
20278   "peep2_regno_dead_p (0, FLAGS_REG)"
20279   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20280               (clobber (reg:CC FLAGS_REG))])]
20281   "")
20282
20283 (define_peephole2
20284   [(set (match_operand:SI 0 "register_operand" "")
20285         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20286                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20287   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20288   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20289               (clobber (reg:CC FLAGS_REG))])]
20290   "operands[2] = gen_lowpart (SImode, operands[2]);")
20291
20292 (define_peephole2
20293   [(set (match_operand:DI 0 "register_operand" "")
20294         (plus:DI (match_dup 0)
20295                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20296   "peep2_regno_dead_p (0, FLAGS_REG)"
20297   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20298               (clobber (reg:CC FLAGS_REG))])]
20299   "")
20300
20301 (define_peephole2
20302   [(set (match_operand:SI 0 "register_operand" "")
20303         (mult:SI (match_dup 0)
20304                  (match_operand:SI 1 "const_int_operand" "")))]
20305   "exact_log2 (INTVAL (operands[1])) >= 0
20306    && peep2_regno_dead_p (0, FLAGS_REG)"
20307   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20308               (clobber (reg:CC FLAGS_REG))])]
20309   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20310
20311 (define_peephole2
20312   [(set (match_operand:DI 0 "register_operand" "")
20313         (mult:DI (match_dup 0)
20314                  (match_operand:DI 1 "const_int_operand" "")))]
20315   "exact_log2 (INTVAL (operands[1])) >= 0
20316    && peep2_regno_dead_p (0, FLAGS_REG)"
20317   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20318               (clobber (reg:CC FLAGS_REG))])]
20319   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20320
20321 (define_peephole2
20322   [(set (match_operand:SI 0 "register_operand" "")
20323         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20324                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20325   "exact_log2 (INTVAL (operands[2])) >= 0
20326    && REGNO (operands[0]) == REGNO (operands[1])
20327    && peep2_regno_dead_p (0, FLAGS_REG)"
20328   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20329               (clobber (reg:CC FLAGS_REG))])]
20330   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20331
20332 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20333 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20334 ;; many CPUs it is also faster, since special hardware to avoid esp
20335 ;; dependencies is present.
20336
20337 ;; While some of these conversions may be done using splitters, we use peepholes
20338 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20339
20340 ;; Convert prologue esp subtractions to push.
20341 ;; We need register to push.  In order to keep verify_flow_info happy we have
20342 ;; two choices
20343 ;; - use scratch and clobber it in order to avoid dependencies
20344 ;; - use already live register
20345 ;; We can't use the second way right now, since there is no reliable way how to
20346 ;; verify that given register is live.  First choice will also most likely in
20347 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20348 ;; call clobbered registers are dead.  We may want to use base pointer as an
20349 ;; alternative when no register is available later.
20350
20351 (define_peephole2
20352   [(match_scratch:SI 0 "r")
20353    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20354               (clobber (reg:CC FLAGS_REG))
20355               (clobber (mem:BLK (scratch)))])]
20356   "optimize_size || !TARGET_SUB_ESP_4"
20357   [(clobber (match_dup 0))
20358    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20359               (clobber (mem:BLK (scratch)))])])
20360
20361 (define_peephole2
20362   [(match_scratch:SI 0 "r")
20363    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20364               (clobber (reg:CC FLAGS_REG))
20365               (clobber (mem:BLK (scratch)))])]
20366   "optimize_size || !TARGET_SUB_ESP_8"
20367   [(clobber (match_dup 0))
20368    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20369    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20370               (clobber (mem:BLK (scratch)))])])
20371
20372 ;; Convert esp subtractions to push.
20373 (define_peephole2
20374   [(match_scratch:SI 0 "r")
20375    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20376               (clobber (reg:CC FLAGS_REG))])]
20377   "optimize_size || !TARGET_SUB_ESP_4"
20378   [(clobber (match_dup 0))
20379    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20380
20381 (define_peephole2
20382   [(match_scratch:SI 0 "r")
20383    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20384               (clobber (reg:CC FLAGS_REG))])]
20385   "optimize_size || !TARGET_SUB_ESP_8"
20386   [(clobber (match_dup 0))
20387    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20388    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20389
20390 ;; Convert epilogue deallocator to pop.
20391 (define_peephole2
20392   [(match_scratch:SI 0 "r")
20393    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20394               (clobber (reg:CC FLAGS_REG))
20395               (clobber (mem:BLK (scratch)))])]
20396   "optimize_size || !TARGET_ADD_ESP_4"
20397   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20398               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20399               (clobber (mem:BLK (scratch)))])]
20400   "")
20401
20402 ;; Two pops case is tricky, since pop causes dependency on destination register.
20403 ;; We use two registers if available.
20404 (define_peephole2
20405   [(match_scratch:SI 0 "r")
20406    (match_scratch:SI 1 "r")
20407    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20408               (clobber (reg:CC FLAGS_REG))
20409               (clobber (mem:BLK (scratch)))])]
20410   "optimize_size || !TARGET_ADD_ESP_8"
20411   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20412               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20413               (clobber (mem:BLK (scratch)))])
20414    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20415               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20416   "")
20417
20418 (define_peephole2
20419   [(match_scratch:SI 0 "r")
20420    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20421               (clobber (reg:CC FLAGS_REG))
20422               (clobber (mem:BLK (scratch)))])]
20423   "optimize_size"
20424   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20425               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20426               (clobber (mem:BLK (scratch)))])
20427    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20428               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20429   "")
20430
20431 ;; Convert esp additions to pop.
20432 (define_peephole2
20433   [(match_scratch:SI 0 "r")
20434    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20435               (clobber (reg:CC FLAGS_REG))])]
20436   ""
20437   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20438               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20439   "")
20440
20441 ;; Two pops case is tricky, since pop causes dependency on destination register.
20442 ;; We use two registers if available.
20443 (define_peephole2
20444   [(match_scratch:SI 0 "r")
20445    (match_scratch:SI 1 "r")
20446    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20447               (clobber (reg:CC FLAGS_REG))])]
20448   ""
20449   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20450               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20451    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20452               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20453   "")
20454
20455 (define_peephole2
20456   [(match_scratch:SI 0 "r")
20457    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20458               (clobber (reg:CC FLAGS_REG))])]
20459   "optimize_size"
20460   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20461               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20462    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20463               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20464   "")
20465 \f
20466 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20467 ;; required and register dies.  Similarly for 128 to plus -128.
20468 (define_peephole2
20469   [(set (match_operand 0 "flags_reg_operand" "")
20470         (match_operator 1 "compare_operator"
20471           [(match_operand 2 "register_operand" "")
20472            (match_operand 3 "const_int_operand" "")]))]
20473   "(INTVAL (operands[3]) == -1
20474     || INTVAL (operands[3]) == 1
20475     || INTVAL (operands[3]) == 128)
20476    && ix86_match_ccmode (insn, CCGCmode)
20477    && peep2_reg_dead_p (1, operands[2])"
20478   [(parallel [(set (match_dup 0)
20479                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20480               (clobber (match_dup 2))])]
20481   "")
20482 \f
20483 (define_peephole2
20484   [(match_scratch:DI 0 "r")
20485    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20486               (clobber (reg:CC FLAGS_REG))
20487               (clobber (mem:BLK (scratch)))])]
20488   "optimize_size || !TARGET_SUB_ESP_4"
20489   [(clobber (match_dup 0))
20490    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20491               (clobber (mem:BLK (scratch)))])])
20492
20493 (define_peephole2
20494   [(match_scratch:DI 0 "r")
20495    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20496               (clobber (reg:CC FLAGS_REG))
20497               (clobber (mem:BLK (scratch)))])]
20498   "optimize_size || !TARGET_SUB_ESP_8"
20499   [(clobber (match_dup 0))
20500    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20501    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20502               (clobber (mem:BLK (scratch)))])])
20503
20504 ;; Convert esp subtractions to push.
20505 (define_peephole2
20506   [(match_scratch:DI 0 "r")
20507    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20508               (clobber (reg:CC FLAGS_REG))])]
20509   "optimize_size || !TARGET_SUB_ESP_4"
20510   [(clobber (match_dup 0))
20511    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20512
20513 (define_peephole2
20514   [(match_scratch:DI 0 "r")
20515    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20516               (clobber (reg:CC FLAGS_REG))])]
20517   "optimize_size || !TARGET_SUB_ESP_8"
20518   [(clobber (match_dup 0))
20519    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20520    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20521
20522 ;; Convert epilogue deallocator to pop.
20523 (define_peephole2
20524   [(match_scratch:DI 0 "r")
20525    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20526               (clobber (reg:CC FLAGS_REG))
20527               (clobber (mem:BLK (scratch)))])]
20528   "optimize_size || !TARGET_ADD_ESP_4"
20529   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20530               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20531               (clobber (mem:BLK (scratch)))])]
20532   "")
20533
20534 ;; Two pops case is tricky, since pop causes dependency on destination register.
20535 ;; We use two registers if available.
20536 (define_peephole2
20537   [(match_scratch:DI 0 "r")
20538    (match_scratch:DI 1 "r")
20539    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20540               (clobber (reg:CC FLAGS_REG))
20541               (clobber (mem:BLK (scratch)))])]
20542   "optimize_size || !TARGET_ADD_ESP_8"
20543   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20544               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20545               (clobber (mem:BLK (scratch)))])
20546    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20547               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20548   "")
20549
20550 (define_peephole2
20551   [(match_scratch:DI 0 "r")
20552    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20553               (clobber (reg:CC FLAGS_REG))
20554               (clobber (mem:BLK (scratch)))])]
20555   "optimize_size"
20556   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20557               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20558               (clobber (mem:BLK (scratch)))])
20559    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20560               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20561   "")
20562
20563 ;; Convert esp additions to pop.
20564 (define_peephole2
20565   [(match_scratch:DI 0 "r")
20566    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20567               (clobber (reg:CC FLAGS_REG))])]
20568   ""
20569   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20570               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20571   "")
20572
20573 ;; Two pops case is tricky, since pop causes dependency on destination register.
20574 ;; We use two registers if available.
20575 (define_peephole2
20576   [(match_scratch:DI 0 "r")
20577    (match_scratch:DI 1 "r")
20578    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20579               (clobber (reg:CC FLAGS_REG))])]
20580   ""
20581   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20582               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20583    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20584               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20585   "")
20586
20587 (define_peephole2
20588   [(match_scratch:DI 0 "r")
20589    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20590               (clobber (reg:CC FLAGS_REG))])]
20591   "optimize_size"
20592   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20593               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20594    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20595               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20596   "")
20597 \f
20598 ;; Convert imul by three, five and nine into lea
20599 (define_peephole2
20600   [(parallel
20601     [(set (match_operand:SI 0 "register_operand" "")
20602           (mult:SI (match_operand:SI 1 "register_operand" "")
20603                    (match_operand:SI 2 "const_int_operand" "")))
20604      (clobber (reg:CC FLAGS_REG))])]
20605   "INTVAL (operands[2]) == 3
20606    || INTVAL (operands[2]) == 5
20607    || INTVAL (operands[2]) == 9"
20608   [(set (match_dup 0)
20609         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20610                  (match_dup 1)))]
20611   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20612
20613 (define_peephole2
20614   [(parallel
20615     [(set (match_operand:SI 0 "register_operand" "")
20616           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20617                    (match_operand:SI 2 "const_int_operand" "")))
20618      (clobber (reg:CC FLAGS_REG))])]
20619   "!optimize_size
20620    && (INTVAL (operands[2]) == 3
20621        || INTVAL (operands[2]) == 5
20622        || INTVAL (operands[2]) == 9)"
20623   [(set (match_dup 0) (match_dup 1))
20624    (set (match_dup 0)
20625         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20626                  (match_dup 0)))]
20627   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20628
20629 (define_peephole2
20630   [(parallel
20631     [(set (match_operand:DI 0 "register_operand" "")
20632           (mult:DI (match_operand:DI 1 "register_operand" "")
20633                    (match_operand:DI 2 "const_int_operand" "")))
20634      (clobber (reg:CC FLAGS_REG))])]
20635   "TARGET_64BIT
20636    && (INTVAL (operands[2]) == 3
20637        || INTVAL (operands[2]) == 5
20638        || INTVAL (operands[2]) == 9)"
20639   [(set (match_dup 0)
20640         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20641                  (match_dup 1)))]
20642   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20643
20644 (define_peephole2
20645   [(parallel
20646     [(set (match_operand:DI 0 "register_operand" "")
20647           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20648                    (match_operand:DI 2 "const_int_operand" "")))
20649      (clobber (reg:CC FLAGS_REG))])]
20650   "TARGET_64BIT
20651    && !optimize_size
20652    && (INTVAL (operands[2]) == 3
20653        || INTVAL (operands[2]) == 5
20654        || INTVAL (operands[2]) == 9)"
20655   [(set (match_dup 0) (match_dup 1))
20656    (set (match_dup 0)
20657         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20658                  (match_dup 0)))]
20659   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20660
20661 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20662 ;; imul $32bit_imm, reg, reg is direct decoded.
20663 (define_peephole2
20664   [(match_scratch:DI 3 "r")
20665    (parallel [(set (match_operand:DI 0 "register_operand" "")
20666                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20667                             (match_operand:DI 2 "immediate_operand" "")))
20668               (clobber (reg:CC FLAGS_REG))])]
20669   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20670    && !satisfies_constraint_K (operands[2])"
20671   [(set (match_dup 3) (match_dup 1))
20672    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20673               (clobber (reg:CC FLAGS_REG))])]
20674 "")
20675
20676 (define_peephole2
20677   [(match_scratch:SI 3 "r")
20678    (parallel [(set (match_operand:SI 0 "register_operand" "")
20679                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20680                             (match_operand:SI 2 "immediate_operand" "")))
20681               (clobber (reg:CC FLAGS_REG))])]
20682   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20683    && !satisfies_constraint_K (operands[2])"
20684   [(set (match_dup 3) (match_dup 1))
20685    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20686               (clobber (reg:CC FLAGS_REG))])]
20687 "")
20688
20689 (define_peephole2
20690   [(match_scratch:SI 3 "r")
20691    (parallel [(set (match_operand:DI 0 "register_operand" "")
20692                    (zero_extend:DI
20693                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20694                               (match_operand:SI 2 "immediate_operand" ""))))
20695               (clobber (reg:CC FLAGS_REG))])]
20696   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20697    && !satisfies_constraint_K (operands[2])"
20698   [(set (match_dup 3) (match_dup 1))
20699    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20700               (clobber (reg:CC FLAGS_REG))])]
20701 "")
20702
20703 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20704 ;; Convert it into imul reg, reg
20705 ;; It would be better to force assembler to encode instruction using long
20706 ;; immediate, but there is apparently no way to do so.
20707 (define_peephole2
20708   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20709                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20710                             (match_operand:DI 2 "const_int_operand" "")))
20711               (clobber (reg:CC FLAGS_REG))])
20712    (match_scratch:DI 3 "r")]
20713   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20714    && satisfies_constraint_K (operands[2])"
20715   [(set (match_dup 3) (match_dup 2))
20716    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20717               (clobber (reg:CC FLAGS_REG))])]
20718 {
20719   if (!rtx_equal_p (operands[0], operands[1]))
20720     emit_move_insn (operands[0], operands[1]);
20721 })
20722
20723 (define_peephole2
20724   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20725                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20726                             (match_operand:SI 2 "const_int_operand" "")))
20727               (clobber (reg:CC FLAGS_REG))])
20728    (match_scratch:SI 3 "r")]
20729   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20730    && satisfies_constraint_K (operands[2])"
20731   [(set (match_dup 3) (match_dup 2))
20732    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20733               (clobber (reg:CC FLAGS_REG))])]
20734 {
20735   if (!rtx_equal_p (operands[0], operands[1]))
20736     emit_move_insn (operands[0], operands[1]);
20737 })
20738
20739 (define_peephole2
20740   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20741                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20742                             (match_operand:HI 2 "immediate_operand" "")))
20743               (clobber (reg:CC FLAGS_REG))])
20744    (match_scratch:HI 3 "r")]
20745   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20746   [(set (match_dup 3) (match_dup 2))
20747    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20748               (clobber (reg:CC FLAGS_REG))])]
20749 {
20750   if (!rtx_equal_p (operands[0], operands[1]))
20751     emit_move_insn (operands[0], operands[1]);
20752 })
20753
20754 ;; After splitting up read-modify operations, array accesses with memory
20755 ;; operands might end up in form:
20756 ;;  sall    $2, %eax
20757 ;;  movl    4(%esp), %edx
20758 ;;  addl    %edx, %eax
20759 ;; instead of pre-splitting:
20760 ;;  sall    $2, %eax
20761 ;;  addl    4(%esp), %eax
20762 ;; Turn it into:
20763 ;;  movl    4(%esp), %edx
20764 ;;  leal    (%edx,%eax,4), %eax
20765
20766 (define_peephole2
20767   [(parallel [(set (match_operand 0 "register_operand" "")
20768                    (ashift (match_operand 1 "register_operand" "")
20769                            (match_operand 2 "const_int_operand" "")))
20770                (clobber (reg:CC FLAGS_REG))])
20771    (set (match_operand 3 "register_operand")
20772         (match_operand 4 "x86_64_general_operand" ""))
20773    (parallel [(set (match_operand 5 "register_operand" "")
20774                    (plus (match_operand 6 "register_operand" "")
20775                          (match_operand 7 "register_operand" "")))
20776                    (clobber (reg:CC FLAGS_REG))])]
20777   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20778    /* Validate MODE for lea.  */
20779    && ((!TARGET_PARTIAL_REG_STALL
20780         && (GET_MODE (operands[0]) == QImode
20781             || GET_MODE (operands[0]) == HImode))
20782        || GET_MODE (operands[0]) == SImode
20783        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20784    /* We reorder load and the shift.  */
20785    && !rtx_equal_p (operands[1], operands[3])
20786    && !reg_overlap_mentioned_p (operands[0], operands[4])
20787    /* Last PLUS must consist of operand 0 and 3.  */
20788    && !rtx_equal_p (operands[0], operands[3])
20789    && (rtx_equal_p (operands[3], operands[6])
20790        || rtx_equal_p (operands[3], operands[7]))
20791    && (rtx_equal_p (operands[0], operands[6])
20792        || rtx_equal_p (operands[0], operands[7]))
20793    /* The intermediate operand 0 must die or be same as output.  */
20794    && (rtx_equal_p (operands[0], operands[5])
20795        || peep2_reg_dead_p (3, operands[0]))"
20796   [(set (match_dup 3) (match_dup 4))
20797    (set (match_dup 0) (match_dup 1))]
20798 {
20799   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20800   int scale = 1 << INTVAL (operands[2]);
20801   rtx index = gen_lowpart (Pmode, operands[1]);
20802   rtx base = gen_lowpart (Pmode, operands[3]);
20803   rtx dest = gen_lowpart (mode, operands[5]);
20804
20805   operands[1] = gen_rtx_PLUS (Pmode, base,
20806                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20807   if (mode != Pmode)
20808     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20809   operands[0] = dest;
20810 })
20811 \f
20812 ;; Call-value patterns last so that the wildcard operand does not
20813 ;; disrupt insn-recog's switch tables.
20814
20815 (define_insn "*call_value_pop_0"
20816   [(set (match_operand 0 "" "")
20817         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20818               (match_operand:SI 2 "" "")))
20819    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20820                             (match_operand:SI 3 "immediate_operand" "")))]
20821   "!TARGET_64BIT"
20822 {
20823   if (SIBLING_CALL_P (insn))
20824     return "jmp\t%P1";
20825   else
20826     return "call\t%P1";
20827 }
20828   [(set_attr "type" "callv")])
20829
20830 (define_insn "*call_value_pop_1"
20831   [(set (match_operand 0 "" "")
20832         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20833               (match_operand:SI 2 "" "")))
20834    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20835                             (match_operand:SI 3 "immediate_operand" "i")))]
20836   "!TARGET_64BIT"
20837 {
20838   if (constant_call_address_operand (operands[1], Pmode))
20839     {
20840       if (SIBLING_CALL_P (insn))
20841         return "jmp\t%P1";
20842       else
20843         return "call\t%P1";
20844     }
20845   if (SIBLING_CALL_P (insn))
20846     return "jmp\t%A1";
20847   else
20848     return "call\t%A1";
20849 }
20850   [(set_attr "type" "callv")])
20851
20852 (define_insn "*call_value_0"
20853   [(set (match_operand 0 "" "")
20854         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20855               (match_operand:SI 2 "" "")))]
20856   "!TARGET_64BIT"
20857 {
20858   if (SIBLING_CALL_P (insn))
20859     return "jmp\t%P1";
20860   else
20861     return "call\t%P1";
20862 }
20863   [(set_attr "type" "callv")])
20864
20865 (define_insn "*call_value_0_rex64"
20866   [(set (match_operand 0 "" "")
20867         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20868               (match_operand:DI 2 "const_int_operand" "")))]
20869   "TARGET_64BIT"
20870 {
20871   if (SIBLING_CALL_P (insn))
20872     return "jmp\t%P1";
20873   else
20874     return "call\t%P1";
20875 }
20876   [(set_attr "type" "callv")])
20877
20878 (define_insn "*call_value_1"
20879   [(set (match_operand 0 "" "")
20880         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20881               (match_operand:SI 2 "" "")))]
20882   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20883 {
20884   if (constant_call_address_operand (operands[1], Pmode))
20885     return "call\t%P1";
20886   return "call\t%A1";
20887 }
20888   [(set_attr "type" "callv")])
20889
20890 (define_insn "*sibcall_value_1"
20891   [(set (match_operand 0 "" "")
20892         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20893               (match_operand:SI 2 "" "")))]
20894   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20895 {
20896   if (constant_call_address_operand (operands[1], Pmode))
20897     return "jmp\t%P1";
20898   return "jmp\t%A1";
20899 }
20900   [(set_attr "type" "callv")])
20901
20902 (define_insn "*call_value_1_rex64"
20903   [(set (match_operand 0 "" "")
20904         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20905               (match_operand:DI 2 "" "")))]
20906   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20907    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20908 {
20909   if (constant_call_address_operand (operands[1], Pmode))
20910     return "call\t%P1";
20911   return "call\t%A1";
20912 }
20913   [(set_attr "type" "callv")])
20914
20915 (define_insn "*call_value_1_rex64_large"
20916   [(set (match_operand 0 "" "")
20917         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20918               (match_operand:DI 2 "" "")))]
20919   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20920   "call\t%A1"
20921   [(set_attr "type" "callv")])
20922
20923 (define_insn "*sibcall_value_1_rex64"
20924   [(set (match_operand 0 "" "")
20925         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20926               (match_operand:DI 2 "" "")))]
20927   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20928   "jmp\t%P1"
20929   [(set_attr "type" "callv")])
20930
20931 (define_insn "*sibcall_value_1_rex64_v"
20932   [(set (match_operand 0 "" "")
20933         (call (mem:QI (reg:DI R11_REG))
20934               (match_operand:DI 1 "" "")))]
20935   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20936   "jmp\t{*%%}r11"
20937   [(set_attr "type" "callv")])
20938 \f
20939 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20940 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20941 ;; caught for use by garbage collectors and the like.  Using an insn that
20942 ;; maps to SIGILL makes it more likely the program will rightfully die.
20943 ;; Keeping with tradition, "6" is in honor of #UD.
20944 (define_insn "trap"
20945   [(trap_if (const_int 1) (const_int 6))]
20946   ""
20947   { return ASM_SHORT "0x0b0f"; }
20948   [(set_attr "length" "2")])
20949
20950 (define_expand "sse_prologue_save"
20951   [(parallel [(set (match_operand:BLK 0 "" "")
20952                    (unspec:BLK [(reg:DI 21)
20953                                 (reg:DI 22)
20954                                 (reg:DI 23)
20955                                 (reg:DI 24)
20956                                 (reg:DI 25)
20957                                 (reg:DI 26)
20958                                 (reg:DI 27)
20959                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20960               (use (match_operand:DI 1 "register_operand" ""))
20961               (use (match_operand:DI 2 "immediate_operand" ""))
20962               (use (label_ref:DI (match_operand 3 "" "")))])]
20963   "TARGET_64BIT"
20964   "")
20965
20966 (define_insn "*sse_prologue_save_insn"
20967   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20968                           (match_operand:DI 4 "const_int_operand" "n")))
20969         (unspec:BLK [(reg:DI 21)
20970                      (reg:DI 22)
20971                      (reg:DI 23)
20972                      (reg:DI 24)
20973                      (reg:DI 25)
20974                      (reg:DI 26)
20975                      (reg:DI 27)
20976                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20977    (use (match_operand:DI 1 "register_operand" "r"))
20978    (use (match_operand:DI 2 "const_int_operand" "i"))
20979    (use (label_ref:DI (match_operand 3 "" "X")))]
20980   "TARGET_64BIT
20981    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20982    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20983 {
20984   int i;
20985   operands[0] = gen_rtx_MEM (Pmode,
20986                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20987   output_asm_insn ("jmp\t%A1", operands);
20988   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20989     {
20990       operands[4] = adjust_address (operands[0], DImode, i*16);
20991       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20992       PUT_MODE (operands[4], TImode);
20993       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20994         output_asm_insn ("rex", operands);
20995       output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
20996     }
20997   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20998                                      CODE_LABEL_NUMBER (operands[3]));
20999   return "";
21000 }
21001   [(set_attr "type" "other")
21002    (set_attr "length_immediate" "0")
21003    (set_attr "length_address" "0")
21004    (set_attr "length" "135")
21005    (set_attr "memory" "store")
21006    (set_attr "modrm" "0")
21007    (set_attr "mode" "DI")])
21008
21009 (define_expand "prefetch"
21010   [(prefetch (match_operand 0 "address_operand" "")
21011              (match_operand:SI 1 "const_int_operand" "")
21012              (match_operand:SI 2 "const_int_operand" ""))]
21013   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21014 {
21015   int rw = INTVAL (operands[1]);
21016   int locality = INTVAL (operands[2]);
21017
21018   gcc_assert (rw == 0 || rw == 1);
21019   gcc_assert (locality >= 0 && locality <= 3);
21020   gcc_assert (GET_MODE (operands[0]) == Pmode
21021               || GET_MODE (operands[0]) == VOIDmode);
21022
21023   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21024      supported by SSE counterpart or the SSE prefetch is not available
21025      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21026      of locality.  */
21027   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21028     operands[2] = GEN_INT (3);
21029   else
21030     operands[1] = const0_rtx;
21031 })
21032
21033 (define_insn "*prefetch_sse"
21034   [(prefetch (match_operand:SI 0 "address_operand" "p")
21035              (const_int 0)
21036              (match_operand:SI 1 "const_int_operand" ""))]
21037   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21038 {
21039   static const char * const patterns[4] = {
21040    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21041   };
21042
21043   int locality = INTVAL (operands[1]);
21044   gcc_assert (locality >= 0 && locality <= 3);
21045
21046   return patterns[locality];
21047 }
21048   [(set_attr "type" "sse")
21049    (set_attr "memory" "none")])
21050
21051 (define_insn "*prefetch_sse_rex"
21052   [(prefetch (match_operand:DI 0 "address_operand" "p")
21053              (const_int 0)
21054              (match_operand:SI 1 "const_int_operand" ""))]
21055   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21056 {
21057   static const char * const patterns[4] = {
21058    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21059   };
21060
21061   int locality = INTVAL (operands[1]);
21062   gcc_assert (locality >= 0 && locality <= 3);
21063
21064   return patterns[locality];
21065 }
21066   [(set_attr "type" "sse")
21067    (set_attr "memory" "none")])
21068
21069 (define_insn "*prefetch_3dnow"
21070   [(prefetch (match_operand:SI 0 "address_operand" "p")
21071              (match_operand:SI 1 "const_int_operand" "n")
21072              (const_int 3))]
21073   "TARGET_3DNOW && !TARGET_64BIT"
21074 {
21075   if (INTVAL (operands[1]) == 0)
21076     return "prefetch\t%a0";
21077   else
21078     return "prefetchw\t%a0";
21079 }
21080   [(set_attr "type" "mmx")
21081    (set_attr "memory" "none")])
21082
21083 (define_insn "*prefetch_3dnow_rex"
21084   [(prefetch (match_operand:DI 0 "address_operand" "p")
21085              (match_operand:SI 1 "const_int_operand" "n")
21086              (const_int 3))]
21087   "TARGET_3DNOW && TARGET_64BIT"
21088 {
21089   if (INTVAL (operands[1]) == 0)
21090     return "prefetch\t%a0";
21091   else
21092     return "prefetchw\t%a0";
21093 }
21094   [(set_attr "type" "mmx")
21095    (set_attr "memory" "none")])
21096
21097 (define_expand "stack_protect_set"
21098   [(match_operand 0 "memory_operand" "")
21099    (match_operand 1 "memory_operand" "")]
21100   ""
21101 {
21102 #ifdef TARGET_THREAD_SSP_OFFSET
21103   if (TARGET_64BIT)
21104     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21105                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21106   else
21107     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21108                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21109 #else
21110   if (TARGET_64BIT)
21111     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21112   else
21113     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21114 #endif
21115   DONE;
21116 })
21117
21118 (define_insn "stack_protect_set_si"
21119   [(set (match_operand:SI 0 "memory_operand" "=m")
21120         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21121    (set (match_scratch:SI 2 "=&r") (const_int 0))
21122    (clobber (reg:CC FLAGS_REG))]
21123   ""
21124   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21125   [(set_attr "type" "multi")])
21126
21127 (define_insn "stack_protect_set_di"
21128   [(set (match_operand:DI 0 "memory_operand" "=m")
21129         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21130    (set (match_scratch:DI 2 "=&r") (const_int 0))
21131    (clobber (reg:CC FLAGS_REG))]
21132   "TARGET_64BIT"
21133   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21134   [(set_attr "type" "multi")])
21135
21136 (define_insn "stack_tls_protect_set_si"
21137   [(set (match_operand:SI 0 "memory_operand" "=m")
21138         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21139    (set (match_scratch:SI 2 "=&r") (const_int 0))
21140    (clobber (reg:CC FLAGS_REG))]
21141   ""
21142   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21143   [(set_attr "type" "multi")])
21144
21145 (define_insn "stack_tls_protect_set_di"
21146   [(set (match_operand:DI 0 "memory_operand" "=m")
21147         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21148    (set (match_scratch:DI 2 "=&r") (const_int 0))
21149    (clobber (reg:CC FLAGS_REG))]
21150   "TARGET_64BIT"
21151   {
21152      /* The kernel uses a different segment register for performance reasons; a
21153         system call would not have to trash the userspace segment register,
21154         which would be expensive */
21155      if (ix86_cmodel != CM_KERNEL)
21156         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21157      else
21158         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21159   }
21160   [(set_attr "type" "multi")])
21161
21162 (define_expand "stack_protect_test"
21163   [(match_operand 0 "memory_operand" "")
21164    (match_operand 1 "memory_operand" "")
21165    (match_operand 2 "" "")]
21166   ""
21167 {
21168   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21169   ix86_compare_op0 = operands[0];
21170   ix86_compare_op1 = operands[1];
21171   ix86_compare_emitted = flags;
21172
21173 #ifdef TARGET_THREAD_SSP_OFFSET
21174   if (TARGET_64BIT)
21175     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21176                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21177   else
21178     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21179                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21180 #else
21181   if (TARGET_64BIT)
21182     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21183   else
21184     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21185 #endif
21186   emit_jump_insn (gen_beq (operands[2]));
21187   DONE;
21188 })
21189
21190 (define_insn "stack_protect_test_si"
21191   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21192         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21193                      (match_operand:SI 2 "memory_operand" "m")]
21194                     UNSPEC_SP_TEST))
21195    (clobber (match_scratch:SI 3 "=&r"))]
21196   ""
21197   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21198   [(set_attr "type" "multi")])
21199
21200 (define_insn "stack_protect_test_di"
21201   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21202         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21203                      (match_operand:DI 2 "memory_operand" "m")]
21204                     UNSPEC_SP_TEST))
21205    (clobber (match_scratch:DI 3 "=&r"))]
21206   "TARGET_64BIT"
21207   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21208   [(set_attr "type" "multi")])
21209
21210 (define_insn "stack_tls_protect_test_si"
21211   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21212         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21213                      (match_operand:SI 2 "const_int_operand" "i")]
21214                     UNSPEC_SP_TLS_TEST))
21215    (clobber (match_scratch:SI 3 "=r"))]
21216   ""
21217   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21218   [(set_attr "type" "multi")])
21219
21220 (define_insn "stack_tls_protect_test_di"
21221   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21222         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21223                      (match_operand:DI 2 "const_int_operand" "i")]
21224                     UNSPEC_SP_TLS_TEST))
21225    (clobber (match_scratch:DI 3 "=r"))]
21226   "TARGET_64BIT"
21227   {
21228      /* The kernel uses a different segment register for performance reasons; a
21229         system call would not have to trash the userspace segment register,
21230         which would be expensive */
21231      if (ix86_cmodel != CM_KERNEL)
21232         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21233      else
21234         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21235   }
21236   [(set_attr "type" "multi")])
21237
21238 (define_mode_iterator CRC32MODE [QI HI SI])
21239 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21240 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21241
21242 (define_insn "sse4_2_crc32<mode>"
21243   [(set (match_operand:SI 0 "register_operand" "=r")
21244         (unspec:SI
21245           [(match_operand:SI 1 "register_operand" "0")
21246            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21247           UNSPEC_CRC32))]
21248   "TARGET_SSE4_2"
21249   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21250   [(set_attr "type" "sselog1")
21251    (set_attr "prefix_rep" "1")
21252    (set_attr "prefix_extra" "1")
21253    (set_attr "mode" "SI")])
21254
21255 (define_insn "sse4_2_crc32di"
21256   [(set (match_operand:DI 0 "register_operand" "=r")
21257         (unspec:DI
21258           [(match_operand:DI 1 "register_operand" "0")
21259            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21260           UNSPEC_CRC32))]
21261   "TARGET_SSE4_2 && TARGET_64BIT"
21262   "crc32q\t{%2, %0|%0, %2}"
21263   [(set_attr "type" "sselog1")
21264    (set_attr "prefix_rep" "1")
21265    (set_attr "prefix_extra" "1")
21266    (set_attr "mode" "DI")])
21267
21268 (include "mmx.md")
21269 (include "sse.md")
21270 (include "sync.md")