OSDN Git Service

* config/i386/i386.md (*fp_jcc_7_387): Use 'const0_operand' instead
[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
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 2, 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 COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_FIX_NOTRUNC          31)
88    (UNSPEC_MASKMOV              32)
89    (UNSPEC_MOVMSK               33)
90    (UNSPEC_MOVNT                34)
91    (UNSPEC_MOVA                 38)
92    (UNSPEC_MOVU                 39)
93    (UNSPEC_SHUFFLE              41)
94    (UNSPEC_RCP                  42)
95    (UNSPEC_RSQRT                43)
96    (UNSPEC_SFENCE               44)
97    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
98    (UNSPEC_PAVGUSB              49)
99    (UNSPEC_PFRCP                50)
100    (UNSPEC_PFRCPIT1             51)
101    (UNSPEC_PFRCPIT2             52)
102    (UNSPEC_PFRSQRT              53)
103    (UNSPEC_PFRSQIT1             54)
104    (UNSPEC_PSHUFLW              55)
105    (UNSPEC_PSHUFHW              56)
106    (UNSPEC_MFENCE               59)
107    (UNSPEC_LFENCE               60)
108    (UNSPEC_PSADBW               61)
109    (UNSPEC_ADDSUB               71)
110    (UNSPEC_HADD                 72)
111    (UNSPEC_HSUB                 73)
112    (UNSPEC_MOVSHDUP             74)
113    (UNSPEC_MOVSLDUP             75)
114    (UNSPEC_LDQQU                76)
115    (UNSPEC_MOVDDUP              77)
116
117    ; x87 Floating point
118    (UNSPEC_FPATAN               65)
119    (UNSPEC_FYL2X                66)
120    (UNSPEC_FYL2XP1              67)
121    (UNSPEC_FRNDINT              68)
122    (UNSPEC_FIST                 69)
123    (UNSPEC_F2XM1                70)
124
125    ; x87 Double output FP
126    (UNSPEC_SINCOS_COS           80)
127    (UNSPEC_SINCOS_SIN           81)
128    (UNSPEC_TAN_ONE              82)
129    (UNSPEC_TAN_TAN              83)
130    (UNSPEC_XTRACT_FRACT         84)
131    (UNSPEC_XTRACT_EXP           85)
132    (UNSPEC_FSCALE_FRACT         86)
133    (UNSPEC_FSCALE_EXP           87)
134    (UNSPEC_FPREM_F              88)
135    (UNSPEC_FPREM_U              89)
136    (UNSPEC_FPREM1_F             90)
137    (UNSPEC_FPREM1_U             91)
138
139    ; x87 Rounding
140    (UNSPEC_FRNDINT_FLOOR        96)
141    (UNSPEC_FRNDINT_CEIL         97)
142    (UNSPEC_FRNDINT_TRUNC        98)
143    (UNSPEC_FRNDINT_MASK_PM      99)
144
145    ; REP instruction
146    (UNSPEC_REP                  75)
147
148    (UNSPEC_EH_RETURN            76)
149
150    (UNSPEC_COPYSIGN             100)
151   ])
152
153 (define_constants
154   [(UNSPECV_BLOCKAGE            0)
155    (UNSPECV_STACK_PROBE         10)
156    (UNSPECV_EMMS                31)
157    (UNSPECV_LDMXCSR             37)
158    (UNSPECV_STMXCSR             40)
159    (UNSPECV_FEMMS               46)
160    (UNSPECV_CLFLUSH             57)
161    (UNSPECV_ALIGN               68)
162    (UNSPECV_MONITOR             69)
163    (UNSPECV_MWAIT               70)
164   ])
165
166 ;; Registers by name.
167 (define_constants
168   [(BP_REG                       6)
169    (SP_REG                       7)
170    (FLAGS_REG                   17)
171    (FPSR_REG                    18)
172    (DIRFLAG_REG                 19)
173   ])
174
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
176 ;; from i386.c.
177
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first.  This allows for better optimization.  For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
182
183 \f
184 ;; Processor type.  This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187   (const (symbol_ref "ix86_tune")))
188
189 ;; A basic instruction type.  Refinements due to arguments to be
190 ;; provided in other attributes.
191 (define_attr "type"
192   "other,multi,
193    alu,alu1,negnot,imov,imovx,lea,
194    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195    icmp,test,ibr,setcc,icmov,
196    push,pop,call,callv,leave,
197    str,cld,
198    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199    sselog,sselog1,sseiadd,sseishft,sseimul,
200    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202   (const_string "other"))
203
204 ;; Main data type used by the insn
205 (define_attr "mode"
206   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207   (const_string "unknown"))
208
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212            (const_string "i387")
213          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
215            (const_string "sse")
216          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
217            (const_string "mmx")
218          (eq_attr "type" "other")
219            (const_string "unknown")]
220          (const_string "integer")))
221
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
225            (const_int 0)
226          (eq_attr "unit" "i387,sse,mmx")
227            (const_int 0)
228          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
229                           imul,icmp,push,pop")
230            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231          (eq_attr "type" "imov,test")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233          (eq_attr "type" "call")
234            (if_then_else (match_operand 0 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          (eq_attr "type" "callv")
238            (if_then_else (match_operand 1 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          ;; We don't know the size before shorten_branches.  Expect
242          ;; the instruction to fit for better scheduling.
243          (eq_attr "type" "ibr")
244            (const_int 1)
245          ]
246          (symbol_ref "/* Update immediate_length and other attributes! */
247                       abort(),1")))
248
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
252            (const_int 0)
253          (and (eq_attr "type" "call")
254               (match_operand 0 "constant_call_address_operand" ""))
255              (const_int 0)
256          (and (eq_attr "type" "callv")
257               (match_operand 1 "constant_call_address_operand" ""))
258              (const_int 0)
259          ]
260          (symbol_ref "ix86_attr_length_address_default (insn)")))
261
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264   (if_then_else (ior (eq_attr "mode" "HI")
265                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
266     (const_int 1)
267     (const_int 0)))
268
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" "" 
271   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
272     (const_int 1)
273     (const_int 0)))
274
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
277   (if_then_else 
278     (ior (eq_attr "type" "imovx,setcc,icmov")
279          (eq_attr "unit" "sse,mmx"))
280     (const_int 1)
281     (const_int 0)))
282
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285   (cond [(and (eq_attr "mode" "DI")
286               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
287            (const_int 1)
288          (and (eq_attr "mode" "QI")
289               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
290                   (const_int 0)))
291            (const_int 1)
292          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
293              (const_int 0))
294            (const_int 1)
295         ]
296         (const_int 0)))
297
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300   (cond [(eq_attr "type" "str,cld,leave")
301            (const_int 0)
302          (eq_attr "unit" "i387")
303            (const_int 0)
304          (and (eq_attr "type" "incdec")
305               (ior (match_operand:SI 1 "register_operand" "")
306                    (match_operand:HI 1 "register_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "push")
309               (not (match_operand 1 "memory_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "pop")
312               (not (match_operand 0 "memory_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "imov")
315               (and (match_operand 0 "register_operand" "")
316                    (match_operand 1 "immediate_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "call")
319               (match_operand 0 "constant_call_address_operand" ""))
320              (const_int 0)
321          (and (eq_attr "type" "callv")
322               (match_operand 1 "constant_call_address_operand" ""))
323              (const_int 0)
324          ]
325          (const_int 1)))
326
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
330 ;; other insns.
331 (define_attr "length" ""
332   (cond [(eq_attr "type" "other,multi,fistp,frndint")
333            (const_int 16)
334          (eq_attr "type" "fcmp")
335            (const_int 4)
336          (eq_attr "unit" "i387")
337            (plus (const_int 2)
338                  (plus (attr "prefix_data16")
339                        (attr "length_address")))]
340          (plus (plus (attr "modrm")
341                      (plus (attr "prefix_0f")
342                            (plus (attr "prefix_rex")
343                                  (const_int 1))))
344                (plus (attr "prefix_rep")
345                      (plus (attr "prefix_data16")
346                            (plus (attr "length_immediate")
347                                  (attr "length_address")))))))
348
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
352
353 (define_attr "memory" "none,load,store,both,unknown"
354   (cond [(eq_attr "type" "other,multi,str")
355            (const_string "unknown")
356          (eq_attr "type" "lea,fcmov,fpspc,cld")
357            (const_string "none")
358          (eq_attr "type" "fistp,leave")
359            (const_string "both")
360          (eq_attr "type" "frndint")
361            (const_string "load")
362          (eq_attr "type" "push")
363            (if_then_else (match_operand 1 "memory_operand" "")
364              (const_string "both")
365              (const_string "store"))
366          (eq_attr "type" "pop")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "both")
369              (const_string "load"))
370          (eq_attr "type" "setcc")
371            (if_then_else (match_operand 0 "memory_operand" "")
372              (const_string "store")
373              (const_string "none"))
374          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375            (if_then_else (ior (match_operand 0 "memory_operand" "")
376                               (match_operand 1 "memory_operand" ""))
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "ibr")
380            (if_then_else (match_operand 0 "memory_operand" "")
381              (const_string "load")
382              (const_string "none"))
383          (eq_attr "type" "call")
384            (if_then_else (match_operand 0 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (eq_attr "type" "callv")
388            (if_then_else (match_operand 1 "constant_call_address_operand" "")
389              (const_string "none")
390              (const_string "load"))
391          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392               (match_operand 1 "memory_operand" ""))
393            (const_string "both")
394          (and (match_operand 0 "memory_operand" "")
395               (match_operand 1 "memory_operand" ""))
396            (const_string "both")
397          (match_operand 0 "memory_operand" "")
398            (const_string "store")
399          (match_operand 1 "memory_operand" "")
400            (const_string "load")
401          (and (eq_attr "type"
402                  "!alu1,negnot,ishift1,
403                    imov,imovx,icmp,test,
404                    fmov,fcmp,fsgn,
405                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406                    mmx,mmxmov,mmxcmp,mmxcvt")
407               (match_operand 2 "memory_operand" ""))
408            (const_string "load")
409          (and (eq_attr "type" "icmov")
410               (match_operand 3 "memory_operand" ""))
411            (const_string "load")
412         ]
413         (const_string "none")))
414
415 ;; Indicates if an instruction has both an immediate and a displacement.
416
417 (define_attr "imm_disp" "false,true,unknown"
418   (cond [(eq_attr "type" "other,multi")
419            (const_string "unknown")
420          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 1 "immediate_operand" "")))
423            (const_string "true")
424          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425               (and (match_operand 0 "memory_displacement_operand" "")
426                    (match_operand 2 "immediate_operand" "")))
427            (const_string "true")
428         ]
429         (const_string "false")))
430
431 ;; Indicates if an FP operation has an integer source.
432
433 (define_attr "fp_int_src" "false,true"
434   (const_string "false"))
435
436 ;; Defines rounding mode of an FP operation.
437
438 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
439   (const_string "any"))
440
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443   [(set_attr "length" "128")
444    (set_attr "type" "multi")])
445
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
448  
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
451
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
454
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
457  
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
460
461 \f
462 ;; Scheduling descriptions
463
464 (include "pentium.md")
465 (include "ppro.md")
466 (include "k6.md")
467 (include "athlon.md")
468
469 \f
470 ;; Operand and operator predicates
471
472 (include "predicates.md")
473
474 \f
475 ;; Compare instructions.
476
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
480
481 (define_expand "cmpdi"
482   [(set (reg:CC FLAGS_REG)
483         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
484                     (match_operand:DI 1 "x86_64_general_operand" "")))]
485   ""
486 {
487   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488     operands[0] = force_reg (DImode, operands[0]);
489   ix86_compare_op0 = operands[0];
490   ix86_compare_op1 = operands[1];
491   DONE;
492 })
493
494 (define_expand "cmpsi"
495   [(set (reg:CC FLAGS_REG)
496         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
497                     (match_operand:SI 1 "general_operand" "")))]
498   ""
499 {
500   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501     operands[0] = force_reg (SImode, operands[0]);
502   ix86_compare_op0 = operands[0];
503   ix86_compare_op1 = operands[1];
504   DONE;
505 })
506
507 (define_expand "cmphi"
508   [(set (reg:CC FLAGS_REG)
509         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
510                     (match_operand:HI 1 "general_operand" "")))]
511   ""
512 {
513   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514     operands[0] = force_reg (HImode, operands[0]);
515   ix86_compare_op0 = operands[0];
516   ix86_compare_op1 = operands[1];
517   DONE;
518 })
519
520 (define_expand "cmpqi"
521   [(set (reg:CC FLAGS_REG)
522         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
523                     (match_operand:QI 1 "general_operand" "")))]
524   "TARGET_QIMODE_MATH"
525 {
526   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527     operands[0] = force_reg (QImode, operands[0]);
528   ix86_compare_op0 = operands[0];
529   ix86_compare_op1 = operands[1];
530   DONE;
531 })
532
533 (define_insn "cmpdi_ccno_1_rex64"
534   [(set (reg FLAGS_REG)
535         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
536                  (match_operand:DI 1 "const0_operand" "n,n")))]
537   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
538   "@
539    test{q}\t{%0, %0|%0, %0}
540    cmp{q}\t{%1, %0|%0, %1}"
541   [(set_attr "type" "test,icmp")
542    (set_attr "length_immediate" "0,1")
543    (set_attr "mode" "DI")])
544
545 (define_insn "*cmpdi_minus_1_rex64"
546   [(set (reg FLAGS_REG)
547         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
548                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
549                  (const_int 0)))]
550   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
551   "cmp{q}\t{%1, %0|%0, %1}"
552   [(set_attr "type" "icmp")
553    (set_attr "mode" "DI")])
554
555 (define_expand "cmpdi_1_rex64"
556   [(set (reg:CC FLAGS_REG)
557         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
558                     (match_operand:DI 1 "general_operand" "")))]
559   "TARGET_64BIT"
560   "")
561
562 (define_insn "cmpdi_1_insn_rex64"
563   [(set (reg FLAGS_REG)
564         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
565                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
566   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
567   "cmp{q}\t{%1, %0|%0, %1}"
568   [(set_attr "type" "icmp")
569    (set_attr "mode" "DI")])
570
571
572 (define_insn "*cmpsi_ccno_1"
573   [(set (reg FLAGS_REG)
574         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
575                  (match_operand:SI 1 "const0_operand" "n,n")))]
576   "ix86_match_ccmode (insn, CCNOmode)"
577   "@
578    test{l}\t{%0, %0|%0, %0}
579    cmp{l}\t{%1, %0|%0, %1}"
580   [(set_attr "type" "test,icmp")
581    (set_attr "length_immediate" "0,1")
582    (set_attr "mode" "SI")])
583
584 (define_insn "*cmpsi_minus_1"
585   [(set (reg FLAGS_REG)
586         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587                            (match_operand:SI 1 "general_operand" "ri,mr"))
588                  (const_int 0)))]
589   "ix86_match_ccmode (insn, CCGOCmode)"
590   "cmp{l}\t{%1, %0|%0, %1}"
591   [(set_attr "type" "icmp")
592    (set_attr "mode" "SI")])
593
594 (define_expand "cmpsi_1"
595   [(set (reg:CC FLAGS_REG)
596         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
597                     (match_operand:SI 1 "general_operand" "ri,mr")))]
598   ""
599   "")
600
601 (define_insn "*cmpsi_1_insn"
602   [(set (reg FLAGS_REG)
603         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
604                  (match_operand:SI 1 "general_operand" "ri,mr")))]
605   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
606     && ix86_match_ccmode (insn, CCmode)"
607   "cmp{l}\t{%1, %0|%0, %1}"
608   [(set_attr "type" "icmp")
609    (set_attr "mode" "SI")])
610
611 (define_insn "*cmphi_ccno_1"
612   [(set (reg FLAGS_REG)
613         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
614                  (match_operand:HI 1 "const0_operand" "n,n")))]
615   "ix86_match_ccmode (insn, CCNOmode)"
616   "@
617    test{w}\t{%0, %0|%0, %0}
618    cmp{w}\t{%1, %0|%0, %1}"
619   [(set_attr "type" "test,icmp")
620    (set_attr "length_immediate" "0,1")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmphi_minus_1"
624   [(set (reg FLAGS_REG)
625         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
626                            (match_operand:HI 1 "general_operand" "ri,mr"))
627                  (const_int 0)))]
628   "ix86_match_ccmode (insn, CCGOCmode)"
629   "cmp{w}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "HI")])
632
633 (define_insn "*cmphi_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
636                  (match_operand:HI 1 "general_operand" "ri,mr")))]
637   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
638    && ix86_match_ccmode (insn, CCmode)"
639   "cmp{w}\t{%1, %0|%0, %1}"
640   [(set_attr "type" "icmp")
641    (set_attr "mode" "HI")])
642
643 (define_insn "*cmpqi_ccno_1"
644   [(set (reg FLAGS_REG)
645         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
646                  (match_operand:QI 1 "const0_operand" "n,n")))]
647   "ix86_match_ccmode (insn, CCNOmode)"
648   "@
649    test{b}\t{%0, %0|%0, %0}
650    cmp{b}\t{$0, %0|%0, 0}"
651   [(set_attr "type" "test,icmp")
652    (set_attr "length_immediate" "0,1")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_1"
656   [(set (reg FLAGS_REG)
657         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
658                  (match_operand:QI 1 "general_operand" "qi,mq")))]
659   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660     && ix86_match_ccmode (insn, CCmode)"
661   "cmp{b}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "QI")])
664
665 (define_insn "*cmpqi_minus_1"
666   [(set (reg FLAGS_REG)
667         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
668                            (match_operand:QI 1 "general_operand" "qi,mq"))
669                  (const_int 0)))]
670   "ix86_match_ccmode (insn, CCGOCmode)"
671   "cmp{b}\t{%1, %0|%0, %1}"
672   [(set_attr "type" "icmp")
673    (set_attr "mode" "QI")])
674
675 (define_insn "*cmpqi_ext_1"
676   [(set (reg FLAGS_REG)
677         (compare
678           (match_operand:QI 0 "general_operand" "Qm")
679           (subreg:QI
680             (zero_extract:SI
681               (match_operand 1 "ext_register_operand" "Q")
682               (const_int 8)
683               (const_int 8)) 0)))]
684   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
685   "cmp{b}\t{%h1, %0|%0, %h1}"
686   [(set_attr "type" "icmp")
687    (set_attr "mode" "QI")])
688
689 (define_insn "*cmpqi_ext_1_rex64"
690   [(set (reg FLAGS_REG)
691         (compare
692           (match_operand:QI 0 "register_operand" "Q")
693           (subreg:QI
694             (zero_extract:SI
695               (match_operand 1 "ext_register_operand" "Q")
696               (const_int 8)
697               (const_int 8)) 0)))]
698   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
699   "cmp{b}\t{%h1, %0|%0, %h1}"
700   [(set_attr "type" "icmp")
701    (set_attr "mode" "QI")])
702
703 (define_insn "*cmpqi_ext_2"
704   [(set (reg FLAGS_REG)
705         (compare
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 0 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)
711           (match_operand:QI 1 "const0_operand" "n")))]
712   "ix86_match_ccmode (insn, CCNOmode)"
713   "test{b}\t%h0, %h0"
714   [(set_attr "type" "test")
715    (set_attr "length_immediate" "0")
716    (set_attr "mode" "QI")])
717
718 (define_expand "cmpqi_ext_3"
719   [(set (reg:CC FLAGS_REG)
720         (compare:CC
721           (subreg:QI
722             (zero_extract:SI
723               (match_operand 0 "ext_register_operand" "")
724               (const_int 8)
725               (const_int 8)) 0)
726           (match_operand:QI 1 "general_operand" "")))]
727   ""
728   "")
729
730 (define_insn "cmpqi_ext_3_insn"
731   [(set (reg FLAGS_REG)
732         (compare
733           (subreg:QI
734             (zero_extract:SI
735               (match_operand 0 "ext_register_operand" "Q")
736               (const_int 8)
737               (const_int 8)) 0)
738           (match_operand:QI 1 "general_operand" "Qmn")))]
739   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
740   "cmp{b}\t{%1, %h0|%h0, %1}"
741   [(set_attr "type" "icmp")
742    (set_attr "mode" "QI")])
743
744 (define_insn "cmpqi_ext_3_insn_rex64"
745   [(set (reg FLAGS_REG)
746         (compare
747           (subreg:QI
748             (zero_extract:SI
749               (match_operand 0 "ext_register_operand" "Q")
750               (const_int 8)
751               (const_int 8)) 0)
752           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
753   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
754   "cmp{b}\t{%1, %h0|%h0, %1}"
755   [(set_attr "type" "icmp")
756    (set_attr "mode" "QI")])
757
758 (define_insn "*cmpqi_ext_4"
759   [(set (reg FLAGS_REG)
760         (compare
761           (subreg:QI
762             (zero_extract:SI
763               (match_operand 0 "ext_register_operand" "Q")
764               (const_int 8)
765               (const_int 8)) 0)
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 1 "ext_register_operand" "Q")
769               (const_int 8)
770               (const_int 8)) 0)))]
771   "ix86_match_ccmode (insn, CCmode)"
772   "cmp{b}\t{%h1, %h0|%h0, %h1}"
773   [(set_attr "type" "icmp")
774    (set_attr "mode" "QI")])
775
776 ;; These implement float point compares.
777 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
778 ;; which would allow mix and match FP modes on the compares.  Which is what
779 ;; the old patterns did, but with many more of them.
780
781 (define_expand "cmpxf"
782   [(set (reg:CC FLAGS_REG)
783         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
784                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
785   "TARGET_80387"
786 {
787   ix86_compare_op0 = operands[0];
788   ix86_compare_op1 = operands[1];
789   DONE;
790 })
791
792 (define_expand "cmpdf"
793   [(set (reg:CC FLAGS_REG)
794         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
795                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
796   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
797 {
798   ix86_compare_op0 = operands[0];
799   ix86_compare_op1 = operands[1];
800   DONE;
801 })
802
803 (define_expand "cmpsf"
804   [(set (reg:CC FLAGS_REG)
805         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
806                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
807   "TARGET_80387 || TARGET_SSE_MATH"
808 {
809   ix86_compare_op0 = operands[0];
810   ix86_compare_op1 = operands[1];
811   DONE;
812 })
813
814 ;; FP compares, step 1:
815 ;; Set the FP condition codes.
816 ;;
817 ;; CCFPmode     compare with exceptions
818 ;; CCFPUmode    compare with no exceptions
819
820 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
821 ;; used to manage the reg stack popping would not be preserved.
822
823 (define_insn "*cmpfp_0_sf"
824   [(set (match_operand:HI 0 "register_operand" "=a")
825         (unspec:HI
826           [(compare:CCFP
827              (match_operand:SF 1 "register_operand" "f")
828              (match_operand:SF 2 "const0_operand" "X"))]
829         UNSPEC_FNSTSW))]
830   "TARGET_80387"
831   "* return output_fp_compare (insn, operands, 0, 0);"
832   [(set_attr "type" "multi")
833    (set_attr "mode" "SF")])
834
835 (define_insn "*cmpfp_0_df"
836   [(set (match_operand:HI 0 "register_operand" "=a")
837         (unspec:HI
838           [(compare:CCFP
839              (match_operand:DF 1 "register_operand" "f")
840              (match_operand:DF 2 "const0_operand" "X"))]
841         UNSPEC_FNSTSW))]
842   "TARGET_80387"
843   "* return output_fp_compare (insn, operands, 0, 0);"
844   [(set_attr "type" "multi")
845    (set_attr "mode" "DF")])
846
847 (define_insn "*cmpfp_0_xf"
848   [(set (match_operand:HI 0 "register_operand" "=a")
849         (unspec:HI
850           [(compare:CCFP
851              (match_operand:XF 1 "register_operand" "f")
852              (match_operand:XF 2 "const0_operand" "X"))]
853         UNSPEC_FNSTSW))]
854   "TARGET_80387"
855   "* return output_fp_compare (insn, operands, 0, 0);"
856   [(set_attr "type" "multi")
857    (set_attr "mode" "XF")])
858
859 (define_insn "*cmpfp_sf"
860   [(set (match_operand:HI 0 "register_operand" "=a")
861         (unspec:HI
862           [(compare:CCFP
863              (match_operand:SF 1 "register_operand" "f")
864              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
865           UNSPEC_FNSTSW))]
866   "TARGET_80387"
867   "* return output_fp_compare (insn, operands, 0, 0);"
868   [(set_attr "type" "multi")
869    (set_attr "mode" "SF")])
870
871 (define_insn "*cmpfp_df"
872   [(set (match_operand:HI 0 "register_operand" "=a")
873         (unspec:HI
874           [(compare:CCFP
875              (match_operand:DF 1 "register_operand" "f")
876              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
877           UNSPEC_FNSTSW))]
878   "TARGET_80387"
879   "* return output_fp_compare (insn, operands, 0, 0);"
880   [(set_attr "type" "multi")
881    (set_attr "mode" "DF")])
882
883 (define_insn "*cmpfp_xf"
884   [(set (match_operand:HI 0 "register_operand" "=a")
885         (unspec:HI
886           [(compare:CCFP
887              (match_operand:XF 1 "register_operand" "f")
888              (match_operand:XF 2 "register_operand" "f"))]
889           UNSPEC_FNSTSW))]
890   "TARGET_80387"
891   "* return output_fp_compare (insn, operands, 0, 0);"
892   [(set_attr "type" "multi")
893    (set_attr "mode" "XF")])
894
895 (define_insn "*cmpfp_u"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFPU
899              (match_operand 1 "register_operand" "f")
900              (match_operand 2 "register_operand" "f"))]
901           UNSPEC_FNSTSW))]
902   "TARGET_80387
903    && FLOAT_MODE_P (GET_MODE (operands[1]))
904    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
905   "* return output_fp_compare (insn, operands, 0, 1);"
906   [(set_attr "type" "multi")
907    (set (attr "mode")
908      (cond [(match_operand:SF 1 "" "")
909               (const_string "SF")
910             (match_operand:DF 1 "" "")
911               (const_string "DF")
912            ]
913            (const_string "XF")))])
914
915 (define_insn "*cmpfp_<mode>"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI
918           [(compare:CCFP
919              (match_operand 1 "register_operand" "f")
920              (match_operator 3 "float_operator"
921                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
922           UNSPEC_FNSTSW))]
923   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
924    && FLOAT_MODE_P (GET_MODE (operands[1]))
925    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
926   "* return output_fp_compare (insn, operands, 0, 0);"
927   [(set_attr "type" "multi")
928    (set_attr "fp_int_src" "true")
929    (set_attr "mode" "<MODE>")])
930
931 ;; FP compares, step 2
932 ;; Move the fpsw to ax.
933
934 (define_insn "x86_fnstsw_1"
935   [(set (match_operand:HI 0 "register_operand" "=a")
936         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
937   "TARGET_80387"
938   "fnstsw\t%0"
939   [(set_attr "length" "2")
940    (set_attr "mode" "SI")
941    (set_attr "unit" "i387")])
942
943 ;; FP compares, step 3
944 ;; Get ax into flags, general case.
945
946 (define_insn "x86_sahf_1"
947   [(set (reg:CC FLAGS_REG)
948         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
949   "!TARGET_64BIT"
950   "sahf"
951   [(set_attr "length" "1")
952    (set_attr "athlon_decode" "vector")
953    (set_attr "mode" "SI")])
954
955 ;; Pentium Pro can do steps 1 through 3 in one go.
956
957 (define_insn "*cmpfp_i_mixed"
958   [(set (reg:CCFP FLAGS_REG)
959         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
960                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
961   "TARGET_MIX_SSE_I387
962    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
963    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
964   "* return output_fp_compare (insn, operands, 1, 0);"
965   [(set_attr "type" "fcmp,ssecomi")
966    (set (attr "mode")
967      (if_then_else (match_operand:SF 1 "" "")
968         (const_string "SF")
969         (const_string "DF")))
970    (set_attr "athlon_decode" "vector")])
971
972 (define_insn "*cmpfp_i_sse"
973   [(set (reg:CCFP FLAGS_REG)
974         (compare:CCFP (match_operand 0 "register_operand" "x")
975                       (match_operand 1 "nonimmediate_operand" "xm")))]
976   "TARGET_SSE_MATH
977    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
978    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
979   "* return output_fp_compare (insn, operands, 1, 0);"
980   [(set_attr "type" "ssecomi")
981    (set (attr "mode")
982      (if_then_else (match_operand:SF 1 "" "")
983         (const_string "SF")
984         (const_string "DF")))
985    (set_attr "athlon_decode" "vector")])
986
987 (define_insn "*cmpfp_i_i387"
988   [(set (reg:CCFP FLAGS_REG)
989         (compare:CCFP (match_operand 0 "register_operand" "f")
990                       (match_operand 1 "register_operand" "f")))]
991   "TARGET_80387 && TARGET_CMOVE
992    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
993    && FLOAT_MODE_P (GET_MODE (operands[0]))
994    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
995   "* return output_fp_compare (insn, operands, 1, 0);"
996   [(set_attr "type" "fcmp")
997    (set (attr "mode")
998      (cond [(match_operand:SF 1 "" "")
999               (const_string "SF")
1000             (match_operand:DF 1 "" "")
1001               (const_string "DF")
1002            ]
1003            (const_string "XF")))
1004    (set_attr "athlon_decode" "vector")])
1005
1006 (define_insn "*cmpfp_iu_mixed"
1007   [(set (reg:CCFPU FLAGS_REG)
1008         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1009                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1010   "TARGET_MIX_SSE_I387
1011    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1012    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1013   "* return output_fp_compare (insn, operands, 1, 1);"
1014   [(set_attr "type" "fcmp,ssecomi")
1015    (set (attr "mode")
1016      (if_then_else (match_operand:SF 1 "" "")
1017         (const_string "SF")
1018         (const_string "DF")))
1019    (set_attr "athlon_decode" "vector")])
1020
1021 (define_insn "*cmpfp_iu_sse"
1022   [(set (reg:CCFPU FLAGS_REG)
1023         (compare:CCFPU (match_operand 0 "register_operand" "x")
1024                        (match_operand 1 "nonimmediate_operand" "xm")))]
1025   "TARGET_SSE_MATH
1026    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1027    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1028   "* return output_fp_compare (insn, operands, 1, 1);"
1029   [(set_attr "type" "ssecomi")
1030    (set (attr "mode")
1031      (if_then_else (match_operand:SF 1 "" "")
1032         (const_string "SF")
1033         (const_string "DF")))
1034    (set_attr "athlon_decode" "vector")])
1035
1036 (define_insn "*cmpfp_iu_387"
1037   [(set (reg:CCFPU FLAGS_REG)
1038         (compare:CCFPU (match_operand 0 "register_operand" "f")
1039                        (match_operand 1 "register_operand" "f")))]
1040   "TARGET_80387 && TARGET_CMOVE
1041    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1042    && FLOAT_MODE_P (GET_MODE (operands[0]))
1043    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1044   "* return output_fp_compare (insn, operands, 1, 1);"
1045   [(set_attr "type" "fcmp")
1046    (set (attr "mode")
1047      (cond [(match_operand:SF 1 "" "")
1048               (const_string "SF")
1049             (match_operand:DF 1 "" "")
1050               (const_string "DF")
1051            ]
1052            (const_string "XF")))
1053    (set_attr "athlon_decode" "vector")])
1054 \f
1055 ;; Move instructions.
1056
1057 ;; General case of fullword move.
1058
1059 (define_expand "movsi"
1060   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1061         (match_operand:SI 1 "general_operand" ""))]
1062   ""
1063   "ix86_expand_move (SImode, operands); DONE;")
1064
1065 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1066 ;; general_operand.
1067 ;;
1068 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1069 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1070 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1071 ;; targets without our curiosities, and it is just as easy to represent
1072 ;; this differently.
1073
1074 (define_insn "*pushsi2"
1075   [(set (match_operand:SI 0 "push_operand" "=<")
1076         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1077   "!TARGET_64BIT"
1078   "push{l}\t%1"
1079   [(set_attr "type" "push")
1080    (set_attr "mode" "SI")])
1081
1082 ;; For 64BIT abi we always round up to 8 bytes.
1083 (define_insn "*pushsi2_rex64"
1084   [(set (match_operand:SI 0 "push_operand" "=X")
1085         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1086   "TARGET_64BIT"
1087   "push{q}\t%q1"
1088   [(set_attr "type" "push")
1089    (set_attr "mode" "SI")])
1090
1091 (define_insn "*pushsi2_prologue"
1092   [(set (match_operand:SI 0 "push_operand" "=<")
1093         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1094    (clobber (mem:BLK (scratch)))]
1095   "!TARGET_64BIT"
1096   "push{l}\t%1"
1097   [(set_attr "type" "push")
1098    (set_attr "mode" "SI")])
1099
1100 (define_insn "*popsi1_epilogue"
1101   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1102         (mem:SI (reg:SI SP_REG)))
1103    (set (reg:SI SP_REG)
1104         (plus:SI (reg:SI SP_REG) (const_int 4)))
1105    (clobber (mem:BLK (scratch)))]
1106   "!TARGET_64BIT"
1107   "pop{l}\t%0"
1108   [(set_attr "type" "pop")
1109    (set_attr "mode" "SI")])
1110
1111 (define_insn "popsi1"
1112   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113         (mem:SI (reg:SI SP_REG)))
1114    (set (reg:SI SP_REG)
1115         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1116   "!TARGET_64BIT"
1117   "pop{l}\t%0"
1118   [(set_attr "type" "pop")
1119    (set_attr "mode" "SI")])
1120
1121 (define_insn "*movsi_xor"
1122   [(set (match_operand:SI 0 "register_operand" "=r")
1123         (match_operand:SI 1 "const0_operand" "i"))
1124    (clobber (reg:CC FLAGS_REG))]
1125   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1126   "xor{l}\t{%0, %0|%0, %0}"
1127   [(set_attr "type" "alu1")
1128    (set_attr "mode" "SI")
1129    (set_attr "length_immediate" "0")])
1130  
1131 (define_insn "*movsi_or"
1132   [(set (match_operand:SI 0 "register_operand" "=r")
1133         (match_operand:SI 1 "immediate_operand" "i"))
1134    (clobber (reg:CC FLAGS_REG))]
1135   "reload_completed
1136    && operands[1] == constm1_rtx
1137    && (TARGET_PENTIUM || optimize_size)"
1138 {
1139   operands[1] = constm1_rtx;
1140   return "or{l}\t{%1, %0|%0, %1}";
1141 }
1142   [(set_attr "type" "alu1")
1143    (set_attr "mode" "SI")
1144    (set_attr "length_immediate" "1")])
1145
1146 (define_insn "*movsi_1"
1147   [(set (match_operand:SI 0 "nonimmediate_operand"
1148                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1149         (match_operand:SI 1 "general_operand"
1150                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1151   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1152 {
1153   switch (get_attr_type (insn))
1154     {
1155     case TYPE_SSELOG1:
1156       if (get_attr_mode (insn) == MODE_TI)
1157         return "pxor\t%0, %0";
1158       return "xorps\t%0, %0";
1159
1160     case TYPE_SSEMOV:
1161       switch (get_attr_mode (insn))
1162         {
1163         case MODE_TI:
1164           return "movdqa\t{%1, %0|%0, %1}";
1165         case MODE_V4SF:
1166           return "movaps\t{%1, %0|%0, %1}";
1167         case MODE_SI:
1168           return "movd\t{%1, %0|%0, %1}";
1169         case MODE_SF:
1170           return "movss\t{%1, %0|%0, %1}";
1171         default:
1172           gcc_unreachable ();
1173         }
1174
1175     case TYPE_MMXADD:
1176       return "pxor\t%0, %0";
1177
1178     case TYPE_MMXMOV:
1179       if (get_attr_mode (insn) == MODE_DI)
1180         return "movq\t{%1, %0|%0, %1}";
1181       return "movd\t{%1, %0|%0, %1}";
1182
1183     case TYPE_LEA:
1184       return "lea{l}\t{%1, %0|%0, %1}";
1185
1186     default:
1187       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1188         abort();
1189       return "mov{l}\t{%1, %0|%0, %1}";
1190     }
1191 }
1192   [(set (attr "type")
1193      (cond [(eq_attr "alternative" "2")
1194               (const_string "mmx")
1195             (eq_attr "alternative" "3,4,5")
1196               (const_string "mmxmov")
1197             (eq_attr "alternative" "6")
1198               (const_string "sselog1")
1199             (eq_attr "alternative" "7,8,9,10,11")
1200               (const_string "ssemov")
1201             (and (ne (symbol_ref "flag_pic") (const_int 0))
1202                  (match_operand:SI 1 "symbolic_operand" ""))
1203               (const_string "lea")
1204            ]
1205            (const_string "imov")))
1206    (set (attr "mode")
1207      (cond [(eq_attr "alternative" "2,3")
1208               (const_string "DI")
1209             (eq_attr "alternative" "6,7")
1210               (if_then_else
1211                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1212                 (const_string "V4SF")
1213                 (const_string "TI"))
1214             (and (eq_attr "alternative" "8,9,10,11")
1215                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1216               (const_string "SF")
1217            ]
1218            (const_string "SI")))])
1219
1220 ;; Stores and loads of ax to arbitrary constant address.
1221 ;; We fake an second form of instruction to force reload to load address
1222 ;; into register when rax is not available
1223 (define_insn "*movabssi_1_rex64"
1224   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1225         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1226   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1227   "@
1228    movabs{l}\t{%1, %P0|%P0, %1}
1229    mov{l}\t{%1, %a0|%a0, %1}"
1230   [(set_attr "type" "imov")
1231    (set_attr "modrm" "0,*")
1232    (set_attr "length_address" "8,0")
1233    (set_attr "length_immediate" "0,*")
1234    (set_attr "memory" "store")
1235    (set_attr "mode" "SI")])
1236
1237 (define_insn "*movabssi_2_rex64"
1238   [(set (match_operand:SI 0 "register_operand" "=a,r")
1239         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1240   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1241   "@
1242    movabs{l}\t{%P1, %0|%0, %P1}
1243    mov{l}\t{%a1, %0|%0, %a1}"
1244   [(set_attr "type" "imov")
1245    (set_attr "modrm" "0,*")
1246    (set_attr "length_address" "8,0")
1247    (set_attr "length_immediate" "0")
1248    (set_attr "memory" "load")
1249    (set_attr "mode" "SI")])
1250
1251 (define_insn "*swapsi"
1252   [(set (match_operand:SI 0 "register_operand" "+r")
1253         (match_operand:SI 1 "register_operand" "+r"))
1254    (set (match_dup 1)
1255         (match_dup 0))]
1256   ""
1257   "xchg{l}\t%1, %0"
1258   [(set_attr "type" "imov")
1259    (set_attr "mode" "SI")
1260    (set_attr "pent_pair" "np")
1261    (set_attr "athlon_decode" "vector")])
1262
1263 (define_expand "movhi"
1264   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1265         (match_operand:HI 1 "general_operand" ""))]
1266   ""
1267   "ix86_expand_move (HImode, operands); DONE;")
1268
1269 (define_insn "*pushhi2"
1270   [(set (match_operand:HI 0 "push_operand" "=<,<")
1271         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1272   "!TARGET_64BIT"
1273   "@
1274    push{w}\t{|WORD PTR }%1
1275    push{w}\t%1"
1276   [(set_attr "type" "push")
1277    (set_attr "mode" "HI")])
1278
1279 ;; For 64BIT abi we always round up to 8 bytes.
1280 (define_insn "*pushhi2_rex64"
1281   [(set (match_operand:HI 0 "push_operand" "=X")
1282         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1283   "TARGET_64BIT"
1284   "push{q}\t%q1"
1285   [(set_attr "type" "push")
1286    (set_attr "mode" "QI")])
1287
1288 (define_insn "*movhi_1"
1289   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1290         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1291   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1292 {
1293   switch (get_attr_type (insn))
1294     {
1295     case TYPE_IMOVX:
1296       /* movzwl is faster than movw on p2 due to partial word stalls,
1297          though not as fast as an aligned movl.  */
1298       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1299     default:
1300       if (get_attr_mode (insn) == MODE_SI)
1301         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1302       else
1303         return "mov{w}\t{%1, %0|%0, %1}";
1304     }
1305 }
1306   [(set (attr "type")
1307      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1308               (const_string "imov")
1309             (and (eq_attr "alternative" "0")
1310                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1311                           (const_int 0))
1312                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1313                           (const_int 0))))
1314               (const_string "imov")
1315             (and (eq_attr "alternative" "1,2")
1316                  (match_operand:HI 1 "aligned_operand" ""))
1317               (const_string "imov")
1318             (and (ne (symbol_ref "TARGET_MOVX")
1319                      (const_int 0))
1320                  (eq_attr "alternative" "0,2"))
1321               (const_string "imovx")
1322            ]
1323            (const_string "imov")))
1324     (set (attr "mode")
1325       (cond [(eq_attr "type" "imovx")
1326                (const_string "SI")
1327              (and (eq_attr "alternative" "1,2")
1328                   (match_operand:HI 1 "aligned_operand" ""))
1329                (const_string "SI")
1330              (and (eq_attr "alternative" "0")
1331                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1332                            (const_int 0))
1333                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1334                            (const_int 0))))
1335                (const_string "SI")
1336             ]
1337             (const_string "HI")))])
1338
1339 ;; Stores and loads of ax to arbitrary constant address.
1340 ;; We fake an second form of instruction to force reload to load address
1341 ;; into register when rax is not available
1342 (define_insn "*movabshi_1_rex64"
1343   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1344         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1345   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1346   "@
1347    movabs{w}\t{%1, %P0|%P0, %1}
1348    mov{w}\t{%1, %a0|%a0, %1}"
1349   [(set_attr "type" "imov")
1350    (set_attr "modrm" "0,*")
1351    (set_attr "length_address" "8,0")
1352    (set_attr "length_immediate" "0,*")
1353    (set_attr "memory" "store")
1354    (set_attr "mode" "HI")])
1355
1356 (define_insn "*movabshi_2_rex64"
1357   [(set (match_operand:HI 0 "register_operand" "=a,r")
1358         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1359   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1360   "@
1361    movabs{w}\t{%P1, %0|%0, %P1}
1362    mov{w}\t{%a1, %0|%0, %a1}"
1363   [(set_attr "type" "imov")
1364    (set_attr "modrm" "0,*")
1365    (set_attr "length_address" "8,0")
1366    (set_attr "length_immediate" "0")
1367    (set_attr "memory" "load")
1368    (set_attr "mode" "HI")])
1369
1370 (define_insn "*swaphi_1"
1371   [(set (match_operand:HI 0 "register_operand" "+r")
1372         (match_operand:HI 1 "register_operand" "+r"))
1373    (set (match_dup 1)
1374         (match_dup 0))]
1375   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1376   "xchg{l}\t%k1, %k0"
1377   [(set_attr "type" "imov")
1378    (set_attr "mode" "SI")
1379    (set_attr "pent_pair" "np")
1380    (set_attr "athlon_decode" "vector")])
1381
1382 (define_insn "*swaphi_2"
1383   [(set (match_operand:HI 0 "register_operand" "+r")
1384         (match_operand:HI 1 "register_operand" "+r"))
1385    (set (match_dup 1)
1386         (match_dup 0))]
1387   "TARGET_PARTIAL_REG_STALL"
1388   "xchg{w}\t%1, %0"
1389   [(set_attr "type" "imov")
1390    (set_attr "mode" "HI")
1391    (set_attr "pent_pair" "np")
1392    (set_attr "athlon_decode" "vector")])
1393
1394 (define_expand "movstricthi"
1395   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1396         (match_operand:HI 1 "general_operand" ""))]
1397   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1398 {
1399   /* Don't generate memory->memory moves, go through a register */
1400   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1401     operands[1] = force_reg (HImode, operands[1]);
1402 })
1403
1404 (define_insn "*movstricthi_1"
1405   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1406         (match_operand:HI 1 "general_operand" "rn,m"))]
1407   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1408    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1409   "mov{w}\t{%1, %0|%0, %1}"
1410   [(set_attr "type" "imov")
1411    (set_attr "mode" "HI")])
1412
1413 (define_insn "*movstricthi_xor"
1414   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1415         (match_operand:HI 1 "const0_operand" "i"))
1416    (clobber (reg:CC FLAGS_REG))]
1417   "reload_completed
1418    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1419   "xor{w}\t{%0, %0|%0, %0}"
1420   [(set_attr "type" "alu1")
1421    (set_attr "mode" "HI")
1422    (set_attr "length_immediate" "0")])
1423
1424 (define_expand "movqi"
1425   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1426         (match_operand:QI 1 "general_operand" ""))]
1427   ""
1428   "ix86_expand_move (QImode, operands); DONE;")
1429
1430 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1431 ;; "push a byte".  But actually we use pushw, which has the effect
1432 ;; of rounding the amount pushed up to a halfword.
1433
1434 (define_insn "*pushqi2"
1435   [(set (match_operand:QI 0 "push_operand" "=X,X")
1436         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1437   "!TARGET_64BIT"
1438   "@
1439    push{w}\t{|word ptr }%1
1440    push{w}\t%w1"
1441   [(set_attr "type" "push")
1442    (set_attr "mode" "HI")])
1443
1444 ;; For 64BIT abi we always round up to 8 bytes.
1445 (define_insn "*pushqi2_rex64"
1446   [(set (match_operand:QI 0 "push_operand" "=X")
1447         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1448   "TARGET_64BIT"
1449   "push{q}\t%q1"
1450   [(set_attr "type" "push")
1451    (set_attr "mode" "QI")])
1452
1453 ;; Situation is quite tricky about when to choose full sized (SImode) move
1454 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1455 ;; partial register dependency machines (such as AMD Athlon), where QImode
1456 ;; moves issue extra dependency and for partial register stalls machines
1457 ;; that don't use QImode patterns (and QImode move cause stall on the next
1458 ;; instruction).
1459 ;;
1460 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1461 ;; register stall machines with, where we use QImode instructions, since
1462 ;; partial register stall can be caused there.  Then we use movzx.
1463 (define_insn "*movqi_1"
1464   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1465         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1466   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1467 {
1468   switch (get_attr_type (insn))
1469     {
1470     case TYPE_IMOVX:
1471       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1472         abort ();
1473       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1474     default:
1475       if (get_attr_mode (insn) == MODE_SI)
1476         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1477       else
1478         return "mov{b}\t{%1, %0|%0, %1}";
1479     }
1480 }
1481   [(set (attr "type")
1482      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1483               (const_string "imov")
1484             (and (eq_attr "alternative" "3")
1485                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1486                           (const_int 0))
1487                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1488                           (const_int 0))))
1489               (const_string "imov")
1490             (eq_attr "alternative" "3,5")
1491               (const_string "imovx")
1492             (and (ne (symbol_ref "TARGET_MOVX")
1493                      (const_int 0))
1494                  (eq_attr "alternative" "2"))
1495               (const_string "imovx")
1496            ]
1497            (const_string "imov")))
1498    (set (attr "mode")
1499       (cond [(eq_attr "alternative" "3,4,5")
1500                (const_string "SI")
1501              (eq_attr "alternative" "6")
1502                (const_string "QI")
1503              (eq_attr "type" "imovx")
1504                (const_string "SI")
1505              (and (eq_attr "type" "imov")
1506                   (and (eq_attr "alternative" "0,1")
1507                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1508                            (const_int 0))))
1509                (const_string "SI")
1510              ;; Avoid partial register stalls when not using QImode arithmetic
1511              (and (eq_attr "type" "imov")
1512                   (and (eq_attr "alternative" "0,1")
1513                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1514                                 (const_int 0))
1515                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1516                                 (const_int 0)))))
1517                (const_string "SI")
1518            ]
1519            (const_string "QI")))])
1520
1521 (define_expand "reload_outqi"
1522   [(parallel [(match_operand:QI 0 "" "=m")
1523               (match_operand:QI 1 "register_operand" "r")
1524               (match_operand:QI 2 "register_operand" "=&q")])]
1525   ""
1526 {
1527   rtx op0, op1, op2;
1528   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1529
1530   if (reg_overlap_mentioned_p (op2, op0))
1531     abort ();
1532   if (! q_regs_operand (op1, QImode))
1533     {
1534       emit_insn (gen_movqi (op2, op1));
1535       op1 = op2;
1536     }
1537   emit_insn (gen_movqi (op0, op1));
1538   DONE;
1539 })
1540
1541 (define_insn "*swapqi_1"
1542   [(set (match_operand:QI 0 "register_operand" "+r")
1543         (match_operand:QI 1 "register_operand" "+r"))
1544    (set (match_dup 1)
1545         (match_dup 0))]
1546   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1547   "xchg{l}\t%k1, %k0"
1548   [(set_attr "type" "imov")
1549    (set_attr "mode" "SI")
1550    (set_attr "pent_pair" "np")
1551    (set_attr "athlon_decode" "vector")])
1552
1553 (define_insn "*swapqi_2"
1554   [(set (match_operand:QI 0 "register_operand" "+q")
1555         (match_operand:QI 1 "register_operand" "+q"))
1556    (set (match_dup 1)
1557         (match_dup 0))]
1558   "TARGET_PARTIAL_REG_STALL"
1559   "xchg{b}\t%1, %0"
1560   [(set_attr "type" "imov")
1561    (set_attr "mode" "QI")
1562    (set_attr "pent_pair" "np")
1563    (set_attr "athlon_decode" "vector")])
1564
1565 (define_expand "movstrictqi"
1566   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1567         (match_operand:QI 1 "general_operand" ""))]
1568   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1569 {
1570   /* Don't generate memory->memory moves, go through a register.  */
1571   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1572     operands[1] = force_reg (QImode, operands[1]);
1573 })
1574
1575 (define_insn "*movstrictqi_1"
1576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1577         (match_operand:QI 1 "general_operand" "*qn,m"))]
1578   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1580   "mov{b}\t{%1, %0|%0, %1}"
1581   [(set_attr "type" "imov")
1582    (set_attr "mode" "QI")])
1583
1584 (define_insn "*movstrictqi_xor"
1585   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1586         (match_operand:QI 1 "const0_operand" "i"))
1587    (clobber (reg:CC FLAGS_REG))]
1588   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1589   "xor{b}\t{%0, %0|%0, %0}"
1590   [(set_attr "type" "alu1")
1591    (set_attr "mode" "QI")
1592    (set_attr "length_immediate" "0")])
1593
1594 (define_insn "*movsi_extv_1"
1595   [(set (match_operand:SI 0 "register_operand" "=R")
1596         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1597                          (const_int 8)
1598                          (const_int 8)))]
1599   ""
1600   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1601   [(set_attr "type" "imovx")
1602    (set_attr "mode" "SI")])
1603
1604 (define_insn "*movhi_extv_1"
1605   [(set (match_operand:HI 0 "register_operand" "=R")
1606         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1607                          (const_int 8)
1608                          (const_int 8)))]
1609   ""
1610   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1611   [(set_attr "type" "imovx")
1612    (set_attr "mode" "SI")])
1613
1614 (define_insn "*movqi_extv_1"
1615   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1616         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1617                          (const_int 8)
1618                          (const_int 8)))]
1619   "!TARGET_64BIT"
1620 {
1621   switch (get_attr_type (insn))
1622     {
1623     case TYPE_IMOVX:
1624       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1625     default:
1626       return "mov{b}\t{%h1, %0|%0, %h1}";
1627     }
1628 }
1629   [(set (attr "type")
1630      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1631                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1632                              (ne (symbol_ref "TARGET_MOVX")
1633                                  (const_int 0))))
1634         (const_string "imovx")
1635         (const_string "imov")))
1636    (set (attr "mode")
1637      (if_then_else (eq_attr "type" "imovx")
1638         (const_string "SI")
1639         (const_string "QI")))])
1640
1641 (define_insn "*movqi_extv_1_rex64"
1642   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1643         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1644                          (const_int 8)
1645                          (const_int 8)))]
1646   "TARGET_64BIT"
1647 {
1648   switch (get_attr_type (insn))
1649     {
1650     case TYPE_IMOVX:
1651       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652     default:
1653       return "mov{b}\t{%h1, %0|%0, %h1}";
1654     }
1655 }
1656   [(set (attr "type")
1657      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1658                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1659                              (ne (symbol_ref "TARGET_MOVX")
1660                                  (const_int 0))))
1661         (const_string "imovx")
1662         (const_string "imov")))
1663    (set (attr "mode")
1664      (if_then_else (eq_attr "type" "imovx")
1665         (const_string "SI")
1666         (const_string "QI")))])
1667
1668 ;; Stores and loads of ax to arbitrary constant address.
1669 ;; We fake an second form of instruction to force reload to load address
1670 ;; into register when rax is not available
1671 (define_insn "*movabsqi_1_rex64"
1672   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1673         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1675   "@
1676    movabs{b}\t{%1, %P0|%P0, %1}
1677    mov{b}\t{%1, %a0|%a0, %1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0,*")
1682    (set_attr "memory" "store")
1683    (set_attr "mode" "QI")])
1684
1685 (define_insn "*movabsqi_2_rex64"
1686   [(set (match_operand:QI 0 "register_operand" "=a,r")
1687         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1688   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1689   "@
1690    movabs{b}\t{%P1, %0|%0, %P1}
1691    mov{b}\t{%a1, %0|%0, %a1}"
1692   [(set_attr "type" "imov")
1693    (set_attr "modrm" "0,*")
1694    (set_attr "length_address" "8,0")
1695    (set_attr "length_immediate" "0")
1696    (set_attr "memory" "load")
1697    (set_attr "mode" "QI")])
1698
1699 (define_insn "*movsi_extzv_1"
1700   [(set (match_operand:SI 0 "register_operand" "=R")
1701         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1702                          (const_int 8)
1703                          (const_int 8)))]
1704   ""
1705   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1706   [(set_attr "type" "imovx")
1707    (set_attr "mode" "SI")])
1708
1709 (define_insn "*movqi_extzv_2"
1710   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1711         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1712                                     (const_int 8)
1713                                     (const_int 8)) 0))]
1714   "!TARGET_64BIT"
1715 {
1716   switch (get_attr_type (insn))
1717     {
1718     case TYPE_IMOVX:
1719       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1720     default:
1721       return "mov{b}\t{%h1, %0|%0, %h1}";
1722     }
1723 }
1724   [(set (attr "type")
1725      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1726                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1727                              (ne (symbol_ref "TARGET_MOVX")
1728                                  (const_int 0))))
1729         (const_string "imovx")
1730         (const_string "imov")))
1731    (set (attr "mode")
1732      (if_then_else (eq_attr "type" "imovx")
1733         (const_string "SI")
1734         (const_string "QI")))])
1735
1736 (define_insn "*movqi_extzv_2_rex64"
1737   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1738         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1739                                     (const_int 8)
1740                                     (const_int 8)) 0))]
1741   "TARGET_64BIT"
1742 {
1743   switch (get_attr_type (insn))
1744     {
1745     case TYPE_IMOVX:
1746       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1747     default:
1748       return "mov{b}\t{%h1, %0|%0, %h1}";
1749     }
1750 }
1751   [(set (attr "type")
1752      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1753                         (ne (symbol_ref "TARGET_MOVX")
1754                             (const_int 0)))
1755         (const_string "imovx")
1756         (const_string "imov")))
1757    (set (attr "mode")
1758      (if_then_else (eq_attr "type" "imovx")
1759         (const_string "SI")
1760         (const_string "QI")))])
1761
1762 (define_insn "movsi_insv_1"
1763   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1764                          (const_int 8)
1765                          (const_int 8))
1766         (match_operand:SI 1 "general_operand" "Qmn"))]
1767   "!TARGET_64BIT"
1768   "mov{b}\t{%b1, %h0|%h0, %b1}"
1769   [(set_attr "type" "imov")
1770    (set_attr "mode" "QI")])
1771
1772 (define_insn "movdi_insv_1_rex64"
1773   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1774                          (const_int 8)
1775                          (const_int 8))
1776         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1777   "TARGET_64BIT"
1778   "mov{b}\t{%b1, %h0|%h0, %b1}"
1779   [(set_attr "type" "imov")
1780    (set_attr "mode" "QI")])
1781
1782 (define_insn "*movqi_insv_2"
1783   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784                          (const_int 8)
1785                          (const_int 8))
1786         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1787                      (const_int 8)))]
1788   ""
1789   "mov{b}\t{%h1, %h0|%h0, %h1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1792
1793 (define_expand "movdi"
1794   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1795         (match_operand:DI 1 "general_operand" ""))]
1796   ""
1797   "ix86_expand_move (DImode, operands); DONE;")
1798
1799 (define_insn "*pushdi"
1800   [(set (match_operand:DI 0 "push_operand" "=<")
1801         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1802   "!TARGET_64BIT"
1803   "#")
1804
1805 (define_insn "*pushdi2_rex64"
1806   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1807         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1808   "TARGET_64BIT"
1809   "@
1810    push{q}\t%1
1811    #"
1812   [(set_attr "type" "push,multi")
1813    (set_attr "mode" "DI")])
1814
1815 ;; Convert impossible pushes of immediate to existing instructions.
1816 ;; First try to get scratch register and go through it.  In case this
1817 ;; fails, push sign extended lower part first and then overwrite
1818 ;; upper part by 32bit move.
1819 (define_peephole2
1820   [(match_scratch:DI 2 "r")
1821    (set (match_operand:DI 0 "push_operand" "")
1822         (match_operand:DI 1 "immediate_operand" ""))]
1823   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1824    && !x86_64_immediate_operand (operands[1], DImode)"
1825   [(set (match_dup 2) (match_dup 1))
1826    (set (match_dup 0) (match_dup 2))]
1827   "")
1828
1829 ;; We need to define this as both peepholer and splitter for case
1830 ;; peephole2 pass is not run.
1831 ;; "&& 1" is needed to keep it from matching the previous pattern.
1832 (define_peephole2
1833   [(set (match_operand:DI 0 "push_operand" "")
1834         (match_operand:DI 1 "immediate_operand" ""))]
1835   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1837   [(set (match_dup 0) (match_dup 1))
1838    (set (match_dup 2) (match_dup 3))]
1839   "split_di (operands + 1, 1, operands + 2, operands + 3);
1840    operands[1] = gen_lowpart (DImode, operands[2]);
1841    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842                                                     GEN_INT (4)));
1843   ")
1844
1845 (define_split
1846   [(set (match_operand:DI 0 "push_operand" "")
1847         (match_operand:DI 1 "immediate_operand" ""))]
1848   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1849    && !symbolic_operand (operands[1], DImode)
1850    && !x86_64_immediate_operand (operands[1], DImode)"
1851   [(set (match_dup 0) (match_dup 1))
1852    (set (match_dup 2) (match_dup 3))]
1853   "split_di (operands + 1, 1, operands + 2, operands + 3);
1854    operands[1] = gen_lowpart (DImode, operands[2]);
1855    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1856                                                     GEN_INT (4)));
1857   ")
1858
1859 (define_insn "*pushdi2_prologue_rex64"
1860   [(set (match_operand:DI 0 "push_operand" "=<")
1861         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1862    (clobber (mem:BLK (scratch)))]
1863   "TARGET_64BIT"
1864   "push{q}\t%1"
1865   [(set_attr "type" "push")
1866    (set_attr "mode" "DI")])
1867
1868 (define_insn "*popdi1_epilogue_rex64"
1869   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1870         (mem:DI (reg:DI SP_REG)))
1871    (set (reg:DI SP_REG)
1872         (plus:DI (reg:DI SP_REG) (const_int 8)))
1873    (clobber (mem:BLK (scratch)))]
1874   "TARGET_64BIT"
1875   "pop{q}\t%0"
1876   [(set_attr "type" "pop")
1877    (set_attr "mode" "DI")])
1878
1879 (define_insn "popdi1"
1880   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1881         (mem:DI (reg:DI SP_REG)))
1882    (set (reg:DI SP_REG)
1883         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1884   "TARGET_64BIT"
1885   "pop{q}\t%0"
1886   [(set_attr "type" "pop")
1887    (set_attr "mode" "DI")])
1888
1889 (define_insn "*movdi_xor_rex64"
1890   [(set (match_operand:DI 0 "register_operand" "=r")
1891         (match_operand:DI 1 "const0_operand" "i"))
1892    (clobber (reg:CC FLAGS_REG))]
1893   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1894    && reload_completed"
1895   "xor{l}\t{%k0, %k0|%k0, %k0}"
1896   [(set_attr "type" "alu1")
1897    (set_attr "mode" "SI")
1898    (set_attr "length_immediate" "0")])
1899
1900 (define_insn "*movdi_or_rex64"
1901   [(set (match_operand:DI 0 "register_operand" "=r")
1902         (match_operand:DI 1 "const_int_operand" "i"))
1903    (clobber (reg:CC FLAGS_REG))]
1904   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1905    && reload_completed
1906    && operands[1] == constm1_rtx"
1907 {
1908   operands[1] = constm1_rtx;
1909   return "or{q}\t{%1, %0|%0, %1}";
1910 }
1911   [(set_attr "type" "alu1")
1912    (set_attr "mode" "DI")
1913    (set_attr "length_immediate" "1")])
1914
1915 (define_insn "*movdi_2"
1916   [(set (match_operand:DI 0 "nonimmediate_operand"
1917                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1918         (match_operand:DI 1 "general_operand"
1919                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1920   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1921   "@
1922    #
1923    #
1924    pxor\t%0, %0
1925    movq\t{%1, %0|%0, %1}
1926    movq\t{%1, %0|%0, %1}
1927    pxor\t%0, %0
1928    movq\t{%1, %0|%0, %1}
1929    movdqa\t{%1, %0|%0, %1}
1930    movq\t{%1, %0|%0, %1}
1931    xorps\t%0, %0
1932    movlps\t{%1, %0|%0, %1}
1933    movaps\t{%1, %0|%0, %1}
1934    movlps\t{%1, %0|%0, %1}"
1935   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1936    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1937
1938 (define_split
1939   [(set (match_operand:DI 0 "push_operand" "")
1940         (match_operand:DI 1 "general_operand" ""))]
1941   "!TARGET_64BIT && reload_completed
1942    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1943   [(const_int 0)]
1944   "ix86_split_long_move (operands); DONE;")
1945
1946 ;; %%% This multiword shite has got to go.
1947 (define_split
1948   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1949         (match_operand:DI 1 "general_operand" ""))]
1950   "!TARGET_64BIT && reload_completed
1951    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1952    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1953   [(const_int 0)]
1954   "ix86_split_long_move (operands); DONE;")
1955
1956 (define_insn "*movdi_1_rex64"
1957   [(set (match_operand:DI 0 "nonimmediate_operand"
1958                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1959         (match_operand:DI 1 "general_operand"
1960                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1961   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1962 {
1963   switch (get_attr_type (insn))
1964     {
1965     case TYPE_SSECVT:
1966       if (which_alternative == 13)
1967         return "movq2dq\t{%1, %0|%0, %1}";
1968       else
1969         return "movdq2q\t{%1, %0|%0, %1}";
1970     case TYPE_SSEMOV:
1971       if (get_attr_mode (insn) == MODE_TI)
1972           return "movdqa\t{%1, %0|%0, %1}";
1973       /* FALLTHRU */
1974     case TYPE_MMXMOV:
1975       /* Moves from and into integer register is done using movd opcode with
1976          REX prefix.  */
1977       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1978           return "movd\t{%1, %0|%0, %1}";
1979       return "movq\t{%1, %0|%0, %1}";
1980     case TYPE_SSELOG1:
1981     case TYPE_MMXADD:
1982       return "pxor\t%0, %0";
1983     case TYPE_MULTI:
1984       return "#";
1985     case TYPE_LEA:
1986       return "lea{q}\t{%a1, %0|%0, %a1}";
1987     default:
1988       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1989         abort ();
1990       if (get_attr_mode (insn) == MODE_SI)
1991         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1992       else if (which_alternative == 2)
1993         return "movabs{q}\t{%1, %0|%0, %1}";
1994       else
1995         return "mov{q}\t{%1, %0|%0, %1}";
1996     }
1997 }
1998   [(set (attr "type")
1999      (cond [(eq_attr "alternative" "5")
2000               (const_string "mmx")
2001             (eq_attr "alternative" "6,7,8")
2002               (const_string "mmxmov")
2003             (eq_attr "alternative" "9")
2004               (const_string "sselog1")
2005             (eq_attr "alternative" "10,11,12")
2006               (const_string "ssemov")
2007             (eq_attr "alternative" "13,14")
2008               (const_string "ssecvt")
2009             (eq_attr "alternative" "4")
2010               (const_string "multi")
2011             (and (ne (symbol_ref "flag_pic") (const_int 0))
2012                  (match_operand:DI 1 "symbolic_operand" ""))
2013               (const_string "lea")
2014            ]
2015            (const_string "imov")))
2016    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2017    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2018    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2019
2020 ;; Stores and loads of ax to arbitrary constant address.
2021 ;; We fake an second form of instruction to force reload to load address
2022 ;; into register when rax is not available
2023 (define_insn "*movabsdi_1_rex64"
2024   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2025         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2026   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2027   "@
2028    movabs{q}\t{%1, %P0|%P0, %1}
2029    mov{q}\t{%1, %a0|%a0, %1}"
2030   [(set_attr "type" "imov")
2031    (set_attr "modrm" "0,*")
2032    (set_attr "length_address" "8,0")
2033    (set_attr "length_immediate" "0,*")
2034    (set_attr "memory" "store")
2035    (set_attr "mode" "DI")])
2036
2037 (define_insn "*movabsdi_2_rex64"
2038   [(set (match_operand:DI 0 "register_operand" "=a,r")
2039         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2040   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2041   "@
2042    movabs{q}\t{%P1, %0|%0, %P1}
2043    mov{q}\t{%a1, %0|%0, %a1}"
2044   [(set_attr "type" "imov")
2045    (set_attr "modrm" "0,*")
2046    (set_attr "length_address" "8,0")
2047    (set_attr "length_immediate" "0")
2048    (set_attr "memory" "load")
2049    (set_attr "mode" "DI")])
2050
2051 ;; Convert impossible stores of immediate to existing instructions.
2052 ;; First try to get scratch register and go through it.  In case this
2053 ;; fails, move by 32bit parts.
2054 (define_peephole2
2055   [(match_scratch:DI 2 "r")
2056    (set (match_operand:DI 0 "memory_operand" "")
2057         (match_operand:DI 1 "immediate_operand" ""))]
2058   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2059    && !x86_64_immediate_operand (operands[1], DImode)"
2060   [(set (match_dup 2) (match_dup 1))
2061    (set (match_dup 0) (match_dup 2))]
2062   "")
2063
2064 ;; We need to define this as both peepholer and splitter for case
2065 ;; peephole2 pass is not run.
2066 ;; "&& 1" is needed to keep it from matching the previous pattern.
2067 (define_peephole2
2068   [(set (match_operand:DI 0 "memory_operand" "")
2069         (match_operand:DI 1 "immediate_operand" ""))]
2070   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2072   [(set (match_dup 2) (match_dup 3))
2073    (set (match_dup 4) (match_dup 5))]
2074   "split_di (operands, 2, operands + 2, operands + 4);")
2075
2076 (define_split
2077   [(set (match_operand:DI 0 "memory_operand" "")
2078         (match_operand:DI 1 "immediate_operand" ""))]
2079   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2080    && !symbolic_operand (operands[1], DImode)
2081    && !x86_64_immediate_operand (operands[1], DImode)"
2082   [(set (match_dup 2) (match_dup 3))
2083    (set (match_dup 4) (match_dup 5))]
2084   "split_di (operands, 2, operands + 2, operands + 4);")
2085
2086 (define_insn "*swapdi_rex64"
2087   [(set (match_operand:DI 0 "register_operand" "+r")
2088         (match_operand:DI 1 "register_operand" "+r"))
2089    (set (match_dup 1)
2090         (match_dup 0))]
2091   "TARGET_64BIT"
2092   "xchg{q}\t%1, %0"
2093   [(set_attr "type" "imov")
2094    (set_attr "mode" "DI")
2095    (set_attr "pent_pair" "np")
2096    (set_attr "athlon_decode" "vector")])
2097
2098 (define_expand "movti"
2099   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2100         (match_operand:TI 1 "nonimmediate_operand" ""))]
2101   "TARGET_SSE || TARGET_64BIT"
2102 {
2103   if (TARGET_64BIT)
2104     ix86_expand_move (TImode, operands);
2105   else
2106     ix86_expand_vector_move (TImode, operands);
2107   DONE;
2108 })
2109
2110 (define_insn "*movti_internal"
2111   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2112         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2113   "TARGET_SSE && !TARGET_64BIT
2114    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2115 {
2116   switch (which_alternative)
2117     {
2118     case 0:
2119       if (get_attr_mode (insn) == MODE_V4SF)
2120         return "xorps\t%0, %0";
2121       else
2122         return "pxor\t%0, %0";
2123     case 1:
2124     case 2:
2125       if (get_attr_mode (insn) == MODE_V4SF)
2126         return "movaps\t{%1, %0|%0, %1}";
2127       else
2128         return "movdqa\t{%1, %0|%0, %1}";
2129     default:
2130       abort ();
2131     }
2132 }
2133   [(set_attr "type" "ssemov,ssemov,ssemov")
2134    (set (attr "mode")
2135         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2136                  (const_string "V4SF")
2137
2138                (eq_attr "alternative" "0,1")
2139                  (if_then_else
2140                    (ne (symbol_ref "optimize_size")
2141                        (const_int 0))
2142                    (const_string "V4SF")
2143                    (const_string "TI"))
2144                (eq_attr "alternative" "2")
2145                  (if_then_else
2146                    (ne (symbol_ref "optimize_size")
2147                        (const_int 0))
2148                    (const_string "V4SF")
2149                    (const_string "TI"))]
2150                (const_string "TI")))])
2151
2152 (define_insn "*movti_rex64"
2153   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2154         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2155   "TARGET_64BIT
2156    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2157 {
2158   switch (which_alternative)
2159     {
2160     case 0:
2161     case 1:
2162       return "#";
2163     case 2:
2164       if (get_attr_mode (insn) == MODE_V4SF)
2165         return "xorps\t%0, %0";
2166       else
2167         return "pxor\t%0, %0";
2168     case 3:
2169     case 4:
2170       if (get_attr_mode (insn) == MODE_V4SF)
2171         return "movaps\t{%1, %0|%0, %1}";
2172       else
2173         return "movdqa\t{%1, %0|%0, %1}";
2174     default:
2175       abort ();
2176     }
2177 }
2178   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2179    (set (attr "mode")
2180         (cond [(eq_attr "alternative" "2,3")
2181                  (if_then_else
2182                    (ne (symbol_ref "optimize_size")
2183                        (const_int 0))
2184                    (const_string "V4SF")
2185                    (const_string "TI"))
2186                (eq_attr "alternative" "4")
2187                  (if_then_else
2188                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2189                             (const_int 0))
2190                         (ne (symbol_ref "optimize_size")
2191                             (const_int 0)))
2192                    (const_string "V4SF")
2193                    (const_string "TI"))]
2194                (const_string "DI")))])
2195
2196 (define_split
2197   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2198         (match_operand:TI 1 "general_operand" ""))]
2199   "reload_completed && !SSE_REG_P (operands[0])
2200    && !SSE_REG_P (operands[1])"
2201   [(const_int 0)]
2202   "ix86_split_long_move (operands); DONE;")
2203
2204 (define_expand "movsf"
2205   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2206         (match_operand:SF 1 "general_operand" ""))]
2207   ""
2208   "ix86_expand_move (SFmode, operands); DONE;")
2209
2210 (define_insn "*pushsf"
2211   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2212         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2213   "!TARGET_64BIT"
2214 {
2215   switch (which_alternative)
2216     {
2217     case 1:
2218       return "push{l}\t%1";
2219
2220     default:
2221       /* This insn should be already split before reg-stack.  */
2222       abort ();
2223     }
2224 }
2225   [(set_attr "type" "multi,push,multi")
2226    (set_attr "mode" "SF,SI,SF")])
2227
2228 (define_insn "*pushsf_rex64"
2229   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2230         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2231   "TARGET_64BIT"
2232 {
2233   switch (which_alternative)
2234     {
2235     case 1:
2236       return "push{q}\t%q1";
2237
2238     default:
2239       /* This insn should be already split before reg-stack.  */
2240       abort ();
2241     }
2242 }
2243   [(set_attr "type" "multi,push,multi")
2244    (set_attr "mode" "SF,DI,SF")])
2245
2246 (define_split
2247   [(set (match_operand:SF 0 "push_operand" "")
2248         (match_operand:SF 1 "memory_operand" ""))]
2249   "reload_completed
2250    && GET_CODE (operands[1]) == MEM
2251    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2252    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2253   [(set (match_dup 0)
2254         (match_dup 1))]
2255   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2256
2257
2258 ;; %%% Kill this when call knows how to work this out.
2259 (define_split
2260   [(set (match_operand:SF 0 "push_operand" "")
2261         (match_operand:SF 1 "any_fp_register_operand" ""))]
2262   "!TARGET_64BIT"
2263   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2264    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2265
2266 (define_split
2267   [(set (match_operand:SF 0 "push_operand" "")
2268         (match_operand:SF 1 "any_fp_register_operand" ""))]
2269   "TARGET_64BIT"
2270   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2271    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2272
2273 (define_insn "*movsf_1"
2274   [(set (match_operand:SF 0 "nonimmediate_operand"
2275           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2276         (match_operand:SF 1 "general_operand"
2277           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2278   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2279    && (reload_in_progress || reload_completed
2280        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2281        || GET_CODE (operands[1]) != CONST_DOUBLE
2282        || memory_operand (operands[0], SFmode))" 
2283 {
2284   switch (which_alternative)
2285     {
2286     case 0:
2287       return output_387_reg_move (insn, operands);
2288
2289     case 1:
2290       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2291         return "fstp%z0\t%y0";
2292       else
2293         return "fst%z0\t%y0";
2294
2295     case 2:
2296       return standard_80387_constant_opcode (operands[1]);
2297
2298     case 3:
2299     case 4:
2300       return "mov{l}\t{%1, %0|%0, %1}";
2301     case 5:
2302       if (get_attr_mode (insn) == MODE_TI)
2303         return "pxor\t%0, %0";
2304       else
2305         return "xorps\t%0, %0";
2306     case 6:
2307       if (get_attr_mode (insn) == MODE_V4SF)
2308         return "movaps\t{%1, %0|%0, %1}";
2309       else
2310         return "movss\t{%1, %0|%0, %1}";
2311     case 7:
2312     case 8:
2313       return "movss\t{%1, %0|%0, %1}";
2314
2315     case 9:
2316     case 10:
2317       return "movd\t{%1, %0|%0, %1}";
2318
2319     case 11:
2320       return "movq\t{%1, %0|%0, %1}";
2321
2322     default:
2323       abort();
2324     }
2325 }
2326   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2327    (set (attr "mode")
2328         (cond [(eq_attr "alternative" "3,4,9,10")
2329                  (const_string "SI")
2330                (eq_attr "alternative" "5")
2331                  (if_then_else
2332                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2333                                  (const_int 0))
2334                              (ne (symbol_ref "TARGET_SSE2")
2335                                  (const_int 0)))
2336                         (eq (symbol_ref "optimize_size")
2337                             (const_int 0)))
2338                    (const_string "TI")
2339                    (const_string "V4SF"))
2340                /* For architectures resolving dependencies on
2341                   whole SSE registers use APS move to break dependency
2342                   chains, otherwise use short move to avoid extra work. 
2343
2344                   Do the same for architectures resolving dependencies on
2345                   the parts.  While in DF mode it is better to always handle
2346                   just register parts, the SF mode is different due to lack
2347                   of instructions to load just part of the register.  It is
2348                   better to maintain the whole registers in single format
2349                   to avoid problems on using packed logical operations.  */
2350                (eq_attr "alternative" "6")
2351                  (if_then_else
2352                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2353                             (const_int 0))
2354                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2355                             (const_int 0)))
2356                    (const_string "V4SF")
2357                    (const_string "SF"))
2358                (eq_attr "alternative" "11")
2359                  (const_string "DI")]
2360                (const_string "SF")))])
2361
2362 (define_insn "*swapsf"
2363   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2364         (match_operand:SF 1 "fp_register_operand" "+f"))
2365    (set (match_dup 1)
2366         (match_dup 0))]
2367   "reload_completed || TARGET_80387"
2368 {
2369   if (STACK_TOP_P (operands[0]))
2370     return "fxch\t%1";
2371   else
2372     return "fxch\t%0";
2373 }
2374   [(set_attr "type" "fxch")
2375    (set_attr "mode" "SF")])
2376
2377 (define_expand "movdf"
2378   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2379         (match_operand:DF 1 "general_operand" ""))]
2380   ""
2381   "ix86_expand_move (DFmode, operands); DONE;")
2382
2383 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2384 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2385 ;; On the average, pushdf using integers can be still shorter.  Allow this
2386 ;; pattern for optimize_size too.
2387
2388 (define_insn "*pushdf_nointeger"
2389   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2390         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2391   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2392 {
2393   /* This insn should be already split before reg-stack.  */
2394   abort ();
2395 }
2396   [(set_attr "type" "multi")
2397    (set_attr "mode" "DF,SI,SI,DF")])
2398
2399 (define_insn "*pushdf_integer"
2400   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2401         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2402   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2403 {
2404   /* This insn should be already split before reg-stack.  */
2405   abort ();
2406 }
2407   [(set_attr "type" "multi")
2408    (set_attr "mode" "DF,SI,DF")])
2409
2410 ;; %%% Kill this when call knows how to work this out.
2411 (define_split
2412   [(set (match_operand:DF 0 "push_operand" "")
2413         (match_operand:DF 1 "any_fp_register_operand" ""))]
2414   "!TARGET_64BIT && reload_completed"
2415   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2416    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2417   "")
2418
2419 (define_split
2420   [(set (match_operand:DF 0 "push_operand" "")
2421         (match_operand:DF 1 "any_fp_register_operand" ""))]
2422   "TARGET_64BIT && reload_completed"
2423   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2424    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2425   "")
2426
2427 (define_split
2428   [(set (match_operand:DF 0 "push_operand" "")
2429         (match_operand:DF 1 "general_operand" ""))]
2430   "reload_completed"
2431   [(const_int 0)]
2432   "ix86_split_long_move (operands); DONE;")
2433
2434 ;; Moving is usually shorter when only FP registers are used. This separate
2435 ;; movdf pattern avoids the use of integer registers for FP operations
2436 ;; when optimizing for size.
2437
2438 (define_insn "*movdf_nointeger"
2439   [(set (match_operand:DF 0 "nonimmediate_operand"
2440                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2441         (match_operand:DF 1 "general_operand"
2442                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2443   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2444    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2445    && (reload_in_progress || reload_completed
2446        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2447        || GET_CODE (operands[1]) != CONST_DOUBLE
2448        || memory_operand (operands[0], DFmode))" 
2449 {
2450   switch (which_alternative)
2451     {
2452     case 0:
2453       return output_387_reg_move (insn, operands);
2454
2455     case 1:
2456       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2457         return "fstp%z0\t%y0";
2458       else
2459         return "fst%z0\t%y0";
2460
2461     case 2:
2462       return standard_80387_constant_opcode (operands[1]);
2463
2464     case 3:
2465     case 4:
2466       return "#";
2467     case 5:
2468       switch (get_attr_mode (insn))
2469         {
2470         case MODE_V4SF:
2471           return "xorps\t%0, %0";
2472         case MODE_V2DF:
2473           return "xorpd\t%0, %0";
2474         case MODE_TI:
2475           return "pxor\t%0, %0";
2476         default:
2477           abort ();
2478         }
2479     case 6:
2480     case 7:
2481     case 8:
2482       switch (get_attr_mode (insn))
2483         {
2484         case MODE_V4SF:
2485           return "movaps\t{%1, %0|%0, %1}";
2486         case MODE_V2DF:
2487           return "movapd\t{%1, %0|%0, %1}";
2488         case MODE_TI:
2489           return "movdqa\t{%1, %0|%0, %1}";
2490         case MODE_DI:
2491           return "movq\t{%1, %0|%0, %1}";
2492         case MODE_DF:
2493           return "movsd\t{%1, %0|%0, %1}";
2494         case MODE_V1DF:
2495           return "movlpd\t{%1, %0|%0, %1}";
2496         case MODE_V2SF:
2497           return "movlps\t{%1, %0|%0, %1}";
2498         default:
2499           abort ();
2500         }
2501
2502     default:
2503       abort();
2504     }
2505 }
2506   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2507    (set (attr "mode")
2508         (cond [(eq_attr "alternative" "0,1,2")
2509                  (const_string "DF")
2510                (eq_attr "alternative" "3,4")
2511                  (const_string "SI")
2512
2513                /* For SSE1, we have many fewer alternatives.  */
2514                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2515                  (cond [(eq_attr "alternative" "5,6")
2516                           (const_string "V4SF")
2517                        ]
2518                    (const_string "V2SF"))
2519
2520                /* xorps is one byte shorter.  */
2521                (eq_attr "alternative" "5")
2522                  (cond [(ne (symbol_ref "optimize_size")
2523                             (const_int 0))
2524                           (const_string "V4SF")
2525                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2526                             (const_int 0))
2527                           (const_string "TI")
2528                        ]
2529                        (const_string "V2DF"))
2530
2531                /* For architectures resolving dependencies on
2532                   whole SSE registers use APD move to break dependency
2533                   chains, otherwise use short move to avoid extra work.
2534
2535                   movaps encodes one byte shorter.  */
2536                (eq_attr "alternative" "6")
2537                  (cond
2538                    [(ne (symbol_ref "optimize_size")
2539                         (const_int 0))
2540                       (const_string "V4SF")
2541                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2542                         (const_int 0))
2543                       (const_string "V2DF")
2544                    ]
2545                    (const_string "DF"))
2546                /* For architectures resolving dependencies on register
2547                   parts we may avoid extra work to zero out upper part
2548                   of register.  */
2549                (eq_attr "alternative" "7")
2550                  (if_then_else
2551                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2552                        (const_int 0))
2553                    (const_string "V1DF")
2554                    (const_string "DF"))
2555               ]
2556               (const_string "DF")))])
2557
2558 (define_insn "*movdf_integer"
2559   [(set (match_operand:DF 0 "nonimmediate_operand"
2560                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2561         (match_operand:DF 1 "general_operand"
2562                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2563   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2564    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2565    && (reload_in_progress || reload_completed
2566        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2567        || GET_CODE (operands[1]) != CONST_DOUBLE
2568        || memory_operand (operands[0], DFmode))" 
2569 {
2570   switch (which_alternative)
2571     {
2572     case 0:
2573       return output_387_reg_move (insn, operands);
2574
2575     case 1:
2576       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2577         return "fstp%z0\t%y0";
2578       else
2579         return "fst%z0\t%y0";
2580
2581     case 2:
2582       return standard_80387_constant_opcode (operands[1]);
2583
2584     case 3:
2585     case 4:
2586       return "#";
2587
2588     case 5:
2589       switch (get_attr_mode (insn))
2590         {
2591         case MODE_V4SF:
2592           return "xorps\t%0, %0";
2593         case MODE_V2DF:
2594           return "xorpd\t%0, %0";
2595         case MODE_TI:
2596           return "pxor\t%0, %0";
2597         default:
2598           abort ();
2599         }
2600     case 6:
2601     case 7:
2602     case 8:
2603       switch (get_attr_mode (insn))
2604         {
2605         case MODE_V4SF:
2606           return "movaps\t{%1, %0|%0, %1}";
2607         case MODE_V2DF:
2608           return "movapd\t{%1, %0|%0, %1}";
2609         case MODE_TI:
2610           return "movdqa\t{%1, %0|%0, %1}";
2611         case MODE_DI:
2612           return "movq\t{%1, %0|%0, %1}";
2613         case MODE_DF:
2614           return "movsd\t{%1, %0|%0, %1}";
2615         case MODE_V1DF:
2616           return "movlpd\t{%1, %0|%0, %1}";
2617         case MODE_V2SF:
2618           return "movlps\t{%1, %0|%0, %1}";
2619         default:
2620           abort ();
2621         }
2622
2623     default:
2624       abort();
2625     }
2626 }
2627   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2628    (set (attr "mode")
2629         (cond [(eq_attr "alternative" "0,1,2")
2630                  (const_string "DF")
2631                (eq_attr "alternative" "3,4")
2632                  (const_string "SI")
2633
2634                /* For SSE1, we have many fewer alternatives.  */
2635                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2636                  (cond [(eq_attr "alternative" "5,6")
2637                           (const_string "V4SF")
2638                        ]
2639                    (const_string "V2SF"))
2640
2641                /* xorps is one byte shorter.  */
2642                (eq_attr "alternative" "5")
2643                  (cond [(ne (symbol_ref "optimize_size")
2644                             (const_int 0))
2645                           (const_string "V4SF")
2646                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2647                             (const_int 0))
2648                           (const_string "TI")
2649                        ]
2650                        (const_string "V2DF"))
2651
2652                /* For architectures resolving dependencies on
2653                   whole SSE registers use APD move to break dependency
2654                   chains, otherwise use short move to avoid extra work.
2655
2656                   movaps encodes one byte shorter.  */
2657                (eq_attr "alternative" "6")
2658                  (cond
2659                    [(ne (symbol_ref "optimize_size")
2660                         (const_int 0))
2661                       (const_string "V4SF")
2662                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2663                         (const_int 0))
2664                       (const_string "V2DF")
2665                    ]
2666                    (const_string "DF"))
2667                /* For architectures resolving dependencies on register
2668                   parts we may avoid extra work to zero out upper part
2669                   of register.  */
2670                (eq_attr "alternative" "7")
2671                  (if_then_else
2672                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673                        (const_int 0))
2674                    (const_string "V1DF")
2675                    (const_string "DF"))
2676               ]
2677               (const_string "DF")))])
2678
2679 (define_split
2680   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2681         (match_operand:DF 1 "general_operand" ""))]
2682   "reload_completed
2683    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2684    && ! (ANY_FP_REG_P (operands[0]) || 
2685          (GET_CODE (operands[0]) == SUBREG
2686           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2687    && ! (ANY_FP_REG_P (operands[1]) || 
2688          (GET_CODE (operands[1]) == SUBREG
2689           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2690   [(const_int 0)]
2691   "ix86_split_long_move (operands); DONE;")
2692
2693 (define_insn "*swapdf"
2694   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2695         (match_operand:DF 1 "fp_register_operand" "+f"))
2696    (set (match_dup 1)
2697         (match_dup 0))]
2698   "reload_completed || TARGET_80387"
2699 {
2700   if (STACK_TOP_P (operands[0]))
2701     return "fxch\t%1";
2702   else
2703     return "fxch\t%0";
2704 }
2705   [(set_attr "type" "fxch")
2706    (set_attr "mode" "DF")])
2707
2708 (define_expand "movxf"
2709   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2710         (match_operand:XF 1 "general_operand" ""))]
2711   ""
2712   "ix86_expand_move (XFmode, operands); DONE;")
2713
2714 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2715 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2716 ;; Pushing using integer instructions is longer except for constants
2717 ;; and direct memory references.
2718 ;; (assuming that any given constant is pushed only once, but this ought to be
2719 ;;  handled elsewhere).
2720
2721 (define_insn "*pushxf_nointeger"
2722   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2723         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2724   "optimize_size"
2725 {
2726   /* This insn should be already split before reg-stack.  */
2727   abort ();
2728 }
2729   [(set_attr "type" "multi")
2730    (set_attr "mode" "XF,SI,SI")])
2731
2732 (define_insn "*pushxf_integer"
2733   [(set (match_operand:XF 0 "push_operand" "=<,<")
2734         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2735   "!optimize_size"
2736 {
2737   /* This insn should be already split before reg-stack.  */
2738   abort ();
2739 }
2740   [(set_attr "type" "multi")
2741    (set_attr "mode" "XF,SI")])
2742
2743 (define_split
2744   [(set (match_operand 0 "push_operand" "")
2745         (match_operand 1 "general_operand" ""))]
2746   "reload_completed
2747    && (GET_MODE (operands[0]) == XFmode
2748        || GET_MODE (operands[0]) == DFmode)
2749    && !ANY_FP_REG_P (operands[1])"
2750   [(const_int 0)]
2751   "ix86_split_long_move (operands); DONE;")
2752
2753 (define_split
2754   [(set (match_operand:XF 0 "push_operand" "")
2755         (match_operand:XF 1 "any_fp_register_operand" ""))]
2756   "!TARGET_64BIT"
2757   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2758    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2759   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2760
2761 (define_split
2762   [(set (match_operand:XF 0 "push_operand" "")
2763         (match_operand:XF 1 "any_fp_register_operand" ""))]
2764   "TARGET_64BIT"
2765   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2766    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2767   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2768
2769 ;; Do not use integer registers when optimizing for size
2770 (define_insn "*movxf_nointeger"
2771   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2772         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2773   "optimize_size
2774    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2775    && (reload_in_progress || reload_completed
2776        || GET_CODE (operands[1]) != CONST_DOUBLE
2777        || memory_operand (operands[0], XFmode))" 
2778 {
2779   switch (which_alternative)
2780     {
2781     case 0:
2782       return output_387_reg_move (insn, operands);
2783
2784     case 1:
2785       /* There is no non-popping store to memory for XFmode.  So if
2786          we need one, follow the store with a load.  */
2787       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2788         return "fstp%z0\t%y0\;fld%z0\t%y0";
2789       else
2790         return "fstp%z0\t%y0";
2791
2792     case 2:
2793       return standard_80387_constant_opcode (operands[1]);
2794
2795     case 3: case 4:
2796       return "#";
2797     }
2798   abort();
2799 }
2800   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2801    (set_attr "mode" "XF,XF,XF,SI,SI")])
2802
2803 (define_insn "*movxf_integer"
2804   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2805         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2806   "!optimize_size
2807    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808    && (reload_in_progress || reload_completed
2809        || GET_CODE (operands[1]) != CONST_DOUBLE
2810        || memory_operand (operands[0], XFmode))" 
2811 {
2812   switch (which_alternative)
2813     {
2814     case 0:
2815       return output_387_reg_move (insn, operands);
2816
2817     case 1:
2818       /* There is no non-popping store to memory for XFmode.  So if
2819          we need one, follow the store with a load.  */
2820       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821         return "fstp%z0\t%y0\;fld%z0\t%y0";
2822       else
2823         return "fstp%z0\t%y0";
2824
2825     case 2:
2826       return standard_80387_constant_opcode (operands[1]);
2827
2828     case 3: case 4:
2829       return "#";
2830     }
2831   abort();
2832 }
2833   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2834    (set_attr "mode" "XF,XF,XF,SI,SI")])
2835
2836 (define_split
2837   [(set (match_operand 0 "nonimmediate_operand" "")
2838         (match_operand 1 "general_operand" ""))]
2839   "reload_completed
2840    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2841    && GET_MODE (operands[0]) == XFmode
2842    && ! (ANY_FP_REG_P (operands[0]) || 
2843          (GET_CODE (operands[0]) == SUBREG
2844           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2845    && ! (ANY_FP_REG_P (operands[1]) || 
2846          (GET_CODE (operands[1]) == SUBREG
2847           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2848   [(const_int 0)]
2849   "ix86_split_long_move (operands); DONE;")
2850
2851 (define_split
2852   [(set (match_operand 0 "register_operand" "")
2853         (match_operand 1 "memory_operand" ""))]
2854   "reload_completed
2855    && GET_CODE (operands[1]) == MEM
2856    && (GET_MODE (operands[0]) == XFmode
2857        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2858    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2859    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2860   [(set (match_dup 0) (match_dup 1))]
2861 {
2862   rtx c = get_pool_constant (XEXP (operands[1], 0));
2863   rtx r = operands[0];
2864
2865   if (GET_CODE (r) == SUBREG)
2866     r = SUBREG_REG (r);
2867
2868   if (SSE_REG_P (r))
2869     {
2870       if (!standard_sse_constant_p (c))
2871         FAIL;
2872     }
2873   else if (FP_REG_P (r))
2874     {
2875       if (!standard_80387_constant_p (c))
2876         FAIL;
2877     }
2878   else if (MMX_REG_P (r))
2879     FAIL;
2880
2881   operands[1] = c;
2882 })
2883
2884 (define_insn "swapxf"
2885   [(set (match_operand:XF 0 "register_operand" "+f")
2886         (match_operand:XF 1 "register_operand" "+f"))
2887    (set (match_dup 1)
2888         (match_dup 0))]
2889   "TARGET_80387"
2890 {
2891   if (STACK_TOP_P (operands[0]))
2892     return "fxch\t%1";
2893   else
2894     return "fxch\t%0";
2895 }
2896   [(set_attr "type" "fxch")
2897    (set_attr "mode" "XF")])
2898
2899 (define_expand "movtf"
2900   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2901         (match_operand:TF 1 "nonimmediate_operand" ""))]
2902   "TARGET_64BIT"
2903 {
2904   ix86_expand_move (TFmode, operands);
2905   DONE;
2906 })
2907
2908 (define_insn "*movtf_internal"
2909   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2910         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2911   "TARGET_64BIT
2912    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2913 {
2914   switch (which_alternative)
2915     {
2916     case 0:
2917     case 1:
2918       return "#";
2919     case 2:
2920       if (get_attr_mode (insn) == MODE_V4SF)
2921         return "xorps\t%0, %0";
2922       else
2923         return "pxor\t%0, %0";
2924     case 3:
2925     case 4:
2926       if (get_attr_mode (insn) == MODE_V4SF)
2927         return "movaps\t{%1, %0|%0, %1}";
2928       else
2929         return "movdqa\t{%1, %0|%0, %1}";
2930     default:
2931       abort ();
2932     }
2933 }
2934   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2935    (set (attr "mode")
2936         (cond [(eq_attr "alternative" "2,3")
2937                  (if_then_else
2938                    (ne (symbol_ref "optimize_size")
2939                        (const_int 0))
2940                    (const_string "V4SF")
2941                    (const_string "TI"))
2942                (eq_attr "alternative" "4")
2943                  (if_then_else
2944                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2945                             (const_int 0))
2946                         (ne (symbol_ref "optimize_size")
2947                             (const_int 0)))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))]
2950                (const_string "DI")))])
2951
2952 (define_split
2953   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2954         (match_operand:TF 1 "general_operand" ""))]
2955   "reload_completed && !SSE_REG_P (operands[0])
2956    && !SSE_REG_P (operands[1])"
2957   [(const_int 0)]
2958   "ix86_split_long_move (operands); DONE;")
2959 \f
2960 ;; Zero extension instructions
2961
2962 (define_expand "zero_extendhisi2"
2963   [(set (match_operand:SI 0 "register_operand" "")
2964      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2965   ""
2966 {
2967   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2968     {
2969       operands[1] = force_reg (HImode, operands[1]);
2970       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2971       DONE;
2972     }
2973 })
2974
2975 (define_insn "zero_extendhisi2_and"
2976   [(set (match_operand:SI 0 "register_operand" "=r")
2977      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2978    (clobber (reg:CC FLAGS_REG))]
2979   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2980   "#"
2981   [(set_attr "type" "alu1")
2982    (set_attr "mode" "SI")])
2983
2984 (define_split
2985   [(set (match_operand:SI 0 "register_operand" "")
2986         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2987    (clobber (reg:CC FLAGS_REG))]
2988   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2989   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2990               (clobber (reg:CC FLAGS_REG))])]
2991   "")
2992
2993 (define_insn "*zero_extendhisi2_movzwl"
2994   [(set (match_operand:SI 0 "register_operand" "=r")
2995      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2996   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2997   "movz{wl|x}\t{%1, %0|%0, %1}"
2998   [(set_attr "type" "imovx")
2999    (set_attr "mode" "SI")])
3000
3001 (define_expand "zero_extendqihi2"
3002   [(parallel
3003     [(set (match_operand:HI 0 "register_operand" "")
3004        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3005      (clobber (reg:CC FLAGS_REG))])]
3006   ""
3007   "")
3008
3009 (define_insn "*zero_extendqihi2_and"
3010   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3011      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3012    (clobber (reg:CC FLAGS_REG))]
3013   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3014   "#"
3015   [(set_attr "type" "alu1")
3016    (set_attr "mode" "HI")])
3017
3018 (define_insn "*zero_extendqihi2_movzbw_and"
3019   [(set (match_operand:HI 0 "register_operand" "=r,r")
3020      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3021    (clobber (reg:CC FLAGS_REG))]
3022   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3023   "#"
3024   [(set_attr "type" "imovx,alu1")
3025    (set_attr "mode" "HI")])
3026
3027 (define_insn "*zero_extendqihi2_movzbw"
3028   [(set (match_operand:HI 0 "register_operand" "=r")
3029      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3030   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3031   "movz{bw|x}\t{%1, %0|%0, %1}"
3032   [(set_attr "type" "imovx")
3033    (set_attr "mode" "HI")])
3034
3035 ;; For the movzbw case strip only the clobber
3036 (define_split
3037   [(set (match_operand:HI 0 "register_operand" "")
3038         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3039    (clobber (reg:CC FLAGS_REG))]
3040   "reload_completed 
3041    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3042    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3043   [(set (match_operand:HI 0 "register_operand" "")
3044         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3045
3046 ;; When source and destination does not overlap, clear destination
3047 ;; first and then do the movb
3048 (define_split
3049   [(set (match_operand:HI 0 "register_operand" "")
3050         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3051    (clobber (reg:CC FLAGS_REG))]
3052   "reload_completed
3053    && ANY_QI_REG_P (operands[0])
3054    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3055    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3056   [(set (match_dup 0) (const_int 0))
3057    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3058   "operands[2] = gen_lowpart (QImode, operands[0]);")
3059
3060 ;; Rest is handled by single and.
3061 (define_split
3062   [(set (match_operand:HI 0 "register_operand" "")
3063         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3064    (clobber (reg:CC FLAGS_REG))]
3065   "reload_completed
3066    && true_regnum (operands[0]) == true_regnum (operands[1])"
3067   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3068               (clobber (reg:CC FLAGS_REG))])]
3069   "")
3070
3071 (define_expand "zero_extendqisi2"
3072   [(parallel
3073     [(set (match_operand:SI 0 "register_operand" "")
3074        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3075      (clobber (reg:CC FLAGS_REG))])]
3076   ""
3077   "")
3078
3079 (define_insn "*zero_extendqisi2_and"
3080   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3081      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3082    (clobber (reg:CC FLAGS_REG))]
3083   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3084   "#"
3085   [(set_attr "type" "alu1")
3086    (set_attr "mode" "SI")])
3087
3088 (define_insn "*zero_extendqisi2_movzbw_and"
3089   [(set (match_operand:SI 0 "register_operand" "=r,r")
3090      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3091    (clobber (reg:CC FLAGS_REG))]
3092   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3093   "#"
3094   [(set_attr "type" "imovx,alu1")
3095    (set_attr "mode" "SI")])
3096
3097 (define_insn "*zero_extendqisi2_movzbw"
3098   [(set (match_operand:SI 0 "register_operand" "=r")
3099      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3100   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3101   "movz{bl|x}\t{%1, %0|%0, %1}"
3102   [(set_attr "type" "imovx")
3103    (set_attr "mode" "SI")])
3104
3105 ;; For the movzbl case strip only the clobber
3106 (define_split
3107   [(set (match_operand:SI 0 "register_operand" "")
3108         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3109    (clobber (reg:CC FLAGS_REG))]
3110   "reload_completed 
3111    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3112    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3113   [(set (match_dup 0)
3114         (zero_extend:SI (match_dup 1)))])
3115
3116 ;; When source and destination does not overlap, clear destination
3117 ;; first and then do the movb
3118 (define_split
3119   [(set (match_operand:SI 0 "register_operand" "")
3120         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3121    (clobber (reg:CC FLAGS_REG))]
3122   "reload_completed
3123    && ANY_QI_REG_P (operands[0])
3124    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3125    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3126    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3127   [(set (match_dup 0) (const_int 0))
3128    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3129   "operands[2] = gen_lowpart (QImode, operands[0]);")
3130
3131 ;; Rest is handled by single and.
3132 (define_split
3133   [(set (match_operand:SI 0 "register_operand" "")
3134         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3135    (clobber (reg:CC FLAGS_REG))]
3136   "reload_completed
3137    && true_regnum (operands[0]) == true_regnum (operands[1])"
3138   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3139               (clobber (reg:CC FLAGS_REG))])]
3140   "")
3141
3142 ;; %%% Kill me once multi-word ops are sane.
3143 (define_expand "zero_extendsidi2"
3144   [(set (match_operand:DI 0 "register_operand" "=r")
3145      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3146   ""
3147   "if (!TARGET_64BIT)
3148      {
3149        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3150        DONE;
3151      }
3152   ")
3153
3154 (define_insn "zero_extendsidi2_32"
3155   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3156         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3157    (clobber (reg:CC FLAGS_REG))]
3158   "!TARGET_64BIT"
3159   "@
3160    #
3161    #
3162    #
3163    movd\t{%1, %0|%0, %1}
3164    movd\t{%1, %0|%0, %1}"
3165   [(set_attr "mode" "SI,SI,SI,DI,TI")
3166    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3167
3168 (define_insn "zero_extendsidi2_rex64"
3169   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3170      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3171   "TARGET_64BIT"
3172   "@
3173    mov\t{%k1, %k0|%k0, %k1}
3174    #
3175    movd\t{%1, %0|%0, %1}
3176    movd\t{%1, %0|%0, %1}"
3177   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3178    (set_attr "mode" "SI,DI,SI,SI")])
3179
3180 (define_split
3181   [(set (match_operand:DI 0 "memory_operand" "")
3182      (zero_extend:DI (match_dup 0)))]
3183   "TARGET_64BIT"
3184   [(set (match_dup 4) (const_int 0))]
3185   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3186
3187 (define_split 
3188   [(set (match_operand:DI 0 "register_operand" "")
3189         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3190    (clobber (reg:CC FLAGS_REG))]
3191   "!TARGET_64BIT && reload_completed
3192    && true_regnum (operands[0]) == true_regnum (operands[1])"
3193   [(set (match_dup 4) (const_int 0))]
3194   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3195
3196 (define_split 
3197   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3198         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3199    (clobber (reg:CC FLAGS_REG))]
3200   "!TARGET_64BIT && reload_completed
3201    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3202   [(set (match_dup 3) (match_dup 1))
3203    (set (match_dup 4) (const_int 0))]
3204   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205
3206 (define_insn "zero_extendhidi2"
3207   [(set (match_operand:DI 0 "register_operand" "=r,r")
3208      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3209   "TARGET_64BIT"
3210   "@
3211    movz{wl|x}\t{%1, %k0|%k0, %1}
3212    movz{wq|x}\t{%1, %0|%0, %1}"
3213   [(set_attr "type" "imovx")
3214    (set_attr "mode" "SI,DI")])
3215
3216 (define_insn "zero_extendqidi2"
3217   [(set (match_operand:DI 0 "register_operand" "=r,r")
3218      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3219   "TARGET_64BIT"
3220   "@
3221    movz{bl|x}\t{%1, %k0|%k0, %1}
3222    movz{bq|x}\t{%1, %0|%0, %1}"
3223   [(set_attr "type" "imovx")
3224    (set_attr "mode" "SI,DI")])
3225 \f
3226 ;; Sign extension instructions
3227
3228 (define_expand "extendsidi2"
3229   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3230                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3231               (clobber (reg:CC FLAGS_REG))
3232               (clobber (match_scratch:SI 2 ""))])]
3233   ""
3234 {
3235   if (TARGET_64BIT)
3236     {
3237       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3238       DONE;
3239     }
3240 })
3241
3242 (define_insn "*extendsidi2_1"
3243   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3244         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3245    (clobber (reg:CC FLAGS_REG))
3246    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3247   "!TARGET_64BIT"
3248   "#")
3249
3250 (define_insn "extendsidi2_rex64"
3251   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3252         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3253   "TARGET_64BIT"
3254   "@
3255    {cltq|cdqe}
3256    movs{lq|x}\t{%1,%0|%0, %1}"
3257   [(set_attr "type" "imovx")
3258    (set_attr "mode" "DI")
3259    (set_attr "prefix_0f" "0")
3260    (set_attr "modrm" "0,1")])
3261
3262 (define_insn "extendhidi2"
3263   [(set (match_operand:DI 0 "register_operand" "=r")
3264         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3265   "TARGET_64BIT"
3266   "movs{wq|x}\t{%1,%0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "DI")])
3269
3270 (define_insn "extendqidi2"
3271   [(set (match_operand:DI 0 "register_operand" "=r")
3272         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3273   "TARGET_64BIT"
3274   "movs{bq|x}\t{%1,%0|%0, %1}"
3275    [(set_attr "type" "imovx")
3276     (set_attr "mode" "DI")])
3277
3278 ;; Extend to memory case when source register does die.
3279 (define_split 
3280   [(set (match_operand:DI 0 "memory_operand" "")
3281         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3282    (clobber (reg:CC FLAGS_REG))
3283    (clobber (match_operand:SI 2 "register_operand" ""))]
3284   "(reload_completed
3285     && dead_or_set_p (insn, operands[1])
3286     && !reg_mentioned_p (operands[1], operands[0]))"
3287   [(set (match_dup 3) (match_dup 1))
3288    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3289               (clobber (reg:CC FLAGS_REG))])
3290    (set (match_dup 4) (match_dup 1))]
3291   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3292
3293 ;; Extend to memory case when source register does not die.
3294 (define_split 
3295   [(set (match_operand:DI 0 "memory_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_operand:SI 2 "register_operand" ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3301 {
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303
3304   emit_move_insn (operands[3], operands[1]);
3305
3306   /* Generate a cltd if possible and doing so it profitable.  */
3307   if (true_regnum (operands[1]) == 0
3308       && true_regnum (operands[2]) == 1
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3312     }
3313   else
3314     {
3315       emit_move_insn (operands[2], operands[1]);
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3317     }
3318   emit_move_insn (operands[4], operands[2]);
3319   DONE;
3320 })
3321
3322 ;; Extend to register case.  Optimize case where source and destination
3323 ;; registers match and cases where we can use cltd.
3324 (define_split 
3325   [(set (match_operand:DI 0 "register_operand" "")
3326         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3327    (clobber (reg:CC FLAGS_REG))
3328    (clobber (match_scratch:SI 2 ""))]
3329   "reload_completed"
3330   [(const_int 0)]
3331 {
3332   split_di (&operands[0], 1, &operands[3], &operands[4]);
3333
3334   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3335     emit_move_insn (operands[3], operands[1]);
3336
3337   /* Generate a cltd if possible and doing so it profitable.  */
3338   if (true_regnum (operands[3]) == 0
3339       && (optimize_size || TARGET_USE_CLTD))
3340     {
3341       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3342       DONE;
3343     }
3344
3345   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3346     emit_move_insn (operands[4], operands[1]);
3347
3348   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3349   DONE;
3350 })
3351
3352 (define_insn "extendhisi2"
3353   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3354         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3355   ""
3356 {
3357   switch (get_attr_prefix_0f (insn))
3358     {
3359     case 0:
3360       return "{cwtl|cwde}";
3361     default:
3362       return "movs{wl|x}\t{%1,%0|%0, %1}";
3363     }
3364 }
3365   [(set_attr "type" "imovx")
3366    (set_attr "mode" "SI")
3367    (set (attr "prefix_0f")
3368      ;; movsx is short decodable while cwtl is vector decoded.
3369      (if_then_else (and (eq_attr "cpu" "!k6")
3370                         (eq_attr "alternative" "0"))
3371         (const_string "0")
3372         (const_string "1")))
3373    (set (attr "modrm")
3374      (if_then_else (eq_attr "prefix_0f" "0")
3375         (const_string "0")
3376         (const_string "1")))])
3377
3378 (define_insn "*extendhisi2_zext"
3379   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3380         (zero_extend:DI
3381           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3382   "TARGET_64BIT"
3383 {
3384   switch (get_attr_prefix_0f (insn))
3385     {
3386     case 0:
3387       return "{cwtl|cwde}";
3388     default:
3389       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3390     }
3391 }
3392   [(set_attr "type" "imovx")
3393    (set_attr "mode" "SI")
3394    (set (attr "prefix_0f")
3395      ;; movsx is short decodable while cwtl is vector decoded.
3396      (if_then_else (and (eq_attr "cpu" "!k6")
3397                         (eq_attr "alternative" "0"))
3398         (const_string "0")
3399         (const_string "1")))
3400    (set (attr "modrm")
3401      (if_then_else (eq_attr "prefix_0f" "0")
3402         (const_string "0")
3403         (const_string "1")))])
3404
3405 (define_insn "extendqihi2"
3406   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3407         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3408   ""
3409 {
3410   switch (get_attr_prefix_0f (insn))
3411     {
3412     case 0:
3413       return "{cbtw|cbw}";
3414     default:
3415       return "movs{bw|x}\t{%1,%0|%0, %1}";
3416     }
3417 }
3418   [(set_attr "type" "imovx")
3419    (set_attr "mode" "HI")
3420    (set (attr "prefix_0f")
3421      ;; movsx is short decodable while cwtl is vector decoded.
3422      (if_then_else (and (eq_attr "cpu" "!k6")
3423                         (eq_attr "alternative" "0"))
3424         (const_string "0")
3425         (const_string "1")))
3426    (set (attr "modrm")
3427      (if_then_else (eq_attr "prefix_0f" "0")
3428         (const_string "0")
3429         (const_string "1")))])
3430
3431 (define_insn "extendqisi2"
3432   [(set (match_operand:SI 0 "register_operand" "=r")
3433         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3434   ""
3435   "movs{bl|x}\t{%1,%0|%0, %1}"
3436    [(set_attr "type" "imovx")
3437     (set_attr "mode" "SI")])
3438
3439 (define_insn "*extendqisi2_zext"
3440   [(set (match_operand:DI 0 "register_operand" "=r")
3441         (zero_extend:DI
3442           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3443   "TARGET_64BIT"
3444   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3445    [(set_attr "type" "imovx")
3446     (set_attr "mode" "SI")])
3447 \f
3448 ;; Conversions between float and double.
3449
3450 ;; These are all no-ops in the model used for the 80387.  So just
3451 ;; emit moves.
3452
3453 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3454 (define_insn "*dummy_extendsfdf2"
3455   [(set (match_operand:DF 0 "push_operand" "=<")
3456         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3457   "0"
3458   "#")
3459
3460 (define_split
3461   [(set (match_operand:DF 0 "push_operand" "")
3462         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3463   "!TARGET_64BIT"
3464   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3465    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3466
3467 (define_split
3468   [(set (match_operand:DF 0 "push_operand" "")
3469         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3470   "TARGET_64BIT"
3471   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3472    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3473
3474 (define_insn "*dummy_extendsfxf2"
3475   [(set (match_operand:XF 0 "push_operand" "=<")
3476         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3477   "0"
3478   "#")
3479
3480 (define_split
3481   [(set (match_operand:XF 0 "push_operand" "")
3482         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3483   ""
3484   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3485    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3486   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3487
3488 (define_split
3489   [(set (match_operand:XF 0 "push_operand" "")
3490         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3491   "TARGET_64BIT"
3492   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3493    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3494   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495
3496 (define_split
3497   [(set (match_operand:XF 0 "push_operand" "")
3498         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3499   ""
3500   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3501    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3502   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3503
3504 (define_split
3505   [(set (match_operand:XF 0 "push_operand" "")
3506         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3507   "TARGET_64BIT"
3508   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3509    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3510   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3511
3512 (define_expand "extendsfdf2"
3513   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3514         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3515   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3516 {
3517   /* ??? Needed for compress_float_constant since all fp constants
3518      are LEGITIMATE_CONSTANT_P.  */
3519   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3520     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3522     operands[1] = force_reg (SFmode, operands[1]);
3523 })
3524
3525 (define_insn "*extendsfdf2_mixed"
3526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3527         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3528   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3529    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3530 {
3531   switch (which_alternative)
3532     {
3533     case 0:
3534       return output_387_reg_move (insn, operands);
3535
3536     case 1:
3537       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3538         return "fstp%z0\t%y0";
3539       else
3540         return "fst%z0\t%y0";
3541
3542     case 2:
3543       return "cvtss2sd\t{%1, %0|%0, %1}";
3544
3545     default:
3546       abort ();
3547     }
3548 }
3549   [(set_attr "type" "fmov,fmov,ssecvt")
3550    (set_attr "mode" "SF,XF,DF")])
3551
3552 (define_insn "*extendsfdf2_sse"
3553   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3554         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3555   "TARGET_SSE2 && TARGET_SSE_MATH
3556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557   "cvtss2sd\t{%1, %0|%0, %1}"
3558   [(set_attr "type" "ssecvt")
3559    (set_attr "mode" "DF")])
3560
3561 (define_insn "*extendsfdf2_i387"
3562   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3563         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3564   "TARGET_80387
3565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3566 {
3567   switch (which_alternative)
3568     {
3569     case 0:
3570       return output_387_reg_move (insn, operands);
3571
3572     case 1:
3573       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3574         return "fstp%z0\t%y0";
3575       else
3576         return "fst%z0\t%y0";
3577
3578     default:
3579       abort ();
3580     }
3581 }
3582   [(set_attr "type" "fmov")
3583    (set_attr "mode" "SF,XF")])
3584
3585 (define_expand "extendsfxf2"
3586   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3587         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3588   "TARGET_80387"
3589 {
3590   /* ??? Needed for compress_float_constant since all fp constants
3591      are LEGITIMATE_CONSTANT_P.  */
3592   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3593     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3594   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3595     operands[1] = force_reg (SFmode, operands[1]);
3596 })
3597
3598 (define_insn "*extendsfxf2_i387"
3599   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3600         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3601   "TARGET_80387
3602    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3603 {
3604   switch (which_alternative)
3605     {
3606     case 0:
3607       return output_387_reg_move (insn, operands);
3608
3609     case 1:
3610       /* There is no non-popping store to memory for XFmode.  So if
3611          we need one, follow the store with a load.  */
3612       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3613         return "fstp%z0\t%y0";
3614       else
3615         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3616
3617     default:
3618       abort ();
3619     }
3620 }
3621   [(set_attr "type" "fmov")
3622    (set_attr "mode" "SF,XF")])
3623
3624 (define_expand "extenddfxf2"
3625   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3626         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3627   "TARGET_80387"
3628 {
3629   /* ??? Needed for compress_float_constant since all fp constants
3630      are LEGITIMATE_CONSTANT_P.  */
3631   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3632     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3633   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3634     operands[1] = force_reg (DFmode, operands[1]);
3635 })
3636
3637 (define_insn "*extenddfxf2_i387"
3638   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3639         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3640   "TARGET_80387
3641    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       return output_387_reg_move (insn, operands);
3647
3648     case 1:
3649       /* There is no non-popping store to memory for XFmode.  So if
3650          we need one, follow the store with a load.  */
3651       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3652         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3653       else
3654         return "fstp%z0\t%y0";
3655
3656     default:
3657       abort ();
3658     }
3659 }
3660   [(set_attr "type" "fmov")
3661    (set_attr "mode" "DF,XF")])
3662
3663 ;; %%% This seems bad bad news.
3664 ;; This cannot output into an f-reg because there is no way to be sure
3665 ;; of truncating in that case.  Otherwise this is just like a simple move
3666 ;; insn.  So we pretend we can output to a reg in order to get better
3667 ;; register preferencing, but we really use a stack slot.
3668
3669 ;; Conversion from DFmode to SFmode.
3670
3671 (define_expand "truncdfsf2"
3672   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3673         (float_truncate:SF
3674           (match_operand:DF 1 "nonimmediate_operand" "")))]
3675   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3676 {
3677   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3678     operands[1] = force_reg (DFmode, operands[1]);
3679
3680   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3681     ;
3682   else if (flag_unsafe_math_optimizations)
3683     ;
3684   else
3685     {
3686       rtx temp = assign_386_stack_local (SFmode, 0);
3687       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3688       DONE;
3689     }
3690 })
3691
3692 (define_expand "truncdfsf2_with_temp"
3693   [(parallel [(set (match_operand:SF 0 "" "")
3694                    (float_truncate:SF (match_operand:DF 1 "" "")))
3695               (clobber (match_operand:SF 2 "" ""))])]
3696   "")
3697
3698 (define_insn "*truncdfsf_fast_mixed"
3699   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3700         (float_truncate:SF
3701           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3702   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3703 {
3704   switch (which_alternative)
3705     {
3706     case 0:
3707       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3708         return "fstp%z0\t%y0";
3709       else
3710         return "fst%z0\t%y0";
3711     case 1:
3712       return output_387_reg_move (insn, operands);
3713     case 2:
3714       return "cvtsd2ss\t{%1, %0|%0, %1}";
3715     default:
3716       abort ();
3717     }
3718 }
3719   [(set_attr "type" "fmov,fmov,ssecvt")
3720    (set_attr "mode" "SF")])
3721
3722 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3723 ;; because nothing we do here is unsafe.
3724 (define_insn "*truncdfsf_fast_sse"
3725   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3726         (float_truncate:SF
3727           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3728   "TARGET_SSE2 && TARGET_SSE_MATH"
3729   "cvtsd2ss\t{%1, %0|%0, %1}"
3730   [(set_attr "type" "ssecvt")
3731    (set_attr "mode" "SF")])
3732
3733 (define_insn "*truncdfsf_fast_i387"
3734   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3735         (float_truncate:SF
3736           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3737   "TARGET_80387 && flag_unsafe_math_optimizations"
3738   "* return output_387_reg_move (insn, operands);"
3739   [(set_attr "type" "fmov")
3740    (set_attr "mode" "SF")])
3741
3742 (define_insn "*truncdfsf_mixed"
3743   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3744         (float_truncate:SF
3745           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3746    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3747   "TARGET_MIX_SSE_I387"
3748 {
3749   switch (which_alternative)
3750     {
3751     case 0:
3752       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3753         return "fstp%z0\t%y0";
3754       else
3755         return "fst%z0\t%y0";
3756     case 1:
3757       return "#";
3758     case 2:
3759       return "cvtsd2ss\t{%1, %0|%0, %1}";
3760     default:
3761       abort ();
3762     }
3763 }
3764   [(set_attr "type" "fmov,multi,ssecvt")
3765    (set_attr "mode" "SF")])
3766
3767 (define_insn "*truncdfsf_i387"
3768   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3769         (float_truncate:SF
3770           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3771    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3772   "TARGET_80387"
3773 {
3774   switch (which_alternative)
3775     {
3776     case 0:
3777       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3778         return "fstp%z0\t%y0";
3779       else
3780         return "fst%z0\t%y0";
3781     case 1:
3782       return "#";
3783     default:
3784       abort ();
3785     }
3786 }
3787   [(set_attr "type" "fmov,multi")
3788    (set_attr "mode" "SF")])
3789
3790 (define_insn "*truncdfsf2_i387_1"
3791   [(set (match_operand:SF 0 "memory_operand" "=m")
3792         (float_truncate:SF
3793           (match_operand:DF 1 "register_operand" "f")))]
3794   "TARGET_80387
3795    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3796    && !TARGET_MIX_SSE_I387"
3797 {
3798   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799     return "fstp%z0\t%y0";
3800   else
3801     return "fst%z0\t%y0";
3802 }
3803   [(set_attr "type" "fmov")
3804    (set_attr "mode" "SF")])
3805
3806 (define_split
3807   [(set (match_operand:SF 0 "register_operand" "")
3808         (float_truncate:SF
3809          (match_operand:DF 1 "fp_register_operand" "")))
3810    (clobber (match_operand 2 "" ""))]
3811   "reload_completed"
3812   [(set (match_dup 2) (match_dup 1))
3813    (set (match_dup 0) (match_dup 2))]
3814 {
3815   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3816 })
3817
3818 ;; Conversion from XFmode to SFmode.
3819
3820 (define_expand "truncxfsf2"
3821   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3822                    (float_truncate:SF
3823                     (match_operand:XF 1 "register_operand" "")))
3824               (clobber (match_dup 2))])]
3825   "TARGET_80387"
3826 {
3827   if (flag_unsafe_math_optimizations)
3828     {
3829       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3830       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3831       if (reg != operands[0])
3832         emit_move_insn (operands[0], reg);
3833       DONE;
3834     }
3835   else
3836     operands[2] = assign_386_stack_local (SFmode, 0);
3837 })
3838
3839 (define_insn "*truncxfsf2_mixed"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844   "TARGET_MIX_SSE_I387"
3845 {
3846   switch (which_alternative)
3847     {
3848     case 0:
3849       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850         return "fstp%z0\t%y0";
3851       else
3852         return "fst%z0\t%y0";
3853     default:
3854       abort();
3855     }
3856 }
3857   [(set_attr "type" "fmov,multi,multi,multi")
3858    (set_attr "mode" "SF")])
3859
3860 (define_insn "truncxfsf2_i387_noop"
3861   [(set (match_operand:SF 0 "register_operand" "=f")
3862         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3863   "TARGET_80387 && flag_unsafe_math_optimizations"
3864 {
3865   return output_387_reg_move (insn, operands);
3866 }
3867   [(set_attr "type" "fmov")
3868    (set_attr "mode" "SF")])
3869
3870 (define_insn "*truncxfsf2_i387"
3871   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3872         (float_truncate:SF
3873          (match_operand:XF 1 "register_operand" "f,f,f")))
3874    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3875   "TARGET_80387"
3876 {
3877   switch (which_alternative)
3878     {
3879     case 0:
3880       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881         return "fstp%z0\t%y0";
3882       else
3883         return "fst%z0\t%y0";
3884     default:
3885       abort ();
3886     }
3887 }
3888   [(set_attr "type" "fmov,multi,multi")
3889    (set_attr "mode" "SF")])
3890
3891 (define_insn "*truncxfsf2_i387_1"
3892   [(set (match_operand:SF 0 "memory_operand" "=m")
3893         (float_truncate:SF
3894          (match_operand:XF 1 "register_operand" "f")))]
3895   "TARGET_80387"
3896 {
3897   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3898     return "fstp%z0\t%y0";
3899   else
3900     return "fst%z0\t%y0";
3901 }
3902   [(set_attr "type" "fmov")
3903    (set_attr "mode" "SF")])
3904
3905 (define_split
3906   [(set (match_operand:SF 0 "register_operand" "")
3907         (float_truncate:SF
3908          (match_operand:XF 1 "register_operand" "")))
3909    (clobber (match_operand:SF 2 "memory_operand" ""))]
3910   "TARGET_80387 && reload_completed"
3911   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3912    (set (match_dup 0) (match_dup 2))]
3913   "")
3914
3915 (define_split
3916   [(set (match_operand:SF 0 "memory_operand" "")
3917         (float_truncate:SF
3918          (match_operand:XF 1 "register_operand" "")))
3919    (clobber (match_operand:SF 2 "memory_operand" ""))]
3920   "TARGET_80387"
3921   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3922   "")
3923
3924 ;; Conversion from XFmode to DFmode.
3925
3926 (define_expand "truncxfdf2"
3927   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3928                    (float_truncate:DF
3929                     (match_operand:XF 1 "register_operand" "")))
3930               (clobber (match_dup 2))])]
3931   "TARGET_80387"
3932 {
3933   if (flag_unsafe_math_optimizations)
3934     {
3935       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3936       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3937       if (reg != operands[0])
3938         emit_move_insn (operands[0], reg);
3939       DONE;
3940     }
3941   else
3942     operands[2] = assign_386_stack_local (DFmode, 0);
3943 })
3944
3945 (define_insn "*truncxfdf2_mixed"
3946   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3947         (float_truncate:DF
3948          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3949    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3950   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3951 {
3952   switch (which_alternative)
3953     {
3954     case 0:
3955       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956         return "fstp%z0\t%y0";
3957       else
3958         return "fst%z0\t%y0";
3959     default:
3960       abort();
3961     }
3962   abort ();
3963 }
3964   [(set_attr "type" "fmov,multi,multi,multi")
3965    (set_attr "mode" "DF")])
3966
3967 (define_insn "truncxfdf2_i387_noop"
3968   [(set (match_operand:DF 0 "register_operand" "=f")
3969         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3970   "TARGET_80387 && flag_unsafe_math_optimizations"
3971 {
3972   return output_387_reg_move (insn, operands);
3973 }
3974   [(set_attr "type" "fmov")
3975    (set_attr "mode" "DF")])
3976
3977 (define_insn "*truncxfdf2_i387"
3978   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3979         (float_truncate:DF
3980          (match_operand:XF 1 "register_operand" "f,f,f")))
3981    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3982   "TARGET_80387"
3983 {
3984   switch (which_alternative)
3985     {
3986     case 0:
3987       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3988         return "fstp%z0\t%y0";
3989       else
3990         return "fst%z0\t%y0";
3991     default:
3992       abort ();
3993     }
3994 }
3995   [(set_attr "type" "fmov,multi,multi")
3996    (set_attr "mode" "DF")])
3997
3998 (define_insn "*truncxfdf2_i387_1"
3999   [(set (match_operand:DF 0 "memory_operand" "=m")
4000         (float_truncate:DF
4001           (match_operand:XF 1 "register_operand" "f")))]
4002   "TARGET_80387"
4003 {
4004   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4005     return "fstp%z0\t%y0";
4006   else
4007     return "fst%z0\t%y0";
4008 }
4009   [(set_attr "type" "fmov")
4010    (set_attr "mode" "DF")])
4011
4012 (define_split
4013   [(set (match_operand:DF 0 "register_operand" "")
4014         (float_truncate:DF
4015          (match_operand:XF 1 "register_operand" "")))
4016    (clobber (match_operand:DF 2 "memory_operand" ""))]
4017   "TARGET_80387 && reload_completed"
4018   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4019    (set (match_dup 0) (match_dup 2))]
4020   "")
4021
4022 (define_split
4023   [(set (match_operand:DF 0 "memory_operand" "")
4024         (float_truncate:DF
4025          (match_operand:XF 1 "register_operand" "")))
4026    (clobber (match_operand:DF 2 "memory_operand" ""))]
4027   "TARGET_80387"
4028   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4029   "")
4030 \f
4031 ;; Signed conversion to DImode.
4032
4033 (define_expand "fix_truncxfdi2"
4034   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4035                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4036               (clobber (reg:CC FLAGS_REG))])]
4037   "TARGET_80387"
4038 {
4039   if (TARGET_FISTTP)
4040    {
4041      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4042      DONE;
4043    }
4044 })
4045
4046 (define_expand "fix_trunc<mode>di2"
4047   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4048                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4049               (clobber (reg:CC FLAGS_REG))])]
4050   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4051 {
4052   if (TARGET_FISTTP
4053       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4054    {
4055      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4056      DONE;
4057    }
4058   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4059    {
4060      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4061      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4062      if (out != operands[0])
4063         emit_move_insn (operands[0], out);
4064      DONE;
4065    }
4066 })
4067
4068 ;; Signed conversion to SImode.
4069
4070 (define_expand "fix_truncxfsi2"
4071   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4072                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4073               (clobber (reg:CC FLAGS_REG))])]
4074   "TARGET_80387"
4075 {
4076   if (TARGET_FISTTP)
4077    {
4078      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4079      DONE;
4080    }
4081 })
4082
4083 (define_expand "fix_trunc<mode>si2"
4084   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4085                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4086               (clobber (reg:CC FLAGS_REG))])]
4087   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4088 {
4089   if (TARGET_FISTTP
4090       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4091    {
4092      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4093      DONE;
4094    }
4095   if (SSE_FLOAT_MODE_P (<MODE>mode))
4096    {
4097      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4098      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4099      if (out != operands[0])
4100         emit_move_insn (operands[0], out);
4101      DONE;
4102    }
4103 })
4104
4105 ;; Signed conversion to HImode.
4106
4107 (define_expand "fix_trunc<mode>hi2"
4108   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4109                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4110               (clobber (reg:CC FLAGS_REG))])]
4111   "TARGET_80387
4112    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4113 {
4114   if (TARGET_FISTTP)
4115    {
4116      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4117      DONE;
4118    }
4119 })
4120
4121 ;; When SSE is available, it is always faster to use it!
4122 (define_insn "fix_truncsfdi_sse"
4123   [(set (match_operand:DI 0 "register_operand" "=r,r")
4124         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4125   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4126   "cvttss2si{q}\t{%1, %0|%0, %1}"
4127   [(set_attr "type" "sseicvt")
4128    (set_attr "mode" "SF")
4129    (set_attr "athlon_decode" "double,vector")])
4130
4131 (define_insn "fix_truncdfdi_sse"
4132   [(set (match_operand:DI 0 "register_operand" "=r,r")
4133         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4134   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4135   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4136   [(set_attr "type" "sseicvt")
4137    (set_attr "mode" "DF")
4138    (set_attr "athlon_decode" "double,vector")])
4139
4140 (define_insn "fix_truncsfsi_sse"
4141   [(set (match_operand:SI 0 "register_operand" "=r,r")
4142         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4143   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144   "cvttss2si\t{%1, %0|%0, %1}"
4145   [(set_attr "type" "sseicvt")
4146    (set_attr "mode" "DF")
4147    (set_attr "athlon_decode" "double,vector")])
4148
4149 (define_insn "fix_truncdfsi_sse"
4150   [(set (match_operand:SI 0 "register_operand" "=r,r")
4151         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153   "cvttsd2si\t{%1, %0|%0, %1}"
4154   [(set_attr "type" "sseicvt")
4155    (set_attr "mode" "DF")
4156    (set_attr "athlon_decode" "double,vector")])
4157
4158 ;; Avoid vector decoded forms of the instruction.
4159 (define_peephole2
4160   [(match_scratch:DF 2 "Y")
4161    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4162         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4163   "TARGET_K8 && !optimize_size"
4164   [(set (match_dup 2) (match_dup 1))
4165    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4166   "")
4167
4168 (define_peephole2
4169   [(match_scratch:SF 2 "x")
4170    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4171         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4172   "TARGET_K8 && !optimize_size"
4173   [(set (match_dup 2) (match_dup 1))
4174    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4175   "")
4176
4177 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4178   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4179         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4180   "TARGET_80387 && TARGET_FISTTP
4181    && FLOAT_MODE_P (GET_MODE (operands[1]))
4182    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4183          && (TARGET_64BIT || <MODE>mode != DImode))
4184         && TARGET_SSE_MATH)
4185    && !(reload_completed || reload_in_progress)"
4186   "#"
4187   "&& 1"
4188   [(const_int 0)]
4189 {
4190   if (memory_operand (operands[0], VOIDmode))
4191     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4192   else
4193     {
4194       operands[2] = assign_386_stack_local (<MODE>mode, 0);
4195       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4196                                                             operands[1],
4197                                                             operands[2]));
4198     }
4199   DONE;
4200 }
4201   [(set_attr "type" "fisttp")
4202    (set_attr "mode" "<MODE>")])
4203
4204 (define_insn "fix_trunc<mode>_i387_fisttp"
4205   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4206         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4207    (clobber (match_scratch:XF 2 "=&1f"))]
4208   "TARGET_80387 && TARGET_FISTTP
4209    && FLOAT_MODE_P (GET_MODE (operands[1]))
4210    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4211          && (TARGET_64BIT || <MODE>mode != DImode))
4212         && TARGET_SSE_MATH)"
4213   "* return output_fix_trunc (insn, operands, 1);"
4214   [(set_attr "type" "fisttp")
4215    (set_attr "mode" "<MODE>")])
4216
4217 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4218   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4219         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4220    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4221    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4222   "TARGET_80387 && TARGET_FISTTP
4223    && FLOAT_MODE_P (GET_MODE (operands[1]))
4224    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4225         && (TARGET_64BIT || <MODE>mode != DImode))
4226         && TARGET_SSE_MATH)"
4227   "#"
4228   [(set_attr "type" "fisttp")
4229    (set_attr "mode" "<MODE>")])
4230
4231 (define_split
4232   [(set (match_operand:X87MODEI 0 "register_operand" "")
4233         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4234    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4235    (clobber (match_scratch 3 ""))]
4236   "reload_completed"
4237   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4238               (clobber (match_dup 3))])
4239    (set (match_dup 0) (match_dup 2))]
4240   "")
4241
4242 (define_split
4243   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4244         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4245    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4246    (clobber (match_scratch 3 ""))]
4247   "reload_completed"
4248   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4249               (clobber (match_dup 3))])]
4250   "")
4251
4252 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4253 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4254 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4255 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4256 ;; function in i386.c.
4257 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4258   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4259         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4260    (clobber (reg:CC FLAGS_REG))]
4261   "TARGET_80387 && !TARGET_FISTTP
4262    && FLOAT_MODE_P (GET_MODE (operands[1]))
4263    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4264          && (TARGET_64BIT || <MODE>mode != DImode))
4265    && !(reload_completed || reload_in_progress)"
4266   "#"
4267   "&& 1"
4268   [(const_int 0)]
4269 {
4270   ix86_optimize_mode_switching = 1;
4271   operands[2] = assign_386_stack_local (HImode, 1);
4272   operands[3] = assign_386_stack_local (HImode, 2);
4273   if (memory_operand (operands[0], VOIDmode))
4274     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4275                                          operands[2], operands[3]));
4276   else
4277     {
4278       operands[4] = assign_386_stack_local (<MODE>mode, 0);
4279       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4280                                                      operands[2], operands[3],
4281                                                      operands[4]));
4282     }
4283   DONE;
4284 }
4285   [(set_attr "type" "fistp")
4286    (set_attr "i387_cw" "trunc")
4287    (set_attr "mode" "<MODE>")])
4288
4289 (define_insn "fix_truncdi_i387"
4290   [(set (match_operand:DI 0 "memory_operand" "=m")
4291         (fix:DI (match_operand 1 "register_operand" "f")))
4292    (use (match_operand:HI 2 "memory_operand" "m"))
4293    (use (match_operand:HI 3 "memory_operand" "m"))
4294    (clobber (match_scratch:XF 4 "=&1f"))]
4295   "TARGET_80387 && !TARGET_FISTTP
4296    && FLOAT_MODE_P (GET_MODE (operands[1]))
4297    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4298   "* return output_fix_trunc (insn, operands, 0);"
4299   [(set_attr "type" "fistp")
4300    (set_attr "i387_cw" "trunc")
4301    (set_attr "mode" "DI")])
4302
4303 (define_insn "fix_truncdi_i387_with_temp"
4304   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4305         (fix:DI (match_operand 1 "register_operand" "f,f")))
4306    (use (match_operand:HI 2 "memory_operand" "m,m"))
4307    (use (match_operand:HI 3 "memory_operand" "m,m"))
4308    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4309    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4310   "TARGET_80387 && !TARGET_FISTTP
4311    && FLOAT_MODE_P (GET_MODE (operands[1]))
4312    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4313   "#"
4314   [(set_attr "type" "fistp")
4315    (set_attr "i387_cw" "trunc")
4316    (set_attr "mode" "DI")])
4317
4318 (define_split 
4319   [(set (match_operand:DI 0 "register_operand" "")
4320         (fix:DI (match_operand 1 "register_operand" "")))
4321    (use (match_operand:HI 2 "memory_operand" ""))
4322    (use (match_operand:HI 3 "memory_operand" ""))
4323    (clobber (match_operand:DI 4 "memory_operand" ""))
4324    (clobber (match_scratch 5 ""))]
4325   "reload_completed"
4326   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4327               (use (match_dup 2))
4328               (use (match_dup 3))
4329               (clobber (match_dup 5))])
4330    (set (match_dup 0) (match_dup 4))]
4331   "")
4332
4333 (define_split 
4334   [(set (match_operand:DI 0 "memory_operand" "")
4335         (fix:DI (match_operand 1 "register_operand" "")))
4336    (use (match_operand:HI 2 "memory_operand" ""))
4337    (use (match_operand:HI 3 "memory_operand" ""))
4338    (clobber (match_operand:DI 4 "memory_operand" ""))
4339    (clobber (match_scratch 5 ""))]
4340   "reload_completed"
4341   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4342               (use (match_dup 2))
4343               (use (match_dup 3))
4344               (clobber (match_dup 5))])]
4345   "")
4346
4347 (define_insn "fix_trunc<mode>_i387"
4348   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4349         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4350    (use (match_operand:HI 2 "memory_operand" "m"))
4351    (use (match_operand:HI 3 "memory_operand" "m"))]
4352   "TARGET_80387 && !TARGET_FISTTP
4353    && FLOAT_MODE_P (GET_MODE (operands[1]))
4354    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4355   "* return output_fix_trunc (insn, operands, 0);"
4356   [(set_attr "type" "fistp")
4357    (set_attr "i387_cw" "trunc")
4358    (set_attr "mode" "<MODE>")])
4359
4360 (define_insn "fix_trunc<mode>_i387_with_temp"
4361   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4362         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4363    (use (match_operand:HI 2 "memory_operand" "m,m"))
4364    (use (match_operand:HI 3 "memory_operand" "m,m"))
4365    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4366   "TARGET_80387 && !TARGET_FISTTP
4367    && FLOAT_MODE_P (GET_MODE (operands[1]))
4368    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4369   "#"
4370   [(set_attr "type" "fistp")
4371    (set_attr "i387_cw" "trunc")
4372    (set_attr "mode" "<MODE>")])
4373
4374 (define_split 
4375   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4376         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4377    (use (match_operand:HI 2 "memory_operand" ""))
4378    (use (match_operand:HI 3 "memory_operand" ""))
4379    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4380   "reload_completed"
4381   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4382               (use (match_dup 2))
4383               (use (match_dup 3))])
4384    (set (match_dup 0) (match_dup 4))]
4385   "")
4386
4387 (define_split 
4388   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4389         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4390    (use (match_operand:HI 2 "memory_operand" ""))
4391    (use (match_operand:HI 3 "memory_operand" ""))
4392    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4393   "reload_completed"
4394   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4395               (use (match_dup 2))
4396               (use (match_dup 3))])]
4397   "")
4398
4399 (define_insn "x86_fnstcw_1"
4400   [(set (match_operand:HI 0 "memory_operand" "=m")
4401         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4402   "TARGET_80387"
4403   "fnstcw\t%0"
4404   [(set_attr "length" "2")
4405    (set_attr "mode" "HI")
4406    (set_attr "unit" "i387")])
4407
4408 (define_insn "x86_fldcw_1"
4409   [(set (reg:HI FPSR_REG)
4410         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4411   "TARGET_80387"
4412   "fldcw\t%0"
4413   [(set_attr "length" "2")
4414    (set_attr "mode" "HI")
4415    (set_attr "unit" "i387")
4416    (set_attr "athlon_decode" "vector")])
4417 \f
4418 ;; Conversion between fixed point and floating point.
4419
4420 ;; Even though we only accept memory inputs, the backend _really_
4421 ;; wants to be able to do this between registers.
4422
4423 (define_expand "floathisf2"
4424   [(set (match_operand:SF 0 "register_operand" "")
4425         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4426   "TARGET_80387 || TARGET_SSE_MATH"
4427 {
4428   if (TARGET_SSE_MATH)
4429     {
4430       emit_insn (gen_floatsisf2 (operands[0],
4431                                  convert_to_mode (SImode, operands[1], 0)));
4432       DONE;
4433     }
4434 })
4435
4436 (define_insn "*floathisf2_i387"
4437   [(set (match_operand:SF 0 "register_operand" "=f,f")
4438         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4439   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4440   "@
4441    fild%z1\t%1
4442    #"
4443   [(set_attr "type" "fmov,multi")
4444    (set_attr "mode" "SF")
4445    (set_attr "fp_int_src" "true")])
4446
4447 (define_expand "floatsisf2"
4448   [(set (match_operand:SF 0 "register_operand" "")
4449         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4450   "TARGET_80387 || TARGET_SSE_MATH"
4451   "")
4452
4453 (define_insn "*floatsisf2_mixed"
4454   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4455         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4456   "TARGET_MIX_SSE_I387"
4457   "@
4458    fild%z1\t%1
4459    #
4460    cvtsi2ss\t{%1, %0|%0, %1}
4461    cvtsi2ss\t{%1, %0|%0, %1}"
4462   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4463    (set_attr "mode" "SF")
4464    (set_attr "athlon_decode" "*,*,vector,double")
4465    (set_attr "fp_int_src" "true")])
4466
4467 (define_insn "*floatsisf2_sse"
4468   [(set (match_operand:SF 0 "register_operand" "=x,x")
4469         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4470   "TARGET_SSE_MATH"
4471   "cvtsi2ss\t{%1, %0|%0, %1}"
4472   [(set_attr "type" "sseicvt")
4473    (set_attr "mode" "SF")
4474    (set_attr "athlon_decode" "vector,double")
4475    (set_attr "fp_int_src" "true")])
4476
4477 (define_insn "*floatsisf2_i387"
4478   [(set (match_operand:SF 0 "register_operand" "=f,f")
4479         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4480   "TARGET_80387"
4481   "@
4482    fild%z1\t%1
4483    #"
4484   [(set_attr "type" "fmov,multi")
4485    (set_attr "mode" "SF")
4486    (set_attr "fp_int_src" "true")])
4487
4488 (define_expand "floatdisf2"
4489   [(set (match_operand:SF 0 "register_operand" "")
4490         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4491   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4492   "")
4493
4494 (define_insn "*floatdisf2_mixed"
4495   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4496         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4497   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4498   "@
4499    fild%z1\t%1
4500    #
4501    cvtsi2ss{q}\t{%1, %0|%0, %1}
4502    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4504    (set_attr "mode" "SF")
4505    (set_attr "athlon_decode" "*,*,vector,double")
4506    (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatdisf2_sse"
4509   [(set (match_operand:SF 0 "register_operand" "=x,x")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4511   "TARGET_64BIT && TARGET_SSE_MATH"
4512   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4513   [(set_attr "type" "sseicvt")
4514    (set_attr "mode" "SF")
4515    (set_attr "athlon_decode" "vector,double")
4516    (set_attr "fp_int_src" "true")])
4517
4518 (define_insn "*floatdisf2_i387"
4519   [(set (match_operand:SF 0 "register_operand" "=f,f")
4520         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4521   "TARGET_80387"
4522   "@
4523    fild%z1\t%1
4524    #"
4525   [(set_attr "type" "fmov,multi")
4526    (set_attr "mode" "SF")
4527    (set_attr "fp_int_src" "true")])
4528
4529 (define_expand "floathidf2"
4530   [(set (match_operand:DF 0 "register_operand" "")
4531         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4532   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4533 {
4534   if (TARGET_SSE2 && TARGET_SSE_MATH)
4535     {
4536       emit_insn (gen_floatsidf2 (operands[0],
4537                                  convert_to_mode (SImode, operands[1], 0)));
4538       DONE;
4539     }
4540 })
4541
4542 (define_insn "*floathidf2_i387"
4543   [(set (match_operand:DF 0 "register_operand" "=f,f")
4544         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4545   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4546   "@
4547    fild%z1\t%1
4548    #"
4549   [(set_attr "type" "fmov,multi")
4550    (set_attr "mode" "DF")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_expand "floatsidf2"
4554   [(set (match_operand:DF 0 "register_operand" "")
4555         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557   "")
4558
4559 (define_insn "*floatsidf2_mixed"
4560   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4561         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4562   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4563   "@
4564    fild%z1\t%1
4565    #
4566    cvtsi2sd\t{%1, %0|%0, %1}
4567    cvtsi2sd\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4569    (set_attr "mode" "DF")
4570    (set_attr "athlon_decode" "*,*,double,direct")
4571    (set_attr "fp_int_src" "true")])
4572
4573 (define_insn "*floatsidf2_sse"
4574   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4575         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4576   "TARGET_SSE2 && TARGET_SSE_MATH"
4577   "cvtsi2sd\t{%1, %0|%0, %1}"
4578   [(set_attr "type" "sseicvt")
4579    (set_attr "mode" "DF")
4580    (set_attr "athlon_decode" "double,direct")
4581    (set_attr "fp_int_src" "true")])
4582
4583 (define_insn "*floatsidf2_i387"
4584   [(set (match_operand:DF 0 "register_operand" "=f,f")
4585         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4586   "TARGET_80387"
4587   "@
4588    fild%z1\t%1
4589    #"
4590   [(set_attr "type" "fmov,multi")
4591    (set_attr "mode" "DF")
4592    (set_attr "fp_int_src" "true")])
4593
4594 (define_expand "floatdidf2"
4595   [(set (match_operand:DF 0 "register_operand" "")
4596         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4597   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4598   "")
4599
4600 (define_insn "*floatdidf2_mixed"
4601   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4602         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4603   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4604   "@
4605    fild%z1\t%1
4606    #
4607    cvtsi2sd{q}\t{%1, %0|%0, %1}
4608    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4609   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4610    (set_attr "mode" "DF")
4611    (set_attr "athlon_decode" "*,*,double,direct")
4612    (set_attr "fp_int_src" "true")])
4613
4614 (define_insn "*floatdidf2_sse"
4615   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4616         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4617   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4618   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4619   [(set_attr "type" "sseicvt")
4620    (set_attr "mode" "DF")
4621    (set_attr "athlon_decode" "double,direct")
4622    (set_attr "fp_int_src" "true")])
4623
4624 (define_insn "*floatdidf2_i387"
4625   [(set (match_operand:DF 0 "register_operand" "=f,f")
4626         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4627   "TARGET_80387"
4628   "@
4629    fild%z1\t%1
4630    #"
4631   [(set_attr "type" "fmov,multi")
4632    (set_attr "mode" "DF")
4633    (set_attr "fp_int_src" "true")])
4634
4635 (define_insn "floathixf2"
4636   [(set (match_operand:XF 0 "register_operand" "=f,f")
4637         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4638   "TARGET_80387"
4639   "@
4640    fild%z1\t%1
4641    #"
4642   [(set_attr "type" "fmov,multi")
4643    (set_attr "mode" "XF")
4644    (set_attr "fp_int_src" "true")])
4645
4646 (define_insn "floatsixf2"
4647   [(set (match_operand:XF 0 "register_operand" "=f,f")
4648         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4649   "TARGET_80387"
4650   "@
4651    fild%z1\t%1
4652    #"
4653   [(set_attr "type" "fmov,multi")
4654    (set_attr "mode" "XF")
4655    (set_attr "fp_int_src" "true")])
4656
4657 (define_insn "floatdixf2"
4658   [(set (match_operand:XF 0 "register_operand" "=f,f")
4659         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4660   "TARGET_80387"
4661   "@
4662    fild%z1\t%1
4663    #"
4664   [(set_attr "type" "fmov,multi")
4665    (set_attr "mode" "XF")
4666    (set_attr "fp_int_src" "true")])
4667
4668 ;; %%% Kill these when reload knows how to do it.
4669 (define_split
4670   [(set (match_operand 0 "fp_register_operand" "")
4671         (float (match_operand 1 "register_operand" "")))]
4672   "reload_completed
4673    && TARGET_80387
4674    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4675   [(const_int 0)]
4676 {
4677   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4678   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4679   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4680   ix86_free_from_memory (GET_MODE (operands[1]));
4681   DONE;
4682 })
4683
4684 (define_expand "floatunssisf2"
4685   [(use (match_operand:SF 0 "register_operand" ""))
4686    (use (match_operand:SI 1 "register_operand" ""))]
4687   "!TARGET_64BIT && TARGET_SSE_MATH"
4688   "x86_emit_floatuns (operands); DONE;")
4689
4690 (define_expand "floatunsdisf2"
4691   [(use (match_operand:SF 0 "register_operand" ""))
4692    (use (match_operand:DI 1 "register_operand" ""))]
4693   "TARGET_64BIT && TARGET_SSE_MATH"
4694   "x86_emit_floatuns (operands); DONE;")
4695
4696 (define_expand "floatunsdidf2"
4697   [(use (match_operand:DF 0 "register_operand" ""))
4698    (use (match_operand:DI 1 "register_operand" ""))]
4699   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4700   "x86_emit_floatuns (operands); DONE;")
4701 \f
4702 ;; SSE extract/set expanders
4703
4704 \f
4705 ;; Add instructions
4706
4707 ;; %%% splits for addsidi3
4708 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4709 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4710 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4711
4712 (define_expand "adddi3"
4713   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4714         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4715                  (match_operand:DI 2 "x86_64_general_operand" "")))
4716    (clobber (reg:CC FLAGS_REG))]
4717   ""
4718   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4719
4720 (define_insn "*adddi3_1"
4721   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4722         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4723                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4724    (clobber (reg:CC FLAGS_REG))]
4725   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4726   "#")
4727
4728 (define_split
4729   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4730         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4731                  (match_operand:DI 2 "general_operand" "")))
4732    (clobber (reg:CC FLAGS_REG))]
4733   "!TARGET_64BIT && reload_completed"
4734   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4735                                           UNSPEC_ADD_CARRY))
4736               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4737    (parallel [(set (match_dup 3)
4738                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4739                                      (match_dup 4))
4740                             (match_dup 5)))
4741               (clobber (reg:CC FLAGS_REG))])]
4742   "split_di (operands+0, 1, operands+0, operands+3);
4743    split_di (operands+1, 1, operands+1, operands+4);
4744    split_di (operands+2, 1, operands+2, operands+5);")
4745
4746 (define_insn "adddi3_carry_rex64"
4747   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4748           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4749                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4750                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4753   "adc{q}\t{%2, %0|%0, %2}"
4754   [(set_attr "type" "alu")
4755    (set_attr "pent_pair" "pu")
4756    (set_attr "mode" "DI")])
4757
4758 (define_insn "*adddi3_cc_rex64"
4759   [(set (reg:CC FLAGS_REG)
4760         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4761                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4762                    UNSPEC_ADD_CARRY))
4763    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4764         (plus:DI (match_dup 1) (match_dup 2)))]
4765   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4766   "add{q}\t{%2, %0|%0, %2}"
4767   [(set_attr "type" "alu")
4768    (set_attr "mode" "DI")])
4769
4770 (define_insn "addqi3_carry"
4771   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4772           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4773                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4774                    (match_operand:QI 2 "general_operand" "qi,qm")))
4775    (clobber (reg:CC FLAGS_REG))]
4776   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4777   "adc{b}\t{%2, %0|%0, %2}"
4778   [(set_attr "type" "alu")
4779    (set_attr "pent_pair" "pu")
4780    (set_attr "mode" "QI")])
4781
4782 (define_insn "addhi3_carry"
4783   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4784           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4785                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4786                    (match_operand:HI 2 "general_operand" "ri,rm")))
4787    (clobber (reg:CC FLAGS_REG))]
4788   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4789   "adc{w}\t{%2, %0|%0, %2}"
4790   [(set_attr "type" "alu")
4791    (set_attr "pent_pair" "pu")
4792    (set_attr "mode" "HI")])
4793
4794 (define_insn "addsi3_carry"
4795   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4796           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4797                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4798                    (match_operand:SI 2 "general_operand" "ri,rm")))
4799    (clobber (reg:CC FLAGS_REG))]
4800   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4801   "adc{l}\t{%2, %0|%0, %2}"
4802   [(set_attr "type" "alu")
4803    (set_attr "pent_pair" "pu")
4804    (set_attr "mode" "SI")])
4805
4806 (define_insn "*addsi3_carry_zext"
4807   [(set (match_operand:DI 0 "register_operand" "=r")
4808           (zero_extend:DI 
4809             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4810                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4811                      (match_operand:SI 2 "general_operand" "rim"))))
4812    (clobber (reg:CC FLAGS_REG))]
4813   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4814   "adc{l}\t{%2, %k0|%k0, %2}"
4815   [(set_attr "type" "alu")
4816    (set_attr "pent_pair" "pu")
4817    (set_attr "mode" "SI")])
4818
4819 (define_insn "*addsi3_cc"
4820   [(set (reg:CC FLAGS_REG)
4821         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4822                     (match_operand:SI 2 "general_operand" "ri,rm")]
4823                    UNSPEC_ADD_CARRY))
4824    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4825         (plus:SI (match_dup 1) (match_dup 2)))]
4826   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4827   "add{l}\t{%2, %0|%0, %2}"
4828   [(set_attr "type" "alu")
4829    (set_attr "mode" "SI")])
4830
4831 (define_insn "addqi3_cc"
4832   [(set (reg:CC FLAGS_REG)
4833         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4834                     (match_operand:QI 2 "general_operand" "qi,qm")]
4835                    UNSPEC_ADD_CARRY))
4836    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4837         (plus:QI (match_dup 1) (match_dup 2)))]
4838   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4839   "add{b}\t{%2, %0|%0, %2}"
4840   [(set_attr "type" "alu")
4841    (set_attr "mode" "QI")])
4842
4843 (define_expand "addsi3"
4844   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4845                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4846                             (match_operand:SI 2 "general_operand" "")))
4847               (clobber (reg:CC FLAGS_REG))])]
4848   ""
4849   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4850
4851 (define_insn "*lea_1"
4852   [(set (match_operand:SI 0 "register_operand" "=r")
4853         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4854   "!TARGET_64BIT"
4855   "lea{l}\t{%a1, %0|%0, %a1}"
4856   [(set_attr "type" "lea")
4857    (set_attr "mode" "SI")])
4858
4859 (define_insn "*lea_1_rex64"
4860   [(set (match_operand:SI 0 "register_operand" "=r")
4861         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4862   "TARGET_64BIT"
4863   "lea{l}\t{%a1, %0|%0, %a1}"
4864   [(set_attr "type" "lea")
4865    (set_attr "mode" "SI")])
4866
4867 (define_insn "*lea_1_zext"
4868   [(set (match_operand:DI 0 "register_operand" "=r")
4869         (zero_extend:DI
4870          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4871   "TARGET_64BIT"
4872   "lea{l}\t{%a1, %k0|%k0, %a1}"
4873   [(set_attr "type" "lea")
4874    (set_attr "mode" "SI")])
4875
4876 (define_insn "*lea_2_rex64"
4877   [(set (match_operand:DI 0 "register_operand" "=r")
4878         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4879   "TARGET_64BIT"
4880   "lea{q}\t{%a1, %0|%0, %a1}"
4881   [(set_attr "type" "lea")
4882    (set_attr "mode" "DI")])
4883
4884 ;; The lea patterns for non-Pmodes needs to be matched by several
4885 ;; insns converted to real lea by splitters.
4886
4887 (define_insn_and_split "*lea_general_1"
4888   [(set (match_operand 0 "register_operand" "=r")
4889         (plus (plus (match_operand 1 "index_register_operand" "l")
4890                     (match_operand 2 "register_operand" "r"))
4891               (match_operand 3 "immediate_operand" "i")))]
4892   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4893     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4894    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4895    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4896    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4897    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4898        || GET_MODE (operands[3]) == VOIDmode)"
4899   "#"
4900   "&& reload_completed"
4901   [(const_int 0)]
4902 {
4903   rtx pat;
4904   operands[0] = gen_lowpart (SImode, operands[0]);
4905   operands[1] = gen_lowpart (Pmode, operands[1]);
4906   operands[2] = gen_lowpart (Pmode, operands[2]);
4907   operands[3] = gen_lowpart (Pmode, operands[3]);
4908   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4909                       operands[3]);
4910   if (Pmode != SImode)
4911     pat = gen_rtx_SUBREG (SImode, pat, 0);
4912   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4913   DONE;
4914 }
4915   [(set_attr "type" "lea")
4916    (set_attr "mode" "SI")])
4917
4918 (define_insn_and_split "*lea_general_1_zext"
4919   [(set (match_operand:DI 0 "register_operand" "=r")
4920         (zero_extend:DI
4921           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4922                             (match_operand:SI 2 "register_operand" "r"))
4923                    (match_operand:SI 3 "immediate_operand" "i"))))]
4924   "TARGET_64BIT"
4925   "#"
4926   "&& reload_completed"
4927   [(set (match_dup 0)
4928         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4929                                                      (match_dup 2))
4930                                             (match_dup 3)) 0)))]
4931 {
4932   operands[1] = gen_lowpart (Pmode, operands[1]);
4933   operands[2] = gen_lowpart (Pmode, operands[2]);
4934   operands[3] = gen_lowpart (Pmode, operands[3]);
4935 }
4936   [(set_attr "type" "lea")
4937    (set_attr "mode" "SI")])
4938
4939 (define_insn_and_split "*lea_general_2"
4940   [(set (match_operand 0 "register_operand" "=r")
4941         (plus (mult (match_operand 1 "index_register_operand" "l")
4942                     (match_operand 2 "const248_operand" "i"))
4943               (match_operand 3 "nonmemory_operand" "ri")))]
4944   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4945     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4946    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4947    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4948    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4949        || GET_MODE (operands[3]) == VOIDmode)"
4950   "#"
4951   "&& reload_completed"
4952   [(const_int 0)]
4953 {
4954   rtx pat;
4955   operands[0] = gen_lowpart (SImode, operands[0]);
4956   operands[1] = gen_lowpart (Pmode, operands[1]);
4957   operands[3] = gen_lowpart (Pmode, operands[3]);
4958   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4959                       operands[3]);
4960   if (Pmode != SImode)
4961     pat = gen_rtx_SUBREG (SImode, pat, 0);
4962   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4963   DONE;
4964 }
4965   [(set_attr "type" "lea")
4966    (set_attr "mode" "SI")])
4967
4968 (define_insn_and_split "*lea_general_2_zext"
4969   [(set (match_operand:DI 0 "register_operand" "=r")
4970         (zero_extend:DI
4971           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4972                             (match_operand:SI 2 "const248_operand" "n"))
4973                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4974   "TARGET_64BIT"
4975   "#"
4976   "&& reload_completed"
4977   [(set (match_dup 0)
4978         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4979                                                      (match_dup 2))
4980                                             (match_dup 3)) 0)))]
4981 {
4982   operands[1] = gen_lowpart (Pmode, operands[1]);
4983   operands[3] = gen_lowpart (Pmode, operands[3]);
4984 }
4985   [(set_attr "type" "lea")
4986    (set_attr "mode" "SI")])
4987
4988 (define_insn_and_split "*lea_general_3"
4989   [(set (match_operand 0 "register_operand" "=r")
4990         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4991                           (match_operand 2 "const248_operand" "i"))
4992                     (match_operand 3 "register_operand" "r"))
4993               (match_operand 4 "immediate_operand" "i")))]
4994   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4995     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4996    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4997    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4998    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4999   "#"
5000   "&& reload_completed"
5001   [(const_int 0)]
5002 {
5003   rtx pat;
5004   operands[0] = gen_lowpart (SImode, operands[0]);
5005   operands[1] = gen_lowpart (Pmode, operands[1]);
5006   operands[3] = gen_lowpart (Pmode, operands[3]);
5007   operands[4] = gen_lowpart (Pmode, operands[4]);
5008   pat = gen_rtx_PLUS (Pmode,
5009                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5010                                                          operands[2]),
5011                                     operands[3]),
5012                       operands[4]);
5013   if (Pmode != SImode)
5014     pat = gen_rtx_SUBREG (SImode, pat, 0);
5015   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5016   DONE;
5017 }
5018   [(set_attr "type" "lea")
5019    (set_attr "mode" "SI")])
5020
5021 (define_insn_and_split "*lea_general_3_zext"
5022   [(set (match_operand:DI 0 "register_operand" "=r")
5023         (zero_extend:DI
5024           (plus:SI (plus:SI (mult:SI
5025                               (match_operand:SI 1 "index_register_operand" "l")
5026                               (match_operand:SI 2 "const248_operand" "n"))
5027                             (match_operand:SI 3 "register_operand" "r"))
5028                    (match_operand:SI 4 "immediate_operand" "i"))))]
5029   "TARGET_64BIT"
5030   "#"
5031   "&& reload_completed"
5032   [(set (match_dup 0)
5033         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5034                                                               (match_dup 2))
5035                                                      (match_dup 3))
5036                                             (match_dup 4)) 0)))]
5037 {
5038   operands[1] = gen_lowpart (Pmode, operands[1]);
5039   operands[3] = gen_lowpart (Pmode, operands[3]);
5040   operands[4] = gen_lowpart (Pmode, operands[4]);
5041 }
5042   [(set_attr "type" "lea")
5043    (set_attr "mode" "SI")])
5044
5045 (define_insn "*adddi_1_rex64"
5046   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5047         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5048                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5049    (clobber (reg:CC FLAGS_REG))]
5050   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5051 {
5052   switch (get_attr_type (insn))
5053     {
5054     case TYPE_LEA:
5055       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5056       return "lea{q}\t{%a2, %0|%0, %a2}";
5057
5058     case TYPE_INCDEC:
5059       if (! rtx_equal_p (operands[0], operands[1]))
5060         abort ();
5061       if (operands[2] == const1_rtx)
5062         return "inc{q}\t%0";
5063       else if (operands[2] == constm1_rtx)
5064         return "dec{q}\t%0";
5065       else
5066         abort ();
5067
5068     default:
5069       if (! rtx_equal_p (operands[0], operands[1]))
5070         abort ();
5071
5072       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5073          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5074       if (GET_CODE (operands[2]) == CONST_INT
5075           /* Avoid overflows.  */
5076           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5077           && (INTVAL (operands[2]) == 128
5078               || (INTVAL (operands[2]) < 0
5079                   && INTVAL (operands[2]) != -128)))
5080         {
5081           operands[2] = GEN_INT (-INTVAL (operands[2]));
5082           return "sub{q}\t{%2, %0|%0, %2}";
5083         }
5084       return "add{q}\t{%2, %0|%0, %2}";
5085     }
5086 }
5087   [(set (attr "type")
5088      (cond [(eq_attr "alternative" "2")
5089               (const_string "lea")
5090             ; Current assemblers are broken and do not allow @GOTOFF in
5091             ; ought but a memory context.
5092             (match_operand:DI 2 "pic_symbolic_operand" "")
5093               (const_string "lea")
5094             (match_operand:DI 2 "incdec_operand" "")
5095               (const_string "incdec")
5096            ]
5097            (const_string "alu")))
5098    (set_attr "mode" "DI")])
5099
5100 ;; Convert lea to the lea pattern to avoid flags dependency.
5101 (define_split
5102   [(set (match_operand:DI 0 "register_operand" "")
5103         (plus:DI (match_operand:DI 1 "register_operand" "")
5104                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5105    (clobber (reg:CC FLAGS_REG))]
5106   "TARGET_64BIT && reload_completed
5107    && true_regnum (operands[0]) != true_regnum (operands[1])"
5108   [(set (match_dup 0)
5109         (plus:DI (match_dup 1)
5110                  (match_dup 2)))]
5111   "")
5112
5113 (define_insn "*adddi_2_rex64"
5114   [(set (reg FLAGS_REG)
5115         (compare
5116           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5117                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5118           (const_int 0)))                       
5119    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5120         (plus:DI (match_dup 1) (match_dup 2)))]
5121   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5122    && ix86_binary_operator_ok (PLUS, DImode, operands)
5123    /* Current assemblers are broken and do not allow @GOTOFF in
5124       ought but a memory context.  */
5125    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5126 {
5127   switch (get_attr_type (insn))
5128     {
5129     case TYPE_INCDEC:
5130       if (! rtx_equal_p (operands[0], operands[1]))
5131         abort ();
5132       if (operands[2] == const1_rtx)
5133         return "inc{q}\t%0";
5134       else if (operands[2] == constm1_rtx)
5135         return "dec{q}\t%0";
5136       else
5137         abort ();
5138
5139     default:
5140       if (! rtx_equal_p (operands[0], operands[1]))
5141         abort ();
5142       /* ???? We ought to handle there the 32bit case too
5143          - do we need new constraint?  */
5144       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5145          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5146       if (GET_CODE (operands[2]) == CONST_INT
5147           /* Avoid overflows.  */
5148           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5149           && (INTVAL (operands[2]) == 128
5150               || (INTVAL (operands[2]) < 0
5151                   && INTVAL (operands[2]) != -128)))
5152         {
5153           operands[2] = GEN_INT (-INTVAL (operands[2]));
5154           return "sub{q}\t{%2, %0|%0, %2}";
5155         }
5156       return "add{q}\t{%2, %0|%0, %2}";
5157     }
5158 }
5159   [(set (attr "type")
5160      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5161         (const_string "incdec")
5162         (const_string "alu")))
5163    (set_attr "mode" "DI")])
5164
5165 (define_insn "*adddi_3_rex64"
5166   [(set (reg FLAGS_REG)
5167         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5168                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5169    (clobber (match_scratch:DI 0 "=r"))]
5170   "TARGET_64BIT
5171    && ix86_match_ccmode (insn, CCZmode)
5172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5173    /* Current assemblers are broken and do not allow @GOTOFF in
5174       ought but a memory context.  */
5175    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5176 {
5177   switch (get_attr_type (insn))
5178     {
5179     case TYPE_INCDEC:
5180       if (! rtx_equal_p (operands[0], operands[1]))
5181         abort ();
5182       if (operands[2] == const1_rtx)
5183         return "inc{q}\t%0";
5184       else if (operands[2] == constm1_rtx)
5185         return "dec{q}\t%0";
5186       else
5187         abort ();
5188
5189     default:
5190       if (! rtx_equal_p (operands[0], operands[1]))
5191         abort ();
5192       /* ???? We ought to handle there the 32bit case too
5193          - do we need new constraint?  */
5194       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5195          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5196       if (GET_CODE (operands[2]) == CONST_INT
5197           /* Avoid overflows.  */
5198           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5199           && (INTVAL (operands[2]) == 128
5200               || (INTVAL (operands[2]) < 0
5201                   && INTVAL (operands[2]) != -128)))
5202         {
5203           operands[2] = GEN_INT (-INTVAL (operands[2]));
5204           return "sub{q}\t{%2, %0|%0, %2}";
5205         }
5206       return "add{q}\t{%2, %0|%0, %2}";
5207     }
5208 }
5209   [(set (attr "type")
5210      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5211         (const_string "incdec")
5212         (const_string "alu")))
5213    (set_attr "mode" "DI")])
5214
5215 ; For comparisons against 1, -1 and 128, we may generate better code
5216 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5217 ; is matched then.  We can't accept general immediate, because for
5218 ; case of overflows,  the result is messed up.
5219 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5220 ; when negated.
5221 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5222 ; only for comparisons not depending on it.
5223 (define_insn "*adddi_4_rex64"
5224   [(set (reg FLAGS_REG)
5225         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5226                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5227    (clobber (match_scratch:DI 0 "=rm"))]
5228   "TARGET_64BIT
5229    &&  ix86_match_ccmode (insn, CCGCmode)"
5230 {
5231   switch (get_attr_type (insn))
5232     {
5233     case TYPE_INCDEC:
5234       if (operands[2] == constm1_rtx)
5235         return "inc{q}\t%0";
5236       else if (operands[2] == const1_rtx)
5237         return "dec{q}\t%0";
5238       else
5239         abort();
5240
5241     default:
5242       if (! rtx_equal_p (operands[0], operands[1]))
5243         abort ();
5244       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5245          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5246       if ((INTVAL (operands[2]) == -128
5247            || (INTVAL (operands[2]) > 0
5248                && INTVAL (operands[2]) != 128))
5249           /* Avoid overflows.  */
5250           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5251         return "sub{q}\t{%2, %0|%0, %2}";
5252       operands[2] = GEN_INT (-INTVAL (operands[2]));
5253       return "add{q}\t{%2, %0|%0, %2}";
5254     }
5255 }
5256   [(set (attr "type")
5257      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5258         (const_string "incdec")
5259         (const_string "alu")))
5260    (set_attr "mode" "DI")])
5261
5262 (define_insn "*adddi_5_rex64"
5263   [(set (reg FLAGS_REG)
5264         (compare
5265           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5266                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5267           (const_int 0)))                       
5268    (clobber (match_scratch:DI 0 "=r"))]
5269   "TARGET_64BIT
5270    && ix86_match_ccmode (insn, CCGOCmode)
5271    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5272    /* Current assemblers are broken and do not allow @GOTOFF in
5273       ought but a memory context.  */
5274    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5275 {
5276   switch (get_attr_type (insn))
5277     {
5278     case TYPE_INCDEC:
5279       if (! rtx_equal_p (operands[0], operands[1]))
5280         abort ();
5281       if (operands[2] == const1_rtx)
5282         return "inc{q}\t%0";
5283       else if (operands[2] == constm1_rtx)
5284         return "dec{q}\t%0";
5285       else
5286         abort();
5287
5288     default:
5289       if (! rtx_equal_p (operands[0], operands[1]))
5290         abort ();
5291       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5292          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5293       if (GET_CODE (operands[2]) == CONST_INT
5294           /* Avoid overflows.  */
5295           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5296           && (INTVAL (operands[2]) == 128
5297               || (INTVAL (operands[2]) < 0
5298                   && INTVAL (operands[2]) != -128)))
5299         {
5300           operands[2] = GEN_INT (-INTVAL (operands[2]));
5301           return "sub{q}\t{%2, %0|%0, %2}";
5302         }
5303       return "add{q}\t{%2, %0|%0, %2}";
5304     }
5305 }
5306   [(set (attr "type")
5307      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5308         (const_string "incdec")
5309         (const_string "alu")))
5310    (set_attr "mode" "DI")])
5311
5312
5313 (define_insn "*addsi_1"
5314   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5315         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5316                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5317    (clobber (reg:CC FLAGS_REG))]
5318   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5319 {
5320   switch (get_attr_type (insn))
5321     {
5322     case TYPE_LEA:
5323       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5324       return "lea{l}\t{%a2, %0|%0, %a2}";
5325
5326     case TYPE_INCDEC:
5327       if (! rtx_equal_p (operands[0], operands[1]))
5328         abort ();
5329       if (operands[2] == const1_rtx)
5330         return "inc{l}\t%0";
5331       else if (operands[2] == constm1_rtx)
5332         return "dec{l}\t%0";
5333       else
5334         abort();
5335
5336     default:
5337       if (! rtx_equal_p (operands[0], operands[1]))
5338         abort ();
5339
5340       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5341          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5342       if (GET_CODE (operands[2]) == CONST_INT
5343           && (INTVAL (operands[2]) == 128
5344               || (INTVAL (operands[2]) < 0
5345                   && INTVAL (operands[2]) != -128)))
5346         {
5347           operands[2] = GEN_INT (-INTVAL (operands[2]));
5348           return "sub{l}\t{%2, %0|%0, %2}";
5349         }
5350       return "add{l}\t{%2, %0|%0, %2}";
5351     }
5352 }
5353   [(set (attr "type")
5354      (cond [(eq_attr "alternative" "2")
5355               (const_string "lea")
5356             ; Current assemblers are broken and do not allow @GOTOFF in
5357             ; ought but a memory context.
5358             (match_operand:SI 2 "pic_symbolic_operand" "")
5359               (const_string "lea")
5360             (match_operand:SI 2 "incdec_operand" "")
5361               (const_string "incdec")
5362            ]
5363            (const_string "alu")))
5364    (set_attr "mode" "SI")])
5365
5366 ;; Convert lea to the lea pattern to avoid flags dependency.
5367 (define_split
5368   [(set (match_operand 0 "register_operand" "")
5369         (plus (match_operand 1 "register_operand" "")
5370               (match_operand 2 "nonmemory_operand" "")))
5371    (clobber (reg:CC FLAGS_REG))]
5372   "reload_completed
5373    && true_regnum (operands[0]) != true_regnum (operands[1])"
5374   [(const_int 0)]
5375 {
5376   rtx pat;
5377   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5378      may confuse gen_lowpart.  */
5379   if (GET_MODE (operands[0]) != Pmode)
5380     {
5381       operands[1] = gen_lowpart (Pmode, operands[1]);
5382       operands[2] = gen_lowpart (Pmode, operands[2]);
5383     }
5384   operands[0] = gen_lowpart (SImode, operands[0]);
5385   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5386   if (Pmode != SImode)
5387     pat = gen_rtx_SUBREG (SImode, pat, 0);
5388   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5389   DONE;
5390 })
5391
5392 ;; It may seem that nonimmediate operand is proper one for operand 1.
5393 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5394 ;; we take care in ix86_binary_operator_ok to not allow two memory
5395 ;; operands so proper swapping will be done in reload.  This allow
5396 ;; patterns constructed from addsi_1 to match.
5397 (define_insn "addsi_1_zext"
5398   [(set (match_operand:DI 0 "register_operand" "=r,r")
5399         (zero_extend:DI
5400           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5401                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5402    (clobber (reg:CC FLAGS_REG))]
5403   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5404 {
5405   switch (get_attr_type (insn))
5406     {
5407     case TYPE_LEA:
5408       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5409       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5410
5411     case TYPE_INCDEC:
5412       if (operands[2] == const1_rtx)
5413         return "inc{l}\t%k0";
5414       else if (operands[2] == constm1_rtx)
5415         return "dec{l}\t%k0";
5416       else
5417         abort();
5418
5419     default:
5420       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5421          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5422       if (GET_CODE (operands[2]) == CONST_INT
5423           && (INTVAL (operands[2]) == 128
5424               || (INTVAL (operands[2]) < 0
5425                   && INTVAL (operands[2]) != -128)))
5426         {
5427           operands[2] = GEN_INT (-INTVAL (operands[2]));
5428           return "sub{l}\t{%2, %k0|%k0, %2}";
5429         }
5430       return "add{l}\t{%2, %k0|%k0, %2}";
5431     }
5432 }
5433   [(set (attr "type")
5434      (cond [(eq_attr "alternative" "1")
5435               (const_string "lea")
5436             ; Current assemblers are broken and do not allow @GOTOFF in
5437             ; ought but a memory context.
5438             (match_operand:SI 2 "pic_symbolic_operand" "")
5439               (const_string "lea")
5440             (match_operand:SI 2 "incdec_operand" "")
5441               (const_string "incdec")
5442            ]
5443            (const_string "alu")))
5444    (set_attr "mode" "SI")])
5445
5446 ;; Convert lea to the lea pattern to avoid flags dependency.
5447 (define_split
5448   [(set (match_operand:DI 0 "register_operand" "")
5449         (zero_extend:DI
5450           (plus:SI (match_operand:SI 1 "register_operand" "")
5451                    (match_operand:SI 2 "nonmemory_operand" ""))))
5452    (clobber (reg:CC FLAGS_REG))]
5453   "TARGET_64BIT && reload_completed
5454    && true_regnum (operands[0]) != true_regnum (operands[1])"
5455   [(set (match_dup 0)
5456         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5457 {
5458   operands[1] = gen_lowpart (Pmode, operands[1]);
5459   operands[2] = gen_lowpart (Pmode, operands[2]);
5460 })
5461
5462 (define_insn "*addsi_2"
5463   [(set (reg FLAGS_REG)
5464         (compare
5465           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5466                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5467           (const_int 0)))                       
5468    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5469         (plus:SI (match_dup 1) (match_dup 2)))]
5470   "ix86_match_ccmode (insn, CCGOCmode)
5471    && ix86_binary_operator_ok (PLUS, SImode, operands)
5472    /* Current assemblers are broken and do not allow @GOTOFF in
5473       ought but a memory context.  */
5474    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5475 {
5476   switch (get_attr_type (insn))
5477     {
5478     case TYPE_INCDEC:
5479       if (! rtx_equal_p (operands[0], operands[1]))
5480         abort ();
5481       if (operands[2] == const1_rtx)
5482         return "inc{l}\t%0";
5483       else if (operands[2] == constm1_rtx)
5484         return "dec{l}\t%0";
5485       else
5486         abort();
5487
5488     default:
5489       if (! rtx_equal_p (operands[0], operands[1]))
5490         abort ();
5491       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5492          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5493       if (GET_CODE (operands[2]) == CONST_INT
5494           && (INTVAL (operands[2]) == 128
5495               || (INTVAL (operands[2]) < 0
5496                   && INTVAL (operands[2]) != -128)))
5497         {
5498           operands[2] = GEN_INT (-INTVAL (operands[2]));
5499           return "sub{l}\t{%2, %0|%0, %2}";
5500         }
5501       return "add{l}\t{%2, %0|%0, %2}";
5502     }
5503 }
5504   [(set (attr "type")
5505      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5506         (const_string "incdec")
5507         (const_string "alu")))
5508    (set_attr "mode" "SI")])
5509
5510 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5511 (define_insn "*addsi_2_zext"
5512   [(set (reg FLAGS_REG)
5513         (compare
5514           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5515                    (match_operand:SI 2 "general_operand" "rmni"))
5516           (const_int 0)))                       
5517    (set (match_operand:DI 0 "register_operand" "=r")
5518         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5519   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5520    && ix86_binary_operator_ok (PLUS, SImode, operands)
5521    /* Current assemblers are broken and do not allow @GOTOFF in
5522       ought but a memory context.  */
5523    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5524 {
5525   switch (get_attr_type (insn))
5526     {
5527     case TYPE_INCDEC:
5528       if (operands[2] == const1_rtx)
5529         return "inc{l}\t%k0";
5530       else if (operands[2] == constm1_rtx)
5531         return "dec{l}\t%k0";
5532       else
5533         abort();
5534
5535     default:
5536       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5537          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5538       if (GET_CODE (operands[2]) == CONST_INT
5539           && (INTVAL (operands[2]) == 128
5540               || (INTVAL (operands[2]) < 0
5541                   && INTVAL (operands[2]) != -128)))
5542         {
5543           operands[2] = GEN_INT (-INTVAL (operands[2]));
5544           return "sub{l}\t{%2, %k0|%k0, %2}";
5545         }
5546       return "add{l}\t{%2, %k0|%k0, %2}";
5547     }
5548 }
5549   [(set (attr "type")
5550      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5551         (const_string "incdec")
5552         (const_string "alu")))
5553    (set_attr "mode" "SI")])
5554
5555 (define_insn "*addsi_3"
5556   [(set (reg FLAGS_REG)
5557         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5558                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5559    (clobber (match_scratch:SI 0 "=r"))]
5560   "ix86_match_ccmode (insn, CCZmode)
5561    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5562    /* Current assemblers are broken and do not allow @GOTOFF in
5563       ought but a memory context.  */
5564    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5565 {
5566   switch (get_attr_type (insn))
5567     {
5568     case TYPE_INCDEC:
5569       if (! rtx_equal_p (operands[0], operands[1]))
5570         abort ();
5571       if (operands[2] == const1_rtx)
5572         return "inc{l}\t%0";
5573       else if (operands[2] == constm1_rtx)
5574         return "dec{l}\t%0";
5575       else
5576         abort();
5577
5578     default:
5579       if (! rtx_equal_p (operands[0], operands[1]))
5580         abort ();
5581       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5582          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5583       if (GET_CODE (operands[2]) == CONST_INT
5584           && (INTVAL (operands[2]) == 128
5585               || (INTVAL (operands[2]) < 0
5586                   && INTVAL (operands[2]) != -128)))
5587         {
5588           operands[2] = GEN_INT (-INTVAL (operands[2]));
5589           return "sub{l}\t{%2, %0|%0, %2}";
5590         }
5591       return "add{l}\t{%2, %0|%0, %2}";
5592     }
5593 }
5594   [(set (attr "type")
5595      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5596         (const_string "incdec")
5597         (const_string "alu")))
5598    (set_attr "mode" "SI")])
5599
5600 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5601 (define_insn "*addsi_3_zext"
5602   [(set (reg FLAGS_REG)
5603         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5604                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5605    (set (match_operand:DI 0 "register_operand" "=r")
5606         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5607   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5608    && ix86_binary_operator_ok (PLUS, SImode, operands)
5609    /* Current assemblers are broken and do not allow @GOTOFF in
5610       ought but a memory context.  */
5611    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5612 {
5613   switch (get_attr_type (insn))
5614     {
5615     case TYPE_INCDEC:
5616       if (operands[2] == const1_rtx)
5617         return "inc{l}\t%k0";
5618       else if (operands[2] == constm1_rtx)
5619         return "dec{l}\t%k0";
5620       else
5621         abort();
5622
5623     default:
5624       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5625          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5626       if (GET_CODE (operands[2]) == CONST_INT
5627           && (INTVAL (operands[2]) == 128
5628               || (INTVAL (operands[2]) < 0
5629                   && INTVAL (operands[2]) != -128)))
5630         {
5631           operands[2] = GEN_INT (-INTVAL (operands[2]));
5632           return "sub{l}\t{%2, %k0|%k0, %2}";
5633         }
5634       return "add{l}\t{%2, %k0|%k0, %2}";
5635     }
5636 }
5637   [(set (attr "type")
5638      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5639         (const_string "incdec")
5640         (const_string "alu")))
5641    (set_attr "mode" "SI")])
5642
5643 ; For comparisons against 1, -1 and 128, we may generate better code
5644 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5645 ; is matched then.  We can't accept general immediate, because for
5646 ; case of overflows,  the result is messed up.
5647 ; This pattern also don't hold of 0x80000000, since the value overflows
5648 ; when negated.
5649 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5650 ; only for comparisons not depending on it.
5651 (define_insn "*addsi_4"
5652   [(set (reg FLAGS_REG)
5653         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5654                  (match_operand:SI 2 "const_int_operand" "n")))
5655    (clobber (match_scratch:SI 0 "=rm"))]
5656   "ix86_match_ccmode (insn, CCGCmode)
5657    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5658 {
5659   switch (get_attr_type (insn))
5660     {
5661     case TYPE_INCDEC:
5662       if (operands[2] == constm1_rtx)
5663         return "inc{l}\t%0";
5664       else if (operands[2] == const1_rtx)
5665         return "dec{l}\t%0";
5666       else
5667         abort();
5668
5669     default:
5670       if (! rtx_equal_p (operands[0], operands[1]))
5671         abort ();
5672       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5673          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5674       if ((INTVAL (operands[2]) == -128
5675            || (INTVAL (operands[2]) > 0
5676                && INTVAL (operands[2]) != 128)))
5677         return "sub{l}\t{%2, %0|%0, %2}";
5678       operands[2] = GEN_INT (-INTVAL (operands[2]));
5679       return "add{l}\t{%2, %0|%0, %2}";
5680     }
5681 }
5682   [(set (attr "type")
5683      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5684         (const_string "incdec")
5685         (const_string "alu")))
5686    (set_attr "mode" "SI")])
5687
5688 (define_insn "*addsi_5"
5689   [(set (reg FLAGS_REG)
5690         (compare
5691           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5692                    (match_operand:SI 2 "general_operand" "rmni"))
5693           (const_int 0)))                       
5694    (clobber (match_scratch:SI 0 "=r"))]
5695   "ix86_match_ccmode (insn, CCGOCmode)
5696    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5697    /* Current assemblers are broken and do not allow @GOTOFF in
5698       ought but a memory context.  */
5699    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5700 {
5701   switch (get_attr_type (insn))
5702     {
5703     case TYPE_INCDEC:
5704       if (! rtx_equal_p (operands[0], operands[1]))
5705         abort ();
5706       if (operands[2] == const1_rtx)
5707         return "inc{l}\t%0";
5708       else if (operands[2] == constm1_rtx)
5709         return "dec{l}\t%0";
5710       else
5711         abort();
5712
5713     default:
5714       if (! rtx_equal_p (operands[0], operands[1]))
5715         abort ();
5716       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5718       if (GET_CODE (operands[2]) == CONST_INT
5719           && (INTVAL (operands[2]) == 128
5720               || (INTVAL (operands[2]) < 0
5721                   && INTVAL (operands[2]) != -128)))
5722         {
5723           operands[2] = GEN_INT (-INTVAL (operands[2]));
5724           return "sub{l}\t{%2, %0|%0, %2}";
5725         }
5726       return "add{l}\t{%2, %0|%0, %2}";
5727     }
5728 }
5729   [(set (attr "type")
5730      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5731         (const_string "incdec")
5732         (const_string "alu")))
5733    (set_attr "mode" "SI")])
5734
5735 (define_expand "addhi3"
5736   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5737                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5738                             (match_operand:HI 2 "general_operand" "")))
5739               (clobber (reg:CC FLAGS_REG))])]
5740   "TARGET_HIMODE_MATH"
5741   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5742
5743 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5744 ;; type optimizations enabled by define-splits.  This is not important
5745 ;; for PII, and in fact harmful because of partial register stalls.
5746
5747 (define_insn "*addhi_1_lea"
5748   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5749         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5750                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5751    (clobber (reg:CC FLAGS_REG))]
5752   "!TARGET_PARTIAL_REG_STALL
5753    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5754 {
5755   switch (get_attr_type (insn))
5756     {
5757     case TYPE_LEA:
5758       return "#";
5759     case TYPE_INCDEC:
5760       if (operands[2] == const1_rtx)
5761         return "inc{w}\t%0";
5762       else if (operands[2] == constm1_rtx)
5763         return "dec{w}\t%0";
5764       abort();
5765
5766     default:
5767       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5768          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5769       if (GET_CODE (operands[2]) == CONST_INT
5770           && (INTVAL (operands[2]) == 128
5771               || (INTVAL (operands[2]) < 0
5772                   && INTVAL (operands[2]) != -128)))
5773         {
5774           operands[2] = GEN_INT (-INTVAL (operands[2]));
5775           return "sub{w}\t{%2, %0|%0, %2}";
5776         }
5777       return "add{w}\t{%2, %0|%0, %2}";
5778     }
5779 }
5780   [(set (attr "type")
5781      (if_then_else (eq_attr "alternative" "2")
5782         (const_string "lea")
5783         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5784            (const_string "incdec")
5785            (const_string "alu"))))
5786    (set_attr "mode" "HI,HI,SI")])
5787
5788 (define_insn "*addhi_1"
5789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5790         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5791                  (match_operand:HI 2 "general_operand" "ri,rm")))
5792    (clobber (reg:CC FLAGS_REG))]
5793   "TARGET_PARTIAL_REG_STALL
5794    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5795 {
5796   switch (get_attr_type (insn))
5797     {
5798     case TYPE_INCDEC:
5799       if (operands[2] == const1_rtx)
5800         return "inc{w}\t%0";
5801       else if (operands[2] == constm1_rtx)
5802         return "dec{w}\t%0";
5803       abort();
5804
5805     default:
5806       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5807          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5808       if (GET_CODE (operands[2]) == CONST_INT
5809           && (INTVAL (operands[2]) == 128
5810               || (INTVAL (operands[2]) < 0
5811                   && INTVAL (operands[2]) != -128)))
5812         {
5813           operands[2] = GEN_INT (-INTVAL (operands[2]));
5814           return "sub{w}\t{%2, %0|%0, %2}";
5815         }
5816       return "add{w}\t{%2, %0|%0, %2}";
5817     }
5818 }
5819   [(set (attr "type")
5820      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5821         (const_string "incdec")
5822         (const_string "alu")))
5823    (set_attr "mode" "HI")])
5824
5825 (define_insn "*addhi_2"
5826   [(set (reg FLAGS_REG)
5827         (compare
5828           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5829                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5830           (const_int 0)))                       
5831    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5832         (plus:HI (match_dup 1) (match_dup 2)))]
5833   "ix86_match_ccmode (insn, CCGOCmode)
5834    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5835 {
5836   switch (get_attr_type (insn))
5837     {
5838     case TYPE_INCDEC:
5839       if (operands[2] == const1_rtx)
5840         return "inc{w}\t%0";
5841       else if (operands[2] == constm1_rtx)
5842         return "dec{w}\t%0";
5843       abort();
5844
5845     default:
5846       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5847          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5848       if (GET_CODE (operands[2]) == CONST_INT
5849           && (INTVAL (operands[2]) == 128
5850               || (INTVAL (operands[2]) < 0
5851                   && INTVAL (operands[2]) != -128)))
5852         {
5853           operands[2] = GEN_INT (-INTVAL (operands[2]));
5854           return "sub{w}\t{%2, %0|%0, %2}";
5855         }
5856       return "add{w}\t{%2, %0|%0, %2}";
5857     }
5858 }
5859   [(set (attr "type")
5860      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5861         (const_string "incdec")
5862         (const_string "alu")))
5863    (set_attr "mode" "HI")])
5864
5865 (define_insn "*addhi_3"
5866   [(set (reg FLAGS_REG)
5867         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5868                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5869    (clobber (match_scratch:HI 0 "=r"))]
5870   "ix86_match_ccmode (insn, CCZmode)
5871    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5872 {
5873   switch (get_attr_type (insn))
5874     {
5875     case TYPE_INCDEC:
5876       if (operands[2] == const1_rtx)
5877         return "inc{w}\t%0";
5878       else if (operands[2] == constm1_rtx)
5879         return "dec{w}\t%0";
5880       abort();
5881
5882     default:
5883       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5884          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5885       if (GET_CODE (operands[2]) == CONST_INT
5886           && (INTVAL (operands[2]) == 128
5887               || (INTVAL (operands[2]) < 0
5888                   && INTVAL (operands[2]) != -128)))
5889         {
5890           operands[2] = GEN_INT (-INTVAL (operands[2]));
5891           return "sub{w}\t{%2, %0|%0, %2}";
5892         }
5893       return "add{w}\t{%2, %0|%0, %2}";
5894     }
5895 }
5896   [(set (attr "type")
5897      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5898         (const_string "incdec")
5899         (const_string "alu")))
5900    (set_attr "mode" "HI")])
5901
5902 ; See comments above addsi_4 for details.
5903 (define_insn "*addhi_4"
5904   [(set (reg FLAGS_REG)
5905         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5906                  (match_operand:HI 2 "const_int_operand" "n")))
5907    (clobber (match_scratch:HI 0 "=rm"))]
5908   "ix86_match_ccmode (insn, CCGCmode)
5909    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5910 {
5911   switch (get_attr_type (insn))
5912     {
5913     case TYPE_INCDEC:
5914       if (operands[2] == constm1_rtx)
5915         return "inc{w}\t%0";
5916       else if (operands[2] == const1_rtx)
5917         return "dec{w}\t%0";
5918       else
5919         abort();
5920
5921     default:
5922       if (! rtx_equal_p (operands[0], operands[1]))
5923         abort ();
5924       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5925          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5926       if ((INTVAL (operands[2]) == -128
5927            || (INTVAL (operands[2]) > 0
5928                && INTVAL (operands[2]) != 128)))
5929         return "sub{w}\t{%2, %0|%0, %2}";
5930       operands[2] = GEN_INT (-INTVAL (operands[2]));
5931       return "add{w}\t{%2, %0|%0, %2}";
5932     }
5933 }
5934   [(set (attr "type")
5935      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936         (const_string "incdec")
5937         (const_string "alu")))
5938    (set_attr "mode" "SI")])
5939
5940
5941 (define_insn "*addhi_5"
5942   [(set (reg FLAGS_REG)
5943         (compare
5944           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5945                    (match_operand:HI 2 "general_operand" "rmni"))
5946           (const_int 0)))                       
5947    (clobber (match_scratch:HI 0 "=r"))]
5948   "ix86_match_ccmode (insn, CCGOCmode)
5949    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5950 {
5951   switch (get_attr_type (insn))
5952     {
5953     case TYPE_INCDEC:
5954       if (operands[2] == const1_rtx)
5955         return "inc{w}\t%0";
5956       else if (operands[2] == constm1_rtx)
5957         return "dec{w}\t%0";
5958       abort();
5959
5960     default:
5961       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5962          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5963       if (GET_CODE (operands[2]) == CONST_INT
5964           && (INTVAL (operands[2]) == 128
5965               || (INTVAL (operands[2]) < 0
5966                   && INTVAL (operands[2]) != -128)))
5967         {
5968           operands[2] = GEN_INT (-INTVAL (operands[2]));
5969           return "sub{w}\t{%2, %0|%0, %2}";
5970         }
5971       return "add{w}\t{%2, %0|%0, %2}";
5972     }
5973 }
5974   [(set (attr "type")
5975      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5976         (const_string "incdec")
5977         (const_string "alu")))
5978    (set_attr "mode" "HI")])
5979
5980 (define_expand "addqi3"
5981   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5982                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5983                             (match_operand:QI 2 "general_operand" "")))
5984               (clobber (reg:CC FLAGS_REG))])]
5985   "TARGET_QIMODE_MATH"
5986   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5987
5988 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5989 (define_insn "*addqi_1_lea"
5990   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5991         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5992                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5993    (clobber (reg:CC FLAGS_REG))]
5994   "!TARGET_PARTIAL_REG_STALL
5995    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5996 {
5997   int widen = (which_alternative == 2);
5998   switch (get_attr_type (insn))
5999     {
6000     case TYPE_LEA:
6001       return "#";
6002     case TYPE_INCDEC:
6003       if (operands[2] == const1_rtx)
6004         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6005       else if (operands[2] == constm1_rtx)
6006         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6007       abort();
6008
6009     default:
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 (GET_CODE (operands[2]) == CONST_INT
6013           && (INTVAL (operands[2]) == 128
6014               || (INTVAL (operands[2]) < 0
6015                   && INTVAL (operands[2]) != -128)))
6016         {
6017           operands[2] = GEN_INT (-INTVAL (operands[2]));
6018           if (widen)
6019             return "sub{l}\t{%2, %k0|%k0, %2}";
6020           else
6021             return "sub{b}\t{%2, %0|%0, %2}";
6022         }
6023       if (widen)
6024         return "add{l}\t{%k2, %k0|%k0, %k2}";
6025       else
6026         return "add{b}\t{%2, %0|%0, %2}";
6027     }
6028 }
6029   [(set (attr "type")
6030      (if_then_else (eq_attr "alternative" "3")
6031         (const_string "lea")
6032         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6033            (const_string "incdec")
6034            (const_string "alu"))))
6035    (set_attr "mode" "QI,QI,SI,SI")])
6036
6037 (define_insn "*addqi_1"
6038   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6039         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6040                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6041    (clobber (reg:CC FLAGS_REG))]
6042   "TARGET_PARTIAL_REG_STALL
6043    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6044 {
6045   int widen = (which_alternative == 2);
6046   switch (get_attr_type (insn))
6047     {
6048     case TYPE_INCDEC:
6049       if (operands[2] == const1_rtx)
6050         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6051       else if (operands[2] == constm1_rtx)
6052         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6053       abort();
6054
6055     default:
6056       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6058       if (GET_CODE (operands[2]) == CONST_INT
6059           && (INTVAL (operands[2]) == 128
6060               || (INTVAL (operands[2]) < 0
6061                   && INTVAL (operands[2]) != -128)))
6062         {
6063           operands[2] = GEN_INT (-INTVAL (operands[2]));
6064           if (widen)
6065             return "sub{l}\t{%2, %k0|%k0, %2}";
6066           else
6067             return "sub{b}\t{%2, %0|%0, %2}";
6068         }
6069       if (widen)
6070         return "add{l}\t{%k2, %k0|%k0, %k2}";
6071       else
6072         return "add{b}\t{%2, %0|%0, %2}";
6073     }
6074 }
6075   [(set (attr "type")
6076      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6077         (const_string "incdec")
6078         (const_string "alu")))
6079    (set_attr "mode" "QI,QI,SI")])
6080
6081 (define_insn "*addqi_1_slp"
6082   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6083         (plus:QI (match_dup 0)
6084                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6085    (clobber (reg:CC FLAGS_REG))]
6086   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6087    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6088 {
6089   switch (get_attr_type (insn))
6090     {
6091     case TYPE_INCDEC:
6092       if (operands[1] == const1_rtx)
6093         return "inc{b}\t%0";
6094       else if (operands[1] == constm1_rtx)
6095         return "dec{b}\t%0";
6096       abort();
6097
6098     default:
6099       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6100       if (GET_CODE (operands[1]) == CONST_INT
6101           && INTVAL (operands[1]) < 0)
6102         {
6103           operands[1] = GEN_INT (-INTVAL (operands[1]));
6104           return "sub{b}\t{%1, %0|%0, %1}";
6105         }
6106       return "add{b}\t{%1, %0|%0, %1}";
6107     }
6108 }
6109   [(set (attr "type")
6110      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6111         (const_string "incdec")
6112         (const_string "alu1")))
6113    (set (attr "memory")
6114      (if_then_else (match_operand 1 "memory_operand" "")
6115         (const_string "load")
6116         (const_string "none")))
6117    (set_attr "mode" "QI")])
6118
6119 (define_insn "*addqi_2"
6120   [(set (reg FLAGS_REG)
6121         (compare
6122           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6123                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6124           (const_int 0)))
6125    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6126         (plus:QI (match_dup 1) (match_dup 2)))]
6127   "ix86_match_ccmode (insn, CCGOCmode)
6128    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6129 {
6130   switch (get_attr_type (insn))
6131     {
6132     case TYPE_INCDEC:
6133       if (operands[2] == const1_rtx)
6134         return "inc{b}\t%0";
6135       else if (operands[2] == constm1_rtx
6136                || (GET_CODE (operands[2]) == CONST_INT
6137                    && INTVAL (operands[2]) == 255))
6138         return "dec{b}\t%0";
6139       abort();
6140
6141     default:
6142       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6143       if (GET_CODE (operands[2]) == CONST_INT
6144           && INTVAL (operands[2]) < 0)
6145         {
6146           operands[2] = GEN_INT (-INTVAL (operands[2]));
6147           return "sub{b}\t{%2, %0|%0, %2}";
6148         }
6149       return "add{b}\t{%2, %0|%0, %2}";
6150     }
6151 }
6152   [(set (attr "type")
6153      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6154         (const_string "incdec")
6155         (const_string "alu")))
6156    (set_attr "mode" "QI")])
6157
6158 (define_insn "*addqi_3"
6159   [(set (reg FLAGS_REG)
6160         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6161                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6162    (clobber (match_scratch:QI 0 "=q"))]
6163   "ix86_match_ccmode (insn, CCZmode)
6164    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6165 {
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[2] == const1_rtx)
6170         return "inc{b}\t%0";
6171       else if (operands[2] == constm1_rtx
6172                || (GET_CODE (operands[2]) == CONST_INT
6173                    && INTVAL (operands[2]) == 255))
6174         return "dec{b}\t%0";
6175       abort();
6176
6177     default:
6178       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6179       if (GET_CODE (operands[2]) == CONST_INT
6180           && INTVAL (operands[2]) < 0)
6181         {
6182           operands[2] = GEN_INT (-INTVAL (operands[2]));
6183           return "sub{b}\t{%2, %0|%0, %2}";
6184         }
6185       return "add{b}\t{%2, %0|%0, %2}";
6186     }
6187 }
6188   [(set (attr "type")
6189      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6190         (const_string "incdec")
6191         (const_string "alu")))
6192    (set_attr "mode" "QI")])
6193
6194 ; See comments above addsi_4 for details.
6195 (define_insn "*addqi_4"
6196   [(set (reg FLAGS_REG)
6197         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6198                  (match_operand:QI 2 "const_int_operand" "n")))
6199    (clobber (match_scratch:QI 0 "=qm"))]
6200   "ix86_match_ccmode (insn, CCGCmode)
6201    && (INTVAL (operands[2]) & 0xff) != 0x80"
6202 {
6203   switch (get_attr_type (insn))
6204     {
6205     case TYPE_INCDEC:
6206       if (operands[2] == constm1_rtx
6207           || (GET_CODE (operands[2]) == CONST_INT
6208               && INTVAL (operands[2]) == 255))
6209         return "inc{b}\t%0";
6210       else if (operands[2] == const1_rtx)
6211         return "dec{b}\t%0";
6212       else
6213         abort();
6214
6215     default:
6216       if (! rtx_equal_p (operands[0], operands[1]))
6217         abort ();
6218       if (INTVAL (operands[2]) < 0)
6219         {
6220           operands[2] = GEN_INT (-INTVAL (operands[2]));
6221           return "add{b}\t{%2, %0|%0, %2}";
6222         }
6223       return "sub{b}\t{%2, %0|%0, %2}";
6224     }
6225 }
6226   [(set (attr "type")
6227      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6228         (const_string "incdec")
6229         (const_string "alu")))
6230    (set_attr "mode" "QI")])
6231
6232
6233 (define_insn "*addqi_5"
6234   [(set (reg FLAGS_REG)
6235         (compare
6236           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6237                    (match_operand:QI 2 "general_operand" "qmni"))
6238           (const_int 0)))
6239    (clobber (match_scratch:QI 0 "=q"))]
6240   "ix86_match_ccmode (insn, CCGOCmode)
6241    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6242 {
6243   switch (get_attr_type (insn))
6244     {
6245     case TYPE_INCDEC:
6246       if (operands[2] == const1_rtx)
6247         return "inc{b}\t%0";
6248       else if (operands[2] == constm1_rtx
6249                || (GET_CODE (operands[2]) == CONST_INT
6250                    && INTVAL (operands[2]) == 255))
6251         return "dec{b}\t%0";
6252       abort();
6253
6254     default:
6255       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6256       if (GET_CODE (operands[2]) == CONST_INT
6257           && INTVAL (operands[2]) < 0)
6258         {
6259           operands[2] = GEN_INT (-INTVAL (operands[2]));
6260           return "sub{b}\t{%2, %0|%0, %2}";
6261         }
6262       return "add{b}\t{%2, %0|%0, %2}";
6263     }
6264 }
6265   [(set (attr "type")
6266      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6267         (const_string "incdec")
6268         (const_string "alu")))
6269    (set_attr "mode" "QI")])
6270
6271
6272 (define_insn "addqi_ext_1"
6273   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6274                          (const_int 8)
6275                          (const_int 8))
6276         (plus:SI
6277           (zero_extract:SI
6278             (match_operand 1 "ext_register_operand" "0")
6279             (const_int 8)
6280             (const_int 8))
6281           (match_operand:QI 2 "general_operand" "Qmn")))
6282    (clobber (reg:CC FLAGS_REG))]
6283   "!TARGET_64BIT"
6284 {
6285   switch (get_attr_type (insn))
6286     {
6287     case TYPE_INCDEC:
6288       if (operands[2] == const1_rtx)
6289         return "inc{b}\t%h0";
6290       else if (operands[2] == constm1_rtx
6291                || (GET_CODE (operands[2]) == CONST_INT
6292                    && INTVAL (operands[2]) == 255))
6293         return "dec{b}\t%h0";
6294       abort();
6295
6296     default:
6297       return "add{b}\t{%2, %h0|%h0, %2}";
6298     }
6299 }
6300   [(set (attr "type")
6301      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6302         (const_string "incdec")
6303         (const_string "alu")))
6304    (set_attr "mode" "QI")])
6305
6306 (define_insn "*addqi_ext_1_rex64"
6307   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6308                          (const_int 8)
6309                          (const_int 8))
6310         (plus:SI
6311           (zero_extract:SI
6312             (match_operand 1 "ext_register_operand" "0")
6313             (const_int 8)
6314             (const_int 8))
6315           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6316    (clobber (reg:CC FLAGS_REG))]
6317   "TARGET_64BIT"
6318 {
6319   switch (get_attr_type (insn))
6320     {
6321     case TYPE_INCDEC:
6322       if (operands[2] == const1_rtx)
6323         return "inc{b}\t%h0";
6324       else if (operands[2] == constm1_rtx
6325                || (GET_CODE (operands[2]) == CONST_INT
6326                    && INTVAL (operands[2]) == 255))
6327         return "dec{b}\t%h0";
6328       abort();
6329
6330     default:
6331       return "add{b}\t{%2, %h0|%h0, %2}";
6332     }
6333 }
6334   [(set (attr "type")
6335      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6336         (const_string "incdec")
6337         (const_string "alu")))
6338    (set_attr "mode" "QI")])
6339
6340 (define_insn "*addqi_ext_2"
6341   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6342                          (const_int 8)
6343                          (const_int 8))
6344         (plus:SI
6345           (zero_extract:SI
6346             (match_operand 1 "ext_register_operand" "%0")
6347             (const_int 8)
6348             (const_int 8))
6349           (zero_extract:SI
6350             (match_operand 2 "ext_register_operand" "Q")
6351             (const_int 8)
6352             (const_int 8))))
6353    (clobber (reg:CC FLAGS_REG))]
6354   ""
6355   "add{b}\t{%h2, %h0|%h0, %h2}"
6356   [(set_attr "type" "alu")
6357    (set_attr "mode" "QI")])
6358
6359 ;; The patterns that match these are at the end of this file.
6360
6361 (define_expand "addxf3"
6362   [(set (match_operand:XF 0 "register_operand" "")
6363         (plus:XF (match_operand:XF 1 "register_operand" "")
6364                  (match_operand:XF 2 "register_operand" "")))]
6365   "TARGET_80387"
6366   "")
6367
6368 (define_expand "adddf3"
6369   [(set (match_operand:DF 0 "register_operand" "")
6370         (plus:DF (match_operand:DF 1 "register_operand" "")
6371                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6372   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6373   "")
6374
6375 (define_expand "addsf3"
6376   [(set (match_operand:SF 0 "register_operand" "")
6377         (plus:SF (match_operand:SF 1 "register_operand" "")
6378                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6379   "TARGET_80387 || TARGET_SSE_MATH"
6380   "")
6381 \f
6382 ;; Subtract instructions
6383
6384 ;; %%% splits for subsidi3
6385
6386 (define_expand "subdi3"
6387   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6388                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6389                              (match_operand:DI 2 "x86_64_general_operand" "")))
6390               (clobber (reg:CC FLAGS_REG))])]
6391   ""
6392   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6393
6394 (define_insn "*subdi3_1"
6395   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6396         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6397                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6398    (clobber (reg:CC FLAGS_REG))]
6399   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6400   "#")
6401
6402 (define_split
6403   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6404         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6405                   (match_operand:DI 2 "general_operand" "")))
6406    (clobber (reg:CC FLAGS_REG))]
6407   "!TARGET_64BIT && reload_completed"
6408   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6409               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6410    (parallel [(set (match_dup 3)
6411                    (minus:SI (match_dup 4)
6412                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6413                                       (match_dup 5))))
6414               (clobber (reg:CC FLAGS_REG))])]
6415   "split_di (operands+0, 1, operands+0, operands+3);
6416    split_di (operands+1, 1, operands+1, operands+4);
6417    split_di (operands+2, 1, operands+2, operands+5);")
6418
6419 (define_insn "subdi3_carry_rex64"
6420   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6421           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6422             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6423                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6424    (clobber (reg:CC FLAGS_REG))]
6425   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6426   "sbb{q}\t{%2, %0|%0, %2}"
6427   [(set_attr "type" "alu")
6428    (set_attr "pent_pair" "pu")
6429    (set_attr "mode" "DI")])
6430
6431 (define_insn "*subdi_1_rex64"
6432   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6433         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6434                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6435    (clobber (reg:CC FLAGS_REG))]
6436   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6437   "sub{q}\t{%2, %0|%0, %2}"
6438   [(set_attr "type" "alu")
6439    (set_attr "mode" "DI")])
6440
6441 (define_insn "*subdi_2_rex64"
6442   [(set (reg FLAGS_REG)
6443         (compare
6444           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6445                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6446           (const_int 0)))
6447    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6448         (minus:DI (match_dup 1) (match_dup 2)))]
6449   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6450    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6451   "sub{q}\t{%2, %0|%0, %2}"
6452   [(set_attr "type" "alu")
6453    (set_attr "mode" "DI")])
6454
6455 (define_insn "*subdi_3_rex63"
6456   [(set (reg FLAGS_REG)
6457         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6458                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6459    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6460         (minus:DI (match_dup 1) (match_dup 2)))]
6461   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6462    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6463   "sub{q}\t{%2, %0|%0, %2}"
6464   [(set_attr "type" "alu")
6465    (set_attr "mode" "DI")])
6466
6467 (define_insn "subqi3_carry"
6468   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6469           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6470             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6471                (match_operand:QI 2 "general_operand" "qi,qm"))))
6472    (clobber (reg:CC FLAGS_REG))]
6473   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6474   "sbb{b}\t{%2, %0|%0, %2}"
6475   [(set_attr "type" "alu")
6476    (set_attr "pent_pair" "pu")
6477    (set_attr "mode" "QI")])
6478
6479 (define_insn "subhi3_carry"
6480   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6481           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6482             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6483                (match_operand:HI 2 "general_operand" "ri,rm"))))
6484    (clobber (reg:CC FLAGS_REG))]
6485   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6486   "sbb{w}\t{%2, %0|%0, %2}"
6487   [(set_attr "type" "alu")
6488    (set_attr "pent_pair" "pu")
6489    (set_attr "mode" "HI")])
6490
6491 (define_insn "subsi3_carry"
6492   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6493           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6494             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6495                (match_operand:SI 2 "general_operand" "ri,rm"))))
6496    (clobber (reg:CC FLAGS_REG))]
6497   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6498   "sbb{l}\t{%2, %0|%0, %2}"
6499   [(set_attr "type" "alu")
6500    (set_attr "pent_pair" "pu")
6501    (set_attr "mode" "SI")])
6502
6503 (define_insn "subsi3_carry_zext"
6504   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6505           (zero_extend:DI
6506             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6507               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6508                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6509    (clobber (reg:CC FLAGS_REG))]
6510   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6511   "sbb{l}\t{%2, %k0|%k0, %2}"
6512   [(set_attr "type" "alu")
6513    (set_attr "pent_pair" "pu")
6514    (set_attr "mode" "SI")])
6515
6516 (define_expand "subsi3"
6517   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6518                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6519                              (match_operand:SI 2 "general_operand" "")))
6520               (clobber (reg:CC FLAGS_REG))])]
6521   ""
6522   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6523
6524 (define_insn "*subsi_1"
6525   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6526         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6527                   (match_operand:SI 2 "general_operand" "ri,rm")))
6528    (clobber (reg:CC FLAGS_REG))]
6529   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6530   "sub{l}\t{%2, %0|%0, %2}"
6531   [(set_attr "type" "alu")
6532    (set_attr "mode" "SI")])
6533
6534 (define_insn "*subsi_1_zext"
6535   [(set (match_operand:DI 0 "register_operand" "=r")
6536         (zero_extend:DI
6537           (minus:SI (match_operand:SI 1 "register_operand" "0")
6538                     (match_operand:SI 2 "general_operand" "rim"))))
6539    (clobber (reg:CC FLAGS_REG))]
6540   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6541   "sub{l}\t{%2, %k0|%k0, %2}"
6542   [(set_attr "type" "alu")
6543    (set_attr "mode" "SI")])
6544
6545 (define_insn "*subsi_2"
6546   [(set (reg FLAGS_REG)
6547         (compare
6548           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6549                     (match_operand:SI 2 "general_operand" "ri,rm"))
6550           (const_int 0)))
6551    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6552         (minus:SI (match_dup 1) (match_dup 2)))]
6553   "ix86_match_ccmode (insn, CCGOCmode)
6554    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555   "sub{l}\t{%2, %0|%0, %2}"
6556   [(set_attr "type" "alu")
6557    (set_attr "mode" "SI")])
6558
6559 (define_insn "*subsi_2_zext"
6560   [(set (reg FLAGS_REG)
6561         (compare
6562           (minus:SI (match_operand:SI 1 "register_operand" "0")
6563                     (match_operand:SI 2 "general_operand" "rim"))
6564           (const_int 0)))
6565    (set (match_operand:DI 0 "register_operand" "=r")
6566         (zero_extend:DI
6567           (minus:SI (match_dup 1)
6568                     (match_dup 2))))]
6569   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6570    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6571   "sub{l}\t{%2, %k0|%k0, %2}"
6572   [(set_attr "type" "alu")
6573    (set_attr "mode" "SI")])
6574
6575 (define_insn "*subsi_3"
6576   [(set (reg FLAGS_REG)
6577         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6578                  (match_operand:SI 2 "general_operand" "ri,rm")))
6579    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6580         (minus:SI (match_dup 1) (match_dup 2)))]
6581   "ix86_match_ccmode (insn, CCmode)
6582    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6583   "sub{l}\t{%2, %0|%0, %2}"
6584   [(set_attr "type" "alu")
6585    (set_attr "mode" "SI")])
6586
6587 (define_insn "*subsi_3_zext"
6588   [(set (reg FLAGS_REG)
6589         (compare (match_operand:SI 1 "register_operand" "0")
6590                  (match_operand:SI 2 "general_operand" "rim")))
6591    (set (match_operand:DI 0 "register_operand" "=r")
6592         (zero_extend:DI
6593           (minus:SI (match_dup 1)
6594                     (match_dup 2))))]
6595   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6596    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6597   "sub{q}\t{%2, %0|%0, %2}"
6598   [(set_attr "type" "alu")
6599    (set_attr "mode" "DI")])
6600
6601 (define_expand "subhi3"
6602   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6603                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6604                              (match_operand:HI 2 "general_operand" "")))
6605               (clobber (reg:CC FLAGS_REG))])]
6606   "TARGET_HIMODE_MATH"
6607   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6608
6609 (define_insn "*subhi_1"
6610   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6611         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6612                   (match_operand:HI 2 "general_operand" "ri,rm")))
6613    (clobber (reg:CC FLAGS_REG))]
6614   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6615   "sub{w}\t{%2, %0|%0, %2}"
6616   [(set_attr "type" "alu")
6617    (set_attr "mode" "HI")])
6618
6619 (define_insn "*subhi_2"
6620   [(set (reg FLAGS_REG)
6621         (compare
6622           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6623                     (match_operand:HI 2 "general_operand" "ri,rm"))
6624           (const_int 0)))
6625    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6626         (minus:HI (match_dup 1) (match_dup 2)))]
6627   "ix86_match_ccmode (insn, CCGOCmode)
6628    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6629   "sub{w}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "mode" "HI")])
6632
6633 (define_insn "*subhi_3"
6634   [(set (reg FLAGS_REG)
6635         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6636                  (match_operand:HI 2 "general_operand" "ri,rm")))
6637    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6638         (minus:HI (match_dup 1) (match_dup 2)))]
6639   "ix86_match_ccmode (insn, CCmode)
6640    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6641   "sub{w}\t{%2, %0|%0, %2}"
6642   [(set_attr "type" "alu")
6643    (set_attr "mode" "HI")])
6644
6645 (define_expand "subqi3"
6646   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6647                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6648                              (match_operand:QI 2 "general_operand" "")))
6649               (clobber (reg:CC FLAGS_REG))])]
6650   "TARGET_QIMODE_MATH"
6651   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6652
6653 (define_insn "*subqi_1"
6654   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6655         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6656                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6659   "sub{b}\t{%2, %0|%0, %2}"
6660   [(set_attr "type" "alu")
6661    (set_attr "mode" "QI")])
6662
6663 (define_insn "*subqi_1_slp"
6664   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6665         (minus:QI (match_dup 0)
6666                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6667    (clobber (reg:CC FLAGS_REG))]
6668   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6669    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6670   "sub{b}\t{%1, %0|%0, %1}"
6671   [(set_attr "type" "alu1")
6672    (set_attr "mode" "QI")])
6673
6674 (define_insn "*subqi_2"
6675   [(set (reg FLAGS_REG)
6676         (compare
6677           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6678                     (match_operand:QI 2 "general_operand" "qi,qm"))
6679           (const_int 0)))
6680    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6681         (minus:HI (match_dup 1) (match_dup 2)))]
6682   "ix86_match_ccmode (insn, CCGOCmode)
6683    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6684   "sub{b}\t{%2, %0|%0, %2}"
6685   [(set_attr "type" "alu")
6686    (set_attr "mode" "QI")])
6687
6688 (define_insn "*subqi_3"
6689   [(set (reg FLAGS_REG)
6690         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6691                  (match_operand:QI 2 "general_operand" "qi,qm")))
6692    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6693         (minus:HI (match_dup 1) (match_dup 2)))]
6694   "ix86_match_ccmode (insn, CCmode)
6695    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6696   "sub{b}\t{%2, %0|%0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "mode" "QI")])
6699
6700 ;; The patterns that match these are at the end of this file.
6701
6702 (define_expand "subxf3"
6703   [(set (match_operand:XF 0 "register_operand" "")
6704         (minus:XF (match_operand:XF 1 "register_operand" "")
6705                   (match_operand:XF 2 "register_operand" "")))]
6706   "TARGET_80387"
6707   "")
6708
6709 (define_expand "subdf3"
6710   [(set (match_operand:DF 0 "register_operand" "")
6711         (minus:DF (match_operand:DF 1 "register_operand" "")
6712                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6713   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6714   "")
6715
6716 (define_expand "subsf3"
6717   [(set (match_operand:SF 0 "register_operand" "")
6718         (minus:SF (match_operand:SF 1 "register_operand" "")
6719                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6720   "TARGET_80387 || TARGET_SSE_MATH"
6721   "")
6722 \f
6723 ;; Multiply instructions
6724
6725 (define_expand "muldi3"
6726   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6727                    (mult:DI (match_operand:DI 1 "register_operand" "")
6728                             (match_operand:DI 2 "x86_64_general_operand" "")))
6729               (clobber (reg:CC FLAGS_REG))])]
6730   "TARGET_64BIT"
6731   "")
6732
6733 (define_insn "*muldi3_1_rex64"
6734   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6735         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6736                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6737    (clobber (reg:CC FLAGS_REG))]
6738   "TARGET_64BIT
6739    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6740   "@
6741    imul{q}\t{%2, %1, %0|%0, %1, %2}
6742    imul{q}\t{%2, %1, %0|%0, %1, %2}
6743    imul{q}\t{%2, %0|%0, %2}"
6744   [(set_attr "type" "imul")
6745    (set_attr "prefix_0f" "0,0,1")
6746    (set (attr "athlon_decode")
6747         (cond [(eq_attr "cpu" "athlon")
6748                   (const_string "vector")
6749                (eq_attr "alternative" "1")
6750                   (const_string "vector")
6751                (and (eq_attr "alternative" "2")
6752                     (match_operand 1 "memory_operand" ""))
6753                   (const_string "vector")]
6754               (const_string "direct")))
6755    (set_attr "mode" "DI")])
6756
6757 (define_expand "mulsi3"
6758   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6759                    (mult:SI (match_operand:SI 1 "register_operand" "")
6760                             (match_operand:SI 2 "general_operand" "")))
6761               (clobber (reg:CC FLAGS_REG))])]
6762   ""
6763   "")
6764
6765 (define_insn "*mulsi3_1"
6766   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6767         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6768                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6769    (clobber (reg:CC FLAGS_REG))]
6770   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6771   "@
6772    imul{l}\t{%2, %1, %0|%0, %1, %2}
6773    imul{l}\t{%2, %1, %0|%0, %1, %2}
6774    imul{l}\t{%2, %0|%0, %2}"
6775   [(set_attr "type" "imul")
6776    (set_attr "prefix_0f" "0,0,1")
6777    (set (attr "athlon_decode")
6778         (cond [(eq_attr "cpu" "athlon")
6779                   (const_string "vector")
6780                (eq_attr "alternative" "1")
6781                   (const_string "vector")
6782                (and (eq_attr "alternative" "2")
6783                     (match_operand 1 "memory_operand" ""))
6784                   (const_string "vector")]
6785               (const_string "direct")))
6786    (set_attr "mode" "SI")])
6787
6788 (define_insn "*mulsi3_1_zext"
6789   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6790         (zero_extend:DI
6791           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6792                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6793    (clobber (reg:CC FLAGS_REG))]
6794   "TARGET_64BIT
6795    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6796   "@
6797    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6798    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6799    imul{l}\t{%2, %k0|%k0, %2}"
6800   [(set_attr "type" "imul")
6801    (set_attr "prefix_0f" "0,0,1")
6802    (set (attr "athlon_decode")
6803         (cond [(eq_attr "cpu" "athlon")
6804                   (const_string "vector")
6805                (eq_attr "alternative" "1")
6806                   (const_string "vector")
6807                (and (eq_attr "alternative" "2")
6808                     (match_operand 1 "memory_operand" ""))
6809                   (const_string "vector")]
6810               (const_string "direct")))
6811    (set_attr "mode" "SI")])
6812
6813 (define_expand "mulhi3"
6814   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6815                    (mult:HI (match_operand:HI 1 "register_operand" "")
6816                             (match_operand:HI 2 "general_operand" "")))
6817               (clobber (reg:CC FLAGS_REG))])]
6818   "TARGET_HIMODE_MATH"
6819   "")
6820
6821 (define_insn "*mulhi3_1"
6822   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6823         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6824                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6825    (clobber (reg:CC FLAGS_REG))]
6826   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6827   "@
6828    imul{w}\t{%2, %1, %0|%0, %1, %2}
6829    imul{w}\t{%2, %1, %0|%0, %1, %2}
6830    imul{w}\t{%2, %0|%0, %2}"
6831   [(set_attr "type" "imul")
6832    (set_attr "prefix_0f" "0,0,1")
6833    (set (attr "athlon_decode")
6834         (cond [(eq_attr "cpu" "athlon")
6835                   (const_string "vector")
6836                (eq_attr "alternative" "1,2")
6837                   (const_string "vector")]
6838               (const_string "direct")))
6839    (set_attr "mode" "HI")])
6840
6841 (define_expand "mulqi3"
6842   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6843                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6844                             (match_operand:QI 2 "register_operand" "")))
6845               (clobber (reg:CC FLAGS_REG))])]
6846   "TARGET_QIMODE_MATH"
6847   "")
6848
6849 (define_insn "*mulqi3_1"
6850   [(set (match_operand:QI 0 "register_operand" "=a")
6851         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6852                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6853    (clobber (reg:CC FLAGS_REG))]
6854   "TARGET_QIMODE_MATH
6855    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6856   "mul{b}\t%2"
6857   [(set_attr "type" "imul")
6858    (set_attr "length_immediate" "0")
6859    (set (attr "athlon_decode")
6860      (if_then_else (eq_attr "cpu" "athlon")
6861         (const_string "vector")
6862         (const_string "direct")))
6863    (set_attr "mode" "QI")])
6864
6865 (define_expand "umulqihi3"
6866   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6867                    (mult:HI (zero_extend:HI
6868                               (match_operand:QI 1 "nonimmediate_operand" ""))
6869                             (zero_extend:HI
6870                               (match_operand:QI 2 "register_operand" ""))))
6871               (clobber (reg:CC FLAGS_REG))])]
6872   "TARGET_QIMODE_MATH"
6873   "")
6874
6875 (define_insn "*umulqihi3_1"
6876   [(set (match_operand:HI 0 "register_operand" "=a")
6877         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6878                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6879    (clobber (reg:CC FLAGS_REG))]
6880   "TARGET_QIMODE_MATH
6881    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6882   "mul{b}\t%2"
6883   [(set_attr "type" "imul")
6884    (set_attr "length_immediate" "0")
6885    (set (attr "athlon_decode")
6886      (if_then_else (eq_attr "cpu" "athlon")
6887         (const_string "vector")
6888         (const_string "direct")))
6889    (set_attr "mode" "QI")])
6890
6891 (define_expand "mulqihi3"
6892   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6893                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6894                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6895               (clobber (reg:CC FLAGS_REG))])]
6896   "TARGET_QIMODE_MATH"
6897   "")
6898
6899 (define_insn "*mulqihi3_insn"
6900   [(set (match_operand:HI 0 "register_operand" "=a")
6901         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6902                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6903    (clobber (reg:CC FLAGS_REG))]
6904   "TARGET_QIMODE_MATH
6905    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6906   "imul{b}\t%2"
6907   [(set_attr "type" "imul")
6908    (set_attr "length_immediate" "0")
6909    (set (attr "athlon_decode")
6910      (if_then_else (eq_attr "cpu" "athlon")
6911         (const_string "vector")
6912         (const_string "direct")))
6913    (set_attr "mode" "QI")])
6914
6915 (define_expand "umulditi3"
6916   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6917                    (mult:TI (zero_extend:TI
6918                               (match_operand:DI 1 "nonimmediate_operand" ""))
6919                             (zero_extend:TI
6920                               (match_operand:DI 2 "register_operand" ""))))
6921               (clobber (reg:CC FLAGS_REG))])]
6922   "TARGET_64BIT"
6923   "")
6924
6925 (define_insn "*umulditi3_insn"
6926   [(set (match_operand:TI 0 "register_operand" "=A")
6927         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6928                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6929    (clobber (reg:CC FLAGS_REG))]
6930   "TARGET_64BIT
6931    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6932   "mul{q}\t%2"
6933   [(set_attr "type" "imul")
6934    (set_attr "length_immediate" "0")
6935    (set (attr "athlon_decode")
6936      (if_then_else (eq_attr "cpu" "athlon")
6937         (const_string "vector")
6938         (const_string "double")))
6939    (set_attr "mode" "DI")])
6940
6941 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6942 (define_expand "umulsidi3"
6943   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6944                    (mult:DI (zero_extend:DI
6945                               (match_operand:SI 1 "nonimmediate_operand" ""))
6946                             (zero_extend:DI
6947                               (match_operand:SI 2 "register_operand" ""))))
6948               (clobber (reg:CC FLAGS_REG))])]
6949   "!TARGET_64BIT"
6950   "")
6951
6952 (define_insn "*umulsidi3_insn"
6953   [(set (match_operand:DI 0 "register_operand" "=A")
6954         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6955                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6956    (clobber (reg:CC FLAGS_REG))]
6957   "!TARGET_64BIT
6958    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6959   "mul{l}\t%2"
6960   [(set_attr "type" "imul")
6961    (set_attr "length_immediate" "0")
6962    (set (attr "athlon_decode")
6963      (if_then_else (eq_attr "cpu" "athlon")
6964         (const_string "vector")
6965         (const_string "double")))
6966    (set_attr "mode" "SI")])
6967
6968 (define_expand "mulditi3"
6969   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6970                    (mult:TI (sign_extend:TI
6971                               (match_operand:DI 1 "nonimmediate_operand" ""))
6972                             (sign_extend:TI
6973                               (match_operand:DI 2 "register_operand" ""))))
6974               (clobber (reg:CC FLAGS_REG))])]
6975   "TARGET_64BIT"
6976   "")
6977
6978 (define_insn "*mulditi3_insn"
6979   [(set (match_operand:TI 0 "register_operand" "=A")
6980         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6981                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6982    (clobber (reg:CC FLAGS_REG))]
6983   "TARGET_64BIT
6984    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6985   "imul{q}\t%2"
6986   [(set_attr "type" "imul")
6987    (set_attr "length_immediate" "0")
6988    (set (attr "athlon_decode")
6989      (if_then_else (eq_attr "cpu" "athlon")
6990         (const_string "vector")
6991         (const_string "double")))
6992    (set_attr "mode" "DI")])
6993
6994 (define_expand "mulsidi3"
6995   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6996                    (mult:DI (sign_extend:DI
6997                               (match_operand:SI 1 "nonimmediate_operand" ""))
6998                             (sign_extend:DI
6999                               (match_operand:SI 2 "register_operand" ""))))
7000               (clobber (reg:CC FLAGS_REG))])]
7001   "!TARGET_64BIT"
7002   "")
7003
7004 (define_insn "*mulsidi3_insn"
7005   [(set (match_operand:DI 0 "register_operand" "=A")
7006         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7007                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7008    (clobber (reg:CC FLAGS_REG))]
7009   "!TARGET_64BIT
7010    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7011   "imul{l}\t%2"
7012   [(set_attr "type" "imul")
7013    (set_attr "length_immediate" "0")
7014    (set (attr "athlon_decode")
7015      (if_then_else (eq_attr "cpu" "athlon")
7016         (const_string "vector")
7017         (const_string "double")))
7018    (set_attr "mode" "SI")])
7019
7020 (define_expand "umuldi3_highpart"
7021   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7022                    (truncate:DI
7023                      (lshiftrt:TI
7024                        (mult:TI (zero_extend:TI
7025                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7026                                 (zero_extend:TI
7027                                   (match_operand:DI 2 "register_operand" "")))
7028                        (const_int 64))))
7029               (clobber (match_scratch:DI 3 ""))
7030               (clobber (reg:CC FLAGS_REG))])]
7031   "TARGET_64BIT"
7032   "")
7033
7034 (define_insn "*umuldi3_highpart_rex64"
7035   [(set (match_operand:DI 0 "register_operand" "=d")
7036         (truncate:DI
7037           (lshiftrt:TI
7038             (mult:TI (zero_extend:TI
7039                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7040                      (zero_extend:TI
7041                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7042             (const_int 64))))
7043    (clobber (match_scratch:DI 3 "=1"))
7044    (clobber (reg:CC FLAGS_REG))]
7045   "TARGET_64BIT
7046    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7047   "mul{q}\t%2"
7048   [(set_attr "type" "imul")
7049    (set_attr "length_immediate" "0")
7050    (set (attr "athlon_decode")
7051      (if_then_else (eq_attr "cpu" "athlon")
7052         (const_string "vector")
7053         (const_string "double")))
7054    (set_attr "mode" "DI")])
7055
7056 (define_expand "umulsi3_highpart"
7057   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7058                    (truncate:SI
7059                      (lshiftrt:DI
7060                        (mult:DI (zero_extend:DI
7061                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7062                                 (zero_extend:DI
7063                                   (match_operand:SI 2 "register_operand" "")))
7064                        (const_int 32))))
7065               (clobber (match_scratch:SI 3 ""))
7066               (clobber (reg:CC FLAGS_REG))])]
7067   ""
7068   "")
7069
7070 (define_insn "*umulsi3_highpart_insn"
7071   [(set (match_operand:SI 0 "register_operand" "=d")
7072         (truncate:SI
7073           (lshiftrt:DI
7074             (mult:DI (zero_extend:DI
7075                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7076                      (zero_extend:DI
7077                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7078             (const_int 32))))
7079    (clobber (match_scratch:SI 3 "=1"))
7080    (clobber (reg:CC FLAGS_REG))]
7081   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7082   "mul{l}\t%2"
7083   [(set_attr "type" "imul")
7084    (set_attr "length_immediate" "0")
7085    (set (attr "athlon_decode")
7086      (if_then_else (eq_attr "cpu" "athlon")
7087         (const_string "vector")
7088         (const_string "double")))
7089    (set_attr "mode" "SI")])
7090
7091 (define_insn "*umulsi3_highpart_zext"
7092   [(set (match_operand:DI 0 "register_operand" "=d")
7093         (zero_extend:DI (truncate:SI
7094           (lshiftrt:DI
7095             (mult:DI (zero_extend:DI
7096                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7097                      (zero_extend:DI
7098                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7099             (const_int 32)))))
7100    (clobber (match_scratch:SI 3 "=1"))
7101    (clobber (reg:CC FLAGS_REG))]
7102   "TARGET_64BIT
7103    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7104   "mul{l}\t%2"
7105   [(set_attr "type" "imul")
7106    (set_attr "length_immediate" "0")
7107    (set (attr "athlon_decode")
7108      (if_then_else (eq_attr "cpu" "athlon")
7109         (const_string "vector")
7110         (const_string "double")))
7111    (set_attr "mode" "SI")])
7112
7113 (define_expand "smuldi3_highpart"
7114   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7115                    (truncate:DI
7116                      (lshiftrt:TI
7117                        (mult:TI (sign_extend:TI
7118                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7119                                 (sign_extend:TI
7120                                   (match_operand:DI 2 "register_operand" "")))
7121                        (const_int 64))))
7122               (clobber (match_scratch:DI 3 ""))
7123               (clobber (reg:CC FLAGS_REG))])]
7124   "TARGET_64BIT"
7125   "")
7126
7127 (define_insn "*smuldi3_highpart_rex64"
7128   [(set (match_operand:DI 0 "register_operand" "=d")
7129         (truncate:DI
7130           (lshiftrt:TI
7131             (mult:TI (sign_extend:TI
7132                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7133                      (sign_extend:TI
7134                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7135             (const_int 64))))
7136    (clobber (match_scratch:DI 3 "=1"))
7137    (clobber (reg:CC FLAGS_REG))]
7138   "TARGET_64BIT
7139    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7140   "imul{q}\t%2"
7141   [(set_attr "type" "imul")
7142    (set (attr "athlon_decode")
7143      (if_then_else (eq_attr "cpu" "athlon")
7144         (const_string "vector")
7145         (const_string "double")))
7146    (set_attr "mode" "DI")])
7147
7148 (define_expand "smulsi3_highpart"
7149   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7150                    (truncate:SI
7151                      (lshiftrt:DI
7152                        (mult:DI (sign_extend:DI
7153                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7154                                 (sign_extend:DI
7155                                   (match_operand:SI 2 "register_operand" "")))
7156                        (const_int 32))))
7157               (clobber (match_scratch:SI 3 ""))
7158               (clobber (reg:CC FLAGS_REG))])]
7159   ""
7160   "")
7161
7162 (define_insn "*smulsi3_highpart_insn"
7163   [(set (match_operand:SI 0 "register_operand" "=d")
7164         (truncate:SI
7165           (lshiftrt:DI
7166             (mult:DI (sign_extend:DI
7167                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7168                      (sign_extend:DI
7169                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7170             (const_int 32))))
7171    (clobber (match_scratch:SI 3 "=1"))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7174   "imul{l}\t%2"
7175   [(set_attr "type" "imul")
7176    (set (attr "athlon_decode")
7177      (if_then_else (eq_attr "cpu" "athlon")
7178         (const_string "vector")
7179         (const_string "double")))
7180    (set_attr "mode" "SI")])
7181
7182 (define_insn "*smulsi3_highpart_zext"
7183   [(set (match_operand:DI 0 "register_operand" "=d")
7184         (zero_extend:DI (truncate:SI
7185           (lshiftrt:DI
7186             (mult:DI (sign_extend:DI
7187                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7188                      (sign_extend:DI
7189                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7190             (const_int 32)))))
7191    (clobber (match_scratch:SI 3 "=1"))
7192    (clobber (reg:CC FLAGS_REG))]
7193   "TARGET_64BIT
7194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195   "imul{l}\t%2"
7196   [(set_attr "type" "imul")
7197    (set (attr "athlon_decode")
7198      (if_then_else (eq_attr "cpu" "athlon")
7199         (const_string "vector")
7200         (const_string "double")))
7201    (set_attr "mode" "SI")])
7202
7203 ;; The patterns that match these are at the end of this file.
7204
7205 (define_expand "mulxf3"
7206   [(set (match_operand:XF 0 "register_operand" "")
7207         (mult:XF (match_operand:XF 1 "register_operand" "")
7208                  (match_operand:XF 2 "register_operand" "")))]
7209   "TARGET_80387"
7210   "")
7211
7212 (define_expand "muldf3"
7213   [(set (match_operand:DF 0 "register_operand" "")
7214         (mult:DF (match_operand:DF 1 "register_operand" "")
7215                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7216   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7217   "")
7218
7219 (define_expand "mulsf3"
7220   [(set (match_operand:SF 0 "register_operand" "")
7221         (mult:SF (match_operand:SF 1 "register_operand" "")
7222                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7223   "TARGET_80387 || TARGET_SSE_MATH"
7224   "")
7225 \f
7226 ;; Divide instructions
7227
7228 (define_insn "divqi3"
7229   [(set (match_operand:QI 0 "register_operand" "=a")
7230         (div:QI (match_operand:HI 1 "register_operand" "0")
7231                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_QIMODE_MATH"
7234   "idiv{b}\t%2"
7235   [(set_attr "type" "idiv")
7236    (set_attr "mode" "QI")])
7237
7238 (define_insn "udivqi3"
7239   [(set (match_operand:QI 0 "register_operand" "=a")
7240         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7241                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7242    (clobber (reg:CC FLAGS_REG))]
7243   "TARGET_QIMODE_MATH"
7244   "div{b}\t%2"
7245   [(set_attr "type" "idiv")
7246    (set_attr "mode" "QI")])
7247
7248 ;; The patterns that match these are at the end of this file.
7249
7250 (define_expand "divxf3"
7251   [(set (match_operand:XF 0 "register_operand" "")
7252         (div:XF (match_operand:XF 1 "register_operand" "")
7253                 (match_operand:XF 2 "register_operand" "")))]
7254   "TARGET_80387"
7255   "")
7256
7257 (define_expand "divdf3"
7258   [(set (match_operand:DF 0 "register_operand" "")
7259         (div:DF (match_operand:DF 1 "register_operand" "")
7260                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7261    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7262    "")
7263  
7264 (define_expand "divsf3"
7265   [(set (match_operand:SF 0 "register_operand" "")
7266         (div:SF (match_operand:SF 1 "register_operand" "")
7267                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7268   "TARGET_80387 || TARGET_SSE_MATH"
7269   "")
7270 \f
7271 ;; Remainder instructions.
7272
7273 (define_expand "divmoddi4"
7274   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7275                    (div:DI (match_operand:DI 1 "register_operand" "")
7276                            (match_operand:DI 2 "nonimmediate_operand" "")))
7277               (set (match_operand:DI 3 "register_operand" "")
7278                    (mod:DI (match_dup 1) (match_dup 2)))
7279               (clobber (reg:CC FLAGS_REG))])]
7280   "TARGET_64BIT"
7281   "")
7282
7283 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7284 ;; Penalize eax case slightly because it results in worse scheduling
7285 ;; of code.
7286 (define_insn "*divmoddi4_nocltd_rex64"
7287   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7288         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7289                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7290    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7291         (mod:DI (match_dup 2) (match_dup 3)))
7292    (clobber (reg:CC FLAGS_REG))]
7293   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7294   "#"
7295   [(set_attr "type" "multi")])
7296
7297 (define_insn "*divmoddi4_cltd_rex64"
7298   [(set (match_operand:DI 0 "register_operand" "=a")
7299         (div:DI (match_operand:DI 2 "register_operand" "a")
7300                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7301    (set (match_operand:DI 1 "register_operand" "=&d")
7302         (mod:DI (match_dup 2) (match_dup 3)))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7305   "#"
7306   [(set_attr "type" "multi")])
7307
7308 (define_insn "*divmoddi_noext_rex64"
7309   [(set (match_operand:DI 0 "register_operand" "=a")
7310         (div:DI (match_operand:DI 1 "register_operand" "0")
7311                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7312    (set (match_operand:DI 3 "register_operand" "=d")
7313         (mod:DI (match_dup 1) (match_dup 2)))
7314    (use (match_operand:DI 4 "register_operand" "3"))
7315    (clobber (reg:CC FLAGS_REG))]
7316   "TARGET_64BIT"
7317   "idiv{q}\t%2"
7318   [(set_attr "type" "idiv")
7319    (set_attr "mode" "DI")])
7320
7321 (define_split
7322   [(set (match_operand:DI 0 "register_operand" "")
7323         (div:DI (match_operand:DI 1 "register_operand" "")
7324                 (match_operand:DI 2 "nonimmediate_operand" "")))
7325    (set (match_operand:DI 3 "register_operand" "")
7326         (mod:DI (match_dup 1) (match_dup 2)))
7327    (clobber (reg:CC FLAGS_REG))]
7328   "TARGET_64BIT && reload_completed"
7329   [(parallel [(set (match_dup 3)
7330                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7331               (clobber (reg:CC FLAGS_REG))])
7332    (parallel [(set (match_dup 0)
7333                    (div:DI (reg:DI 0) (match_dup 2)))
7334               (set (match_dup 3)
7335                    (mod:DI (reg:DI 0) (match_dup 2)))
7336               (use (match_dup 3))
7337               (clobber (reg:CC FLAGS_REG))])]
7338 {
7339   /* Avoid use of cltd in favor of a mov+shift.  */
7340   if (!TARGET_USE_CLTD && !optimize_size)
7341     {
7342       if (true_regnum (operands[1]))
7343         emit_move_insn (operands[0], operands[1]);
7344       else
7345         emit_move_insn (operands[3], operands[1]);
7346       operands[4] = operands[3];
7347     }
7348   else
7349     {
7350       if (true_regnum (operands[1]))
7351         abort();
7352       operands[4] = operands[1];
7353     }
7354 })
7355
7356
7357 (define_expand "divmodsi4"
7358   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7359                    (div:SI (match_operand:SI 1 "register_operand" "")
7360                            (match_operand:SI 2 "nonimmediate_operand" "")))
7361               (set (match_operand:SI 3 "register_operand" "")
7362                    (mod:SI (match_dup 1) (match_dup 2)))
7363               (clobber (reg:CC FLAGS_REG))])]
7364   ""
7365   "")
7366
7367 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7368 ;; Penalize eax case slightly because it results in worse scheduling
7369 ;; of code.
7370 (define_insn "*divmodsi4_nocltd"
7371   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7372         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7373                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7374    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7375         (mod:SI (match_dup 2) (match_dup 3)))
7376    (clobber (reg:CC FLAGS_REG))]
7377   "!optimize_size && !TARGET_USE_CLTD"
7378   "#"
7379   [(set_attr "type" "multi")])
7380
7381 (define_insn "*divmodsi4_cltd"
7382   [(set (match_operand:SI 0 "register_operand" "=a")
7383         (div:SI (match_operand:SI 2 "register_operand" "a")
7384                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7385    (set (match_operand:SI 1 "register_operand" "=&d")
7386         (mod:SI (match_dup 2) (match_dup 3)))
7387    (clobber (reg:CC FLAGS_REG))]
7388   "optimize_size || TARGET_USE_CLTD"
7389   "#"
7390   [(set_attr "type" "multi")])
7391
7392 (define_insn "*divmodsi_noext"
7393   [(set (match_operand:SI 0 "register_operand" "=a")
7394         (div:SI (match_operand:SI 1 "register_operand" "0")
7395                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7396    (set (match_operand:SI 3 "register_operand" "=d")
7397         (mod:SI (match_dup 1) (match_dup 2)))
7398    (use (match_operand:SI 4 "register_operand" "3"))
7399    (clobber (reg:CC FLAGS_REG))]
7400   ""
7401   "idiv{l}\t%2"
7402   [(set_attr "type" "idiv")
7403    (set_attr "mode" "SI")])
7404
7405 (define_split
7406   [(set (match_operand:SI 0 "register_operand" "")
7407         (div:SI (match_operand:SI 1 "register_operand" "")
7408                 (match_operand:SI 2 "nonimmediate_operand" "")))
7409    (set (match_operand:SI 3 "register_operand" "")
7410         (mod:SI (match_dup 1) (match_dup 2)))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "reload_completed"
7413   [(parallel [(set (match_dup 3)
7414                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7415               (clobber (reg:CC FLAGS_REG))])
7416    (parallel [(set (match_dup 0)
7417                    (div:SI (reg:SI 0) (match_dup 2)))
7418               (set (match_dup 3)
7419                    (mod:SI (reg:SI 0) (match_dup 2)))
7420               (use (match_dup 3))
7421               (clobber (reg:CC FLAGS_REG))])]
7422 {
7423   /* Avoid use of cltd in favor of a mov+shift.  */
7424   if (!TARGET_USE_CLTD && !optimize_size)
7425     {
7426       if (true_regnum (operands[1]))
7427         emit_move_insn (operands[0], operands[1]);
7428       else
7429         emit_move_insn (operands[3], operands[1]);
7430       operands[4] = operands[3];
7431     }
7432   else
7433     {
7434       if (true_regnum (operands[1]))
7435         abort();
7436       operands[4] = operands[1];
7437     }
7438 })
7439 ;; %%% Split me.
7440 (define_insn "divmodhi4"
7441   [(set (match_operand:HI 0 "register_operand" "=a")
7442         (div:HI (match_operand:HI 1 "register_operand" "0")
7443                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7444    (set (match_operand:HI 3 "register_operand" "=&d")
7445         (mod:HI (match_dup 1) (match_dup 2)))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "TARGET_HIMODE_MATH"
7448   "cwtd\;idiv{w}\t%2"
7449   [(set_attr "type" "multi")
7450    (set_attr "length_immediate" "0")
7451    (set_attr "mode" "SI")])
7452
7453 (define_insn "udivmoddi4"
7454   [(set (match_operand:DI 0 "register_operand" "=a")
7455         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7456                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7457    (set (match_operand:DI 3 "register_operand" "=&d")
7458         (umod:DI (match_dup 1) (match_dup 2)))
7459    (clobber (reg:CC FLAGS_REG))]
7460   "TARGET_64BIT"
7461   "xor{q}\t%3, %3\;div{q}\t%2"
7462   [(set_attr "type" "multi")
7463    (set_attr "length_immediate" "0")
7464    (set_attr "mode" "DI")])
7465
7466 (define_insn "*udivmoddi4_noext"
7467   [(set (match_operand:DI 0 "register_operand" "=a")
7468         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7469                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7470    (set (match_operand:DI 3 "register_operand" "=d")
7471         (umod:DI (match_dup 1) (match_dup 2)))
7472    (use (match_dup 3))
7473    (clobber (reg:CC FLAGS_REG))]
7474   "TARGET_64BIT"
7475   "div{q}\t%2"
7476   [(set_attr "type" "idiv")
7477    (set_attr "mode" "DI")])
7478
7479 (define_split
7480   [(set (match_operand:DI 0 "register_operand" "")
7481         (udiv:DI (match_operand:DI 1 "register_operand" "")
7482                  (match_operand:DI 2 "nonimmediate_operand" "")))
7483    (set (match_operand:DI 3 "register_operand" "")
7484         (umod:DI (match_dup 1) (match_dup 2)))
7485    (clobber (reg:CC FLAGS_REG))]
7486   "TARGET_64BIT && reload_completed"
7487   [(set (match_dup 3) (const_int 0))
7488    (parallel [(set (match_dup 0)
7489                    (udiv:DI (match_dup 1) (match_dup 2)))
7490               (set (match_dup 3)
7491                    (umod:DI (match_dup 1) (match_dup 2)))
7492               (use (match_dup 3))
7493               (clobber (reg:CC FLAGS_REG))])]
7494   "")
7495
7496 (define_insn "udivmodsi4"
7497   [(set (match_operand:SI 0 "register_operand" "=a")
7498         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7499                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7500    (set (match_operand:SI 3 "register_operand" "=&d")
7501         (umod:SI (match_dup 1) (match_dup 2)))
7502    (clobber (reg:CC FLAGS_REG))]
7503   ""
7504   "xor{l}\t%3, %3\;div{l}\t%2"
7505   [(set_attr "type" "multi")
7506    (set_attr "length_immediate" "0")
7507    (set_attr "mode" "SI")])
7508
7509 (define_insn "*udivmodsi4_noext"
7510   [(set (match_operand:SI 0 "register_operand" "=a")
7511         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7512                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7513    (set (match_operand:SI 3 "register_operand" "=d")
7514         (umod:SI (match_dup 1) (match_dup 2)))
7515    (use (match_dup 3))
7516    (clobber (reg:CC FLAGS_REG))]
7517   ""
7518   "div{l}\t%2"
7519   [(set_attr "type" "idiv")
7520    (set_attr "mode" "SI")])
7521
7522 (define_split
7523   [(set (match_operand:SI 0 "register_operand" "")
7524         (udiv:SI (match_operand:SI 1 "register_operand" "")
7525                  (match_operand:SI 2 "nonimmediate_operand" "")))
7526    (set (match_operand:SI 3 "register_operand" "")
7527         (umod:SI (match_dup 1) (match_dup 2)))
7528    (clobber (reg:CC FLAGS_REG))]
7529   "reload_completed"
7530   [(set (match_dup 3) (const_int 0))
7531    (parallel [(set (match_dup 0)
7532                    (udiv:SI (match_dup 1) (match_dup 2)))
7533               (set (match_dup 3)
7534                    (umod:SI (match_dup 1) (match_dup 2)))
7535               (use (match_dup 3))
7536               (clobber (reg:CC FLAGS_REG))])]
7537   "")
7538
7539 (define_expand "udivmodhi4"
7540   [(set (match_dup 4) (const_int 0))
7541    (parallel [(set (match_operand:HI 0 "register_operand" "")
7542                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7543                             (match_operand:HI 2 "nonimmediate_operand" "")))
7544               (set (match_operand:HI 3 "register_operand" "")
7545                    (umod:HI (match_dup 1) (match_dup 2)))
7546               (use (match_dup 4))
7547               (clobber (reg:CC FLAGS_REG))])]
7548   "TARGET_HIMODE_MATH"
7549   "operands[4] = gen_reg_rtx (HImode);")
7550
7551 (define_insn "*udivmodhi_noext"
7552   [(set (match_operand:HI 0 "register_operand" "=a")
7553         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7554                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7555    (set (match_operand:HI 3 "register_operand" "=d")
7556         (umod:HI (match_dup 1) (match_dup 2)))
7557    (use (match_operand:HI 4 "register_operand" "3"))
7558    (clobber (reg:CC FLAGS_REG))]
7559   ""
7560   "div{w}\t%2"
7561   [(set_attr "type" "idiv")
7562    (set_attr "mode" "HI")])
7563
7564 ;; We cannot use div/idiv for double division, because it causes
7565 ;; "division by zero" on the overflow and that's not what we expect
7566 ;; from truncate.  Because true (non truncating) double division is
7567 ;; never generated, we can't create this insn anyway.
7568 ;
7569 ;(define_insn ""
7570 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7571 ;       (truncate:SI
7572 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7573 ;                  (zero_extend:DI
7574 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7575 ;   (set (match_operand:SI 3 "register_operand" "=d")
7576 ;       (truncate:SI
7577 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7578 ;   (clobber (reg:CC FLAGS_REG))]
7579 ;  ""
7580 ;  "div{l}\t{%2, %0|%0, %2}"
7581 ;  [(set_attr "type" "idiv")])
7582 \f
7583 ;;- Logical AND instructions
7584
7585 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7586 ;; Note that this excludes ah.
7587
7588 (define_insn "*testdi_1_rex64"
7589   [(set (reg FLAGS_REG)
7590         (compare
7591           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7592                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7593           (const_int 0)))]
7594   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7596   "@
7597    test{l}\t{%k1, %k0|%k0, %k1}
7598    test{l}\t{%k1, %k0|%k0, %k1}
7599    test{q}\t{%1, %0|%0, %1}
7600    test{q}\t{%1, %0|%0, %1}
7601    test{q}\t{%1, %0|%0, %1}"
7602   [(set_attr "type" "test")
7603    (set_attr "modrm" "0,1,0,1,1")
7604    (set_attr "mode" "SI,SI,DI,DI,DI")
7605    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7606
7607 (define_insn "testsi_1"
7608   [(set (reg FLAGS_REG)
7609         (compare
7610           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7611                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7612           (const_int 0)))]
7613   "ix86_match_ccmode (insn, CCNOmode)
7614    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7615   "test{l}\t{%1, %0|%0, %1}"
7616   [(set_attr "type" "test")
7617    (set_attr "modrm" "0,1,1")
7618    (set_attr "mode" "SI")
7619    (set_attr "pent_pair" "uv,np,uv")])
7620
7621 (define_expand "testsi_ccno_1"
7622   [(set (reg:CCNO FLAGS_REG)
7623         (compare:CCNO
7624           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7625                   (match_operand:SI 1 "nonmemory_operand" ""))
7626           (const_int 0)))]
7627   ""
7628   "")
7629
7630 (define_insn "*testhi_1"
7631   [(set (reg FLAGS_REG)
7632         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7633                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7634                  (const_int 0)))]
7635   "ix86_match_ccmode (insn, CCNOmode)
7636    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7637   "test{w}\t{%1, %0|%0, %1}"
7638   [(set_attr "type" "test")
7639    (set_attr "modrm" "0,1,1")
7640    (set_attr "mode" "HI")
7641    (set_attr "pent_pair" "uv,np,uv")])
7642
7643 (define_expand "testqi_ccz_1"
7644   [(set (reg:CCZ FLAGS_REG)
7645         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7646                              (match_operand:QI 1 "nonmemory_operand" ""))
7647                  (const_int 0)))]
7648   ""
7649   "")
7650
7651 (define_insn "*testqi_1_maybe_si"
7652   [(set (reg FLAGS_REG)
7653         (compare
7654           (and:QI
7655             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7656             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7657           (const_int 0)))]
7658    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7659     && ix86_match_ccmode (insn,
7660                          GET_CODE (operands[1]) == CONST_INT
7661                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7662 {
7663   if (which_alternative == 3)
7664     {
7665       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7666         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7667       return "test{l}\t{%1, %k0|%k0, %1}";
7668     }
7669   return "test{b}\t{%1, %0|%0, %1}";
7670 }
7671   [(set_attr "type" "test")
7672    (set_attr "modrm" "0,1,1,1")
7673    (set_attr "mode" "QI,QI,QI,SI")
7674    (set_attr "pent_pair" "uv,np,uv,np")])
7675
7676 (define_insn "*testqi_1"
7677   [(set (reg FLAGS_REG)
7678         (compare
7679           (and:QI
7680             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7681             (match_operand:QI 1 "general_operand" "n,n,qn"))
7682           (const_int 0)))]
7683   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7684    && ix86_match_ccmode (insn, CCNOmode)"
7685   "test{b}\t{%1, %0|%0, %1}"
7686   [(set_attr "type" "test")
7687    (set_attr "modrm" "0,1,1")
7688    (set_attr "mode" "QI")
7689    (set_attr "pent_pair" "uv,np,uv")])
7690
7691 (define_expand "testqi_ext_ccno_0"
7692   [(set (reg:CCNO FLAGS_REG)
7693         (compare:CCNO
7694           (and:SI
7695             (zero_extract:SI
7696               (match_operand 0 "ext_register_operand" "")
7697               (const_int 8)
7698               (const_int 8))
7699             (match_operand 1 "const_int_operand" ""))
7700           (const_int 0)))]
7701   ""
7702   "")
7703
7704 (define_insn "*testqi_ext_0"
7705   [(set (reg FLAGS_REG)
7706         (compare
7707           (and:SI
7708             (zero_extract:SI
7709               (match_operand 0 "ext_register_operand" "Q")
7710               (const_int 8)
7711               (const_int 8))
7712             (match_operand 1 "const_int_operand" "n"))
7713           (const_int 0)))]
7714   "ix86_match_ccmode (insn, CCNOmode)"
7715   "test{b}\t{%1, %h0|%h0, %1}"
7716   [(set_attr "type" "test")
7717    (set_attr "mode" "QI")
7718    (set_attr "length_immediate" "1")
7719    (set_attr "pent_pair" "np")])
7720
7721 (define_insn "*testqi_ext_1"
7722   [(set (reg FLAGS_REG)
7723         (compare
7724           (and:SI
7725             (zero_extract:SI
7726               (match_operand 0 "ext_register_operand" "Q")
7727               (const_int 8)
7728               (const_int 8))
7729             (zero_extend:SI
7730               (match_operand:QI 1 "general_operand" "Qm")))
7731           (const_int 0)))]
7732   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7733    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7734   "test{b}\t{%1, %h0|%h0, %1}"
7735   [(set_attr "type" "test")
7736    (set_attr "mode" "QI")])
7737
7738 (define_insn "*testqi_ext_1_rex64"
7739   [(set (reg FLAGS_REG)
7740         (compare
7741           (and:SI
7742             (zero_extract:SI
7743               (match_operand 0 "ext_register_operand" "Q")
7744               (const_int 8)
7745               (const_int 8))
7746             (zero_extend:SI
7747               (match_operand:QI 1 "register_operand" "Q")))
7748           (const_int 0)))]
7749   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7750   "test{b}\t{%1, %h0|%h0, %1}"
7751   [(set_attr "type" "test")
7752    (set_attr "mode" "QI")])
7753
7754 (define_insn "*testqi_ext_2"
7755   [(set (reg FLAGS_REG)
7756         (compare
7757           (and:SI
7758             (zero_extract:SI
7759               (match_operand 0 "ext_register_operand" "Q")
7760               (const_int 8)
7761               (const_int 8))
7762             (zero_extract:SI
7763               (match_operand 1 "ext_register_operand" "Q")
7764               (const_int 8)
7765               (const_int 8)))
7766           (const_int 0)))]
7767   "ix86_match_ccmode (insn, CCNOmode)"
7768   "test{b}\t{%h1, %h0|%h0, %h1}"
7769   [(set_attr "type" "test")
7770    (set_attr "mode" "QI")])
7771
7772 ;; Combine likes to form bit extractions for some tests.  Humor it.
7773 (define_insn "*testqi_ext_3"
7774   [(set (reg FLAGS_REG)
7775         (compare (zero_extract:SI
7776                    (match_operand 0 "nonimmediate_operand" "rm")
7777                    (match_operand:SI 1 "const_int_operand" "")
7778                    (match_operand:SI 2 "const_int_operand" ""))
7779                  (const_int 0)))]
7780   "ix86_match_ccmode (insn, CCNOmode)
7781    && (GET_MODE (operands[0]) == SImode
7782        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7783        || GET_MODE (operands[0]) == HImode
7784        || GET_MODE (operands[0]) == QImode)"
7785   "#")
7786
7787 (define_insn "*testqi_ext_3_rex64"
7788   [(set (reg FLAGS_REG)
7789         (compare (zero_extract:DI
7790                    (match_operand 0 "nonimmediate_operand" "rm")
7791                    (match_operand:DI 1 "const_int_operand" "")
7792                    (match_operand:DI 2 "const_int_operand" ""))
7793                  (const_int 0)))]
7794   "TARGET_64BIT
7795    && ix86_match_ccmode (insn, CCNOmode)
7796    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7797    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7798    /* Ensure that resulting mask is zero or sign extended operand.  */
7799    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7800        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7801            && INTVAL (operands[1]) > 32))
7802    && (GET_MODE (operands[0]) == SImode
7803        || GET_MODE (operands[0]) == DImode
7804        || GET_MODE (operands[0]) == HImode
7805        || GET_MODE (operands[0]) == QImode)"
7806   "#")
7807
7808 (define_split
7809   [(set (match_operand 0 "flags_reg_operand" "")
7810         (match_operator 1 "compare_operator"
7811           [(zero_extract
7812              (match_operand 2 "nonimmediate_operand" "")
7813              (match_operand 3 "const_int_operand" "")
7814              (match_operand 4 "const_int_operand" ""))
7815            (const_int 0)]))]
7816   "ix86_match_ccmode (insn, CCNOmode)"
7817   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7818 {
7819   rtx val = operands[2];
7820   HOST_WIDE_INT len = INTVAL (operands[3]);
7821   HOST_WIDE_INT pos = INTVAL (operands[4]);
7822   HOST_WIDE_INT mask;
7823   enum machine_mode mode, submode;
7824
7825   mode = GET_MODE (val);
7826   if (GET_CODE (val) == MEM)
7827     {
7828       /* ??? Combine likes to put non-volatile mem extractions in QImode
7829          no matter the size of the test.  So find a mode that works.  */
7830       if (! MEM_VOLATILE_P (val))
7831         {
7832           mode = smallest_mode_for_size (pos + len, MODE_INT);
7833           val = adjust_address (val, mode, 0);
7834         }
7835     }
7836   else if (GET_CODE (val) == SUBREG
7837            && (submode = GET_MODE (SUBREG_REG (val)),
7838                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7839            && pos + len <= GET_MODE_BITSIZE (submode))
7840     {
7841       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7842       mode = submode;
7843       val = SUBREG_REG (val);
7844     }
7845   else if (mode == HImode && pos + len <= 8)
7846     {
7847       /* Small HImode tests can be converted to QImode.  */
7848       mode = QImode;
7849       val = gen_lowpart (QImode, val);
7850     }
7851
7852   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7853   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7854
7855   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7856 })
7857
7858 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7859 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7860 ;; this is relatively important trick.
7861 ;; Do the conversion only post-reload to avoid limiting of the register class
7862 ;; to QI regs.
7863 (define_split
7864   [(set (match_operand 0 "flags_reg_operand" "")
7865         (match_operator 1 "compare_operator"
7866           [(and (match_operand 2 "register_operand" "")
7867                 (match_operand 3 "const_int_operand" ""))
7868            (const_int 0)]))]
7869    "reload_completed
7870     && QI_REG_P (operands[2])
7871     && GET_MODE (operands[2]) != QImode
7872     && ((ix86_match_ccmode (insn, CCZmode)
7873          && !(INTVAL (operands[3]) & ~(255 << 8)))
7874         || (ix86_match_ccmode (insn, CCNOmode)
7875             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7876   [(set (match_dup 0)
7877         (match_op_dup 1
7878           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7879                    (match_dup 3))
7880            (const_int 0)]))]
7881   "operands[2] = gen_lowpart (SImode, operands[2]);
7882    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7883
7884 (define_split
7885   [(set (match_operand 0 "flags_reg_operand" "")
7886         (match_operator 1 "compare_operator"
7887           [(and (match_operand 2 "nonimmediate_operand" "")
7888                 (match_operand 3 "const_int_operand" ""))
7889            (const_int 0)]))]
7890    "reload_completed
7891     && GET_MODE (operands[2]) != QImode
7892     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7893     && ((ix86_match_ccmode (insn, CCZmode)
7894          && !(INTVAL (operands[3]) & ~255))
7895         || (ix86_match_ccmode (insn, CCNOmode)
7896             && !(INTVAL (operands[3]) & ~127)))"
7897   [(set (match_dup 0)
7898         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7899                          (const_int 0)]))]
7900   "operands[2] = gen_lowpart (QImode, operands[2]);
7901    operands[3] = gen_lowpart (QImode, operands[3]);")
7902
7903
7904 ;; %%% This used to optimize known byte-wide and operations to memory,
7905 ;; and sometimes to QImode registers.  If this is considered useful,
7906 ;; it should be done with splitters.
7907
7908 (define_expand "anddi3"
7909   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7910         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7911                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7912    (clobber (reg:CC FLAGS_REG))]
7913   "TARGET_64BIT"
7914   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7915
7916 (define_insn "*anddi_1_rex64"
7917   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7918         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7919                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7920    (clobber (reg:CC FLAGS_REG))]
7921   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7922 {
7923   switch (get_attr_type (insn))
7924     {
7925     case TYPE_IMOVX:
7926       {
7927         enum machine_mode mode;
7928
7929         if (GET_CODE (operands[2]) != CONST_INT)
7930           abort ();
7931         if (INTVAL (operands[2]) == 0xff)
7932           mode = QImode;
7933         else if (INTVAL (operands[2]) == 0xffff)
7934           mode = HImode;
7935         else
7936           abort ();
7937         
7938         operands[1] = gen_lowpart (mode, operands[1]);
7939         if (mode == QImode)
7940           return "movz{bq|x}\t{%1,%0|%0, %1}";
7941         else
7942           return "movz{wq|x}\t{%1,%0|%0, %1}";
7943       }
7944
7945     default:
7946       if (! rtx_equal_p (operands[0], operands[1]))
7947         abort ();
7948       if (get_attr_mode (insn) == MODE_SI)
7949         return "and{l}\t{%k2, %k0|%k0, %k2}";
7950       else
7951         return "and{q}\t{%2, %0|%0, %2}";
7952     }
7953 }
7954   [(set_attr "type" "alu,alu,alu,imovx")
7955    (set_attr "length_immediate" "*,*,*,0")
7956    (set_attr "mode" "SI,DI,DI,DI")])
7957
7958 (define_insn "*anddi_2"
7959   [(set (reg FLAGS_REG)
7960         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7961                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7962                  (const_int 0)))
7963    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7964         (and:DI (match_dup 1) (match_dup 2)))]
7965   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7966    && ix86_binary_operator_ok (AND, DImode, operands)"
7967   "@
7968    and{l}\t{%k2, %k0|%k0, %k2}
7969    and{q}\t{%2, %0|%0, %2}
7970    and{q}\t{%2, %0|%0, %2}"
7971   [(set_attr "type" "alu")
7972    (set_attr "mode" "SI,DI,DI")])
7973
7974 (define_expand "andsi3"
7975   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7976         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7977                 (match_operand:SI 2 "general_operand" "")))
7978    (clobber (reg:CC FLAGS_REG))]
7979   ""
7980   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7981
7982 (define_insn "*andsi_1"
7983   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7984         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7985                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7986    (clobber (reg:CC FLAGS_REG))]
7987   "ix86_binary_operator_ok (AND, SImode, operands)"
7988 {
7989   switch (get_attr_type (insn))
7990     {
7991     case TYPE_IMOVX:
7992       {
7993         enum machine_mode mode;
7994
7995         if (GET_CODE (operands[2]) != CONST_INT)
7996           abort ();
7997         if (INTVAL (operands[2]) == 0xff)
7998           mode = QImode;
7999         else if (INTVAL (operands[2]) == 0xffff)
8000           mode = HImode;
8001         else
8002           abort ();
8003         
8004         operands[1] = gen_lowpart (mode, operands[1]);
8005         if (mode == QImode)
8006           return "movz{bl|x}\t{%1,%0|%0, %1}";
8007         else
8008           return "movz{wl|x}\t{%1,%0|%0, %1}";
8009       }
8010
8011     default:
8012       if (! rtx_equal_p (operands[0], operands[1]))
8013         abort ();
8014       return "and{l}\t{%2, %0|%0, %2}";
8015     }
8016 }
8017   [(set_attr "type" "alu,alu,imovx")
8018    (set_attr "length_immediate" "*,*,0")
8019    (set_attr "mode" "SI")])
8020
8021 (define_split
8022   [(set (match_operand 0 "register_operand" "")
8023         (and (match_dup 0)
8024              (const_int -65536)))
8025    (clobber (reg:CC FLAGS_REG))]
8026   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8027   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8028   "operands[1] = gen_lowpart (HImode, operands[0]);")
8029
8030 (define_split
8031   [(set (match_operand 0 "ext_register_operand" "")
8032         (and (match_dup 0)
8033              (const_int -256)))
8034    (clobber (reg:CC FLAGS_REG))]
8035   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8036   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8037   "operands[1] = gen_lowpart (QImode, operands[0]);")
8038
8039 (define_split
8040   [(set (match_operand 0 "ext_register_operand" "")
8041         (and (match_dup 0)
8042              (const_int -65281)))
8043    (clobber (reg:CC FLAGS_REG))]
8044   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8045   [(parallel [(set (zero_extract:SI (match_dup 0)
8046                                     (const_int 8)
8047                                     (const_int 8))
8048                    (xor:SI 
8049                      (zero_extract:SI (match_dup 0)
8050                                       (const_int 8)
8051                                       (const_int 8))
8052                      (zero_extract:SI (match_dup 0)
8053                                       (const_int 8)
8054                                       (const_int 8))))
8055               (clobber (reg:CC FLAGS_REG))])]
8056   "operands[0] = gen_lowpart (SImode, operands[0]);")
8057
8058 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8059 (define_insn "*andsi_1_zext"
8060   [(set (match_operand:DI 0 "register_operand" "=r")
8061         (zero_extend:DI
8062           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8063                   (match_operand:SI 2 "general_operand" "rim"))))
8064    (clobber (reg:CC FLAGS_REG))]
8065   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8066   "and{l}\t{%2, %k0|%k0, %2}"
8067   [(set_attr "type" "alu")
8068    (set_attr "mode" "SI")])
8069
8070 (define_insn "*andsi_2"
8071   [(set (reg FLAGS_REG)
8072         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8073                          (match_operand:SI 2 "general_operand" "rim,ri"))
8074                  (const_int 0)))
8075    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8076         (and:SI (match_dup 1) (match_dup 2)))]
8077   "ix86_match_ccmode (insn, CCNOmode)
8078    && ix86_binary_operator_ok (AND, SImode, operands)"
8079   "and{l}\t{%2, %0|%0, %2}"
8080   [(set_attr "type" "alu")
8081    (set_attr "mode" "SI")])
8082
8083 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8084 (define_insn "*andsi_2_zext"
8085   [(set (reg FLAGS_REG)
8086         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8087                          (match_operand:SI 2 "general_operand" "rim"))
8088                  (const_int 0)))
8089    (set (match_operand:DI 0 "register_operand" "=r")
8090         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8091   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8092    && ix86_binary_operator_ok (AND, SImode, operands)"
8093   "and{l}\t{%2, %k0|%k0, %2}"
8094   [(set_attr "type" "alu")
8095    (set_attr "mode" "SI")])
8096
8097 (define_expand "andhi3"
8098   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8099         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8100                 (match_operand:HI 2 "general_operand" "")))
8101    (clobber (reg:CC FLAGS_REG))]
8102   "TARGET_HIMODE_MATH"
8103   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8104
8105 (define_insn "*andhi_1"
8106   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8107         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8108                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8109    (clobber (reg:CC FLAGS_REG))]
8110   "ix86_binary_operator_ok (AND, HImode, operands)"
8111 {
8112   switch (get_attr_type (insn))
8113     {
8114     case TYPE_IMOVX:
8115       if (GET_CODE (operands[2]) != CONST_INT)
8116         abort ();
8117       if (INTVAL (operands[2]) == 0xff)
8118         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8119       abort ();
8120
8121     default:
8122       if (! rtx_equal_p (operands[0], operands[1]))
8123         abort ();
8124
8125       return "and{w}\t{%2, %0|%0, %2}";
8126     }
8127 }
8128   [(set_attr "type" "alu,alu,imovx")
8129    (set_attr "length_immediate" "*,*,0")
8130    (set_attr "mode" "HI,HI,SI")])
8131
8132 (define_insn "*andhi_2"
8133   [(set (reg FLAGS_REG)
8134         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8135                          (match_operand:HI 2 "general_operand" "rim,ri"))
8136                  (const_int 0)))
8137    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8138         (and:HI (match_dup 1) (match_dup 2)))]
8139   "ix86_match_ccmode (insn, CCNOmode)
8140    && ix86_binary_operator_ok (AND, HImode, operands)"
8141   "and{w}\t{%2, %0|%0, %2}"
8142   [(set_attr "type" "alu")
8143    (set_attr "mode" "HI")])
8144
8145 (define_expand "andqi3"
8146   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8147         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8148                 (match_operand:QI 2 "general_operand" "")))
8149    (clobber (reg:CC FLAGS_REG))]
8150   "TARGET_QIMODE_MATH"
8151   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8152
8153 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8154 (define_insn "*andqi_1"
8155   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8156         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8157                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8158    (clobber (reg:CC FLAGS_REG))]
8159   "ix86_binary_operator_ok (AND, QImode, operands)"
8160   "@
8161    and{b}\t{%2, %0|%0, %2}
8162    and{b}\t{%2, %0|%0, %2}
8163    and{l}\t{%k2, %k0|%k0, %k2}"
8164   [(set_attr "type" "alu")
8165    (set_attr "mode" "QI,QI,SI")])
8166
8167 (define_insn "*andqi_1_slp"
8168   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8169         (and:QI (match_dup 0)
8170                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8171    (clobber (reg:CC FLAGS_REG))]
8172   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8173    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8174   "and{b}\t{%1, %0|%0, %1}"
8175   [(set_attr "type" "alu1")
8176    (set_attr "mode" "QI")])
8177
8178 (define_insn "*andqi_2_maybe_si"
8179   [(set (reg FLAGS_REG)
8180         (compare (and:QI
8181                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8182                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8183                  (const_int 0)))
8184    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8185         (and:QI (match_dup 1) (match_dup 2)))]
8186   "ix86_binary_operator_ok (AND, QImode, operands)
8187    && ix86_match_ccmode (insn,
8188                          GET_CODE (operands[2]) == CONST_INT
8189                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8190 {
8191   if (which_alternative == 2)
8192     {
8193       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8194         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8195       return "and{l}\t{%2, %k0|%k0, %2}";
8196     }
8197   return "and{b}\t{%2, %0|%0, %2}";
8198 }
8199   [(set_attr "type" "alu")
8200    (set_attr "mode" "QI,QI,SI")])
8201
8202 (define_insn "*andqi_2"
8203   [(set (reg FLAGS_REG)
8204         (compare (and:QI
8205                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8206                    (match_operand:QI 2 "general_operand" "qim,qi"))
8207                  (const_int 0)))
8208    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8209         (and:QI (match_dup 1) (match_dup 2)))]
8210   "ix86_match_ccmode (insn, CCNOmode)
8211    && ix86_binary_operator_ok (AND, QImode, operands)"
8212   "and{b}\t{%2, %0|%0, %2}"
8213   [(set_attr "type" "alu")
8214    (set_attr "mode" "QI")])
8215
8216 (define_insn "*andqi_2_slp"
8217   [(set (reg FLAGS_REG)
8218         (compare (and:QI
8219                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8220                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8221                  (const_int 0)))
8222    (set (strict_low_part (match_dup 0))
8223         (and:QI (match_dup 0) (match_dup 1)))]
8224   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8225    && ix86_match_ccmode (insn, CCNOmode)
8226    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8227   "and{b}\t{%1, %0|%0, %1}"
8228   [(set_attr "type" "alu1")
8229    (set_attr "mode" "QI")])
8230
8231 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8232 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8233 ;; for a QImode operand, which of course failed.
8234
8235 (define_insn "andqi_ext_0"
8236   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8237                          (const_int 8)
8238                          (const_int 8))
8239         (and:SI 
8240           (zero_extract:SI
8241             (match_operand 1 "ext_register_operand" "0")
8242             (const_int 8)
8243             (const_int 8))
8244           (match_operand 2 "const_int_operand" "n")))
8245    (clobber (reg:CC FLAGS_REG))]
8246   ""
8247   "and{b}\t{%2, %h0|%h0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "length_immediate" "1")
8250    (set_attr "mode" "QI")])
8251
8252 ;; Generated by peephole translating test to and.  This shows up
8253 ;; often in fp comparisons.
8254
8255 (define_insn "*andqi_ext_0_cc"
8256   [(set (reg FLAGS_REG)
8257         (compare
8258           (and:SI
8259             (zero_extract:SI
8260               (match_operand 1 "ext_register_operand" "0")
8261               (const_int 8)
8262               (const_int 8))
8263             (match_operand 2 "const_int_operand" "n"))
8264           (const_int 0)))
8265    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8266                          (const_int 8)
8267                          (const_int 8))
8268         (and:SI 
8269           (zero_extract:SI
8270             (match_dup 1)
8271             (const_int 8)
8272             (const_int 8))
8273           (match_dup 2)))]
8274   "ix86_match_ccmode (insn, CCNOmode)"
8275   "and{b}\t{%2, %h0|%h0, %2}"
8276   [(set_attr "type" "alu")
8277    (set_attr "length_immediate" "1")
8278    (set_attr "mode" "QI")])
8279
8280 (define_insn "*andqi_ext_1"
8281   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8282                          (const_int 8)
8283                          (const_int 8))
8284         (and:SI 
8285           (zero_extract:SI
8286             (match_operand 1 "ext_register_operand" "0")
8287             (const_int 8)
8288             (const_int 8))
8289           (zero_extend:SI
8290             (match_operand:QI 2 "general_operand" "Qm"))))
8291    (clobber (reg:CC FLAGS_REG))]
8292   "!TARGET_64BIT"
8293   "and{b}\t{%2, %h0|%h0, %2}"
8294   [(set_attr "type" "alu")
8295    (set_attr "length_immediate" "0")
8296    (set_attr "mode" "QI")])
8297
8298 (define_insn "*andqi_ext_1_rex64"
8299   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8300                          (const_int 8)
8301                          (const_int 8))
8302         (and:SI 
8303           (zero_extract:SI
8304             (match_operand 1 "ext_register_operand" "0")
8305             (const_int 8)
8306             (const_int 8))
8307           (zero_extend:SI
8308             (match_operand 2 "ext_register_operand" "Q"))))
8309    (clobber (reg:CC FLAGS_REG))]
8310   "TARGET_64BIT"
8311   "and{b}\t{%2, %h0|%h0, %2}"
8312   [(set_attr "type" "alu")
8313    (set_attr "length_immediate" "0")
8314    (set_attr "mode" "QI")])
8315
8316 (define_insn "*andqi_ext_2"
8317   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8318                          (const_int 8)
8319                          (const_int 8))
8320         (and:SI
8321           (zero_extract:SI
8322             (match_operand 1 "ext_register_operand" "%0")
8323             (const_int 8)
8324             (const_int 8))
8325           (zero_extract:SI
8326             (match_operand 2 "ext_register_operand" "Q")
8327             (const_int 8)
8328             (const_int 8))))
8329    (clobber (reg:CC FLAGS_REG))]
8330   ""
8331   "and{b}\t{%h2, %h0|%h0, %h2}"
8332   [(set_attr "type" "alu")
8333    (set_attr "length_immediate" "0")
8334    (set_attr "mode" "QI")])
8335
8336 ;; Convert wide AND instructions with immediate operand to shorter QImode
8337 ;; equivalents when possible.
8338 ;; Don't do the splitting with memory operands, since it introduces risk
8339 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8340 ;; for size, but that can (should?) be handled by generic code instead.
8341 (define_split
8342   [(set (match_operand 0 "register_operand" "")
8343         (and (match_operand 1 "register_operand" "")
8344              (match_operand 2 "const_int_operand" "")))
8345    (clobber (reg:CC FLAGS_REG))]
8346    "reload_completed
8347     && QI_REG_P (operands[0])
8348     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8349     && !(~INTVAL (operands[2]) & ~(255 << 8))
8350     && GET_MODE (operands[0]) != QImode"
8351   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8352                    (and:SI (zero_extract:SI (match_dup 1)
8353                                             (const_int 8) (const_int 8))
8354                            (match_dup 2)))
8355               (clobber (reg:CC FLAGS_REG))])]
8356   "operands[0] = gen_lowpart (SImode, operands[0]);
8357    operands[1] = gen_lowpart (SImode, operands[1]);
8358    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8359
8360 ;; Since AND can be encoded with sign extended immediate, this is only
8361 ;; profitable when 7th bit is not set.
8362 (define_split
8363   [(set (match_operand 0 "register_operand" "")
8364         (and (match_operand 1 "general_operand" "")
8365              (match_operand 2 "const_int_operand" "")))
8366    (clobber (reg:CC FLAGS_REG))]
8367    "reload_completed
8368     && ANY_QI_REG_P (operands[0])
8369     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8370     && !(~INTVAL (operands[2]) & ~255)
8371     && !(INTVAL (operands[2]) & 128)
8372     && GET_MODE (operands[0]) != QImode"
8373   [(parallel [(set (strict_low_part (match_dup 0))
8374                    (and:QI (match_dup 1)
8375                            (match_dup 2)))
8376               (clobber (reg:CC FLAGS_REG))])]
8377   "operands[0] = gen_lowpart (QImode, operands[0]);
8378    operands[1] = gen_lowpart (QImode, operands[1]);
8379    operands[2] = gen_lowpart (QImode, operands[2]);")
8380 \f
8381 ;; Logical inclusive OR instructions
8382
8383 ;; %%% This used to optimize known byte-wide and operations to memory.
8384 ;; If this is considered useful, it should be done with splitters.
8385
8386 (define_expand "iordi3"
8387   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8388         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8389                 (match_operand:DI 2 "x86_64_general_operand" "")))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "TARGET_64BIT"
8392   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8393
8394 (define_insn "*iordi_1_rex64"
8395   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8396         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8397                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8398    (clobber (reg:CC FLAGS_REG))]
8399   "TARGET_64BIT
8400    && ix86_binary_operator_ok (IOR, DImode, operands)"
8401   "or{q}\t{%2, %0|%0, %2}"
8402   [(set_attr "type" "alu")
8403    (set_attr "mode" "DI")])
8404
8405 (define_insn "*iordi_2_rex64"
8406   [(set (reg FLAGS_REG)
8407         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8408                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8409                  (const_int 0)))
8410    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8411         (ior:DI (match_dup 1) (match_dup 2)))]
8412   "TARGET_64BIT
8413    && ix86_match_ccmode (insn, CCNOmode)
8414    && ix86_binary_operator_ok (IOR, DImode, operands)"
8415   "or{q}\t{%2, %0|%0, %2}"
8416   [(set_attr "type" "alu")
8417    (set_attr "mode" "DI")])
8418
8419 (define_insn "*iordi_3_rex64"
8420   [(set (reg FLAGS_REG)
8421         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8422                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8423                  (const_int 0)))
8424    (clobber (match_scratch:DI 0 "=r"))]
8425   "TARGET_64BIT
8426    && ix86_match_ccmode (insn, CCNOmode)
8427    && ix86_binary_operator_ok (IOR, DImode, operands)"
8428   "or{q}\t{%2, %0|%0, %2}"
8429   [(set_attr "type" "alu")
8430    (set_attr "mode" "DI")])
8431
8432
8433 (define_expand "iorsi3"
8434   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8435         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8436                 (match_operand:SI 2 "general_operand" "")))
8437    (clobber (reg:CC FLAGS_REG))]
8438   ""
8439   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8440
8441 (define_insn "*iorsi_1"
8442   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8443         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8444                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8445    (clobber (reg:CC FLAGS_REG))]
8446   "ix86_binary_operator_ok (IOR, SImode, operands)"
8447   "or{l}\t{%2, %0|%0, %2}"
8448   [(set_attr "type" "alu")
8449    (set_attr "mode" "SI")])
8450
8451 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8452 (define_insn "*iorsi_1_zext"
8453   [(set (match_operand:DI 0 "register_operand" "=rm")
8454         (zero_extend:DI
8455           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8456                   (match_operand:SI 2 "general_operand" "rim"))))
8457    (clobber (reg:CC FLAGS_REG))]
8458   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8459   "or{l}\t{%2, %k0|%k0, %2}"
8460   [(set_attr "type" "alu")
8461    (set_attr "mode" "SI")])
8462
8463 (define_insn "*iorsi_1_zext_imm"
8464   [(set (match_operand:DI 0 "register_operand" "=rm")
8465         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8466                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8467    (clobber (reg:CC FLAGS_REG))]
8468   "TARGET_64BIT"
8469   "or{l}\t{%2, %k0|%k0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "mode" "SI")])
8472
8473 (define_insn "*iorsi_2"
8474   [(set (reg FLAGS_REG)
8475         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8476                          (match_operand:SI 2 "general_operand" "rim,ri"))
8477                  (const_int 0)))
8478    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8479         (ior:SI (match_dup 1) (match_dup 2)))]
8480   "ix86_match_ccmode (insn, CCNOmode)
8481    && ix86_binary_operator_ok (IOR, SImode, operands)"
8482   "or{l}\t{%2, %0|%0, %2}"
8483   [(set_attr "type" "alu")
8484    (set_attr "mode" "SI")])
8485
8486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8487 ;; ??? Special case for immediate operand is missing - it is tricky.
8488 (define_insn "*iorsi_2_zext"
8489   [(set (reg FLAGS_REG)
8490         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8491                          (match_operand:SI 2 "general_operand" "rim"))
8492                  (const_int 0)))
8493    (set (match_operand:DI 0 "register_operand" "=r")
8494         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8495   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8496    && ix86_binary_operator_ok (IOR, SImode, operands)"
8497   "or{l}\t{%2, %k0|%k0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "mode" "SI")])
8500
8501 (define_insn "*iorsi_2_zext_imm"
8502   [(set (reg FLAGS_REG)
8503         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8504                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8505                  (const_int 0)))
8506    (set (match_operand:DI 0 "register_operand" "=r")
8507         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8508   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8509    && ix86_binary_operator_ok (IOR, SImode, operands)"
8510   "or{l}\t{%2, %k0|%k0, %2}"
8511   [(set_attr "type" "alu")
8512    (set_attr "mode" "SI")])
8513
8514 (define_insn "*iorsi_3"
8515   [(set (reg FLAGS_REG)
8516         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8517                          (match_operand:SI 2 "general_operand" "rim"))
8518                  (const_int 0)))
8519    (clobber (match_scratch:SI 0 "=r"))]
8520   "ix86_match_ccmode (insn, CCNOmode)
8521    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8522   "or{l}\t{%2, %0|%0, %2}"
8523   [(set_attr "type" "alu")
8524    (set_attr "mode" "SI")])
8525
8526 (define_expand "iorhi3"
8527   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8528         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8529                 (match_operand:HI 2 "general_operand" "")))
8530    (clobber (reg:CC FLAGS_REG))]
8531   "TARGET_HIMODE_MATH"
8532   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8533
8534 (define_insn "*iorhi_1"
8535   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8536         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8537                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8538    (clobber (reg:CC FLAGS_REG))]
8539   "ix86_binary_operator_ok (IOR, HImode, operands)"
8540   "or{w}\t{%2, %0|%0, %2}"
8541   [(set_attr "type" "alu")
8542    (set_attr "mode" "HI")])
8543
8544 (define_insn "*iorhi_2"
8545   [(set (reg FLAGS_REG)
8546         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8547                          (match_operand:HI 2 "general_operand" "rim,ri"))
8548                  (const_int 0)))
8549    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8550         (ior:HI (match_dup 1) (match_dup 2)))]
8551   "ix86_match_ccmode (insn, CCNOmode)
8552    && ix86_binary_operator_ok (IOR, HImode, operands)"
8553   "or{w}\t{%2, %0|%0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "mode" "HI")])
8556
8557 (define_insn "*iorhi_3"
8558   [(set (reg FLAGS_REG)
8559         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8560                          (match_operand:HI 2 "general_operand" "rim"))
8561                  (const_int 0)))
8562    (clobber (match_scratch:HI 0 "=r"))]
8563   "ix86_match_ccmode (insn, CCNOmode)
8564    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8565   "or{w}\t{%2, %0|%0, %2}"
8566   [(set_attr "type" "alu")
8567    (set_attr "mode" "HI")])
8568
8569 (define_expand "iorqi3"
8570   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8571         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8572                 (match_operand:QI 2 "general_operand" "")))
8573    (clobber (reg:CC FLAGS_REG))]
8574   "TARGET_QIMODE_MATH"
8575   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8576
8577 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8578 (define_insn "*iorqi_1"
8579   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8580         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8581                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8582    (clobber (reg:CC FLAGS_REG))]
8583   "ix86_binary_operator_ok (IOR, QImode, operands)"
8584   "@
8585    or{b}\t{%2, %0|%0, %2}
8586    or{b}\t{%2, %0|%0, %2}
8587    or{l}\t{%k2, %k0|%k0, %k2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "mode" "QI,QI,SI")])
8590
8591 (define_insn "*iorqi_1_slp"
8592   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8593         (ior:QI (match_dup 0)
8594                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8595    (clobber (reg:CC FLAGS_REG))]
8596   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8597    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8598   "or{b}\t{%1, %0|%0, %1}"
8599   [(set_attr "type" "alu1")
8600    (set_attr "mode" "QI")])
8601
8602 (define_insn "*iorqi_2"
8603   [(set (reg FLAGS_REG)
8604         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8605                          (match_operand:QI 2 "general_operand" "qim,qi"))
8606                  (const_int 0)))
8607    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8608         (ior:QI (match_dup 1) (match_dup 2)))]
8609   "ix86_match_ccmode (insn, CCNOmode)
8610    && ix86_binary_operator_ok (IOR, QImode, operands)"
8611   "or{b}\t{%2, %0|%0, %2}"
8612   [(set_attr "type" "alu")
8613    (set_attr "mode" "QI")])
8614
8615 (define_insn "*iorqi_2_slp"
8616   [(set (reg FLAGS_REG)
8617         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8618                          (match_operand:QI 1 "general_operand" "qim,qi"))
8619                  (const_int 0)))
8620    (set (strict_low_part (match_dup 0))
8621         (ior:QI (match_dup 0) (match_dup 1)))]
8622   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8623    && ix86_match_ccmode (insn, CCNOmode)
8624    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8625   "or{b}\t{%1, %0|%0, %1}"
8626   [(set_attr "type" "alu1")
8627    (set_attr "mode" "QI")])
8628
8629 (define_insn "*iorqi_3"
8630   [(set (reg FLAGS_REG)
8631         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8632                          (match_operand:QI 2 "general_operand" "qim"))
8633                  (const_int 0)))
8634    (clobber (match_scratch:QI 0 "=q"))]
8635   "ix86_match_ccmode (insn, CCNOmode)
8636    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8637   "or{b}\t{%2, %0|%0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "QI")])
8640
8641 (define_insn "iorqi_ext_0"
8642   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8643                          (const_int 8)
8644                          (const_int 8))
8645         (ior:SI 
8646           (zero_extract:SI
8647             (match_operand 1 "ext_register_operand" "0")
8648             (const_int 8)
8649             (const_int 8))
8650           (match_operand 2 "const_int_operand" "n")))
8651    (clobber (reg:CC FLAGS_REG))]
8652   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8653   "or{b}\t{%2, %h0|%h0, %2}"
8654   [(set_attr "type" "alu")
8655    (set_attr "length_immediate" "1")
8656    (set_attr "mode" "QI")])
8657
8658 (define_insn "*iorqi_ext_1"
8659   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8660                          (const_int 8)
8661                          (const_int 8))
8662         (ior:SI 
8663           (zero_extract:SI
8664             (match_operand 1 "ext_register_operand" "0")
8665             (const_int 8)
8666             (const_int 8))
8667           (zero_extend:SI
8668             (match_operand:QI 2 "general_operand" "Qm"))))
8669    (clobber (reg:CC FLAGS_REG))]
8670   "!TARGET_64BIT
8671    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8672   "or{b}\t{%2, %h0|%h0, %2}"
8673   [(set_attr "type" "alu")
8674    (set_attr "length_immediate" "0")
8675    (set_attr "mode" "QI")])
8676
8677 (define_insn "*iorqi_ext_1_rex64"
8678   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8679                          (const_int 8)
8680                          (const_int 8))
8681         (ior:SI 
8682           (zero_extract:SI
8683             (match_operand 1 "ext_register_operand" "0")
8684             (const_int 8)
8685             (const_int 8))
8686           (zero_extend:SI
8687             (match_operand 2 "ext_register_operand" "Q"))))
8688    (clobber (reg:CC FLAGS_REG))]
8689   "TARGET_64BIT
8690    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8691   "or{b}\t{%2, %h0|%h0, %2}"
8692   [(set_attr "type" "alu")
8693    (set_attr "length_immediate" "0")
8694    (set_attr "mode" "QI")])
8695
8696 (define_insn "*iorqi_ext_2"
8697   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8698                          (const_int 8)
8699                          (const_int 8))
8700         (ior:SI 
8701           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8702                            (const_int 8)
8703                            (const_int 8))
8704           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8705                            (const_int 8)
8706                            (const_int 8))))
8707    (clobber (reg:CC FLAGS_REG))]
8708   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8709   "ior{b}\t{%h2, %h0|%h0, %h2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "length_immediate" "0")
8712    (set_attr "mode" "QI")])
8713
8714 (define_split
8715   [(set (match_operand 0 "register_operand" "")
8716         (ior (match_operand 1 "register_operand" "")
8717              (match_operand 2 "const_int_operand" "")))
8718    (clobber (reg:CC FLAGS_REG))]
8719    "reload_completed
8720     && QI_REG_P (operands[0])
8721     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8722     && !(INTVAL (operands[2]) & ~(255 << 8))
8723     && GET_MODE (operands[0]) != QImode"
8724   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8725                    (ior:SI (zero_extract:SI (match_dup 1)
8726                                             (const_int 8) (const_int 8))
8727                            (match_dup 2)))
8728               (clobber (reg:CC FLAGS_REG))])]
8729   "operands[0] = gen_lowpart (SImode, operands[0]);
8730    operands[1] = gen_lowpart (SImode, operands[1]);
8731    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8732
8733 ;; Since OR can be encoded with sign extended immediate, this is only
8734 ;; profitable when 7th bit is set.
8735 (define_split
8736   [(set (match_operand 0 "register_operand" "")
8737         (ior (match_operand 1 "general_operand" "")
8738              (match_operand 2 "const_int_operand" "")))
8739    (clobber (reg:CC FLAGS_REG))]
8740    "reload_completed
8741     && ANY_QI_REG_P (operands[0])
8742     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8743     && !(INTVAL (operands[2]) & ~255)
8744     && (INTVAL (operands[2]) & 128)
8745     && GET_MODE (operands[0]) != QImode"
8746   [(parallel [(set (strict_low_part (match_dup 0))
8747                    (ior:QI (match_dup 1)
8748                            (match_dup 2)))
8749               (clobber (reg:CC FLAGS_REG))])]
8750   "operands[0] = gen_lowpart (QImode, operands[0]);
8751    operands[1] = gen_lowpart (QImode, operands[1]);
8752    operands[2] = gen_lowpart (QImode, operands[2]);")
8753 \f
8754 ;; Logical XOR instructions
8755
8756 ;; %%% This used to optimize known byte-wide and operations to memory.
8757 ;; If this is considered useful, it should be done with splitters.
8758
8759 (define_expand "xordi3"
8760   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8761         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8762                 (match_operand:DI 2 "x86_64_general_operand" "")))
8763    (clobber (reg:CC FLAGS_REG))]
8764   "TARGET_64BIT"
8765   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8766
8767 (define_insn "*xordi_1_rex64"
8768   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8769         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8770                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "TARGET_64BIT
8773    && ix86_binary_operator_ok (XOR, DImode, operands)"
8774   "@
8775    xor{q}\t{%2, %0|%0, %2}
8776    xor{q}\t{%2, %0|%0, %2}"
8777   [(set_attr "type" "alu")
8778    (set_attr "mode" "DI,DI")])
8779
8780 (define_insn "*xordi_2_rex64"
8781   [(set (reg FLAGS_REG)
8782         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8783                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8784                  (const_int 0)))
8785    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8786         (xor:DI (match_dup 1) (match_dup 2)))]
8787   "TARGET_64BIT
8788    && ix86_match_ccmode (insn, CCNOmode)
8789    && ix86_binary_operator_ok (XOR, DImode, operands)"
8790   "@
8791    xor{q}\t{%2, %0|%0, %2}
8792    xor{q}\t{%2, %0|%0, %2}"
8793   [(set_attr "type" "alu")
8794    (set_attr "mode" "DI,DI")])
8795
8796 (define_insn "*xordi_3_rex64"
8797   [(set (reg FLAGS_REG)
8798         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8799                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8800                  (const_int 0)))
8801    (clobber (match_scratch:DI 0 "=r"))]
8802   "TARGET_64BIT
8803    && ix86_match_ccmode (insn, CCNOmode)
8804    && ix86_binary_operator_ok (XOR, DImode, operands)"
8805   "xor{q}\t{%2, %0|%0, %2}"
8806   [(set_attr "type" "alu")
8807    (set_attr "mode" "DI")])
8808
8809 (define_expand "xorsi3"
8810   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8811         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8812                 (match_operand:SI 2 "general_operand" "")))
8813    (clobber (reg:CC FLAGS_REG))]
8814   ""
8815   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8816
8817 (define_insn "*xorsi_1"
8818   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8819         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8820                 (match_operand:SI 2 "general_operand" "ri,rm")))
8821    (clobber (reg:CC FLAGS_REG))]
8822   "ix86_binary_operator_ok (XOR, SImode, operands)"
8823   "xor{l}\t{%2, %0|%0, %2}"
8824   [(set_attr "type" "alu")
8825    (set_attr "mode" "SI")])
8826
8827 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8828 ;; Add speccase for immediates
8829 (define_insn "*xorsi_1_zext"
8830   [(set (match_operand:DI 0 "register_operand" "=r")
8831         (zero_extend:DI
8832           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8833                   (match_operand:SI 2 "general_operand" "rim"))))
8834    (clobber (reg:CC FLAGS_REG))]
8835   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8836   "xor{l}\t{%2, %k0|%k0, %2}"
8837   [(set_attr "type" "alu")
8838    (set_attr "mode" "SI")])
8839
8840 (define_insn "*xorsi_1_zext_imm"
8841   [(set (match_operand:DI 0 "register_operand" "=r")
8842         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8843                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8844    (clobber (reg:CC FLAGS_REG))]
8845   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8846   "xor{l}\t{%2, %k0|%k0, %2}"
8847   [(set_attr "type" "alu")
8848    (set_attr "mode" "SI")])
8849
8850 (define_insn "*xorsi_2"
8851   [(set (reg FLAGS_REG)
8852         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8853                          (match_operand:SI 2 "general_operand" "rim,ri"))
8854                  (const_int 0)))
8855    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8856         (xor:SI (match_dup 1) (match_dup 2)))]
8857   "ix86_match_ccmode (insn, CCNOmode)
8858    && ix86_binary_operator_ok (XOR, SImode, operands)"
8859   "xor{l}\t{%2, %0|%0, %2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "mode" "SI")])
8862
8863 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8864 ;; ??? Special case for immediate operand is missing - it is tricky.
8865 (define_insn "*xorsi_2_zext"
8866   [(set (reg FLAGS_REG)
8867         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8868                          (match_operand:SI 2 "general_operand" "rim"))
8869                  (const_int 0)))
8870    (set (match_operand:DI 0 "register_operand" "=r")
8871         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8872   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8873    && ix86_binary_operator_ok (XOR, SImode, operands)"
8874   "xor{l}\t{%2, %k0|%k0, %2}"
8875   [(set_attr "type" "alu")
8876    (set_attr "mode" "SI")])
8877
8878 (define_insn "*xorsi_2_zext_imm"
8879   [(set (reg FLAGS_REG)
8880         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8881                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8882                  (const_int 0)))
8883    (set (match_operand:DI 0 "register_operand" "=r")
8884         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8885   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8886    && ix86_binary_operator_ok (XOR, SImode, operands)"
8887   "xor{l}\t{%2, %k0|%k0, %2}"
8888   [(set_attr "type" "alu")
8889    (set_attr "mode" "SI")])
8890
8891 (define_insn "*xorsi_3"
8892   [(set (reg FLAGS_REG)
8893         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8894                          (match_operand:SI 2 "general_operand" "rim"))
8895                  (const_int 0)))
8896    (clobber (match_scratch:SI 0 "=r"))]
8897   "ix86_match_ccmode (insn, CCNOmode)
8898    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8899   "xor{l}\t{%2, %0|%0, %2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "SI")])
8902
8903 (define_expand "xorhi3"
8904   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8905         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8906                 (match_operand:HI 2 "general_operand" "")))
8907    (clobber (reg:CC FLAGS_REG))]
8908   "TARGET_HIMODE_MATH"
8909   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8910
8911 (define_insn "*xorhi_1"
8912   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8913         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8914                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8915    (clobber (reg:CC FLAGS_REG))]
8916   "ix86_binary_operator_ok (XOR, HImode, operands)"
8917   "xor{w}\t{%2, %0|%0, %2}"
8918   [(set_attr "type" "alu")
8919    (set_attr "mode" "HI")])
8920
8921 (define_insn "*xorhi_2"
8922   [(set (reg FLAGS_REG)
8923         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8924                          (match_operand:HI 2 "general_operand" "rim,ri"))
8925                  (const_int 0)))
8926    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8927         (xor:HI (match_dup 1) (match_dup 2)))]
8928   "ix86_match_ccmode (insn, CCNOmode)
8929    && ix86_binary_operator_ok (XOR, HImode, operands)"
8930   "xor{w}\t{%2, %0|%0, %2}"
8931   [(set_attr "type" "alu")
8932    (set_attr "mode" "HI")])
8933
8934 (define_insn "*xorhi_3"
8935   [(set (reg FLAGS_REG)
8936         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8937                          (match_operand:HI 2 "general_operand" "rim"))
8938                  (const_int 0)))
8939    (clobber (match_scratch:HI 0 "=r"))]
8940   "ix86_match_ccmode (insn, CCNOmode)
8941    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8942   "xor{w}\t{%2, %0|%0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "mode" "HI")])
8945
8946 (define_expand "xorqi3"
8947   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8948         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8949                 (match_operand:QI 2 "general_operand" "")))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "TARGET_QIMODE_MATH"
8952   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8953
8954 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8955 (define_insn "*xorqi_1"
8956   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8957         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8958                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "ix86_binary_operator_ok (XOR, QImode, operands)"
8961   "@
8962    xor{b}\t{%2, %0|%0, %2}
8963    xor{b}\t{%2, %0|%0, %2}
8964    xor{l}\t{%k2, %k0|%k0, %k2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "mode" "QI,QI,SI")])
8967
8968 (define_insn "*xorqi_1_slp"
8969   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8970         (xor:QI (match_dup 0)
8971                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8972    (clobber (reg:CC FLAGS_REG))]
8973   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8974    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8975   "xor{b}\t{%1, %0|%0, %1}"
8976   [(set_attr "type" "alu1")
8977    (set_attr "mode" "QI")])
8978
8979 (define_insn "xorqi_ext_0"
8980   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8981                          (const_int 8)
8982                          (const_int 8))
8983         (xor:SI 
8984           (zero_extract:SI
8985             (match_operand 1 "ext_register_operand" "0")
8986             (const_int 8)
8987             (const_int 8))
8988           (match_operand 2 "const_int_operand" "n")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8991   "xor{b}\t{%2, %h0|%h0, %2}"
8992   [(set_attr "type" "alu")
8993    (set_attr "length_immediate" "1")
8994    (set_attr "mode" "QI")])
8995
8996 (define_insn "*xorqi_ext_1"
8997   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8998                          (const_int 8)
8999                          (const_int 8))
9000         (xor:SI 
9001           (zero_extract:SI
9002             (match_operand 1 "ext_register_operand" "0")
9003             (const_int 8)
9004             (const_int 8))
9005           (zero_extend:SI
9006             (match_operand:QI 2 "general_operand" "Qm"))))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "!TARGET_64BIT
9009    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9010   "xor{b}\t{%2, %h0|%h0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "length_immediate" "0")
9013    (set_attr "mode" "QI")])
9014
9015 (define_insn "*xorqi_ext_1_rex64"
9016   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9017                          (const_int 8)
9018                          (const_int 8))
9019         (xor:SI 
9020           (zero_extract:SI
9021             (match_operand 1 "ext_register_operand" "0")
9022             (const_int 8)
9023             (const_int 8))
9024           (zero_extend:SI
9025             (match_operand 2 "ext_register_operand" "Q"))))
9026    (clobber (reg:CC FLAGS_REG))]
9027   "TARGET_64BIT
9028    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9029   "xor{b}\t{%2, %h0|%h0, %2}"
9030   [(set_attr "type" "alu")
9031    (set_attr "length_immediate" "0")
9032    (set_attr "mode" "QI")])
9033
9034 (define_insn "*xorqi_ext_2"
9035   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9036                          (const_int 8)
9037                          (const_int 8))
9038         (xor:SI 
9039           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9040                            (const_int 8)
9041                            (const_int 8))
9042           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9043                            (const_int 8)
9044                            (const_int 8))))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9047   "xor{b}\t{%h2, %h0|%h0, %h2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "length_immediate" "0")
9050    (set_attr "mode" "QI")])
9051
9052 (define_insn "*xorqi_cc_1"
9053   [(set (reg FLAGS_REG)
9054         (compare
9055           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9056                   (match_operand:QI 2 "general_operand" "qim,qi"))
9057           (const_int 0)))
9058    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9059         (xor:QI (match_dup 1) (match_dup 2)))]
9060   "ix86_match_ccmode (insn, CCNOmode)
9061    && ix86_binary_operator_ok (XOR, QImode, operands)"
9062   "xor{b}\t{%2, %0|%0, %2}"
9063   [(set_attr "type" "alu")
9064    (set_attr "mode" "QI")])
9065
9066 (define_insn "*xorqi_2_slp"
9067   [(set (reg FLAGS_REG)
9068         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9069                          (match_operand:QI 1 "general_operand" "qim,qi"))
9070                  (const_int 0)))
9071    (set (strict_low_part (match_dup 0))
9072         (xor:QI (match_dup 0) (match_dup 1)))]
9073   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9074    && ix86_match_ccmode (insn, CCNOmode)
9075    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9076   "xor{b}\t{%1, %0|%0, %1}"
9077   [(set_attr "type" "alu1")
9078    (set_attr "mode" "QI")])
9079
9080 (define_insn "*xorqi_cc_2"
9081   [(set (reg FLAGS_REG)
9082         (compare
9083           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9084                   (match_operand:QI 2 "general_operand" "qim"))
9085           (const_int 0)))
9086    (clobber (match_scratch:QI 0 "=q"))]
9087   "ix86_match_ccmode (insn, CCNOmode)
9088    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9089   "xor{b}\t{%2, %0|%0, %2}"
9090   [(set_attr "type" "alu")
9091    (set_attr "mode" "QI")])
9092
9093 (define_insn "*xorqi_cc_ext_1"
9094   [(set (reg FLAGS_REG)
9095         (compare
9096           (xor:SI
9097             (zero_extract:SI
9098               (match_operand 1 "ext_register_operand" "0")
9099               (const_int 8)
9100               (const_int 8))
9101             (match_operand:QI 2 "general_operand" "qmn"))
9102           (const_int 0)))
9103    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9104                          (const_int 8)
9105                          (const_int 8))
9106         (xor:SI 
9107           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9108           (match_dup 2)))]
9109   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9110   "xor{b}\t{%2, %h0|%h0, %2}"
9111   [(set_attr "type" "alu")
9112    (set_attr "mode" "QI")])
9113
9114 (define_insn "*xorqi_cc_ext_1_rex64"
9115   [(set (reg FLAGS_REG)
9116         (compare
9117           (xor:SI
9118             (zero_extract:SI
9119               (match_operand 1 "ext_register_operand" "0")
9120               (const_int 8)
9121               (const_int 8))
9122             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9123           (const_int 0)))
9124    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9125                          (const_int 8)
9126                          (const_int 8))
9127         (xor:SI 
9128           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9129           (match_dup 2)))]
9130   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9131   "xor{b}\t{%2, %h0|%h0, %2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "mode" "QI")])
9134
9135 (define_expand "xorqi_cc_ext_1"
9136   [(parallel [
9137      (set (reg:CCNO FLAGS_REG)
9138           (compare:CCNO
9139             (xor:SI
9140               (zero_extract:SI
9141                 (match_operand 1 "ext_register_operand" "")
9142                 (const_int 8)
9143                 (const_int 8))
9144               (match_operand:QI 2 "general_operand" ""))
9145             (const_int 0)))
9146      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9147                            (const_int 8)
9148                            (const_int 8))
9149           (xor:SI 
9150             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9151             (match_dup 2)))])]
9152   ""
9153   "")
9154
9155 (define_split
9156   [(set (match_operand 0 "register_operand" "")
9157         (xor (match_operand 1 "register_operand" "")
9158              (match_operand 2 "const_int_operand" "")))
9159    (clobber (reg:CC FLAGS_REG))]
9160    "reload_completed
9161     && QI_REG_P (operands[0])
9162     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9163     && !(INTVAL (operands[2]) & ~(255 << 8))
9164     && GET_MODE (operands[0]) != QImode"
9165   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9166                    (xor:SI (zero_extract:SI (match_dup 1)
9167                                             (const_int 8) (const_int 8))
9168                            (match_dup 2)))
9169               (clobber (reg:CC FLAGS_REG))])]
9170   "operands[0] = gen_lowpart (SImode, operands[0]);
9171    operands[1] = gen_lowpart (SImode, operands[1]);
9172    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9173
9174 ;; Since XOR can be encoded with sign extended immediate, this is only
9175 ;; profitable when 7th bit is set.
9176 (define_split
9177   [(set (match_operand 0 "register_operand" "")
9178         (xor (match_operand 1 "general_operand" "")
9179              (match_operand 2 "const_int_operand" "")))
9180    (clobber (reg:CC FLAGS_REG))]
9181    "reload_completed
9182     && ANY_QI_REG_P (operands[0])
9183     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9184     && !(INTVAL (operands[2]) & ~255)
9185     && (INTVAL (operands[2]) & 128)
9186     && GET_MODE (operands[0]) != QImode"
9187   [(parallel [(set (strict_low_part (match_dup 0))
9188                    (xor:QI (match_dup 1)
9189                            (match_dup 2)))
9190               (clobber (reg:CC FLAGS_REG))])]
9191   "operands[0] = gen_lowpart (QImode, operands[0]);
9192    operands[1] = gen_lowpart (QImode, operands[1]);
9193    operands[2] = gen_lowpart (QImode, operands[2]);")
9194 \f
9195 ;; Negation instructions
9196
9197 (define_expand "negdi2"
9198   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9199                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9200               (clobber (reg:CC FLAGS_REG))])]
9201   ""
9202   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9203
9204 (define_insn "*negdi2_1"
9205   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9206         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9207    (clobber (reg:CC FLAGS_REG))]
9208   "!TARGET_64BIT
9209    && ix86_unary_operator_ok (NEG, DImode, operands)"
9210   "#")
9211
9212 (define_split
9213   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9214         (neg:DI (match_operand:DI 1 "general_operand" "")))
9215    (clobber (reg:CC FLAGS_REG))]
9216   "!TARGET_64BIT && reload_completed"
9217   [(parallel
9218     [(set (reg:CCZ FLAGS_REG)
9219           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9220      (set (match_dup 0) (neg:SI (match_dup 2)))])
9221    (parallel
9222     [(set (match_dup 1)
9223           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9224                             (match_dup 3))
9225                    (const_int 0)))
9226      (clobber (reg:CC FLAGS_REG))])
9227    (parallel
9228     [(set (match_dup 1)
9229           (neg:SI (match_dup 1)))
9230      (clobber (reg:CC FLAGS_REG))])]
9231   "split_di (operands+1, 1, operands+2, operands+3);
9232    split_di (operands+0, 1, operands+0, operands+1);")
9233
9234 (define_insn "*negdi2_1_rex64"
9235   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9236         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9237    (clobber (reg:CC FLAGS_REG))]
9238   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9239   "neg{q}\t%0"
9240   [(set_attr "type" "negnot")
9241    (set_attr "mode" "DI")])
9242
9243 ;; The problem with neg is that it does not perform (compare x 0),
9244 ;; it really performs (compare 0 x), which leaves us with the zero
9245 ;; flag being the only useful item.
9246
9247 (define_insn "*negdi2_cmpz_rex64"
9248   [(set (reg:CCZ FLAGS_REG)
9249         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9250                      (const_int 0)))
9251    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9252         (neg:DI (match_dup 1)))]
9253   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9254   "neg{q}\t%0"
9255   [(set_attr "type" "negnot")
9256    (set_attr "mode" "DI")])
9257
9258
9259 (define_expand "negsi2"
9260   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9261                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9262               (clobber (reg:CC FLAGS_REG))])]
9263   ""
9264   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9265
9266 (define_insn "*negsi2_1"
9267   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9268         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9269    (clobber (reg:CC FLAGS_REG))]
9270   "ix86_unary_operator_ok (NEG, SImode, operands)"
9271   "neg{l}\t%0"
9272   [(set_attr "type" "negnot")
9273    (set_attr "mode" "SI")])
9274
9275 ;; Combine is quite creative about this pattern.
9276 (define_insn "*negsi2_1_zext"
9277   [(set (match_operand:DI 0 "register_operand" "=r")
9278         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9279                                         (const_int 32)))
9280                      (const_int 32)))
9281    (clobber (reg:CC FLAGS_REG))]
9282   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9283   "neg{l}\t%k0"
9284   [(set_attr "type" "negnot")
9285    (set_attr "mode" "SI")])
9286
9287 ;; The problem with neg is that it does not perform (compare x 0),
9288 ;; it really performs (compare 0 x), which leaves us with the zero
9289 ;; flag being the only useful item.
9290
9291 (define_insn "*negsi2_cmpz"
9292   [(set (reg:CCZ FLAGS_REG)
9293         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9294                      (const_int 0)))
9295    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9296         (neg:SI (match_dup 1)))]
9297   "ix86_unary_operator_ok (NEG, SImode, operands)"
9298   "neg{l}\t%0"
9299   [(set_attr "type" "negnot")
9300    (set_attr "mode" "SI")])
9301
9302 (define_insn "*negsi2_cmpz_zext"
9303   [(set (reg:CCZ FLAGS_REG)
9304         (compare:CCZ (lshiftrt:DI
9305                        (neg:DI (ashift:DI
9306                                  (match_operand:DI 1 "register_operand" "0")
9307                                  (const_int 32)))
9308                        (const_int 32))
9309                      (const_int 0)))
9310    (set (match_operand:DI 0 "register_operand" "=r")
9311         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9312                                         (const_int 32)))
9313                      (const_int 32)))]
9314   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9315   "neg{l}\t%k0"
9316   [(set_attr "type" "negnot")
9317    (set_attr "mode" "SI")])
9318
9319 (define_expand "neghi2"
9320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9321                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9322               (clobber (reg:CC FLAGS_REG))])]
9323   "TARGET_HIMODE_MATH"
9324   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9325
9326 (define_insn "*neghi2_1"
9327   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9328         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9329    (clobber (reg:CC FLAGS_REG))]
9330   "ix86_unary_operator_ok (NEG, HImode, operands)"
9331   "neg{w}\t%0"
9332   [(set_attr "type" "negnot")
9333    (set_attr "mode" "HI")])
9334
9335 (define_insn "*neghi2_cmpz"
9336   [(set (reg:CCZ FLAGS_REG)
9337         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9338                      (const_int 0)))
9339    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9340         (neg:HI (match_dup 1)))]
9341   "ix86_unary_operator_ok (NEG, HImode, operands)"
9342   "neg{w}\t%0"
9343   [(set_attr "type" "negnot")
9344    (set_attr "mode" "HI")])
9345
9346 (define_expand "negqi2"
9347   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9348                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9349               (clobber (reg:CC FLAGS_REG))])]
9350   "TARGET_QIMODE_MATH"
9351   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9352
9353 (define_insn "*negqi2_1"
9354   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9355         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9356    (clobber (reg:CC FLAGS_REG))]
9357   "ix86_unary_operator_ok (NEG, QImode, operands)"
9358   "neg{b}\t%0"
9359   [(set_attr "type" "negnot")
9360    (set_attr "mode" "QI")])
9361
9362 (define_insn "*negqi2_cmpz"
9363   [(set (reg:CCZ FLAGS_REG)
9364         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9365                      (const_int 0)))
9366    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9367         (neg:QI (match_dup 1)))]
9368   "ix86_unary_operator_ok (NEG, QImode, operands)"
9369   "neg{b}\t%0"
9370   [(set_attr "type" "negnot")
9371    (set_attr "mode" "QI")])
9372
9373 ;; Changing of sign for FP values is doable using integer unit too.
9374
9375 (define_expand "negsf2"
9376   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9377         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9378   "TARGET_80387 || TARGET_SSE_MATH"
9379   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9380
9381 (define_expand "abssf2"
9382   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9383         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9384   "TARGET_80387 || TARGET_SSE_MATH"
9385   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9386
9387 (define_insn "*absnegsf2_mixed"
9388   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9389         (match_operator:SF 3 "absneg_operator"
9390           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9391    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9392    (clobber (reg:CC FLAGS_REG))]
9393   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9394    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9395   "#")
9396
9397 (define_insn "*absnegsf2_sse"
9398   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9399         (match_operator:SF 3 "absneg_operator"
9400           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9401    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_SSE_MATH
9404    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9405   "#")
9406
9407 (define_insn "*absnegsf2_i387"
9408   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9409         (match_operator:SF 3 "absneg_operator"
9410           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9411    (use (match_operand 2 "" ""))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "TARGET_80387 && !TARGET_SSE_MATH
9414    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9415   "#")
9416
9417 (define_expand "copysignsf3"
9418   [(match_operand:SF 0 "register_operand" "")
9419    (match_operand:SF 1 "nonmemory_operand" "")
9420    (match_operand:SF 2 "register_operand" "")]
9421   "TARGET_SSE_MATH"
9422 {
9423   ix86_expand_copysign (operands);
9424   DONE;
9425 })
9426
9427 (define_insn_and_split "copysignsf3_const"
9428   [(set (match_operand:SF 0 "register_operand"          "=x")
9429         (unspec:SF
9430           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9431            (match_operand:SF 2 "register_operand"       "0")
9432            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9433           UNSPEC_COPYSIGN))]
9434   "TARGET_SSE_MATH"
9435   "#"
9436   "&& reload_completed"
9437   [(const_int 0)]
9438 {
9439   ix86_split_copysign_const (operands);
9440   DONE;
9441 })
9442
9443 (define_insn "copysignsf3_var"
9444   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9445         (unspec:SF
9446           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9447            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9448            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9449            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9450           UNSPEC_COPYSIGN))
9451    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9452   "TARGET_SSE_MATH"
9453   "#")
9454
9455 (define_split
9456   [(set (match_operand:SF 0 "register_operand" "")
9457         (unspec:SF
9458           [(match_operand:SF 2 "register_operand" "")
9459            (match_operand:SF 3 "register_operand" "")
9460            (match_operand:V4SF 4 "" "")
9461            (match_operand:V4SF 5 "" "")]
9462           UNSPEC_COPYSIGN))
9463    (clobber (match_scratch:V4SF 1 ""))]
9464   "TARGET_SSE_MATH && reload_completed"
9465   [(const_int 0)]
9466 {
9467   ix86_split_copysign_var (operands);
9468   DONE;
9469 })
9470
9471 (define_expand "negdf2"
9472   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9473         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9474   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9475   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9476
9477 (define_expand "absdf2"
9478   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9479         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9480   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9481   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9482
9483 (define_insn "*absnegdf2_mixed"
9484   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9485         (match_operator:DF 3 "absneg_operator"
9486           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9487    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9490    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9491   "#")
9492
9493 (define_insn "*absnegdf2_sse"
9494   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9495         (match_operator:DF 3 "absneg_operator"
9496           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9497    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9498    (clobber (reg:CC FLAGS_REG))]
9499   "TARGET_SSE2 && TARGET_SSE_MATH
9500    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9501   "#")
9502
9503 (define_insn "*absnegdf2_i387"
9504   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9505         (match_operator:DF 3 "absneg_operator"
9506           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9507    (use (match_operand 2 "" ""))
9508    (clobber (reg:CC FLAGS_REG))]
9509   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9510    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9511   "#")
9512
9513 (define_expand "copysigndf3"
9514   [(match_operand:DF 0 "register_operand" "")
9515    (match_operand:DF 1 "nonmemory_operand" "")
9516    (match_operand:DF 2 "register_operand" "")]
9517   "TARGET_SSE2 && TARGET_SSE_MATH"
9518 {
9519   ix86_expand_copysign (operands);
9520   DONE;
9521 })
9522
9523 (define_insn_and_split "copysigndf3_const"
9524   [(set (match_operand:DF 0 "register_operand"          "=x")
9525         (unspec:DF
9526           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9527            (match_operand:DF 2 "register_operand"       "0")
9528            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9529           UNSPEC_COPYSIGN))]
9530   "TARGET_SSE2 && TARGET_SSE_MATH"
9531   "#"
9532   "&& reload_completed"
9533   [(const_int 0)]
9534 {
9535   ix86_split_copysign_const (operands);
9536   DONE;
9537 })
9538
9539 (define_insn "copysigndf3_var"
9540   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9541         (unspec:DF
9542           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9543            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9544            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9545            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9546           UNSPEC_COPYSIGN))
9547    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9548   "TARGET_SSE2 && TARGET_SSE_MATH"
9549   "#")
9550
9551 (define_split
9552   [(set (match_operand:DF 0 "register_operand" "")
9553         (unspec:DF
9554           [(match_operand:DF 2 "register_operand" "")
9555            (match_operand:DF 3 "register_operand" "")
9556            (match_operand:V2DF 4 "" "")
9557            (match_operand:V2DF 5 "" "")]
9558           UNSPEC_COPYSIGN))
9559    (clobber (match_scratch:V2DF 1 ""))]
9560   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9561   [(const_int 0)]
9562 {
9563   ix86_split_copysign_var (operands);
9564   DONE;
9565 })
9566
9567 (define_expand "negxf2"
9568   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9569         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9570   "TARGET_80387"
9571   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9572
9573 (define_expand "absxf2"
9574   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9575         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9576   "TARGET_80387"
9577   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9578
9579 (define_insn "*absnegxf2_i387"
9580   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9581         (match_operator:XF 3 "absneg_operator"
9582           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9583    (use (match_operand 2 "" ""))
9584    (clobber (reg:CC FLAGS_REG))]
9585   "TARGET_80387
9586    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9587   "#")
9588
9589 ;; Splitters for fp abs and neg.
9590
9591 (define_split
9592   [(set (match_operand 0 "fp_register_operand" "")
9593         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9594    (use (match_operand 2 "" ""))
9595    (clobber (reg:CC FLAGS_REG))]
9596   "reload_completed"
9597   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9598
9599 (define_split
9600   [(set (match_operand 0 "register_operand" "")
9601         (match_operator 3 "absneg_operator"
9602           [(match_operand 1 "register_operand" "")]))
9603    (use (match_operand 2 "nonimmediate_operand" ""))
9604    (clobber (reg:CC FLAGS_REG))]
9605   "reload_completed && SSE_REG_P (operands[0])"
9606   [(set (match_dup 0) (match_dup 3))]
9607 {
9608   enum machine_mode mode = GET_MODE (operands[0]);
9609   enum machine_mode vmode = GET_MODE (operands[2]);
9610   rtx tmp;
9611   
9612   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9613   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9614   if (operands_match_p (operands[0], operands[2]))
9615     {
9616       tmp = operands[1];
9617       operands[1] = operands[2];
9618       operands[2] = tmp;
9619     }
9620   if (GET_CODE (operands[3]) == ABS)
9621     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9622   else
9623     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9624   operands[3] = tmp;
9625 })
9626
9627 (define_split
9628   [(set (match_operand:SF 0 "register_operand" "")
9629         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9630    (use (match_operand:V4SF 2 "" ""))
9631    (clobber (reg:CC FLAGS_REG))]
9632   "reload_completed"
9633   [(parallel [(set (match_dup 0) (match_dup 1))
9634               (clobber (reg:CC FLAGS_REG))])]
9635
9636   rtx tmp;
9637   operands[0] = gen_lowpart (SImode, operands[0]);
9638   if (GET_CODE (operands[1]) == ABS)
9639     {
9640       tmp = gen_int_mode (0x7fffffff, SImode);
9641       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9642     }
9643   else
9644     {
9645       tmp = gen_int_mode (0x80000000, SImode);
9646       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9647     }
9648   operands[1] = tmp;
9649 })
9650
9651 (define_split
9652   [(set (match_operand:DF 0 "register_operand" "")
9653         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9654    (use (match_operand 2 "" ""))
9655    (clobber (reg:CC FLAGS_REG))]
9656   "reload_completed"
9657   [(parallel [(set (match_dup 0) (match_dup 1))
9658               (clobber (reg:CC FLAGS_REG))])]
9659 {
9660   rtx tmp;
9661   if (TARGET_64BIT)
9662     {
9663       tmp = gen_lowpart (DImode, operands[0]);
9664       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9665       operands[0] = tmp;
9666
9667       if (GET_CODE (operands[1]) == ABS)
9668         tmp = const0_rtx;
9669       else
9670         tmp = gen_rtx_NOT (DImode, tmp);
9671     }
9672   else
9673     {
9674       operands[0] = gen_highpart (SImode, operands[0]);
9675       if (GET_CODE (operands[1]) == ABS)
9676         {
9677           tmp = gen_int_mode (0x7fffffff, SImode);
9678           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9679         }
9680       else
9681         {
9682           tmp = gen_int_mode (0x80000000, SImode);
9683           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9684         }
9685     }
9686   operands[1] = tmp;
9687 })
9688
9689 (define_split
9690   [(set (match_operand:XF 0 "register_operand" "")
9691         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9692    (use (match_operand 2 "" ""))
9693    (clobber (reg:CC FLAGS_REG))]
9694   "reload_completed"
9695   [(parallel [(set (match_dup 0) (match_dup 1))
9696               (clobber (reg:CC FLAGS_REG))])]
9697 {
9698   rtx tmp;
9699   operands[0] = gen_rtx_REG (SImode,
9700                              true_regnum (operands[0])
9701                              + (TARGET_64BIT ? 1 : 2));
9702   if (GET_CODE (operands[1]) == ABS)
9703     {
9704       tmp = GEN_INT (0x7fff);
9705       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9706     }
9707   else
9708     {
9709       tmp = GEN_INT (0x8000);
9710       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9711     }
9712   operands[1] = tmp;
9713 })
9714
9715 (define_split
9716   [(set (match_operand 0 "memory_operand" "")
9717         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9718    (use (match_operand 2 "" ""))
9719    (clobber (reg:CC FLAGS_REG))]
9720   "reload_completed"
9721   [(parallel [(set (match_dup 0) (match_dup 1))
9722               (clobber (reg:CC FLAGS_REG))])]
9723 {
9724   enum machine_mode mode = GET_MODE (operands[0]);
9725   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9726   rtx tmp;
9727
9728   operands[0] = adjust_address (operands[0], QImode, size - 1);
9729   if (GET_CODE (operands[1]) == ABS)
9730     {
9731       tmp = gen_int_mode (0x7f, QImode);
9732       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9733     }
9734   else
9735     {
9736       tmp = gen_int_mode (0x80, QImode);
9737       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9738     }
9739   operands[1] = tmp;
9740 })
9741
9742 ;; Conditionalize these after reload. If they match before reload, we 
9743 ;; lose the clobber and ability to use integer instructions.
9744
9745 (define_insn "*negsf2_1"
9746   [(set (match_operand:SF 0 "register_operand" "=f")
9747         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9748   "TARGET_80387 && reload_completed"
9749   "fchs"
9750   [(set_attr "type" "fsgn")
9751    (set_attr "mode" "SF")])
9752
9753 (define_insn "*negdf2_1"
9754   [(set (match_operand:DF 0 "register_operand" "=f")
9755         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9756   "TARGET_80387 && reload_completed"
9757   "fchs"
9758   [(set_attr "type" "fsgn")
9759    (set_attr "mode" "DF")])
9760
9761 (define_insn "*negxf2_1"
9762   [(set (match_operand:XF 0 "register_operand" "=f")
9763         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9764   "TARGET_80387 && reload_completed"
9765   "fchs"
9766   [(set_attr "type" "fsgn")
9767    (set_attr "mode" "XF")])
9768
9769 (define_insn "*abssf2_1"
9770   [(set (match_operand:SF 0 "register_operand" "=f")
9771         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9772   "TARGET_80387 && reload_completed"
9773   "fabs"
9774   [(set_attr "type" "fsgn")
9775    (set_attr "mode" "SF")])
9776
9777 (define_insn "*absdf2_1"
9778   [(set (match_operand:DF 0 "register_operand" "=f")
9779         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9780   "TARGET_80387 && reload_completed"
9781   "fabs"
9782   [(set_attr "type" "fsgn")
9783    (set_attr "mode" "DF")])
9784
9785 (define_insn "*absxf2_1"
9786   [(set (match_operand:XF 0 "register_operand" "=f")
9787         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9788   "TARGET_80387 && reload_completed"
9789   "fabs"
9790   [(set_attr "type" "fsgn")
9791    (set_attr "mode" "DF")])
9792
9793 (define_insn "*negextendsfdf2"
9794   [(set (match_operand:DF 0 "register_operand" "=f")
9795         (neg:DF (float_extend:DF
9796                   (match_operand:SF 1 "register_operand" "0"))))]
9797   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9798   "fchs"
9799   [(set_attr "type" "fsgn")
9800    (set_attr "mode" "DF")])
9801
9802 (define_insn "*negextenddfxf2"
9803   [(set (match_operand:XF 0 "register_operand" "=f")
9804         (neg:XF (float_extend:XF
9805                   (match_operand:DF 1 "register_operand" "0"))))]
9806   "TARGET_80387"
9807   "fchs"
9808   [(set_attr "type" "fsgn")
9809    (set_attr "mode" "XF")])
9810
9811 (define_insn "*negextendsfxf2"
9812   [(set (match_operand:XF 0 "register_operand" "=f")
9813         (neg:XF (float_extend:XF
9814                   (match_operand:SF 1 "register_operand" "0"))))]
9815   "TARGET_80387"
9816   "fchs"
9817   [(set_attr "type" "fsgn")
9818    (set_attr "mode" "XF")])
9819
9820 (define_insn "*absextendsfdf2"
9821   [(set (match_operand:DF 0 "register_operand" "=f")
9822         (abs:DF (float_extend:DF
9823                   (match_operand:SF 1 "register_operand" "0"))))]
9824   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9825   "fabs"
9826   [(set_attr "type" "fsgn")
9827    (set_attr "mode" "DF")])
9828
9829 (define_insn "*absextenddfxf2"
9830   [(set (match_operand:XF 0 "register_operand" "=f")
9831         (abs:XF (float_extend:XF
9832           (match_operand:DF 1 "register_operand" "0"))))]
9833   "TARGET_80387"
9834   "fabs"
9835   [(set_attr "type" "fsgn")
9836    (set_attr "mode" "XF")])
9837
9838 (define_insn "*absextendsfxf2"
9839   [(set (match_operand:XF 0 "register_operand" "=f")
9840         (abs:XF (float_extend:XF
9841           (match_operand:SF 1 "register_operand" "0"))))]
9842   "TARGET_80387"
9843   "fabs"
9844   [(set_attr "type" "fsgn")
9845    (set_attr "mode" "XF")])
9846 \f
9847 ;; One complement instructions
9848
9849 (define_expand "one_cmpldi2"
9850   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9851         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9852   "TARGET_64BIT"
9853   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9854
9855 (define_insn "*one_cmpldi2_1_rex64"
9856   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9857         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9858   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9859   "not{q}\t%0"
9860   [(set_attr "type" "negnot")
9861    (set_attr "mode" "DI")])
9862
9863 (define_insn "*one_cmpldi2_2_rex64"
9864   [(set (reg FLAGS_REG)
9865         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9866                  (const_int 0)))
9867    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9868         (not:DI (match_dup 1)))]
9869   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9870    && ix86_unary_operator_ok (NOT, DImode, operands)"
9871   "#"
9872   [(set_attr "type" "alu1")
9873    (set_attr "mode" "DI")])
9874
9875 (define_split
9876   [(set (match_operand 0 "flags_reg_operand" "")
9877         (match_operator 2 "compare_operator"
9878           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9879            (const_int 0)]))
9880    (set (match_operand:DI 1 "nonimmediate_operand" "")
9881         (not:DI (match_dup 3)))]
9882   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9883   [(parallel [(set (match_dup 0)
9884                    (match_op_dup 2
9885                      [(xor:DI (match_dup 3) (const_int -1))
9886                       (const_int 0)]))
9887               (set (match_dup 1)
9888                    (xor:DI (match_dup 3) (const_int -1)))])]
9889   "")
9890
9891 (define_expand "one_cmplsi2"
9892   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9893         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9894   ""
9895   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9896
9897 (define_insn "*one_cmplsi2_1"
9898   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9899         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9900   "ix86_unary_operator_ok (NOT, SImode, operands)"
9901   "not{l}\t%0"
9902   [(set_attr "type" "negnot")
9903    (set_attr "mode" "SI")])
9904
9905 ;; ??? Currently never generated - xor is used instead.
9906 (define_insn "*one_cmplsi2_1_zext"
9907   [(set (match_operand:DI 0 "register_operand" "=r")
9908         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9909   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9910   "not{l}\t%k0"
9911   [(set_attr "type" "negnot")
9912    (set_attr "mode" "SI")])
9913
9914 (define_insn "*one_cmplsi2_2"
9915   [(set (reg FLAGS_REG)
9916         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9917                  (const_int 0)))
9918    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9919         (not:SI (match_dup 1)))]
9920   "ix86_match_ccmode (insn, CCNOmode)
9921    && ix86_unary_operator_ok (NOT, SImode, operands)"
9922   "#"
9923   [(set_attr "type" "alu1")
9924    (set_attr "mode" "SI")])
9925
9926 (define_split
9927   [(set (match_operand 0 "flags_reg_operand" "")
9928         (match_operator 2 "compare_operator"
9929           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9930            (const_int 0)]))
9931    (set (match_operand:SI 1 "nonimmediate_operand" "")
9932         (not:SI (match_dup 3)))]
9933   "ix86_match_ccmode (insn, CCNOmode)"
9934   [(parallel [(set (match_dup 0)
9935                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9936                                     (const_int 0)]))
9937               (set (match_dup 1)
9938                    (xor:SI (match_dup 3) (const_int -1)))])]
9939   "")
9940
9941 ;; ??? Currently never generated - xor is used instead.
9942 (define_insn "*one_cmplsi2_2_zext"
9943   [(set (reg FLAGS_REG)
9944         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9945                  (const_int 0)))
9946    (set (match_operand:DI 0 "register_operand" "=r")
9947         (zero_extend:DI (not:SI (match_dup 1))))]
9948   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9949    && ix86_unary_operator_ok (NOT, SImode, operands)"
9950   "#"
9951   [(set_attr "type" "alu1")
9952    (set_attr "mode" "SI")])
9953
9954 (define_split
9955   [(set (match_operand 0 "flags_reg_operand" "")
9956         (match_operator 2 "compare_operator"
9957           [(not:SI (match_operand:SI 3 "register_operand" ""))
9958            (const_int 0)]))
9959    (set (match_operand:DI 1 "register_operand" "")
9960         (zero_extend:DI (not:SI (match_dup 3))))]
9961   "ix86_match_ccmode (insn, CCNOmode)"
9962   [(parallel [(set (match_dup 0)
9963                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9964                                     (const_int 0)]))
9965               (set (match_dup 1)
9966                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9967   "")
9968
9969 (define_expand "one_cmplhi2"
9970   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9971         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9972   "TARGET_HIMODE_MATH"
9973   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9974
9975 (define_insn "*one_cmplhi2_1"
9976   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9977         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9978   "ix86_unary_operator_ok (NOT, HImode, operands)"
9979   "not{w}\t%0"
9980   [(set_attr "type" "negnot")
9981    (set_attr "mode" "HI")])
9982
9983 (define_insn "*one_cmplhi2_2"
9984   [(set (reg FLAGS_REG)
9985         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9986                  (const_int 0)))
9987    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9988         (not:HI (match_dup 1)))]
9989   "ix86_match_ccmode (insn, CCNOmode)
9990    && ix86_unary_operator_ok (NEG, HImode, operands)"
9991   "#"
9992   [(set_attr "type" "alu1")
9993    (set_attr "mode" "HI")])
9994
9995 (define_split
9996   [(set (match_operand 0 "flags_reg_operand" "")
9997         (match_operator 2 "compare_operator"
9998           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9999            (const_int 0)]))
10000    (set (match_operand:HI 1 "nonimmediate_operand" "")
10001         (not:HI (match_dup 3)))]
10002   "ix86_match_ccmode (insn, CCNOmode)"
10003   [(parallel [(set (match_dup 0)
10004                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10005                                     (const_int 0)]))
10006               (set (match_dup 1)
10007                    (xor:HI (match_dup 3) (const_int -1)))])]
10008   "")
10009
10010 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10011 (define_expand "one_cmplqi2"
10012   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10013         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10014   "TARGET_QIMODE_MATH"
10015   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10016
10017 (define_insn "*one_cmplqi2_1"
10018   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10019         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10020   "ix86_unary_operator_ok (NOT, QImode, operands)"
10021   "@
10022    not{b}\t%0
10023    not{l}\t%k0"
10024   [(set_attr "type" "negnot")
10025    (set_attr "mode" "QI,SI")])
10026
10027 (define_insn "*one_cmplqi2_2"
10028   [(set (reg FLAGS_REG)
10029         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10030                  (const_int 0)))
10031    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10032         (not:QI (match_dup 1)))]
10033   "ix86_match_ccmode (insn, CCNOmode)
10034    && ix86_unary_operator_ok (NOT, QImode, operands)"
10035   "#"
10036   [(set_attr "type" "alu1")
10037    (set_attr "mode" "QI")])
10038
10039 (define_split
10040   [(set (match_operand 0 "flags_reg_operand" "")
10041         (match_operator 2 "compare_operator"
10042           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10043            (const_int 0)]))
10044    (set (match_operand:QI 1 "nonimmediate_operand" "")
10045         (not:QI (match_dup 3)))]
10046   "ix86_match_ccmode (insn, CCNOmode)"
10047   [(parallel [(set (match_dup 0)
10048                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10049                                     (const_int 0)]))
10050               (set (match_dup 1)
10051                    (xor:QI (match_dup 3) (const_int -1)))])]
10052   "")
10053 \f
10054 ;; Arithmetic shift instructions
10055
10056 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10057 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10058 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10059 ;; from the assembler input.
10060 ;;
10061 ;; This instruction shifts the target reg/mem as usual, but instead of
10062 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10063 ;; is a left shift double, bits are taken from the high order bits of
10064 ;; reg, else if the insn is a shift right double, bits are taken from the
10065 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10066 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10067 ;;
10068 ;; Since sh[lr]d does not change the `reg' operand, that is done
10069 ;; separately, making all shifts emit pairs of shift double and normal
10070 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10071 ;; support a 63 bit shift, each shift where the count is in a reg expands
10072 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10073 ;;
10074 ;; If the shift count is a constant, we need never emit more than one
10075 ;; shift pair, instead using moves and sign extension for counts greater
10076 ;; than 31.
10077
10078 (define_expand "ashldi3"
10079   [(set (match_operand:DI 0 "shiftdi_operand" "")
10080         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10081                    (match_operand:QI 2 "nonmemory_operand" "")))]
10082   ""
10083   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10084
10085 (define_insn "*ashldi3_1_rex64"
10086   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10087         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10088                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10089    (clobber (reg:CC FLAGS_REG))]
10090   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10091 {
10092   switch (get_attr_type (insn))
10093     {
10094     case TYPE_ALU:
10095       if (operands[2] != const1_rtx)
10096         abort ();
10097       if (!rtx_equal_p (operands[0], operands[1]))
10098         abort ();
10099       return "add{q}\t{%0, %0|%0, %0}";
10100
10101     case TYPE_LEA:
10102       if (GET_CODE (operands[2]) != CONST_INT
10103           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10104         abort ();
10105       operands[1] = gen_rtx_MULT (DImode, operands[1],
10106                                   GEN_INT (1 << INTVAL (operands[2])));
10107       return "lea{q}\t{%a1, %0|%0, %a1}";
10108
10109     default:
10110       if (REG_P (operands[2]))
10111         return "sal{q}\t{%b2, %0|%0, %b2}";
10112       else if (operands[2] == const1_rtx
10113                && (TARGET_SHIFT1 || optimize_size))
10114         return "sal{q}\t%0";
10115       else
10116         return "sal{q}\t{%2, %0|%0, %2}";
10117     }
10118 }
10119   [(set (attr "type")
10120      (cond [(eq_attr "alternative" "1")
10121               (const_string "lea")
10122             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10123                           (const_int 0))
10124                       (match_operand 0 "register_operand" ""))
10125                  (match_operand 2 "const1_operand" ""))
10126               (const_string "alu")
10127            ]
10128            (const_string "ishift")))
10129    (set_attr "mode" "DI")])
10130
10131 ;; Convert lea to the lea pattern to avoid flags dependency.
10132 (define_split
10133   [(set (match_operand:DI 0 "register_operand" "")
10134         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10135                    (match_operand:QI 2 "immediate_operand" "")))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "TARGET_64BIT && reload_completed
10138    && true_regnum (operands[0]) != true_regnum (operands[1])"
10139   [(set (match_dup 0)
10140         (mult:DI (match_dup 1)
10141                  (match_dup 2)))]
10142   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10143
10144 ;; This pattern can't accept a variable shift count, since shifts by
10145 ;; zero don't affect the flags.  We assume that shifts by constant
10146 ;; zero are optimized away.
10147 (define_insn "*ashldi3_cmp_rex64"
10148   [(set (reg FLAGS_REG)
10149         (compare
10150           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10151                      (match_operand:QI 2 "immediate_operand" "e"))
10152           (const_int 0)))
10153    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10154         (ashift:DI (match_dup 1) (match_dup 2)))]
10155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10156    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10157 {
10158   switch (get_attr_type (insn))
10159     {
10160     case TYPE_ALU:
10161       if (operands[2] != const1_rtx)
10162         abort ();
10163       return "add{q}\t{%0, %0|%0, %0}";
10164
10165     default:
10166       if (REG_P (operands[2]))
10167         return "sal{q}\t{%b2, %0|%0, %b2}";
10168       else if (operands[2] == const1_rtx
10169                && (TARGET_SHIFT1 || optimize_size))
10170         return "sal{q}\t%0";
10171       else
10172         return "sal{q}\t{%2, %0|%0, %2}";
10173     }
10174 }
10175   [(set (attr "type")
10176      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10177                           (const_int 0))
10178                       (match_operand 0 "register_operand" ""))
10179                  (match_operand 2 "const1_operand" ""))
10180               (const_string "alu")
10181            ]
10182            (const_string "ishift")))
10183    (set_attr "mode" "DI")])
10184
10185 (define_insn "*ashldi3_1"
10186   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10187         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10188                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10189    (clobber (reg:CC FLAGS_REG))]
10190   "!TARGET_64BIT"
10191   "#"
10192   [(set_attr "type" "multi")])
10193
10194 ;; By default we don't ask for a scratch register, because when DImode
10195 ;; values are manipulated, registers are already at a premium.  But if
10196 ;; we have one handy, we won't turn it away.
10197 (define_peephole2
10198   [(match_scratch:SI 3 "r")
10199    (parallel [(set (match_operand:DI 0 "register_operand" "")
10200                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10201                               (match_operand:QI 2 "nonmemory_operand" "")))
10202               (clobber (reg:CC FLAGS_REG))])
10203    (match_dup 3)]
10204   "!TARGET_64BIT && TARGET_CMOVE"
10205   [(const_int 0)]
10206   "ix86_split_ashldi (operands, operands[3]); DONE;")
10207
10208 (define_split
10209   [(set (match_operand:DI 0 "register_operand" "")
10210         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10211                    (match_operand:QI 2 "nonmemory_operand" "")))
10212    (clobber (reg:CC FLAGS_REG))]
10213   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10214   [(const_int 0)]
10215   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10216
10217 (define_insn "x86_shld_1"
10218   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10219         (ior:SI (ashift:SI (match_dup 0)
10220                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10221                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10222                   (minus:QI (const_int 32) (match_dup 2)))))
10223    (clobber (reg:CC FLAGS_REG))]
10224   ""
10225   "@
10226    shld{l}\t{%2, %1, %0|%0, %1, %2}
10227    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10228   [(set_attr "type" "ishift")
10229    (set_attr "prefix_0f" "1")
10230    (set_attr "mode" "SI")
10231    (set_attr "pent_pair" "np")
10232    (set_attr "athlon_decode" "vector")])
10233
10234 (define_expand "x86_shift_adj_1"
10235   [(set (reg:CCZ FLAGS_REG)
10236         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10237                              (const_int 32))
10238                      (const_int 0)))
10239    (set (match_operand:SI 0 "register_operand" "")
10240         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10241                          (match_operand:SI 1 "register_operand" "")
10242                          (match_dup 0)))
10243    (set (match_dup 1)
10244         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10245                          (match_operand:SI 3 "register_operand" "r")
10246                          (match_dup 1)))]
10247   "TARGET_CMOVE"
10248   "")
10249
10250 (define_expand "x86_shift_adj_2"
10251   [(use (match_operand:SI 0 "register_operand" ""))
10252    (use (match_operand:SI 1 "register_operand" ""))
10253    (use (match_operand:QI 2 "register_operand" ""))]
10254   ""
10255 {
10256   rtx label = gen_label_rtx ();
10257   rtx tmp;
10258
10259   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10260
10261   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10262   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10263   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10264                               gen_rtx_LABEL_REF (VOIDmode, label),
10265                               pc_rtx);
10266   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10267   JUMP_LABEL (tmp) = label;
10268
10269   emit_move_insn (operands[0], operands[1]);
10270   ix86_expand_clear (operands[1]);
10271
10272   emit_label (label);
10273   LABEL_NUSES (label) = 1;
10274
10275   DONE;
10276 })
10277
10278 (define_expand "ashlsi3"
10279   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10280         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10281                    (match_operand:QI 2 "nonmemory_operand" "")))
10282    (clobber (reg:CC FLAGS_REG))]
10283   ""
10284   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10285
10286 (define_insn "*ashlsi3_1"
10287   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10288         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10289                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10290    (clobber (reg:CC FLAGS_REG))]
10291   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10292 {
10293   switch (get_attr_type (insn))
10294     {
10295     case TYPE_ALU:
10296       if (operands[2] != const1_rtx)
10297         abort ();
10298       if (!rtx_equal_p (operands[0], operands[1]))
10299         abort ();
10300       return "add{l}\t{%0, %0|%0, %0}";
10301
10302     case TYPE_LEA:
10303       return "#";
10304
10305     default:
10306       if (REG_P (operands[2]))
10307         return "sal{l}\t{%b2, %0|%0, %b2}";
10308       else if (operands[2] == const1_rtx
10309                && (TARGET_SHIFT1 || optimize_size))
10310         return "sal{l}\t%0";
10311       else
10312         return "sal{l}\t{%2, %0|%0, %2}";
10313     }
10314 }
10315   [(set (attr "type")
10316      (cond [(eq_attr "alternative" "1")
10317               (const_string "lea")
10318             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10319                           (const_int 0))
10320                       (match_operand 0 "register_operand" ""))
10321                  (match_operand 2 "const1_operand" ""))
10322               (const_string "alu")
10323            ]
10324            (const_string "ishift")))
10325    (set_attr "mode" "SI")])
10326
10327 ;; Convert lea to the lea pattern to avoid flags dependency.
10328 (define_split
10329   [(set (match_operand 0 "register_operand" "")
10330         (ashift (match_operand 1 "index_register_operand" "")
10331                 (match_operand:QI 2 "const_int_operand" "")))
10332    (clobber (reg:CC FLAGS_REG))]
10333   "reload_completed
10334    && true_regnum (operands[0]) != true_regnum (operands[1])
10335    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10336   [(const_int 0)]
10337 {
10338   rtx pat;
10339   enum machine_mode mode = GET_MODE (operands[0]);
10340
10341   if (GET_MODE_SIZE (mode) < 4)
10342     operands[0] = gen_lowpart (SImode, operands[0]);
10343   if (mode != Pmode)
10344     operands[1] = gen_lowpart (Pmode, operands[1]);
10345   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10346
10347   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10348   if (Pmode != SImode)
10349     pat = gen_rtx_SUBREG (SImode, pat, 0);
10350   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10351   DONE;
10352 })
10353
10354 ;; Rare case of shifting RSP is handled by generating move and shift
10355 (define_split
10356   [(set (match_operand 0 "register_operand" "")
10357         (ashift (match_operand 1 "register_operand" "")
10358                 (match_operand:QI 2 "const_int_operand" "")))
10359    (clobber (reg:CC FLAGS_REG))]
10360   "reload_completed
10361    && true_regnum (operands[0]) != true_regnum (operands[1])"
10362   [(const_int 0)]
10363 {
10364   rtx pat, clob;
10365   emit_move_insn (operands[1], operands[0]);
10366   pat = gen_rtx_SET (VOIDmode, operands[0],
10367                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10368                                      operands[0], operands[2]));
10369   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10370   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10371   DONE;
10372 })
10373
10374 (define_insn "*ashlsi3_1_zext"
10375   [(set (match_operand:DI 0 "register_operand" "=r,r")
10376         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10377                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10378    (clobber (reg:CC FLAGS_REG))]
10379   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10380 {
10381   switch (get_attr_type (insn))
10382     {
10383     case TYPE_ALU:
10384       if (operands[2] != const1_rtx)
10385         abort ();
10386       return "add{l}\t{%k0, %k0|%k0, %k0}";
10387
10388     case TYPE_LEA:
10389       return "#";
10390
10391     default:
10392       if (REG_P (operands[2]))
10393         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10394       else if (operands[2] == const1_rtx
10395                && (TARGET_SHIFT1 || optimize_size))
10396         return "sal{l}\t%k0";
10397       else
10398         return "sal{l}\t{%2, %k0|%k0, %2}";
10399     }
10400 }
10401   [(set (attr "type")
10402      (cond [(eq_attr "alternative" "1")
10403               (const_string "lea")
10404             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10405                      (const_int 0))
10406                  (match_operand 2 "const1_operand" ""))
10407               (const_string "alu")
10408            ]
10409            (const_string "ishift")))
10410    (set_attr "mode" "SI")])
10411
10412 ;; Convert lea to the lea pattern to avoid flags dependency.
10413 (define_split
10414   [(set (match_operand:DI 0 "register_operand" "")
10415         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10416                                 (match_operand:QI 2 "const_int_operand" ""))))
10417    (clobber (reg:CC FLAGS_REG))]
10418   "TARGET_64BIT && reload_completed
10419    && true_regnum (operands[0]) != true_regnum (operands[1])"
10420   [(set (match_dup 0) (zero_extend:DI
10421                         (subreg:SI (mult:SI (match_dup 1)
10422                                             (match_dup 2)) 0)))]
10423 {
10424   operands[1] = gen_lowpart (Pmode, operands[1]);
10425   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10426 })
10427
10428 ;; This pattern can't accept a variable shift count, since shifts by
10429 ;; zero don't affect the flags.  We assume that shifts by constant
10430 ;; zero are optimized away.
10431 (define_insn "*ashlsi3_cmp"
10432   [(set (reg FLAGS_REG)
10433         (compare
10434           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10435                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10436           (const_int 0)))
10437    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10438         (ashift:SI (match_dup 1) (match_dup 2)))]
10439   "ix86_match_ccmode (insn, CCGOCmode)
10440    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10441 {
10442   switch (get_attr_type (insn))
10443     {
10444     case TYPE_ALU:
10445       if (operands[2] != const1_rtx)
10446         abort ();
10447       return "add{l}\t{%0, %0|%0, %0}";
10448
10449     default:
10450       if (REG_P (operands[2]))
10451         return "sal{l}\t{%b2, %0|%0, %b2}";
10452       else if (operands[2] == const1_rtx
10453                && (TARGET_SHIFT1 || optimize_size))
10454         return "sal{l}\t%0";
10455       else
10456         return "sal{l}\t{%2, %0|%0, %2}";
10457     }
10458 }
10459   [(set (attr "type")
10460      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10461                           (const_int 0))
10462                       (match_operand 0 "register_operand" ""))
10463                  (match_operand 2 "const1_operand" ""))
10464               (const_string "alu")
10465            ]
10466            (const_string "ishift")))
10467    (set_attr "mode" "SI")])
10468
10469 (define_insn "*ashlsi3_cmp_zext"
10470   [(set (reg FLAGS_REG)
10471         (compare
10472           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10473                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10474           (const_int 0)))
10475    (set (match_operand:DI 0 "register_operand" "=r")
10476         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10477   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10478    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10479 {
10480   switch (get_attr_type (insn))
10481     {
10482     case TYPE_ALU:
10483       if (operands[2] != const1_rtx)
10484         abort ();
10485       return "add{l}\t{%k0, %k0|%k0, %k0}";
10486
10487     default:
10488       if (REG_P (operands[2]))
10489         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10490       else if (operands[2] == const1_rtx
10491                && (TARGET_SHIFT1 || optimize_size))
10492         return "sal{l}\t%k0";
10493       else
10494         return "sal{l}\t{%2, %k0|%k0, %2}";
10495     }
10496 }
10497   [(set (attr "type")
10498      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10499                      (const_int 0))
10500                  (match_operand 2 "const1_operand" ""))
10501               (const_string "alu")
10502            ]
10503            (const_string "ishift")))
10504    (set_attr "mode" "SI")])
10505
10506 (define_expand "ashlhi3"
10507   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10508         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10509                    (match_operand:QI 2 "nonmemory_operand" "")))
10510    (clobber (reg:CC FLAGS_REG))]
10511   "TARGET_HIMODE_MATH"
10512   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10513
10514 (define_insn "*ashlhi3_1_lea"
10515   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10516         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10517                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10518    (clobber (reg:CC FLAGS_REG))]
10519   "!TARGET_PARTIAL_REG_STALL
10520    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10521 {
10522   switch (get_attr_type (insn))
10523     {
10524     case TYPE_LEA:
10525       return "#";
10526     case TYPE_ALU:
10527       if (operands[2] != const1_rtx)
10528         abort ();
10529       return "add{w}\t{%0, %0|%0, %0}";
10530
10531     default:
10532       if (REG_P (operands[2]))
10533         return "sal{w}\t{%b2, %0|%0, %b2}";
10534       else if (operands[2] == const1_rtx
10535                && (TARGET_SHIFT1 || optimize_size))
10536         return "sal{w}\t%0";
10537       else
10538         return "sal{w}\t{%2, %0|%0, %2}";
10539     }
10540 }
10541   [(set (attr "type")
10542      (cond [(eq_attr "alternative" "1")
10543               (const_string "lea")
10544             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10545                           (const_int 0))
10546                       (match_operand 0 "register_operand" ""))
10547                  (match_operand 2 "const1_operand" ""))
10548               (const_string "alu")
10549            ]
10550            (const_string "ishift")))
10551    (set_attr "mode" "HI,SI")])
10552
10553 (define_insn "*ashlhi3_1"
10554   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10555         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10556                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10557    (clobber (reg:CC FLAGS_REG))]
10558   "TARGET_PARTIAL_REG_STALL
10559    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10560 {
10561   switch (get_attr_type (insn))
10562     {
10563     case TYPE_ALU:
10564       if (operands[2] != const1_rtx)
10565         abort ();
10566       return "add{w}\t{%0, %0|%0, %0}";
10567
10568     default:
10569       if (REG_P (operands[2]))
10570         return "sal{w}\t{%b2, %0|%0, %b2}";
10571       else if (operands[2] == const1_rtx
10572                && (TARGET_SHIFT1 || optimize_size))
10573         return "sal{w}\t%0";
10574       else
10575         return "sal{w}\t{%2, %0|%0, %2}";
10576     }
10577 }
10578   [(set (attr "type")
10579      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10580                           (const_int 0))
10581                       (match_operand 0 "register_operand" ""))
10582                  (match_operand 2 "const1_operand" ""))
10583               (const_string "alu")
10584            ]
10585            (const_string "ishift")))
10586    (set_attr "mode" "HI")])
10587
10588 ;; This pattern can't accept a variable shift count, since shifts by
10589 ;; zero don't affect the flags.  We assume that shifts by constant
10590 ;; zero are optimized away.
10591 (define_insn "*ashlhi3_cmp"
10592   [(set (reg FLAGS_REG)
10593         (compare
10594           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10595                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10596           (const_int 0)))
10597    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10598         (ashift:HI (match_dup 1) (match_dup 2)))]
10599   "ix86_match_ccmode (insn, CCGOCmode)
10600    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10601 {
10602   switch (get_attr_type (insn))
10603     {
10604     case TYPE_ALU:
10605       if (operands[2] != const1_rtx)
10606         abort ();
10607       return "add{w}\t{%0, %0|%0, %0}";
10608
10609     default:
10610       if (REG_P (operands[2]))
10611         return "sal{w}\t{%b2, %0|%0, %b2}";
10612       else if (operands[2] == const1_rtx
10613                && (TARGET_SHIFT1 || optimize_size))
10614         return "sal{w}\t%0";
10615       else
10616         return "sal{w}\t{%2, %0|%0, %2}";
10617     }
10618 }
10619   [(set (attr "type")
10620      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10621                           (const_int 0))
10622                       (match_operand 0 "register_operand" ""))
10623                  (match_operand 2 "const1_operand" ""))
10624               (const_string "alu")
10625            ]
10626            (const_string "ishift")))
10627    (set_attr "mode" "HI")])
10628
10629 (define_expand "ashlqi3"
10630   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10631         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10632                    (match_operand:QI 2 "nonmemory_operand" "")))
10633    (clobber (reg:CC FLAGS_REG))]
10634   "TARGET_QIMODE_MATH"
10635   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10636
10637 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10638
10639 (define_insn "*ashlqi3_1_lea"
10640   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10641         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10642                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10643    (clobber (reg:CC FLAGS_REG))]
10644   "!TARGET_PARTIAL_REG_STALL
10645    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10646 {
10647   switch (get_attr_type (insn))
10648     {
10649     case TYPE_LEA:
10650       return "#";
10651     case TYPE_ALU:
10652       if (operands[2] != const1_rtx)
10653         abort ();
10654       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10655         return "add{l}\t{%k0, %k0|%k0, %k0}";
10656       else
10657         return "add{b}\t{%0, %0|%0, %0}";
10658
10659     default:
10660       if (REG_P (operands[2]))
10661         {
10662           if (get_attr_mode (insn) == MODE_SI)
10663             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10664           else
10665             return "sal{b}\t{%b2, %0|%0, %b2}";
10666         }
10667       else if (operands[2] == const1_rtx
10668                && (TARGET_SHIFT1 || optimize_size))
10669         {
10670           if (get_attr_mode (insn) == MODE_SI)
10671             return "sal{l}\t%0";
10672           else
10673             return "sal{b}\t%0";
10674         }
10675       else
10676         {
10677           if (get_attr_mode (insn) == MODE_SI)
10678             return "sal{l}\t{%2, %k0|%k0, %2}";
10679           else
10680             return "sal{b}\t{%2, %0|%0, %2}";
10681         }
10682     }
10683 }
10684   [(set (attr "type")
10685      (cond [(eq_attr "alternative" "2")
10686               (const_string "lea")
10687             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10688                           (const_int 0))
10689                       (match_operand 0 "register_operand" ""))
10690                  (match_operand 2 "const1_operand" ""))
10691               (const_string "alu")
10692            ]
10693            (const_string "ishift")))
10694    (set_attr "mode" "QI,SI,SI")])
10695
10696 (define_insn "*ashlqi3_1"
10697   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10698         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10699                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10700    (clobber (reg:CC FLAGS_REG))]
10701   "TARGET_PARTIAL_REG_STALL
10702    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10703 {
10704   switch (get_attr_type (insn))
10705     {
10706     case TYPE_ALU:
10707       if (operands[2] != const1_rtx)
10708         abort ();
10709       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10710         return "add{l}\t{%k0, %k0|%k0, %k0}";
10711       else
10712         return "add{b}\t{%0, %0|%0, %0}";
10713
10714     default:
10715       if (REG_P (operands[2]))
10716         {
10717           if (get_attr_mode (insn) == MODE_SI)
10718             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10719           else
10720             return "sal{b}\t{%b2, %0|%0, %b2}";
10721         }
10722       else if (operands[2] == const1_rtx
10723                && (TARGET_SHIFT1 || optimize_size))
10724         {
10725           if (get_attr_mode (insn) == MODE_SI)
10726             return "sal{l}\t%0";
10727           else
10728             return "sal{b}\t%0";
10729         }
10730       else
10731         {
10732           if (get_attr_mode (insn) == MODE_SI)
10733             return "sal{l}\t{%2, %k0|%k0, %2}";
10734           else
10735             return "sal{b}\t{%2, %0|%0, %2}";
10736         }
10737     }
10738 }
10739   [(set (attr "type")
10740      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10741                           (const_int 0))
10742                       (match_operand 0 "register_operand" ""))
10743                  (match_operand 2 "const1_operand" ""))
10744               (const_string "alu")
10745            ]
10746            (const_string "ishift")))
10747    (set_attr "mode" "QI,SI")])
10748
10749 ;; This pattern can't accept a variable shift count, since shifts by
10750 ;; zero don't affect the flags.  We assume that shifts by constant
10751 ;; zero are optimized away.
10752 (define_insn "*ashlqi3_cmp"
10753   [(set (reg FLAGS_REG)
10754         (compare
10755           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10756                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10757           (const_int 0)))
10758    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10759         (ashift:QI (match_dup 1) (match_dup 2)))]
10760   "ix86_match_ccmode (insn, CCGOCmode)
10761    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10762 {
10763   switch (get_attr_type (insn))
10764     {
10765     case TYPE_ALU:
10766       if (operands[2] != const1_rtx)
10767         abort ();
10768       return "add{b}\t{%0, %0|%0, %0}";
10769
10770     default:
10771       if (REG_P (operands[2]))
10772         return "sal{b}\t{%b2, %0|%0, %b2}";
10773       else if (operands[2] == const1_rtx
10774                && (TARGET_SHIFT1 || optimize_size))
10775         return "sal{b}\t%0";
10776       else
10777         return "sal{b}\t{%2, %0|%0, %2}";
10778     }
10779 }
10780   [(set (attr "type")
10781      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782                           (const_int 0))
10783                       (match_operand 0 "register_operand" ""))
10784                  (match_operand 2 "const1_operand" ""))
10785               (const_string "alu")
10786            ]
10787            (const_string "ishift")))
10788    (set_attr "mode" "QI")])
10789
10790 ;; See comment above `ashldi3' about how this works.
10791
10792 (define_expand "ashrdi3"
10793   [(set (match_operand:DI 0 "shiftdi_operand" "")
10794         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10795                      (match_operand:QI 2 "nonmemory_operand" "")))]
10796   ""
10797   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10798
10799 (define_insn "*ashrdi3_63_rex64"
10800   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10801         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10802                      (match_operand:DI 2 "const_int_operand" "i,i")))
10803    (clobber (reg:CC FLAGS_REG))]
10804   "TARGET_64BIT && INTVAL (operands[2]) == 63
10805    && (TARGET_USE_CLTD || optimize_size)
10806    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10807   "@
10808    {cqto|cqo}
10809    sar{q}\t{%2, %0|%0, %2}"
10810   [(set_attr "type" "imovx,ishift")
10811    (set_attr "prefix_0f" "0,*")
10812    (set_attr "length_immediate" "0,*")
10813    (set_attr "modrm" "0,1")
10814    (set_attr "mode" "DI")])
10815
10816 (define_insn "*ashrdi3_1_one_bit_rex64"
10817   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10818         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10819                      (match_operand:QI 2 "const1_operand" "")))
10820    (clobber (reg:CC FLAGS_REG))]
10821   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10822    && (TARGET_SHIFT1 || optimize_size)"
10823   "sar{q}\t%0"
10824   [(set_attr "type" "ishift")
10825    (set (attr "length") 
10826      (if_then_else (match_operand:DI 0 "register_operand" "") 
10827         (const_string "2")
10828         (const_string "*")))])
10829
10830 (define_insn "*ashrdi3_1_rex64"
10831   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10832         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10833                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10834    (clobber (reg:CC FLAGS_REG))]
10835   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10836   "@
10837    sar{q}\t{%2, %0|%0, %2}
10838    sar{q}\t{%b2, %0|%0, %b2}"
10839   [(set_attr "type" "ishift")
10840    (set_attr "mode" "DI")])
10841
10842 ;; This pattern can't accept a variable shift count, since shifts by
10843 ;; zero don't affect the flags.  We assume that shifts by constant
10844 ;; zero are optimized away.
10845 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10846   [(set (reg FLAGS_REG)
10847         (compare
10848           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10849                        (match_operand:QI 2 "const1_operand" ""))
10850           (const_int 0)))
10851    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10852         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10853   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10854    && (TARGET_SHIFT1 || optimize_size)
10855    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10856   "sar{q}\t%0"
10857   [(set_attr "type" "ishift")
10858    (set (attr "length") 
10859      (if_then_else (match_operand:DI 0 "register_operand" "") 
10860         (const_string "2")
10861         (const_string "*")))])
10862
10863 ;; This pattern can't accept a variable shift count, since shifts by
10864 ;; zero don't affect the flags.  We assume that shifts by constant
10865 ;; zero are optimized away.
10866 (define_insn "*ashrdi3_cmp_rex64"
10867   [(set (reg FLAGS_REG)
10868         (compare
10869           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10870                        (match_operand:QI 2 "const_int_operand" "n"))
10871           (const_int 0)))
10872    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10873         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10874   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10875    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10876   "sar{q}\t{%2, %0|%0, %2}"
10877   [(set_attr "type" "ishift")
10878    (set_attr "mode" "DI")])
10879
10880 (define_insn "*ashrdi3_1"
10881   [(set (match_operand:DI 0 "register_operand" "=r")
10882         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10883                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10884    (clobber (reg:CC FLAGS_REG))]
10885   "!TARGET_64BIT"
10886   "#"
10887   [(set_attr "type" "multi")])
10888
10889 ;; By default we don't ask for a scratch register, because when DImode
10890 ;; values are manipulated, registers are already at a premium.  But if
10891 ;; we have one handy, we won't turn it away.
10892 (define_peephole2
10893   [(match_scratch:SI 3 "r")
10894    (parallel [(set (match_operand:DI 0 "register_operand" "")
10895                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10896                                 (match_operand:QI 2 "nonmemory_operand" "")))
10897               (clobber (reg:CC FLAGS_REG))])
10898    (match_dup 3)]
10899   "!TARGET_64BIT && TARGET_CMOVE"
10900   [(const_int 0)]
10901   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10902
10903 (define_split
10904   [(set (match_operand:DI 0 "register_operand" "")
10905         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10906                      (match_operand:QI 2 "nonmemory_operand" "")))
10907    (clobber (reg:CC FLAGS_REG))]
10908   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10909   [(const_int 0)]
10910   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10911
10912 (define_insn "x86_shrd_1"
10913   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10914         (ior:SI (ashiftrt:SI (match_dup 0)
10915                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10916                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10917                   (minus:QI (const_int 32) (match_dup 2)))))
10918    (clobber (reg:CC FLAGS_REG))]
10919   ""
10920   "@
10921    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10922    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10923   [(set_attr "type" "ishift")
10924    (set_attr "prefix_0f" "1")
10925    (set_attr "pent_pair" "np")
10926    (set_attr "mode" "SI")])
10927
10928 (define_expand "x86_shift_adj_3"
10929   [(use (match_operand:SI 0 "register_operand" ""))
10930    (use (match_operand:SI 1 "register_operand" ""))
10931    (use (match_operand:QI 2 "register_operand" ""))]
10932   ""
10933 {
10934   rtx label = gen_label_rtx ();
10935   rtx tmp;
10936
10937   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10938
10939   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10940   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10941   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10942                               gen_rtx_LABEL_REF (VOIDmode, label),
10943                               pc_rtx);
10944   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10945   JUMP_LABEL (tmp) = label;
10946
10947   emit_move_insn (operands[0], operands[1]);
10948   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10949
10950   emit_label (label);
10951   LABEL_NUSES (label) = 1;
10952
10953   DONE;
10954 })
10955
10956 (define_insn "ashrsi3_31"
10957   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10958         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10959                      (match_operand:SI 2 "const_int_operand" "i,i")))
10960    (clobber (reg:CC FLAGS_REG))]
10961   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10962    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10963   "@
10964    {cltd|cdq}
10965    sar{l}\t{%2, %0|%0, %2}"
10966   [(set_attr "type" "imovx,ishift")
10967    (set_attr "prefix_0f" "0,*")
10968    (set_attr "length_immediate" "0,*")
10969    (set_attr "modrm" "0,1")
10970    (set_attr "mode" "SI")])
10971
10972 (define_insn "*ashrsi3_31_zext"
10973   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10974         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10975                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10976    (clobber (reg:CC FLAGS_REG))]
10977   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10978    && INTVAL (operands[2]) == 31
10979    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10980   "@
10981    {cltd|cdq}
10982    sar{l}\t{%2, %k0|%k0, %2}"
10983   [(set_attr "type" "imovx,ishift")
10984    (set_attr "prefix_0f" "0,*")
10985    (set_attr "length_immediate" "0,*")
10986    (set_attr "modrm" "0,1")
10987    (set_attr "mode" "SI")])
10988
10989 (define_expand "ashrsi3"
10990   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10991         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10992                      (match_operand:QI 2 "nonmemory_operand" "")))
10993    (clobber (reg:CC FLAGS_REG))]
10994   ""
10995   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10996
10997 (define_insn "*ashrsi3_1_one_bit"
10998   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10999         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11000                      (match_operand:QI 2 "const1_operand" "")))
11001    (clobber (reg:CC FLAGS_REG))]
11002   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11003    && (TARGET_SHIFT1 || optimize_size)"
11004   "sar{l}\t%0"
11005   [(set_attr "type" "ishift")
11006    (set (attr "length") 
11007      (if_then_else (match_operand:SI 0 "register_operand" "") 
11008         (const_string "2")
11009         (const_string "*")))])
11010
11011 (define_insn "*ashrsi3_1_one_bit_zext"
11012   [(set (match_operand:DI 0 "register_operand" "=r")
11013         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11014                                      (match_operand:QI 2 "const1_operand" ""))))
11015    (clobber (reg:CC FLAGS_REG))]
11016   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11017    && (TARGET_SHIFT1 || optimize_size)"
11018   "sar{l}\t%k0"
11019   [(set_attr "type" "ishift")
11020    (set_attr "length" "2")])
11021
11022 (define_insn "*ashrsi3_1"
11023   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11024         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11025                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11026    (clobber (reg:CC FLAGS_REG))]
11027   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11028   "@
11029    sar{l}\t{%2, %0|%0, %2}
11030    sar{l}\t{%b2, %0|%0, %b2}"
11031   [(set_attr "type" "ishift")
11032    (set_attr "mode" "SI")])
11033
11034 (define_insn "*ashrsi3_1_zext"
11035   [(set (match_operand:DI 0 "register_operand" "=r,r")
11036         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11037                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11038    (clobber (reg:CC FLAGS_REG))]
11039   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11040   "@
11041    sar{l}\t{%2, %k0|%k0, %2}
11042    sar{l}\t{%b2, %k0|%k0, %b2}"
11043   [(set_attr "type" "ishift")
11044    (set_attr "mode" "SI")])
11045
11046 ;; This pattern can't accept a variable shift count, since shifts by
11047 ;; zero don't affect the flags.  We assume that shifts by constant
11048 ;; zero are optimized away.
11049 (define_insn "*ashrsi3_one_bit_cmp"
11050   [(set (reg FLAGS_REG)
11051         (compare
11052           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11053                        (match_operand:QI 2 "const1_operand" ""))
11054           (const_int 0)))
11055    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11056         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11057   "ix86_match_ccmode (insn, CCGOCmode)
11058    && (TARGET_SHIFT1 || optimize_size)
11059    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11060   "sar{l}\t%0"
11061   [(set_attr "type" "ishift")
11062    (set (attr "length") 
11063      (if_then_else (match_operand:SI 0 "register_operand" "") 
11064         (const_string "2")
11065         (const_string "*")))])
11066
11067 (define_insn "*ashrsi3_one_bit_cmp_zext"
11068   [(set (reg FLAGS_REG)
11069         (compare
11070           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11071                        (match_operand:QI 2 "const1_operand" ""))
11072           (const_int 0)))
11073    (set (match_operand:DI 0 "register_operand" "=r")
11074         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11075   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11076    && (TARGET_SHIFT1 || optimize_size)
11077    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11078   "sar{l}\t%k0"
11079   [(set_attr "type" "ishift")
11080    (set_attr "length" "2")])
11081
11082 ;; This pattern can't accept a variable shift count, since shifts by
11083 ;; zero don't affect the flags.  We assume that shifts by constant
11084 ;; zero are optimized away.
11085 (define_insn "*ashrsi3_cmp"
11086   [(set (reg FLAGS_REG)
11087         (compare
11088           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11089                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11090           (const_int 0)))
11091    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11092         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11093   "ix86_match_ccmode (insn, CCGOCmode)
11094    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11095   "sar{l}\t{%2, %0|%0, %2}"
11096   [(set_attr "type" "ishift")
11097    (set_attr "mode" "SI")])
11098
11099 (define_insn "*ashrsi3_cmp_zext"
11100   [(set (reg FLAGS_REG)
11101         (compare
11102           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11103                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11104           (const_int 0)))
11105    (set (match_operand:DI 0 "register_operand" "=r")
11106         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11107   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11108    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11109   "sar{l}\t{%2, %k0|%k0, %2}"
11110   [(set_attr "type" "ishift")
11111    (set_attr "mode" "SI")])
11112
11113 (define_expand "ashrhi3"
11114   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11115         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11116                      (match_operand:QI 2 "nonmemory_operand" "")))
11117    (clobber (reg:CC FLAGS_REG))]
11118   "TARGET_HIMODE_MATH"
11119   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11120
11121 (define_insn "*ashrhi3_1_one_bit"
11122   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11123         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11124                      (match_operand:QI 2 "const1_operand" "")))
11125    (clobber (reg:CC FLAGS_REG))]
11126   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11127    && (TARGET_SHIFT1 || optimize_size)"
11128   "sar{w}\t%0"
11129   [(set_attr "type" "ishift")
11130    (set (attr "length") 
11131      (if_then_else (match_operand 0 "register_operand" "") 
11132         (const_string "2")
11133         (const_string "*")))])
11134
11135 (define_insn "*ashrhi3_1"
11136   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11137         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11138                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11139    (clobber (reg:CC FLAGS_REG))]
11140   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11141   "@
11142    sar{w}\t{%2, %0|%0, %2}
11143    sar{w}\t{%b2, %0|%0, %b2}"
11144   [(set_attr "type" "ishift")
11145    (set_attr "mode" "HI")])
11146
11147 ;; This pattern can't accept a variable shift count, since shifts by
11148 ;; zero don't affect the flags.  We assume that shifts by constant
11149 ;; zero are optimized away.
11150 (define_insn "*ashrhi3_one_bit_cmp"
11151   [(set (reg FLAGS_REG)
11152         (compare
11153           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11154                        (match_operand:QI 2 "const1_operand" ""))
11155           (const_int 0)))
11156    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11157         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11158   "ix86_match_ccmode (insn, CCGOCmode)
11159    && (TARGET_SHIFT1 || optimize_size)
11160    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11161   "sar{w}\t%0"
11162   [(set_attr "type" "ishift")
11163    (set (attr "length") 
11164      (if_then_else (match_operand 0 "register_operand" "") 
11165         (const_string "2")
11166         (const_string "*")))])
11167
11168 ;; This pattern can't accept a variable shift count, since shifts by
11169 ;; zero don't affect the flags.  We assume that shifts by constant
11170 ;; zero are optimized away.
11171 (define_insn "*ashrhi3_cmp"
11172   [(set (reg FLAGS_REG)
11173         (compare
11174           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11175                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11176           (const_int 0)))
11177    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11178         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11179   "ix86_match_ccmode (insn, CCGOCmode)
11180    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11181   "sar{w}\t{%2, %0|%0, %2}"
11182   [(set_attr "type" "ishift")
11183    (set_attr "mode" "HI")])
11184
11185 (define_expand "ashrqi3"
11186   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11187         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11188                      (match_operand:QI 2 "nonmemory_operand" "")))
11189    (clobber (reg:CC FLAGS_REG))]
11190   "TARGET_QIMODE_MATH"
11191   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11192
11193 (define_insn "*ashrqi3_1_one_bit"
11194   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11195         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11196                      (match_operand:QI 2 "const1_operand" "")))
11197    (clobber (reg:CC FLAGS_REG))]
11198   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11199    && (TARGET_SHIFT1 || optimize_size)"
11200   "sar{b}\t%0"
11201   [(set_attr "type" "ishift")
11202    (set (attr "length") 
11203      (if_then_else (match_operand 0 "register_operand" "") 
11204         (const_string "2")
11205         (const_string "*")))])
11206
11207 (define_insn "*ashrqi3_1_one_bit_slp"
11208   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11209         (ashiftrt:QI (match_dup 0)
11210                      (match_operand:QI 1 "const1_operand" "")))
11211    (clobber (reg:CC FLAGS_REG))]
11212   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11213    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11214    && (TARGET_SHIFT1 || optimize_size)"
11215   "sar{b}\t%0"
11216   [(set_attr "type" "ishift1")
11217    (set (attr "length") 
11218      (if_then_else (match_operand 0 "register_operand" "") 
11219         (const_string "2")
11220         (const_string "*")))])
11221
11222 (define_insn "*ashrqi3_1"
11223   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11224         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11225                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11226    (clobber (reg:CC FLAGS_REG))]
11227   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11228   "@
11229    sar{b}\t{%2, %0|%0, %2}
11230    sar{b}\t{%b2, %0|%0, %b2}"
11231   [(set_attr "type" "ishift")
11232    (set_attr "mode" "QI")])
11233
11234 (define_insn "*ashrqi3_1_slp"
11235   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11236         (ashiftrt:QI (match_dup 0)
11237                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11240    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11241   "@
11242    sar{b}\t{%1, %0|%0, %1}
11243    sar{b}\t{%b1, %0|%0, %b1}"
11244   [(set_attr "type" "ishift1")
11245    (set_attr "mode" "QI")])
11246
11247 ;; This pattern can't accept a variable shift count, since shifts by
11248 ;; zero don't affect the flags.  We assume that shifts by constant
11249 ;; zero are optimized away.
11250 (define_insn "*ashrqi3_one_bit_cmp"
11251   [(set (reg FLAGS_REG)
11252         (compare
11253           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11254                        (match_operand:QI 2 "const1_operand" "I"))
11255           (const_int 0)))
11256    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11257         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11258   "ix86_match_ccmode (insn, CCGOCmode)
11259    && (TARGET_SHIFT1 || optimize_size)
11260    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11261   "sar{b}\t%0"
11262   [(set_attr "type" "ishift")
11263    (set (attr "length") 
11264      (if_then_else (match_operand 0 "register_operand" "") 
11265         (const_string "2")
11266         (const_string "*")))])
11267
11268 ;; This pattern can't accept a variable shift count, since shifts by
11269 ;; zero don't affect the flags.  We assume that shifts by constant
11270 ;; zero are optimized away.
11271 (define_insn "*ashrqi3_cmp"
11272   [(set (reg FLAGS_REG)
11273         (compare
11274           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11276           (const_int 0)))
11277    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11278         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11279   "ix86_match_ccmode (insn, CCGOCmode)
11280    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11281   "sar{b}\t{%2, %0|%0, %2}"
11282   [(set_attr "type" "ishift")
11283    (set_attr "mode" "QI")])
11284 \f
11285 ;; Logical shift instructions
11286
11287 ;; See comment above `ashldi3' about how this works.
11288
11289 (define_expand "lshrdi3"
11290   [(set (match_operand:DI 0 "shiftdi_operand" "")
11291         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11292                      (match_operand:QI 2 "nonmemory_operand" "")))]
11293   ""
11294   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11295
11296 (define_insn "*lshrdi3_1_one_bit_rex64"
11297   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11298         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11299                      (match_operand:QI 2 "const1_operand" "")))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11302    && (TARGET_SHIFT1 || optimize_size)"
11303   "shr{q}\t%0"
11304   [(set_attr "type" "ishift")
11305    (set (attr "length") 
11306      (if_then_else (match_operand:DI 0 "register_operand" "") 
11307         (const_string "2")
11308         (const_string "*")))])
11309
11310 (define_insn "*lshrdi3_1_rex64"
11311   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11312         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11313                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11314    (clobber (reg:CC FLAGS_REG))]
11315   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11316   "@
11317    shr{q}\t{%2, %0|%0, %2}
11318    shr{q}\t{%b2, %0|%0, %b2}"
11319   [(set_attr "type" "ishift")
11320    (set_attr "mode" "DI")])
11321
11322 ;; This pattern can't accept a variable shift count, since shifts by
11323 ;; zero don't affect the flags.  We assume that shifts by constant
11324 ;; zero are optimized away.
11325 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11326   [(set (reg FLAGS_REG)
11327         (compare
11328           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11329                        (match_operand:QI 2 "const1_operand" ""))
11330           (const_int 0)))
11331    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11332         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11333   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11334    && (TARGET_SHIFT1 || optimize_size)
11335    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11336   "shr{q}\t%0"
11337   [(set_attr "type" "ishift")
11338    (set (attr "length") 
11339      (if_then_else (match_operand:DI 0 "register_operand" "") 
11340         (const_string "2")
11341         (const_string "*")))])
11342
11343 ;; This pattern can't accept a variable shift count, since shifts by
11344 ;; zero don't affect the flags.  We assume that shifts by constant
11345 ;; zero are optimized away.
11346 (define_insn "*lshrdi3_cmp_rex64"
11347   [(set (reg FLAGS_REG)
11348         (compare
11349           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11350                        (match_operand:QI 2 "const_int_operand" "e"))
11351           (const_int 0)))
11352    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11353         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11354   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11355    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11356   "shr{q}\t{%2, %0|%0, %2}"
11357   [(set_attr "type" "ishift")
11358    (set_attr "mode" "DI")])
11359
11360 (define_insn "*lshrdi3_1"
11361   [(set (match_operand:DI 0 "register_operand" "=r")
11362         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11363                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11364    (clobber (reg:CC FLAGS_REG))]
11365   "!TARGET_64BIT"
11366   "#"
11367   [(set_attr "type" "multi")])
11368
11369 ;; By default we don't ask for a scratch register, because when DImode
11370 ;; values are manipulated, registers are already at a premium.  But if
11371 ;; we have one handy, we won't turn it away.
11372 (define_peephole2
11373   [(match_scratch:SI 3 "r")
11374    (parallel [(set (match_operand:DI 0 "register_operand" "")
11375                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11376                                 (match_operand:QI 2 "nonmemory_operand" "")))
11377               (clobber (reg:CC FLAGS_REG))])
11378    (match_dup 3)]
11379   "!TARGET_64BIT && TARGET_CMOVE"
11380   [(const_int 0)]
11381   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11382
11383 (define_split 
11384   [(set (match_operand:DI 0 "register_operand" "")
11385         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11386                      (match_operand:QI 2 "nonmemory_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11389   [(const_int 0)]
11390   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11391
11392 (define_expand "lshrsi3"
11393   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11394         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11395                      (match_operand:QI 2 "nonmemory_operand" "")))
11396    (clobber (reg:CC FLAGS_REG))]
11397   ""
11398   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11399
11400 (define_insn "*lshrsi3_1_one_bit"
11401   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11402         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11403                      (match_operand:QI 2 "const1_operand" "")))
11404    (clobber (reg:CC FLAGS_REG))]
11405   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11406    && (TARGET_SHIFT1 || optimize_size)"
11407   "shr{l}\t%0"
11408   [(set_attr "type" "ishift")
11409    (set (attr "length") 
11410      (if_then_else (match_operand:SI 0 "register_operand" "") 
11411         (const_string "2")
11412         (const_string "*")))])
11413
11414 (define_insn "*lshrsi3_1_one_bit_zext"
11415   [(set (match_operand:DI 0 "register_operand" "=r")
11416         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11417                      (match_operand:QI 2 "const1_operand" "")))
11418    (clobber (reg:CC FLAGS_REG))]
11419   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11420    && (TARGET_SHIFT1 || optimize_size)"
11421   "shr{l}\t%k0"
11422   [(set_attr "type" "ishift")
11423    (set_attr "length" "2")])
11424
11425 (define_insn "*lshrsi3_1"
11426   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11427         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11428                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11429    (clobber (reg:CC FLAGS_REG))]
11430   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11431   "@
11432    shr{l}\t{%2, %0|%0, %2}
11433    shr{l}\t{%b2, %0|%0, %b2}"
11434   [(set_attr "type" "ishift")
11435    (set_attr "mode" "SI")])
11436
11437 (define_insn "*lshrsi3_1_zext"
11438   [(set (match_operand:DI 0 "register_operand" "=r,r")
11439         (zero_extend:DI
11440           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11441                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11442    (clobber (reg:CC FLAGS_REG))]
11443   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11444   "@
11445    shr{l}\t{%2, %k0|%k0, %2}
11446    shr{l}\t{%b2, %k0|%k0, %b2}"
11447   [(set_attr "type" "ishift")
11448    (set_attr "mode" "SI")])
11449
11450 ;; This pattern can't accept a variable shift count, since shifts by
11451 ;; zero don't affect the flags.  We assume that shifts by constant
11452 ;; zero are optimized away.
11453 (define_insn "*lshrsi3_one_bit_cmp"
11454   [(set (reg FLAGS_REG)
11455         (compare
11456           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11457                        (match_operand:QI 2 "const1_operand" ""))
11458           (const_int 0)))
11459    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11460         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11461   "ix86_match_ccmode (insn, CCGOCmode)
11462    && (TARGET_SHIFT1 || optimize_size)
11463    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11464   "shr{l}\t%0"
11465   [(set_attr "type" "ishift")
11466    (set (attr "length") 
11467      (if_then_else (match_operand:SI 0 "register_operand" "") 
11468         (const_string "2")
11469         (const_string "*")))])
11470
11471 (define_insn "*lshrsi3_cmp_one_bit_zext"
11472   [(set (reg FLAGS_REG)
11473         (compare
11474           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11475                        (match_operand:QI 2 "const1_operand" ""))
11476           (const_int 0)))
11477    (set (match_operand:DI 0 "register_operand" "=r")
11478         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11479   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11480    && (TARGET_SHIFT1 || optimize_size)
11481    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11482   "shr{l}\t%k0"
11483   [(set_attr "type" "ishift")
11484    (set_attr "length" "2")])
11485
11486 ;; This pattern can't accept a variable shift count, since shifts by
11487 ;; zero don't affect the flags.  We assume that shifts by constant
11488 ;; zero are optimized away.
11489 (define_insn "*lshrsi3_cmp"
11490   [(set (reg FLAGS_REG)
11491         (compare
11492           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11493                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11494           (const_int 0)))
11495    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11496         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11497   "ix86_match_ccmode (insn, CCGOCmode)
11498    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11499   "shr{l}\t{%2, %0|%0, %2}"
11500   [(set_attr "type" "ishift")
11501    (set_attr "mode" "SI")])
11502
11503 (define_insn "*lshrsi3_cmp_zext"
11504   [(set (reg FLAGS_REG)
11505         (compare
11506           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11507                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11508           (const_int 0)))
11509    (set (match_operand:DI 0 "register_operand" "=r")
11510         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11511   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11512    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11513   "shr{l}\t{%2, %k0|%k0, %2}"
11514   [(set_attr "type" "ishift")
11515    (set_attr "mode" "SI")])
11516
11517 (define_expand "lshrhi3"
11518   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11519         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11520                      (match_operand:QI 2 "nonmemory_operand" "")))
11521    (clobber (reg:CC FLAGS_REG))]
11522   "TARGET_HIMODE_MATH"
11523   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11524
11525 (define_insn "*lshrhi3_1_one_bit"
11526   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11527         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11528                      (match_operand:QI 2 "const1_operand" "")))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11531    && (TARGET_SHIFT1 || optimize_size)"
11532   "shr{w}\t%0"
11533   [(set_attr "type" "ishift")
11534    (set (attr "length") 
11535      (if_then_else (match_operand 0 "register_operand" "") 
11536         (const_string "2")
11537         (const_string "*")))])
11538
11539 (define_insn "*lshrhi3_1"
11540   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11541         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11542                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11543    (clobber (reg:CC FLAGS_REG))]
11544   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11545   "@
11546    shr{w}\t{%2, %0|%0, %2}
11547    shr{w}\t{%b2, %0|%0, %b2}"
11548   [(set_attr "type" "ishift")
11549    (set_attr "mode" "HI")])
11550
11551 ;; This pattern can't accept a variable shift count, since shifts by
11552 ;; zero don't affect the flags.  We assume that shifts by constant
11553 ;; zero are optimized away.
11554 (define_insn "*lshrhi3_one_bit_cmp"
11555   [(set (reg FLAGS_REG)
11556         (compare
11557           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11558                        (match_operand:QI 2 "const1_operand" ""))
11559           (const_int 0)))
11560    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11561         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11562   "ix86_match_ccmode (insn, CCGOCmode)
11563    && (TARGET_SHIFT1 || optimize_size)
11564    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11565   "shr{w}\t%0"
11566   [(set_attr "type" "ishift")
11567    (set (attr "length") 
11568      (if_then_else (match_operand:SI 0 "register_operand" "") 
11569         (const_string "2")
11570         (const_string "*")))])
11571
11572 ;; This pattern can't accept a variable shift count, since shifts by
11573 ;; zero don't affect the flags.  We assume that shifts by constant
11574 ;; zero are optimized away.
11575 (define_insn "*lshrhi3_cmp"
11576   [(set (reg FLAGS_REG)
11577         (compare
11578           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11579                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11580           (const_int 0)))
11581    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11582         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11583   "ix86_match_ccmode (insn, CCGOCmode)
11584    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11585   "shr{w}\t{%2, %0|%0, %2}"
11586   [(set_attr "type" "ishift")
11587    (set_attr "mode" "HI")])
11588
11589 (define_expand "lshrqi3"
11590   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11591         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11592                      (match_operand:QI 2 "nonmemory_operand" "")))
11593    (clobber (reg:CC FLAGS_REG))]
11594   "TARGET_QIMODE_MATH"
11595   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11596
11597 (define_insn "*lshrqi3_1_one_bit"
11598   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11599         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11600                      (match_operand:QI 2 "const1_operand" "")))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11603    && (TARGET_SHIFT1 || optimize_size)"
11604   "shr{b}\t%0"
11605   [(set_attr "type" "ishift")
11606    (set (attr "length") 
11607      (if_then_else (match_operand 0 "register_operand" "") 
11608         (const_string "2")
11609         (const_string "*")))])
11610
11611 (define_insn "*lshrqi3_1_one_bit_slp"
11612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11613         (lshiftrt:QI (match_dup 0)
11614                      (match_operand:QI 1 "const1_operand" "")))
11615    (clobber (reg:CC FLAGS_REG))]
11616   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11617    && (TARGET_SHIFT1 || optimize_size)"
11618   "shr{b}\t%0"
11619   [(set_attr "type" "ishift1")
11620    (set (attr "length") 
11621      (if_then_else (match_operand 0 "register_operand" "") 
11622         (const_string "2")
11623         (const_string "*")))])
11624
11625 (define_insn "*lshrqi3_1"
11626   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11627         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11628                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11629    (clobber (reg:CC FLAGS_REG))]
11630   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11631   "@
11632    shr{b}\t{%2, %0|%0, %2}
11633    shr{b}\t{%b2, %0|%0, %b2}"
11634   [(set_attr "type" "ishift")
11635    (set_attr "mode" "QI")])
11636
11637 (define_insn "*lshrqi3_1_slp"
11638   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11639         (lshiftrt:QI (match_dup 0)
11640                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11641    (clobber (reg:CC FLAGS_REG))]
11642   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11643    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11644   "@
11645    shr{b}\t{%1, %0|%0, %1}
11646    shr{b}\t{%b1, %0|%0, %b1}"
11647   [(set_attr "type" "ishift1")
11648    (set_attr "mode" "QI")])
11649
11650 ;; This pattern can't accept a variable shift count, since shifts by
11651 ;; zero don't affect the flags.  We assume that shifts by constant
11652 ;; zero are optimized away.
11653 (define_insn "*lshrqi2_one_bit_cmp"
11654   [(set (reg FLAGS_REG)
11655         (compare
11656           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11657                        (match_operand:QI 2 "const1_operand" ""))
11658           (const_int 0)))
11659    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11660         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11661   "ix86_match_ccmode (insn, CCGOCmode)
11662    && (TARGET_SHIFT1 || optimize_size)
11663    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11664   "shr{b}\t%0"
11665   [(set_attr "type" "ishift")
11666    (set (attr "length") 
11667      (if_then_else (match_operand:SI 0 "register_operand" "") 
11668         (const_string "2")
11669         (const_string "*")))])
11670
11671 ;; This pattern can't accept a variable shift count, since shifts by
11672 ;; zero don't affect the flags.  We assume that shifts by constant
11673 ;; zero are optimized away.
11674 (define_insn "*lshrqi2_cmp"
11675   [(set (reg FLAGS_REG)
11676         (compare
11677           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11678                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11679           (const_int 0)))
11680    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11681         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11682   "ix86_match_ccmode (insn, CCGOCmode)
11683    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11684   "shr{b}\t{%2, %0|%0, %2}"
11685   [(set_attr "type" "ishift")
11686    (set_attr "mode" "QI")])
11687 \f
11688 ;; Rotate instructions
11689
11690 (define_expand "rotldi3"
11691   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11692         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11693                    (match_operand:QI 2 "nonmemory_operand" "")))
11694    (clobber (reg:CC FLAGS_REG))]
11695   "TARGET_64BIT"
11696   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11697
11698 (define_insn "*rotlsi3_1_one_bit_rex64"
11699   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11700         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11701                    (match_operand:QI 2 "const1_operand" "")))
11702    (clobber (reg:CC FLAGS_REG))]
11703   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11704    && (TARGET_SHIFT1 || optimize_size)"
11705   "rol{q}\t%0"
11706   [(set_attr "type" "rotate")
11707    (set (attr "length") 
11708      (if_then_else (match_operand:DI 0 "register_operand" "") 
11709         (const_string "2")
11710         (const_string "*")))])
11711
11712 (define_insn "*rotldi3_1_rex64"
11713   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11714         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11715                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11716    (clobber (reg:CC FLAGS_REG))]
11717   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11718   "@
11719    rol{q}\t{%2, %0|%0, %2}
11720    rol{q}\t{%b2, %0|%0, %b2}"
11721   [(set_attr "type" "rotate")
11722    (set_attr "mode" "DI")])
11723
11724 (define_expand "rotlsi3"
11725   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11726         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11727                    (match_operand:QI 2 "nonmemory_operand" "")))
11728    (clobber (reg:CC FLAGS_REG))]
11729   ""
11730   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11731
11732 (define_insn "*rotlsi3_1_one_bit"
11733   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11734         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11735                    (match_operand:QI 2 "const1_operand" "")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11738    && (TARGET_SHIFT1 || optimize_size)"
11739   "rol{l}\t%0"
11740   [(set_attr "type" "rotate")
11741    (set (attr "length") 
11742      (if_then_else (match_operand:SI 0 "register_operand" "") 
11743         (const_string "2")
11744         (const_string "*")))])
11745
11746 (define_insn "*rotlsi3_1_one_bit_zext"
11747   [(set (match_operand:DI 0 "register_operand" "=r")
11748         (zero_extend:DI
11749           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11750                      (match_operand:QI 2 "const1_operand" ""))))
11751    (clobber (reg:CC FLAGS_REG))]
11752   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11753    && (TARGET_SHIFT1 || optimize_size)"
11754   "rol{l}\t%k0"
11755   [(set_attr "type" "rotate")
11756    (set_attr "length" "2")])
11757
11758 (define_insn "*rotlsi3_1"
11759   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11760         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11761                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11764   "@
11765    rol{l}\t{%2, %0|%0, %2}
11766    rol{l}\t{%b2, %0|%0, %b2}"
11767   [(set_attr "type" "rotate")
11768    (set_attr "mode" "SI")])
11769
11770 (define_insn "*rotlsi3_1_zext"
11771   [(set (match_operand:DI 0 "register_operand" "=r,r")
11772         (zero_extend:DI
11773           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11774                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11775    (clobber (reg:CC FLAGS_REG))]
11776   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11777   "@
11778    rol{l}\t{%2, %k0|%k0, %2}
11779    rol{l}\t{%b2, %k0|%k0, %b2}"
11780   [(set_attr "type" "rotate")
11781    (set_attr "mode" "SI")])
11782
11783 (define_expand "rotlhi3"
11784   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11785         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11786                    (match_operand:QI 2 "nonmemory_operand" "")))
11787    (clobber (reg:CC FLAGS_REG))]
11788   "TARGET_HIMODE_MATH"
11789   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11790
11791 (define_insn "*rotlhi3_1_one_bit"
11792   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11793         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11794                    (match_operand:QI 2 "const1_operand" "")))
11795    (clobber (reg:CC FLAGS_REG))]
11796   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11797    && (TARGET_SHIFT1 || optimize_size)"
11798   "rol{w}\t%0"
11799   [(set_attr "type" "rotate")
11800    (set (attr "length") 
11801      (if_then_else (match_operand 0 "register_operand" "") 
11802         (const_string "2")
11803         (const_string "*")))])
11804
11805 (define_insn "*rotlhi3_1"
11806   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11807         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11808                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11811   "@
11812    rol{w}\t{%2, %0|%0, %2}
11813    rol{w}\t{%b2, %0|%0, %b2}"
11814   [(set_attr "type" "rotate")
11815    (set_attr "mode" "HI")])
11816
11817 (define_expand "rotlqi3"
11818   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11819         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11820                    (match_operand:QI 2 "nonmemory_operand" "")))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "TARGET_QIMODE_MATH"
11823   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11824
11825 (define_insn "*rotlqi3_1_one_bit_slp"
11826   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11827         (rotate:QI (match_dup 0)
11828                    (match_operand:QI 1 "const1_operand" "")))
11829    (clobber (reg:CC FLAGS_REG))]
11830   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11831    && (TARGET_SHIFT1 || optimize_size)"
11832   "rol{b}\t%0"
11833   [(set_attr "type" "rotate1")
11834    (set (attr "length") 
11835      (if_then_else (match_operand 0 "register_operand" "") 
11836         (const_string "2")
11837         (const_string "*")))])
11838
11839 (define_insn "*rotlqi3_1_one_bit"
11840   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11841         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11842                    (match_operand:QI 2 "const1_operand" "")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11845    && (TARGET_SHIFT1 || optimize_size)"
11846   "rol{b}\t%0"
11847   [(set_attr "type" "rotate")
11848    (set (attr "length") 
11849      (if_then_else (match_operand 0 "register_operand" "") 
11850         (const_string "2")
11851         (const_string "*")))])
11852
11853 (define_insn "*rotlqi3_1_slp"
11854   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11855         (rotate:QI (match_dup 0)
11856                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11857    (clobber (reg:CC FLAGS_REG))]
11858   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11859    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11860   "@
11861    rol{b}\t{%1, %0|%0, %1}
11862    rol{b}\t{%b1, %0|%0, %b1}"
11863   [(set_attr "type" "rotate1")
11864    (set_attr "mode" "QI")])
11865
11866 (define_insn "*rotlqi3_1"
11867   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11868         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11869                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11870    (clobber (reg:CC FLAGS_REG))]
11871   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11872   "@
11873    rol{b}\t{%2, %0|%0, %2}
11874    rol{b}\t{%b2, %0|%0, %b2}"
11875   [(set_attr "type" "rotate")
11876    (set_attr "mode" "QI")])
11877
11878 (define_expand "rotrdi3"
11879   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11880         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11881                      (match_operand:QI 2 "nonmemory_operand" "")))
11882    (clobber (reg:CC FLAGS_REG))]
11883   "TARGET_64BIT"
11884   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11885
11886 (define_insn "*rotrdi3_1_one_bit_rex64"
11887   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11888         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11889                      (match_operand:QI 2 "const1_operand" "")))
11890    (clobber (reg:CC FLAGS_REG))]
11891   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11892    && (TARGET_SHIFT1 || optimize_size)"
11893   "ror{q}\t%0"
11894   [(set_attr "type" "rotate")
11895    (set (attr "length") 
11896      (if_then_else (match_operand:DI 0 "register_operand" "") 
11897         (const_string "2")
11898         (const_string "*")))])
11899
11900 (define_insn "*rotrdi3_1_rex64"
11901   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11902         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11903                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11904    (clobber (reg:CC FLAGS_REG))]
11905   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11906   "@
11907    ror{q}\t{%2, %0|%0, %2}
11908    ror{q}\t{%b2, %0|%0, %b2}"
11909   [(set_attr "type" "rotate")
11910    (set_attr "mode" "DI")])
11911
11912 (define_expand "rotrsi3"
11913   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11914         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11915                      (match_operand:QI 2 "nonmemory_operand" "")))
11916    (clobber (reg:CC FLAGS_REG))]
11917   ""
11918   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11919
11920 (define_insn "*rotrsi3_1_one_bit"
11921   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11922         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11923                      (match_operand:QI 2 "const1_operand" "")))
11924    (clobber (reg:CC FLAGS_REG))]
11925   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11926    && (TARGET_SHIFT1 || optimize_size)"
11927   "ror{l}\t%0"
11928   [(set_attr "type" "rotate")
11929    (set (attr "length") 
11930      (if_then_else (match_operand:SI 0 "register_operand" "") 
11931         (const_string "2")
11932         (const_string "*")))])
11933
11934 (define_insn "*rotrsi3_1_one_bit_zext"
11935   [(set (match_operand:DI 0 "register_operand" "=r")
11936         (zero_extend:DI
11937           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11938                        (match_operand:QI 2 "const1_operand" ""))))
11939    (clobber (reg:CC FLAGS_REG))]
11940   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11941    && (TARGET_SHIFT1 || optimize_size)"
11942   "ror{l}\t%k0"
11943   [(set_attr "type" "rotate")
11944    (set (attr "length") 
11945      (if_then_else (match_operand:SI 0 "register_operand" "") 
11946         (const_string "2")
11947         (const_string "*")))])
11948
11949 (define_insn "*rotrsi3_1"
11950   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11951         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11952                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11953    (clobber (reg:CC FLAGS_REG))]
11954   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11955   "@
11956    ror{l}\t{%2, %0|%0, %2}
11957    ror{l}\t{%b2, %0|%0, %b2}"
11958   [(set_attr "type" "rotate")
11959    (set_attr "mode" "SI")])
11960
11961 (define_insn "*rotrsi3_1_zext"
11962   [(set (match_operand:DI 0 "register_operand" "=r,r")
11963         (zero_extend:DI
11964           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11965                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11966    (clobber (reg:CC FLAGS_REG))]
11967   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11968   "@
11969    ror{l}\t{%2, %k0|%k0, %2}
11970    ror{l}\t{%b2, %k0|%k0, %b2}"
11971   [(set_attr "type" "rotate")
11972    (set_attr "mode" "SI")])
11973
11974 (define_expand "rotrhi3"
11975   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11976         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11977                      (match_operand:QI 2 "nonmemory_operand" "")))
11978    (clobber (reg:CC FLAGS_REG))]
11979   "TARGET_HIMODE_MATH"
11980   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11981
11982 (define_insn "*rotrhi3_one_bit"
11983   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11984         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11985                      (match_operand:QI 2 "const1_operand" "")))
11986    (clobber (reg:CC FLAGS_REG))]
11987   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11988    && (TARGET_SHIFT1 || optimize_size)"
11989   "ror{w}\t%0"
11990   [(set_attr "type" "rotate")
11991    (set (attr "length") 
11992      (if_then_else (match_operand 0 "register_operand" "") 
11993         (const_string "2")
11994         (const_string "*")))])
11995
11996 (define_insn "*rotrhi3"
11997   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11998         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11999                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12000    (clobber (reg:CC FLAGS_REG))]
12001   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12002   "@
12003    ror{w}\t{%2, %0|%0, %2}
12004    ror{w}\t{%b2, %0|%0, %b2}"
12005   [(set_attr "type" "rotate")
12006    (set_attr "mode" "HI")])
12007
12008 (define_expand "rotrqi3"
12009   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12010         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12011                      (match_operand:QI 2 "nonmemory_operand" "")))
12012    (clobber (reg:CC FLAGS_REG))]
12013   "TARGET_QIMODE_MATH"
12014   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12015
12016 (define_insn "*rotrqi3_1_one_bit"
12017   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12018         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12019                      (match_operand:QI 2 "const1_operand" "")))
12020    (clobber (reg:CC FLAGS_REG))]
12021   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12022    && (TARGET_SHIFT1 || optimize_size)"
12023   "ror{b}\t%0"
12024   [(set_attr "type" "rotate")
12025    (set (attr "length") 
12026      (if_then_else (match_operand 0 "register_operand" "") 
12027         (const_string "2")
12028         (const_string "*")))])
12029
12030 (define_insn "*rotrqi3_1_one_bit_slp"
12031   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12032         (rotatert:QI (match_dup 0)
12033                      (match_operand:QI 1 "const1_operand" "")))
12034    (clobber (reg:CC FLAGS_REG))]
12035   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12036    && (TARGET_SHIFT1 || optimize_size)"
12037   "ror{b}\t%0"
12038   [(set_attr "type" "rotate1")
12039    (set (attr "length") 
12040      (if_then_else (match_operand 0 "register_operand" "") 
12041         (const_string "2")
12042         (const_string "*")))])
12043
12044 (define_insn "*rotrqi3_1"
12045   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12046         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12047                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12048    (clobber (reg:CC FLAGS_REG))]
12049   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12050   "@
12051    ror{b}\t{%2, %0|%0, %2}
12052    ror{b}\t{%b2, %0|%0, %b2}"
12053   [(set_attr "type" "rotate")
12054    (set_attr "mode" "QI")])
12055
12056 (define_insn "*rotrqi3_1_slp"
12057   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12058         (rotatert:QI (match_dup 0)
12059                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12060    (clobber (reg:CC FLAGS_REG))]
12061   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12062    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12063   "@
12064    ror{b}\t{%1, %0|%0, %1}
12065    ror{b}\t{%b1, %0|%0, %b1}"
12066   [(set_attr "type" "rotate1")
12067    (set_attr "mode" "QI")])
12068 \f
12069 ;; Bit set / bit test instructions
12070
12071 (define_expand "extv"
12072   [(set (match_operand:SI 0 "register_operand" "")
12073         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12074                          (match_operand:SI 2 "immediate_operand" "")
12075                          (match_operand:SI 3 "immediate_operand" "")))]
12076   ""
12077 {
12078   /* Handle extractions from %ah et al.  */
12079   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12080     FAIL;
12081
12082   /* From mips.md: extract_bit_field doesn't verify that our source
12083      matches the predicate, so check it again here.  */
12084   if (! ext_register_operand (operands[1], VOIDmode))
12085     FAIL;
12086 })
12087
12088 (define_expand "extzv"
12089   [(set (match_operand:SI 0 "register_operand" "")
12090         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12091                          (match_operand:SI 2 "immediate_operand" "")
12092                          (match_operand:SI 3 "immediate_operand" "")))]
12093   ""
12094 {
12095   /* Handle extractions from %ah et al.  */
12096   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12097     FAIL;
12098
12099   /* From mips.md: extract_bit_field doesn't verify that our source
12100      matches the predicate, so check it again here.  */
12101   if (! ext_register_operand (operands[1], VOIDmode))
12102     FAIL;
12103 })
12104
12105 (define_expand "insv"
12106   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12107                       (match_operand 1 "immediate_operand" "")
12108                       (match_operand 2 "immediate_operand" ""))
12109         (match_operand 3 "register_operand" ""))]
12110   ""
12111 {
12112   /* Handle extractions from %ah et al.  */
12113   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12114     FAIL;
12115
12116   /* From mips.md: insert_bit_field doesn't verify that our source
12117      matches the predicate, so check it again here.  */
12118   if (! ext_register_operand (operands[0], VOIDmode))
12119     FAIL;
12120
12121   if (TARGET_64BIT)
12122     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12123   else
12124     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12125
12126   DONE;
12127 })
12128
12129 ;; %%% bts, btr, btc, bt.
12130 ;; In general these instructions are *slow* when applied to memory,
12131 ;; since they enforce atomic operation.  When applied to registers,
12132 ;; it depends on the cpu implementation.  They're never faster than
12133 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12134 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12135 ;; within the instruction itself, so operating on bits in the high
12136 ;; 32-bits of a register becomes easier.
12137 ;;
12138 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12139 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12140 ;; negdf respectively, so they can never be disabled entirely.
12141
12142 (define_insn "*btsq"
12143   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12144                          (const_int 1)
12145                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12146         (const_int 1))
12147    (clobber (reg:CC FLAGS_REG))]
12148   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12149   "bts{q} %1,%0"
12150   [(set_attr "type" "alu1")])
12151
12152 (define_insn "*btrq"
12153   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12154                          (const_int 1)
12155                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12156         (const_int 0))
12157    (clobber (reg:CC FLAGS_REG))]
12158   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12159   "btr{q} %1,%0"
12160   [(set_attr "type" "alu1")])
12161
12162 (define_insn "*btcq"
12163   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12164                          (const_int 1)
12165                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12166         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12167    (clobber (reg:CC FLAGS_REG))]
12168   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12169   "btc{q} %1,%0"
12170   [(set_attr "type" "alu1")])
12171
12172 ;; Allow Nocona to avoid these instructions if a register is available.
12173
12174 (define_peephole2
12175   [(match_scratch:DI 2 "r")
12176    (parallel [(set (zero_extract:DI
12177                      (match_operand:DI 0 "register_operand" "")
12178                      (const_int 1)
12179                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12180                    (const_int 1))
12181               (clobber (reg:CC FLAGS_REG))])]
12182   "TARGET_64BIT && !TARGET_USE_BT"
12183   [(const_int 0)]
12184 {
12185   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12186   rtx op1;
12187
12188   if (HOST_BITS_PER_WIDE_INT >= 64)
12189     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12190   else if (i < HOST_BITS_PER_WIDE_INT)
12191     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12192   else
12193     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12194
12195   op1 = immed_double_const (lo, hi, DImode);
12196   if (i >= 31)
12197     {
12198       emit_move_insn (operands[2], op1);
12199       op1 = operands[2];
12200     }
12201
12202   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12203   DONE;
12204 })
12205
12206 (define_peephole2
12207   [(match_scratch:DI 2 "r")
12208    (parallel [(set (zero_extract:DI
12209                      (match_operand:DI 0 "register_operand" "")
12210                      (const_int 1)
12211                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12212                    (const_int 0))
12213               (clobber (reg:CC FLAGS_REG))])]
12214   "TARGET_64BIT && !TARGET_USE_BT"
12215   [(const_int 0)]
12216 {
12217   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12218   rtx op1;
12219
12220   if (HOST_BITS_PER_WIDE_INT >= 64)
12221     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12222   else if (i < HOST_BITS_PER_WIDE_INT)
12223     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12224   else
12225     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12226
12227   op1 = immed_double_const (~lo, ~hi, DImode);
12228   if (i >= 32)
12229     {
12230       emit_move_insn (operands[2], op1);
12231       op1 = operands[2];
12232     }
12233
12234   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12235   DONE;
12236 })
12237
12238 (define_peephole2
12239   [(match_scratch:DI 2 "r")
12240    (parallel [(set (zero_extract:DI
12241                      (match_operand:DI 0 "register_operand" "")
12242                      (const_int 1)
12243                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12244               (not:DI (zero_extract:DI
12245                         (match_dup 0) (const_int 1) (match_dup 1))))
12246               (clobber (reg:CC FLAGS_REG))])]
12247   "TARGET_64BIT && !TARGET_USE_BT"
12248   [(const_int 0)]
12249 {
12250   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12251   rtx op1;
12252
12253   if (HOST_BITS_PER_WIDE_INT >= 64)
12254     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12255   else if (i < HOST_BITS_PER_WIDE_INT)
12256     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12257   else
12258     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12259
12260   op1 = immed_double_const (lo, hi, DImode);
12261   if (i >= 31)
12262     {
12263       emit_move_insn (operands[2], op1);
12264       op1 = operands[2];
12265     }
12266
12267   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12268   DONE;
12269 })
12270 \f
12271 ;; Store-flag instructions.
12272
12273 ;; For all sCOND expanders, also expand the compare or test insn that
12274 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12275
12276 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12277 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12278 ;; way, which can later delete the movzx if only QImode is needed.
12279
12280 (define_expand "seq"
12281   [(set (match_operand:QI 0 "register_operand" "")
12282         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12283   ""
12284   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12285
12286 (define_expand "sne"
12287   [(set (match_operand:QI 0 "register_operand" "")
12288         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12289   ""
12290   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12291
12292 (define_expand "sgt"
12293   [(set (match_operand:QI 0 "register_operand" "")
12294         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12295   ""
12296   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12297
12298 (define_expand "sgtu"
12299   [(set (match_operand:QI 0 "register_operand" "")
12300         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12301   ""
12302   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12303
12304 (define_expand "slt"
12305   [(set (match_operand:QI 0 "register_operand" "")
12306         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12307   ""
12308   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12309
12310 (define_expand "sltu"
12311   [(set (match_operand:QI 0 "register_operand" "")
12312         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12313   ""
12314   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12315
12316 (define_expand "sge"
12317   [(set (match_operand:QI 0 "register_operand" "")
12318         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12319   ""
12320   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12321
12322 (define_expand "sgeu"
12323   [(set (match_operand:QI 0 "register_operand" "")
12324         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12325   ""
12326   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12327
12328 (define_expand "sle"
12329   [(set (match_operand:QI 0 "register_operand" "")
12330         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12331   ""
12332   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12333
12334 (define_expand "sleu"
12335   [(set (match_operand:QI 0 "register_operand" "")
12336         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12337   ""
12338   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12339
12340 (define_expand "sunordered"
12341   [(set (match_operand:QI 0 "register_operand" "")
12342         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12343   "TARGET_80387 || TARGET_SSE"
12344   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12345
12346 (define_expand "sordered"
12347   [(set (match_operand:QI 0 "register_operand" "")
12348         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12349   "TARGET_80387"
12350   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12351
12352 (define_expand "suneq"
12353   [(set (match_operand:QI 0 "register_operand" "")
12354         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12355   "TARGET_80387 || TARGET_SSE"
12356   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12357
12358 (define_expand "sunge"
12359   [(set (match_operand:QI 0 "register_operand" "")
12360         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12361   "TARGET_80387 || TARGET_SSE"
12362   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12363
12364 (define_expand "sungt"
12365   [(set (match_operand:QI 0 "register_operand" "")
12366         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12367   "TARGET_80387 || TARGET_SSE"
12368   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12369
12370 (define_expand "sunle"
12371   [(set (match_operand:QI 0 "register_operand" "")
12372         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12373   "TARGET_80387 || TARGET_SSE"
12374   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12375
12376 (define_expand "sunlt"
12377   [(set (match_operand:QI 0 "register_operand" "")
12378         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12379   "TARGET_80387 || TARGET_SSE"
12380   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12381
12382 (define_expand "sltgt"
12383   [(set (match_operand:QI 0 "register_operand" "")
12384         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12385   "TARGET_80387 || TARGET_SSE"
12386   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12387
12388 (define_insn "*setcc_1"
12389   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12390         (match_operator:QI 1 "ix86_comparison_operator"
12391           [(reg FLAGS_REG) (const_int 0)]))]
12392   ""
12393   "set%C1\t%0"
12394   [(set_attr "type" "setcc")
12395    (set_attr "mode" "QI")])
12396
12397 (define_insn "*setcc_2"
12398   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12399         (match_operator:QI 1 "ix86_comparison_operator"
12400           [(reg FLAGS_REG) (const_int 0)]))]
12401   ""
12402   "set%C1\t%0"
12403   [(set_attr "type" "setcc")
12404    (set_attr "mode" "QI")])
12405
12406 ;; In general it is not safe to assume too much about CCmode registers,
12407 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12408 ;; conditions this is safe on x86, so help combine not create
12409 ;;
12410 ;;      seta    %al
12411 ;;      testb   %al, %al
12412 ;;      sete    %al
12413
12414 (define_split 
12415   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12416         (ne:QI (match_operator 1 "ix86_comparison_operator"
12417                  [(reg FLAGS_REG) (const_int 0)])
12418             (const_int 0)))]
12419   ""
12420   [(set (match_dup 0) (match_dup 1))]
12421 {
12422   PUT_MODE (operands[1], QImode);
12423 })
12424
12425 (define_split 
12426   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12427         (ne:QI (match_operator 1 "ix86_comparison_operator"
12428                  [(reg FLAGS_REG) (const_int 0)])
12429             (const_int 0)))]
12430   ""
12431   [(set (match_dup 0) (match_dup 1))]
12432 {
12433   PUT_MODE (operands[1], QImode);
12434 })
12435
12436 (define_split 
12437   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12438         (eq:QI (match_operator 1 "ix86_comparison_operator"
12439                  [(reg FLAGS_REG) (const_int 0)])
12440             (const_int 0)))]
12441   ""
12442   [(set (match_dup 0) (match_dup 1))]
12443 {
12444   rtx new_op1 = copy_rtx (operands[1]);
12445   operands[1] = new_op1;
12446   PUT_MODE (new_op1, QImode);
12447   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12448                                              GET_MODE (XEXP (new_op1, 0))));
12449
12450   /* Make sure that (a) the CCmode we have for the flags is strong
12451      enough for the reversed compare or (b) we have a valid FP compare.  */
12452   if (! ix86_comparison_operator (new_op1, VOIDmode))
12453     FAIL;
12454 })
12455
12456 (define_split 
12457   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12458         (eq:QI (match_operator 1 "ix86_comparison_operator"
12459                  [(reg FLAGS_REG) (const_int 0)])
12460             (const_int 0)))]
12461   ""
12462   [(set (match_dup 0) (match_dup 1))]
12463 {
12464   rtx new_op1 = copy_rtx (operands[1]);
12465   operands[1] = new_op1;
12466   PUT_MODE (new_op1, QImode);
12467   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12468                                              GET_MODE (XEXP (new_op1, 0))));
12469
12470   /* Make sure that (a) the CCmode we have for the flags is strong
12471      enough for the reversed compare or (b) we have a valid FP compare.  */
12472   if (! ix86_comparison_operator (new_op1, VOIDmode))
12473     FAIL;
12474 })
12475
12476 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12477 ;; subsequent logical operations are used to imitate conditional moves.
12478 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12479 ;; it directly.  Further holding this value in pseudo register might bring
12480 ;; problem in implicit normalization in spill code.
12481 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12482 ;; instructions after reload by splitting the conditional move patterns.
12483
12484 (define_insn "*sse_setccsf"
12485   [(set (match_operand:SF 0 "register_operand" "=x")
12486         (match_operator:SF 1 "sse_comparison_operator"
12487           [(match_operand:SF 2 "register_operand" "0")
12488            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12489   "TARGET_SSE && reload_completed"
12490   "cmp%D1ss\t{%3, %0|%0, %3}"
12491   [(set_attr "type" "ssecmp")
12492    (set_attr "mode" "SF")])
12493
12494 (define_insn "*sse_setccdf"
12495   [(set (match_operand:DF 0 "register_operand" "=Y")
12496         (match_operator:DF 1 "sse_comparison_operator"
12497           [(match_operand:DF 2 "register_operand" "0")
12498            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12499   "TARGET_SSE2 && reload_completed"
12500   "cmp%D1sd\t{%3, %0|%0, %3}"
12501   [(set_attr "type" "ssecmp")
12502    (set_attr "mode" "DF")])
12503 \f
12504 ;; Basic conditional jump instructions.
12505 ;; We ignore the overflow flag for signed branch instructions.
12506
12507 ;; For all bCOND expanders, also expand the compare or test insn that
12508 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12509
12510 (define_expand "beq"
12511   [(set (pc)
12512         (if_then_else (match_dup 1)
12513                       (label_ref (match_operand 0 "" ""))
12514                       (pc)))]
12515   ""
12516   "ix86_expand_branch (EQ, operands[0]); DONE;")
12517
12518 (define_expand "bne"
12519   [(set (pc)
12520         (if_then_else (match_dup 1)
12521                       (label_ref (match_operand 0 "" ""))
12522                       (pc)))]
12523   ""
12524   "ix86_expand_branch (NE, operands[0]); DONE;")
12525
12526 (define_expand "bgt"
12527   [(set (pc)
12528         (if_then_else (match_dup 1)
12529                       (label_ref (match_operand 0 "" ""))
12530                       (pc)))]
12531   ""
12532   "ix86_expand_branch (GT, operands[0]); DONE;")
12533
12534 (define_expand "bgtu"
12535   [(set (pc)
12536         (if_then_else (match_dup 1)
12537                       (label_ref (match_operand 0 "" ""))
12538                       (pc)))]
12539   ""
12540   "ix86_expand_branch (GTU, operands[0]); DONE;")
12541
12542 (define_expand "blt"
12543   [(set (pc)
12544         (if_then_else (match_dup 1)
12545                       (label_ref (match_operand 0 "" ""))
12546                       (pc)))]
12547   ""
12548   "ix86_expand_branch (LT, operands[0]); DONE;")
12549
12550 (define_expand "bltu"
12551   [(set (pc)
12552         (if_then_else (match_dup 1)
12553                       (label_ref (match_operand 0 "" ""))
12554                       (pc)))]
12555   ""
12556   "ix86_expand_branch (LTU, operands[0]); DONE;")
12557
12558 (define_expand "bge"
12559   [(set (pc)
12560         (if_then_else (match_dup 1)
12561                       (label_ref (match_operand 0 "" ""))
12562                       (pc)))]
12563   ""
12564   "ix86_expand_branch (GE, operands[0]); DONE;")
12565
12566 (define_expand "bgeu"
12567   [(set (pc)
12568         (if_then_else (match_dup 1)
12569                       (label_ref (match_operand 0 "" ""))
12570                       (pc)))]
12571   ""
12572   "ix86_expand_branch (GEU, operands[0]); DONE;")
12573
12574 (define_expand "ble"
12575   [(set (pc)
12576         (if_then_else (match_dup 1)
12577                       (label_ref (match_operand 0 "" ""))
12578                       (pc)))]
12579   ""
12580   "ix86_expand_branch (LE, operands[0]); DONE;")
12581
12582 (define_expand "bleu"
12583   [(set (pc)
12584         (if_then_else (match_dup 1)
12585                       (label_ref (match_operand 0 "" ""))
12586                       (pc)))]
12587   ""
12588   "ix86_expand_branch (LEU, operands[0]); DONE;")
12589
12590 (define_expand "bunordered"
12591   [(set (pc)
12592         (if_then_else (match_dup 1)
12593                       (label_ref (match_operand 0 "" ""))
12594                       (pc)))]
12595   "TARGET_80387 || TARGET_SSE_MATH"
12596   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12597
12598 (define_expand "bordered"
12599   [(set (pc)
12600         (if_then_else (match_dup 1)
12601                       (label_ref (match_operand 0 "" ""))
12602                       (pc)))]
12603   "TARGET_80387 || TARGET_SSE_MATH"
12604   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12605
12606 (define_expand "buneq"
12607   [(set (pc)
12608         (if_then_else (match_dup 1)
12609                       (label_ref (match_operand 0 "" ""))
12610                       (pc)))]
12611   "TARGET_80387 || TARGET_SSE_MATH"
12612   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12613
12614 (define_expand "bunge"
12615   [(set (pc)
12616         (if_then_else (match_dup 1)
12617                       (label_ref (match_operand 0 "" ""))
12618                       (pc)))]
12619   "TARGET_80387 || TARGET_SSE_MATH"
12620   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12621
12622 (define_expand "bungt"
12623   [(set (pc)
12624         (if_then_else (match_dup 1)
12625                       (label_ref (match_operand 0 "" ""))
12626                       (pc)))]
12627   "TARGET_80387 || TARGET_SSE_MATH"
12628   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12629
12630 (define_expand "bunle"
12631   [(set (pc)
12632         (if_then_else (match_dup 1)
12633                       (label_ref (match_operand 0 "" ""))
12634                       (pc)))]
12635   "TARGET_80387 || TARGET_SSE_MATH"
12636   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12637
12638 (define_expand "bunlt"
12639   [(set (pc)
12640         (if_then_else (match_dup 1)
12641                       (label_ref (match_operand 0 "" ""))
12642                       (pc)))]
12643   "TARGET_80387 || TARGET_SSE_MATH"
12644   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12645
12646 (define_expand "bltgt"
12647   [(set (pc)
12648         (if_then_else (match_dup 1)
12649                       (label_ref (match_operand 0 "" ""))
12650                       (pc)))]
12651   "TARGET_80387 || TARGET_SSE_MATH"
12652   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12653
12654 (define_insn "*jcc_1"
12655   [(set (pc)
12656         (if_then_else (match_operator 1 "ix86_comparison_operator"
12657                                       [(reg FLAGS_REG) (const_int 0)])
12658                       (label_ref (match_operand 0 "" ""))
12659                       (pc)))]
12660   ""
12661   "%+j%C1\t%l0"
12662   [(set_attr "type" "ibr")
12663    (set_attr "modrm" "0")
12664    (set (attr "length")
12665            (if_then_else (and (ge (minus (match_dup 0) (pc))
12666                                   (const_int -126))
12667                               (lt (minus (match_dup 0) (pc))
12668                                   (const_int 128)))
12669              (const_int 2)
12670              (const_int 6)))])
12671
12672 (define_insn "*jcc_2"
12673   [(set (pc)
12674         (if_then_else (match_operator 1 "ix86_comparison_operator"
12675                                       [(reg FLAGS_REG) (const_int 0)])
12676                       (pc)
12677                       (label_ref (match_operand 0 "" ""))))]
12678   ""
12679   "%+j%c1\t%l0"
12680   [(set_attr "type" "ibr")
12681    (set_attr "modrm" "0")
12682    (set (attr "length")
12683            (if_then_else (and (ge (minus (match_dup 0) (pc))
12684                                   (const_int -126))
12685                               (lt (minus (match_dup 0) (pc))
12686                                   (const_int 128)))
12687              (const_int 2)
12688              (const_int 6)))])
12689
12690 ;; In general it is not safe to assume too much about CCmode registers,
12691 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12692 ;; conditions this is safe on x86, so help combine not create
12693 ;;
12694 ;;      seta    %al
12695 ;;      testb   %al, %al
12696 ;;      je      Lfoo
12697
12698 (define_split 
12699   [(set (pc)
12700         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12701                                       [(reg FLAGS_REG) (const_int 0)])
12702                           (const_int 0))
12703                       (label_ref (match_operand 1 "" ""))
12704                       (pc)))]
12705   ""
12706   [(set (pc)
12707         (if_then_else (match_dup 0)
12708                       (label_ref (match_dup 1))
12709                       (pc)))]
12710 {
12711   PUT_MODE (operands[0], VOIDmode);
12712 })
12713   
12714 (define_split 
12715   [(set (pc)
12716         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12717                                       [(reg FLAGS_REG) (const_int 0)])
12718                           (const_int 0))
12719                       (label_ref (match_operand 1 "" ""))
12720                       (pc)))]
12721   ""
12722   [(set (pc)
12723         (if_then_else (match_dup 0)
12724                       (label_ref (match_dup 1))
12725                       (pc)))]
12726 {
12727   rtx new_op0 = copy_rtx (operands[0]);
12728   operands[0] = new_op0;
12729   PUT_MODE (new_op0, VOIDmode);
12730   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12731                                              GET_MODE (XEXP (new_op0, 0))));
12732
12733   /* Make sure that (a) the CCmode we have for the flags is strong
12734      enough for the reversed compare or (b) we have a valid FP compare.  */
12735   if (! ix86_comparison_operator (new_op0, VOIDmode))
12736     FAIL;
12737 })
12738
12739 ;; Define combination compare-and-branch fp compare instructions to use
12740 ;; during early optimization.  Splitting the operation apart early makes
12741 ;; for bad code when we want to reverse the operation.
12742
12743 (define_insn "*fp_jcc_1_mixed"
12744   [(set (pc)
12745         (if_then_else (match_operator 0 "comparison_operator"
12746                         [(match_operand 1 "register_operand" "f#x,x#f")
12747                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12748           (label_ref (match_operand 3 "" ""))
12749           (pc)))
12750    (clobber (reg:CCFP FPSR_REG))
12751    (clobber (reg:CCFP FLAGS_REG))]
12752   "TARGET_MIX_SSE_I387
12753    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12754    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12755    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12756   "#")
12757
12758 (define_insn "*fp_jcc_1_sse"
12759   [(set (pc)
12760         (if_then_else (match_operator 0 "comparison_operator"
12761                         [(match_operand 1 "register_operand" "x")
12762                          (match_operand 2 "nonimmediate_operand" "xm")])
12763           (label_ref (match_operand 3 "" ""))
12764           (pc)))
12765    (clobber (reg:CCFP FPSR_REG))
12766    (clobber (reg:CCFP FLAGS_REG))]
12767   "TARGET_SSE_MATH
12768    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12769    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12770    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12771   "#")
12772
12773 (define_insn "*fp_jcc_1_387"
12774   [(set (pc)
12775         (if_then_else (match_operator 0 "comparison_operator"
12776                         [(match_operand 1 "register_operand" "f")
12777                          (match_operand 2 "register_operand" "f")])
12778           (label_ref (match_operand 3 "" ""))
12779           (pc)))
12780    (clobber (reg:CCFP FPSR_REG))
12781    (clobber (reg:CCFP FLAGS_REG))]
12782   "TARGET_CMOVE && TARGET_80387
12783    && FLOAT_MODE_P (GET_MODE (operands[1]))
12784    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12785    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12786   "#")
12787
12788 (define_insn "*fp_jcc_2_mixed"
12789   [(set (pc)
12790         (if_then_else (match_operator 0 "comparison_operator"
12791                         [(match_operand 1 "register_operand" "f#x,x#f")
12792                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12793           (pc)
12794           (label_ref (match_operand 3 "" ""))))
12795    (clobber (reg:CCFP FPSR_REG))
12796    (clobber (reg:CCFP FLAGS_REG))]
12797   "TARGET_MIX_SSE_I387
12798    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12799    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12800    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12801   "#")
12802
12803 (define_insn "*fp_jcc_2_sse"
12804   [(set (pc)
12805         (if_then_else (match_operator 0 "comparison_operator"
12806                         [(match_operand 1 "register_operand" "x")
12807                          (match_operand 2 "nonimmediate_operand" "xm")])
12808           (pc)
12809           (label_ref (match_operand 3 "" ""))))
12810    (clobber (reg:CCFP FPSR_REG))
12811    (clobber (reg:CCFP FLAGS_REG))]
12812   "TARGET_SSE_MATH
12813    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12814    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12815    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12816   "#")
12817
12818 (define_insn "*fp_jcc_2_387"
12819   [(set (pc)
12820         (if_then_else (match_operator 0 "comparison_operator"
12821                         [(match_operand 1 "register_operand" "f")
12822                          (match_operand 2 "register_operand" "f")])
12823           (pc)
12824           (label_ref (match_operand 3 "" ""))))
12825    (clobber (reg:CCFP FPSR_REG))
12826    (clobber (reg:CCFP FLAGS_REG))]
12827   "TARGET_CMOVE && TARGET_80387
12828    && FLOAT_MODE_P (GET_MODE (operands[1]))
12829    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12830    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12831   "#")
12832
12833 (define_insn "*fp_jcc_3_387"
12834   [(set (pc)
12835         (if_then_else (match_operator 0 "comparison_operator"
12836                         [(match_operand 1 "register_operand" "f")
12837                          (match_operand 2 "nonimmediate_operand" "fm")])
12838           (label_ref (match_operand 3 "" ""))
12839           (pc)))
12840    (clobber (reg:CCFP FPSR_REG))
12841    (clobber (reg:CCFP FLAGS_REG))
12842    (clobber (match_scratch:HI 4 "=a"))]
12843   "TARGET_80387
12844    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12845    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12846    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12847    && SELECT_CC_MODE (GET_CODE (operands[0]),
12848                       operands[1], operands[2]) == CCFPmode
12849    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12850   "#")
12851
12852 (define_insn "*fp_jcc_4_387"
12853   [(set (pc)
12854         (if_then_else (match_operator 0 "comparison_operator"
12855                         [(match_operand 1 "register_operand" "f")
12856                          (match_operand 2 "nonimmediate_operand" "fm")])
12857           (pc)
12858           (label_ref (match_operand 3 "" ""))))
12859    (clobber (reg:CCFP FPSR_REG))
12860    (clobber (reg:CCFP FLAGS_REG))
12861    (clobber (match_scratch:HI 4 "=a"))]
12862   "TARGET_80387
12863    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12864    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12865    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12866    && SELECT_CC_MODE (GET_CODE (operands[0]),
12867                       operands[1], operands[2]) == CCFPmode
12868    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12869   "#")
12870
12871 (define_insn "*fp_jcc_5_387"
12872   [(set (pc)
12873         (if_then_else (match_operator 0 "comparison_operator"
12874                         [(match_operand 1 "register_operand" "f")
12875                          (match_operand 2 "register_operand" "f")])
12876           (label_ref (match_operand 3 "" ""))
12877           (pc)))
12878    (clobber (reg:CCFP FPSR_REG))
12879    (clobber (reg:CCFP FLAGS_REG))
12880    (clobber (match_scratch:HI 4 "=a"))]
12881   "TARGET_80387
12882    && FLOAT_MODE_P (GET_MODE (operands[1]))
12883    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12884    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12885   "#")
12886
12887 (define_insn "*fp_jcc_6_387"
12888   [(set (pc)
12889         (if_then_else (match_operator 0 "comparison_operator"
12890                         [(match_operand 1 "register_operand" "f")
12891                          (match_operand 2 "register_operand" "f")])
12892           (pc)
12893           (label_ref (match_operand 3 "" ""))))
12894    (clobber (reg:CCFP FPSR_REG))
12895    (clobber (reg:CCFP FLAGS_REG))
12896    (clobber (match_scratch:HI 4 "=a"))]
12897   "TARGET_80387
12898    && FLOAT_MODE_P (GET_MODE (operands[1]))
12899    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12900    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12901   "#")
12902
12903 (define_insn "*fp_jcc_7_387"
12904   [(set (pc)
12905         (if_then_else (match_operator 0 "comparison_operator"
12906                         [(match_operand 1 "register_operand" "f")
12907                          (match_operand 2 "const0_operand" "X")])
12908           (label_ref (match_operand 3 "" ""))
12909           (pc)))
12910    (clobber (reg:CCFP FPSR_REG))
12911    (clobber (reg:CCFP FLAGS_REG))
12912    (clobber (match_scratch:HI 4 "=a"))]
12913   "TARGET_80387
12914    && FLOAT_MODE_P (GET_MODE (operands[1]))
12915    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12916    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12917    && SELECT_CC_MODE (GET_CODE (operands[0]),
12918                       operands[1], operands[2]) == CCFPmode
12919    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12920   "#")
12921
12922 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12923 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12924 ;; with a precedence over other operators and is always put in the first
12925 ;; place. Swap condition and operands to match ficom instruction.
12926
12927 (define_insn "*fp_jcc_8<mode>_387"
12928   [(set (pc)
12929         (if_then_else (match_operator 0 "comparison_operator"
12930                         [(match_operator 1 "float_operator"
12931                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12932                            (match_operand 3 "register_operand" "f,f")])
12933           (label_ref (match_operand 4 "" ""))
12934           (pc)))
12935    (clobber (reg:CCFP FPSR_REG))
12936    (clobber (reg:CCFP FLAGS_REG))
12937    (clobber (match_scratch:HI 5 "=a,a"))]
12938   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12939    && FLOAT_MODE_P (GET_MODE (operands[3]))
12940    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12941    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12942    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12943    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12944   "#")
12945
12946 (define_split
12947   [(set (pc)
12948         (if_then_else (match_operator 0 "comparison_operator"
12949                         [(match_operand 1 "register_operand" "")
12950                          (match_operand 2 "nonimmediate_operand" "")])
12951           (match_operand 3 "" "")
12952           (match_operand 4 "" "")))
12953    (clobber (reg:CCFP FPSR_REG))
12954    (clobber (reg:CCFP FLAGS_REG))]
12955   "reload_completed"
12956   [(const_int 0)]
12957 {
12958   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12959                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12960   DONE;
12961 })
12962
12963 (define_split
12964   [(set (pc)
12965         (if_then_else (match_operator 0 "comparison_operator"
12966                         [(match_operand 1 "register_operand" "")
12967                          (match_operand 2 "general_operand" "")])
12968           (match_operand 3 "" "")
12969           (match_operand 4 "" "")))
12970    (clobber (reg:CCFP FPSR_REG))
12971    (clobber (reg:CCFP FLAGS_REG))
12972    (clobber (match_scratch:HI 5 "=a"))]
12973   "reload_completed"
12974   [(const_int 0)]
12975 {
12976   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12977                         operands[3], operands[4], operands[5], NULL_RTX);
12978   DONE;
12979 })
12980
12981 (define_split
12982   [(set (pc)
12983         (if_then_else (match_operator 0 "comparison_operator"
12984                         [(match_operator 1 "float_operator"
12985                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12986                            (match_operand 3 "register_operand" "")])
12987           (match_operand 4 "" "")
12988           (match_operand 5 "" "")))
12989    (clobber (reg:CCFP FPSR_REG))
12990    (clobber (reg:CCFP FLAGS_REG))
12991    (clobber (match_scratch:HI 6 "=a"))]
12992   "reload_completed"
12993   [(const_int 0)]
12994 {
12995   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12996   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12997                         operands[3], operands[7],
12998                         operands[4], operands[5], operands[6], NULL_RTX);
12999   DONE;
13000 })
13001
13002 ;; %%% Kill this when reload knows how to do it.
13003 (define_split
13004   [(set (pc)
13005         (if_then_else (match_operator 0 "comparison_operator"
13006                         [(match_operator 1 "float_operator"
13007                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13008                            (match_operand 3 "register_operand" "")])
13009           (match_operand 4 "" "")
13010           (match_operand 5 "" "")))
13011    (clobber (reg:CCFP FPSR_REG))
13012    (clobber (reg:CCFP FLAGS_REG))
13013    (clobber (match_scratch:HI 6 "=a"))]
13014   "reload_completed"
13015   [(const_int 0)]
13016 {
13017   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13018   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13019   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13020                         operands[3], operands[7],
13021                         operands[4], operands[5], operands[6], operands[2]);
13022   DONE;
13023 })
13024 \f
13025 ;; Unconditional and other jump instructions
13026
13027 (define_insn "jump"
13028   [(set (pc)
13029         (label_ref (match_operand 0 "" "")))]
13030   ""
13031   "jmp\t%l0"
13032   [(set_attr "type" "ibr")
13033    (set (attr "length")
13034            (if_then_else (and (ge (minus (match_dup 0) (pc))
13035                                   (const_int -126))
13036                               (lt (minus (match_dup 0) (pc))
13037                                   (const_int 128)))
13038              (const_int 2)
13039              (const_int 5)))
13040    (set_attr "modrm" "0")])
13041
13042 (define_expand "indirect_jump"
13043   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13044   ""
13045   "")
13046
13047 (define_insn "*indirect_jump"
13048   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13049   "!TARGET_64BIT"
13050   "jmp\t%A0"
13051   [(set_attr "type" "ibr")
13052    (set_attr "length_immediate" "0")])
13053
13054 (define_insn "*indirect_jump_rtx64"
13055   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13056   "TARGET_64BIT"
13057   "jmp\t%A0"
13058   [(set_attr "type" "ibr")
13059    (set_attr "length_immediate" "0")])
13060
13061 (define_expand "tablejump"
13062   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13063               (use (label_ref (match_operand 1 "" "")))])]
13064   ""
13065 {
13066   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13067      relative.  Convert the relative address to an absolute address.  */
13068   if (flag_pic)
13069     {
13070       rtx op0, op1;
13071       enum rtx_code code;
13072
13073       if (TARGET_64BIT)
13074         {
13075           code = PLUS;
13076           op0 = operands[0];
13077           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13078         }
13079       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13080         {
13081           code = PLUS;
13082           op0 = operands[0];
13083           op1 = pic_offset_table_rtx;
13084         }
13085       else
13086         {
13087           code = MINUS;
13088           op0 = pic_offset_table_rtx;
13089           op1 = operands[0];
13090         }
13091
13092       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13093                                          OPTAB_DIRECT);
13094     }
13095 })
13096
13097 (define_insn "*tablejump_1"
13098   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13099    (use (label_ref (match_operand 1 "" "")))]
13100   "!TARGET_64BIT"
13101   "jmp\t%A0"
13102   [(set_attr "type" "ibr")
13103    (set_attr "length_immediate" "0")])
13104
13105 (define_insn "*tablejump_1_rtx64"
13106   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13107    (use (label_ref (match_operand 1 "" "")))]
13108   "TARGET_64BIT"
13109   "jmp\t%A0"
13110   [(set_attr "type" "ibr")
13111    (set_attr "length_immediate" "0")])
13112 \f
13113 ;; Loop instruction
13114 ;;
13115 ;; This is all complicated by the fact that since this is a jump insn
13116 ;; we must handle our own reloads.
13117
13118 (define_expand "doloop_end"
13119   [(use (match_operand 0 "" ""))        ; loop pseudo
13120    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13121    (use (match_operand 2 "" ""))        ; max iterations
13122    (use (match_operand 3 "" ""))        ; loop level 
13123    (use (match_operand 4 "" ""))]       ; label
13124   "!TARGET_64BIT && TARGET_USE_LOOP"
13125   "                                 
13126 {
13127   /* Only use cloop on innermost loops.  */
13128   if (INTVAL (operands[3]) > 1)
13129     FAIL;
13130   if (GET_MODE (operands[0]) != SImode)
13131     FAIL;
13132   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13133                                            operands[0]));
13134   DONE;
13135 }")
13136
13137 (define_insn "doloop_end_internal"
13138   [(set (pc)
13139         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13140                           (const_int 1))
13141                       (label_ref (match_operand 0 "" ""))
13142                       (pc)))
13143    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13144         (plus:SI (match_dup 1)
13145                  (const_int -1)))
13146    (clobber (match_scratch:SI 3 "=X,X,r"))
13147    (clobber (reg:CC FLAGS_REG))]
13148   "!TARGET_64BIT && TARGET_USE_LOOP
13149    && (reload_in_progress || reload_completed
13150        || register_operand (operands[2], VOIDmode))"
13151 {
13152   if (which_alternative != 0)
13153     return "#";
13154   if (get_attr_length (insn) == 2)
13155     return "%+loop\t%l0";
13156   else
13157     return "dec{l}\t%1\;%+jne\t%l0";
13158 }
13159   [(set (attr "length")
13160         (if_then_else (and (eq_attr "alternative" "0")
13161                            (and (ge (minus (match_dup 0) (pc))
13162                                     (const_int -126))
13163                                 (lt (minus (match_dup 0) (pc))
13164                                     (const_int 128))))
13165                       (const_int 2)
13166                       (const_int 16)))
13167    ;; We don't know the type before shorten branches.  Optimistically expect
13168    ;; the loop instruction to match.
13169    (set (attr "type") (const_string "ibr"))])
13170
13171 (define_split
13172   [(set (pc)
13173         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13174                           (const_int 1))
13175                       (match_operand 0 "" "")
13176                       (pc)))
13177    (set (match_dup 1)
13178         (plus:SI (match_dup 1)
13179                  (const_int -1)))
13180    (clobber (match_scratch:SI 2 ""))
13181    (clobber (reg:CC FLAGS_REG))]
13182   "!TARGET_64BIT && TARGET_USE_LOOP
13183    && reload_completed
13184    && REGNO (operands[1]) != 2"
13185   [(parallel [(set (reg:CCZ FLAGS_REG)
13186                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13187                                  (const_int 0)))
13188               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13189    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13190                            (match_dup 0)
13191                            (pc)))]
13192   "")
13193   
13194 (define_split
13195   [(set (pc)
13196         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13197                           (const_int 1))
13198                       (match_operand 0 "" "")
13199                       (pc)))
13200    (set (match_operand:SI 2 "nonimmediate_operand" "")
13201         (plus:SI (match_dup 1)
13202                  (const_int -1)))
13203    (clobber (match_scratch:SI 3 ""))
13204    (clobber (reg:CC FLAGS_REG))]
13205   "!TARGET_64BIT && TARGET_USE_LOOP
13206    && reload_completed
13207    && (! REG_P (operands[2])
13208        || ! rtx_equal_p (operands[1], operands[2]))"
13209   [(set (match_dup 3) (match_dup 1))
13210    (parallel [(set (reg:CCZ FLAGS_REG)
13211                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13212                                 (const_int 0)))
13213               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13214    (set (match_dup 2) (match_dup 3))
13215    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13216                            (match_dup 0)
13217                            (pc)))]
13218   "")
13219
13220 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13221
13222 (define_peephole2
13223   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13224    (set (match_operand:QI 1 "register_operand" "")
13225         (match_operator:QI 2 "ix86_comparison_operator"
13226           [(reg FLAGS_REG) (const_int 0)]))
13227    (set (match_operand 3 "q_regs_operand" "")
13228         (zero_extend (match_dup 1)))]
13229   "(peep2_reg_dead_p (3, operands[1])
13230     || operands_match_p (operands[1], operands[3]))
13231    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13232   [(set (match_dup 4) (match_dup 0))
13233    (set (strict_low_part (match_dup 5))
13234         (match_dup 2))]
13235 {
13236   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13237   operands[5] = gen_lowpart (QImode, operands[3]);
13238   ix86_expand_clear (operands[3]);
13239 })
13240
13241 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13242
13243 (define_peephole2
13244   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13245    (set (match_operand:QI 1 "register_operand" "")
13246         (match_operator:QI 2 "ix86_comparison_operator"
13247           [(reg FLAGS_REG) (const_int 0)]))
13248    (parallel [(set (match_operand 3 "q_regs_operand" "")
13249                    (zero_extend (match_dup 1)))
13250               (clobber (reg:CC FLAGS_REG))])]
13251   "(peep2_reg_dead_p (3, operands[1])
13252     || operands_match_p (operands[1], operands[3]))
13253    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13254   [(set (match_dup 4) (match_dup 0))
13255    (set (strict_low_part (match_dup 5))
13256         (match_dup 2))]
13257 {
13258   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13259   operands[5] = gen_lowpart (QImode, operands[3]);
13260   ix86_expand_clear (operands[3]);
13261 })
13262 \f
13263 ;; Call instructions.
13264
13265 ;; The predicates normally associated with named expanders are not properly
13266 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13267 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13268
13269 ;; Call subroutine returning no value.
13270
13271 (define_expand "call_pop"
13272   [(parallel [(call (match_operand:QI 0 "" "")
13273                     (match_operand:SI 1 "" ""))
13274               (set (reg:SI SP_REG)
13275                    (plus:SI (reg:SI SP_REG)
13276                             (match_operand:SI 3 "" "")))])]
13277   "!TARGET_64BIT"
13278 {
13279   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13280   DONE;
13281 })
13282
13283 (define_insn "*call_pop_0"
13284   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13285          (match_operand:SI 1 "" ""))
13286    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13287                             (match_operand:SI 2 "immediate_operand" "")))]
13288   "!TARGET_64BIT"
13289 {
13290   if (SIBLING_CALL_P (insn))
13291     return "jmp\t%P0";
13292   else
13293     return "call\t%P0";
13294 }
13295   [(set_attr "type" "call")])
13296   
13297 (define_insn "*call_pop_1"
13298   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13299          (match_operand:SI 1 "" ""))
13300    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13301                             (match_operand:SI 2 "immediate_operand" "i")))]
13302   "!TARGET_64BIT"
13303 {
13304   if (constant_call_address_operand (operands[0], Pmode))
13305     {
13306       if (SIBLING_CALL_P (insn))
13307         return "jmp\t%P0";
13308       else
13309         return "call\t%P0";
13310     }
13311   if (SIBLING_CALL_P (insn))
13312     return "jmp\t%A0";
13313   else
13314     return "call\t%A0";
13315 }
13316   [(set_attr "type" "call")])
13317
13318 (define_expand "call"
13319   [(call (match_operand:QI 0 "" "")
13320          (match_operand 1 "" ""))
13321    (use (match_operand 2 "" ""))]
13322   ""
13323 {
13324   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13325   DONE;
13326 })
13327
13328 (define_expand "sibcall"
13329   [(call (match_operand:QI 0 "" "")
13330          (match_operand 1 "" ""))
13331    (use (match_operand 2 "" ""))]
13332   ""
13333 {
13334   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13335   DONE;
13336 })
13337
13338 (define_insn "*call_0"
13339   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13340          (match_operand 1 "" ""))]
13341   ""
13342 {
13343   if (SIBLING_CALL_P (insn))
13344     return "jmp\t%P0";
13345   else
13346     return "call\t%P0";
13347 }
13348   [(set_attr "type" "call")])
13349
13350 (define_insn "*call_1"
13351   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13352          (match_operand 1 "" ""))]
13353   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13354 {
13355   if (constant_call_address_operand (operands[0], Pmode))
13356     return "call\t%P0";
13357   return "call\t%A0";
13358 }
13359   [(set_attr "type" "call")])
13360
13361 (define_insn "*sibcall_1"
13362   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13363          (match_operand 1 "" ""))]
13364   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13365 {
13366   if (constant_call_address_operand (operands[0], Pmode))
13367     return "jmp\t%P0";
13368   return "jmp\t%A0";
13369 }
13370   [(set_attr "type" "call")])
13371
13372 (define_insn "*call_1_rex64"
13373   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13374          (match_operand 1 "" ""))]
13375   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13376 {
13377   if (constant_call_address_operand (operands[0], Pmode))
13378     return "call\t%P0";
13379   return "call\t%A0";
13380 }
13381   [(set_attr "type" "call")])
13382
13383 (define_insn "*sibcall_1_rex64"
13384   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13385          (match_operand 1 "" ""))]
13386   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13387   "jmp\t%P0"
13388   [(set_attr "type" "call")])
13389
13390 (define_insn "*sibcall_1_rex64_v"
13391   [(call (mem:QI (reg:DI 40))
13392          (match_operand 0 "" ""))]
13393   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13394   "jmp\t*%%r11"
13395   [(set_attr "type" "call")])
13396
13397
13398 ;; Call subroutine, returning value in operand 0
13399
13400 (define_expand "call_value_pop"
13401   [(parallel [(set (match_operand 0 "" "")
13402                    (call (match_operand:QI 1 "" "")
13403                          (match_operand:SI 2 "" "")))
13404               (set (reg:SI SP_REG)
13405                    (plus:SI (reg:SI SP_REG)
13406                             (match_operand:SI 4 "" "")))])]
13407   "!TARGET_64BIT"
13408 {
13409   ix86_expand_call (operands[0], operands[1], operands[2],
13410                     operands[3], operands[4], 0);
13411   DONE;
13412 })
13413
13414 (define_expand "call_value"
13415   [(set (match_operand 0 "" "")
13416         (call (match_operand:QI 1 "" "")
13417               (match_operand:SI 2 "" "")))
13418    (use (match_operand:SI 3 "" ""))]
13419   ;; Operand 2 not used on the i386.
13420   ""
13421 {
13422   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13423   DONE;
13424 })
13425
13426 (define_expand "sibcall_value"
13427   [(set (match_operand 0 "" "")
13428         (call (match_operand:QI 1 "" "")
13429               (match_operand:SI 2 "" "")))
13430    (use (match_operand:SI 3 "" ""))]
13431   ;; Operand 2 not used on the i386.
13432   ""
13433 {
13434   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13435   DONE;
13436 })
13437
13438 ;; Call subroutine returning any type.
13439
13440 (define_expand "untyped_call"
13441   [(parallel [(call (match_operand 0 "" "")
13442                     (const_int 0))
13443               (match_operand 1 "" "")
13444               (match_operand 2 "" "")])]
13445   ""
13446 {
13447   int i;
13448
13449   /* In order to give reg-stack an easier job in validating two
13450      coprocessor registers as containing a possible return value,
13451      simply pretend the untyped call returns a complex long double
13452      value.  */
13453
13454   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13455                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13456                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13457                     NULL, 0);
13458
13459   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13460     {
13461       rtx set = XVECEXP (operands[2], 0, i);
13462       emit_move_insn (SET_DEST (set), SET_SRC (set));
13463     }
13464
13465   /* The optimizer does not know that the call sets the function value
13466      registers we stored in the result block.  We avoid problems by
13467      claiming that all hard registers are used and clobbered at this
13468      point.  */
13469   emit_insn (gen_blockage (const0_rtx));
13470
13471   DONE;
13472 })
13473 \f
13474 ;; Prologue and epilogue instructions
13475
13476 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13477 ;; all of memory.  This blocks insns from being moved across this point.
13478
13479 (define_insn "blockage"
13480   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13481   ""
13482   ""
13483   [(set_attr "length" "0")])
13484
13485 ;; Insn emitted into the body of a function to return from a function.
13486 ;; This is only done if the function's epilogue is known to be simple.
13487 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13488
13489 (define_expand "return"
13490   [(return)]
13491   "ix86_can_use_return_insn_p ()"
13492 {
13493   if (current_function_pops_args)
13494     {
13495       rtx popc = GEN_INT (current_function_pops_args);
13496       emit_jump_insn (gen_return_pop_internal (popc));
13497       DONE;
13498     }
13499 })
13500
13501 (define_insn "return_internal"
13502   [(return)]
13503   "reload_completed"
13504   "ret"
13505   [(set_attr "length" "1")
13506    (set_attr "length_immediate" "0")
13507    (set_attr "modrm" "0")])
13508
13509 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13510 ;; instruction Athlon and K8 have.
13511
13512 (define_insn "return_internal_long"
13513   [(return)
13514    (unspec [(const_int 0)] UNSPEC_REP)]
13515   "reload_completed"
13516   "rep {;} ret"
13517   [(set_attr "length" "1")
13518    (set_attr "length_immediate" "0")
13519    (set_attr "prefix_rep" "1")
13520    (set_attr "modrm" "0")])
13521
13522 (define_insn "return_pop_internal"
13523   [(return)
13524    (use (match_operand:SI 0 "const_int_operand" ""))]
13525   "reload_completed"
13526   "ret\t%0"
13527   [(set_attr "length" "3")
13528    (set_attr "length_immediate" "2")
13529    (set_attr "modrm" "0")])
13530
13531 (define_insn "return_indirect_internal"
13532   [(return)
13533    (use (match_operand:SI 0 "register_operand" "r"))]
13534   "reload_completed"
13535   "jmp\t%A0"
13536   [(set_attr "type" "ibr")
13537    (set_attr "length_immediate" "0")])
13538
13539 (define_insn "nop"
13540   [(const_int 0)]
13541   ""
13542   "nop"
13543   [(set_attr "length" "1")
13544    (set_attr "length_immediate" "0")
13545    (set_attr "modrm" "0")])
13546
13547 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13548 ;; branch prediction penalty for the third jump in a 16-byte
13549 ;; block on K8.
13550
13551 (define_insn "align"
13552   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13553   ""
13554 {
13555 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13556   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13557 #else
13558   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13559      The align insn is used to avoid 3 jump instructions in the row to improve
13560      branch prediction and the benefits hardly outweight the cost of extra 8
13561      nops on the average inserted by full alignment pseudo operation.  */
13562 #endif
13563   return "";
13564 }
13565   [(set_attr "length" "16")])
13566
13567 (define_expand "prologue"
13568   [(const_int 1)]
13569   ""
13570   "ix86_expand_prologue (); DONE;")
13571
13572 (define_insn "set_got"
13573   [(set (match_operand:SI 0 "register_operand" "=r")
13574         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13575    (clobber (reg:CC FLAGS_REG))]
13576   "!TARGET_64BIT"
13577   { return output_set_got (operands[0]); }
13578   [(set_attr "type" "multi")
13579    (set_attr "length" "12")])
13580
13581 (define_expand "epilogue"
13582   [(const_int 1)]
13583   ""
13584   "ix86_expand_epilogue (1); DONE;")
13585
13586 (define_expand "sibcall_epilogue"
13587   [(const_int 1)]
13588   ""
13589   "ix86_expand_epilogue (0); DONE;")
13590
13591 (define_expand "eh_return"
13592   [(use (match_operand 0 "register_operand" ""))]
13593   ""
13594 {
13595   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13596
13597   /* Tricky bit: we write the address of the handler to which we will
13598      be returning into someone else's stack frame, one word below the
13599      stack address we wish to restore.  */
13600   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13601   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13602   tmp = gen_rtx_MEM (Pmode, tmp);
13603   emit_move_insn (tmp, ra);
13604
13605   if (Pmode == SImode)
13606     emit_jump_insn (gen_eh_return_si (sa));
13607   else
13608     emit_jump_insn (gen_eh_return_di (sa));
13609   emit_barrier ();
13610   DONE;
13611 })
13612
13613 (define_insn_and_split "eh_return_si"
13614   [(set (pc) 
13615         (unspec [(match_operand:SI 0 "register_operand" "c")]
13616                  UNSPEC_EH_RETURN))]
13617   "!TARGET_64BIT"
13618   "#"
13619   "reload_completed"
13620   [(const_int 1)]
13621   "ix86_expand_epilogue (2); DONE;")
13622
13623 (define_insn_and_split "eh_return_di"
13624   [(set (pc) 
13625         (unspec [(match_operand:DI 0 "register_operand" "c")]
13626                  UNSPEC_EH_RETURN))]
13627   "TARGET_64BIT"
13628   "#"
13629   "reload_completed"
13630   [(const_int 1)]
13631   "ix86_expand_epilogue (2); DONE;")
13632
13633 (define_insn "leave"
13634   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13635    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13636    (clobber (mem:BLK (scratch)))]
13637   "!TARGET_64BIT"
13638   "leave"
13639   [(set_attr "type" "leave")])
13640
13641 (define_insn "leave_rex64"
13642   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13643    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13644    (clobber (mem:BLK (scratch)))]
13645   "TARGET_64BIT"
13646   "leave"
13647   [(set_attr "type" "leave")])
13648 \f
13649 (define_expand "ffssi2"
13650   [(parallel
13651      [(set (match_operand:SI 0 "register_operand" "") 
13652            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13653       (clobber (match_scratch:SI 2 ""))
13654       (clobber (reg:CC FLAGS_REG))])]
13655   ""
13656   "")
13657
13658 (define_insn_and_split "*ffs_cmove"
13659   [(set (match_operand:SI 0 "register_operand" "=r") 
13660         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13661    (clobber (match_scratch:SI 2 "=&r"))
13662    (clobber (reg:CC FLAGS_REG))]
13663   "TARGET_CMOVE"
13664   "#"
13665   "&& reload_completed"
13666   [(set (match_dup 2) (const_int -1))
13667    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13668               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13669    (set (match_dup 0) (if_then_else:SI
13670                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13671                         (match_dup 2)
13672                         (match_dup 0)))
13673    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13674               (clobber (reg:CC FLAGS_REG))])]
13675   "")
13676
13677 (define_insn_and_split "*ffs_no_cmove"
13678   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13679         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13680    (clobber (match_scratch:SI 2 "=&q"))
13681    (clobber (reg:CC FLAGS_REG))]
13682   ""
13683   "#"
13684   "reload_completed"
13685   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13686               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13687    (set (strict_low_part (match_dup 3))
13688         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13689    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13690               (clobber (reg:CC FLAGS_REG))])
13691    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13692               (clobber (reg:CC FLAGS_REG))])
13693    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13694               (clobber (reg:CC FLAGS_REG))])]
13695 {
13696   operands[3] = gen_lowpart (QImode, operands[2]);
13697   ix86_expand_clear (operands[2]);
13698 })
13699
13700 (define_insn "*ffssi_1"
13701   [(set (reg:CCZ FLAGS_REG)
13702         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13703                      (const_int 0)))
13704    (set (match_operand:SI 0 "register_operand" "=r")
13705         (ctz:SI (match_dup 1)))]
13706   ""
13707   "bsf{l}\t{%1, %0|%0, %1}"
13708   [(set_attr "prefix_0f" "1")])
13709
13710 (define_expand "ffsdi2"
13711   [(parallel
13712      [(set (match_operand:DI 0 "register_operand" "") 
13713            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13714       (clobber (match_scratch:DI 2 ""))
13715       (clobber (reg:CC FLAGS_REG))])]
13716   "TARGET_64BIT && TARGET_CMOVE"
13717   "")
13718
13719 (define_insn_and_split "*ffs_rex64"
13720   [(set (match_operand:DI 0 "register_operand" "=r") 
13721         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13722    (clobber (match_scratch:DI 2 "=&r"))
13723    (clobber (reg:CC FLAGS_REG))]
13724   "TARGET_64BIT && TARGET_CMOVE"
13725   "#"
13726   "&& reload_completed"
13727   [(set (match_dup 2) (const_int -1))
13728    (parallel [(set (reg:CCZ FLAGS_REG)
13729                    (compare:CCZ (match_dup 1) (const_int 0)))
13730               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13731    (set (match_dup 0) (if_then_else:DI
13732                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13733                         (match_dup 2)
13734                         (match_dup 0)))
13735    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13736               (clobber (reg:CC FLAGS_REG))])]
13737   "")
13738
13739 (define_insn "*ffsdi_1"
13740   [(set (reg:CCZ FLAGS_REG)
13741         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13742                      (const_int 0)))
13743    (set (match_operand:DI 0 "register_operand" "=r")
13744         (ctz:DI (match_dup 1)))]
13745   "TARGET_64BIT"
13746   "bsf{q}\t{%1, %0|%0, %1}"
13747   [(set_attr "prefix_0f" "1")])
13748
13749 (define_insn "ctzsi2"
13750   [(set (match_operand:SI 0 "register_operand" "=r")
13751         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13752    (clobber (reg:CC FLAGS_REG))]
13753   ""
13754   "bsf{l}\t{%1, %0|%0, %1}"
13755   [(set_attr "prefix_0f" "1")])
13756
13757 (define_insn "ctzdi2"
13758   [(set (match_operand:DI 0 "register_operand" "=r")
13759         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13760    (clobber (reg:CC FLAGS_REG))]
13761   "TARGET_64BIT"
13762   "bsf{q}\t{%1, %0|%0, %1}"
13763   [(set_attr "prefix_0f" "1")])
13764
13765 (define_expand "clzsi2"
13766   [(parallel
13767      [(set (match_operand:SI 0 "register_operand" "")
13768            (minus:SI (const_int 31)
13769                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13770       (clobber (reg:CC FLAGS_REG))])
13771    (parallel
13772      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13773       (clobber (reg:CC FLAGS_REG))])]
13774   ""
13775   "")
13776
13777 (define_insn "*bsr"
13778   [(set (match_operand:SI 0 "register_operand" "=r")
13779         (minus:SI (const_int 31)
13780                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13781    (clobber (reg:CC FLAGS_REG))]
13782   ""
13783   "bsr{l}\t{%1, %0|%0, %1}"
13784   [(set_attr "prefix_0f" "1")])
13785
13786 (define_expand "clzdi2"
13787   [(parallel
13788      [(set (match_operand:DI 0 "register_operand" "")
13789            (minus:DI (const_int 63)
13790                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13791       (clobber (reg:CC FLAGS_REG))])
13792    (parallel
13793      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13794       (clobber (reg:CC FLAGS_REG))])]
13795   "TARGET_64BIT"
13796   "")
13797
13798 (define_insn "*bsr_rex64"
13799   [(set (match_operand:DI 0 "register_operand" "=r")
13800         (minus:DI (const_int 63)
13801                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13802    (clobber (reg:CC FLAGS_REG))]
13803   "TARGET_64BIT"
13804   "bsr{q}\t{%1, %0|%0, %1}"
13805   [(set_attr "prefix_0f" "1")])
13806 \f
13807 ;; Thread-local storage patterns for ELF.
13808 ;;
13809 ;; Note that these code sequences must appear exactly as shown
13810 ;; in order to allow linker relaxation.
13811
13812 (define_insn "*tls_global_dynamic_32_gnu"
13813   [(set (match_operand:SI 0 "register_operand" "=a")
13814         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13815                     (match_operand:SI 2 "tls_symbolic_operand" "")
13816                     (match_operand:SI 3 "call_insn_operand" "")]
13817                     UNSPEC_TLS_GD))
13818    (clobber (match_scratch:SI 4 "=d"))
13819    (clobber (match_scratch:SI 5 "=c"))
13820    (clobber (reg:CC FLAGS_REG))]
13821   "!TARGET_64BIT && TARGET_GNU_TLS"
13822   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13823   [(set_attr "type" "multi")
13824    (set_attr "length" "12")])
13825
13826 (define_insn "*tls_global_dynamic_32_sun"
13827   [(set (match_operand:SI 0 "register_operand" "=a")
13828         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13829                     (match_operand:SI 2 "tls_symbolic_operand" "")
13830                     (match_operand:SI 3 "call_insn_operand" "")]
13831                     UNSPEC_TLS_GD))
13832    (clobber (match_scratch:SI 4 "=d"))
13833    (clobber (match_scratch:SI 5 "=c"))
13834    (clobber (reg:CC FLAGS_REG))]
13835   "!TARGET_64BIT && TARGET_SUN_TLS"
13836   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13837         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13838   [(set_attr "type" "multi")
13839    (set_attr "length" "14")])
13840
13841 (define_expand "tls_global_dynamic_32"
13842   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13843                    (unspec:SI
13844                     [(match_dup 2)
13845                      (match_operand:SI 1 "tls_symbolic_operand" "")
13846                      (match_dup 3)]
13847                     UNSPEC_TLS_GD))
13848               (clobber (match_scratch:SI 4 ""))
13849               (clobber (match_scratch:SI 5 ""))
13850               (clobber (reg:CC FLAGS_REG))])]
13851   ""
13852 {
13853   if (flag_pic)
13854     operands[2] = pic_offset_table_rtx;
13855   else
13856     {
13857       operands[2] = gen_reg_rtx (Pmode);
13858       emit_insn (gen_set_got (operands[2]));
13859     }
13860   operands[3] = ix86_tls_get_addr ();
13861 })
13862
13863 (define_insn "*tls_global_dynamic_64"
13864   [(set (match_operand:DI 0 "register_operand" "=a")
13865         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13866                       (match_operand:DI 3 "" "")))
13867    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13868               UNSPEC_TLS_GD)]
13869   "TARGET_64BIT"
13870   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13871   [(set_attr "type" "multi")
13872    (set_attr "length" "16")])
13873
13874 (define_expand "tls_global_dynamic_64"
13875   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13876                    (call (mem:QI (match_dup 2)) (const_int 0)))
13877               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13878                          UNSPEC_TLS_GD)])]
13879   ""
13880 {
13881   operands[2] = ix86_tls_get_addr ();
13882 })
13883
13884 (define_insn "*tls_local_dynamic_base_32_gnu"
13885   [(set (match_operand:SI 0 "register_operand" "=a")
13886         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13887                     (match_operand:SI 2 "call_insn_operand" "")]
13888                    UNSPEC_TLS_LD_BASE))
13889    (clobber (match_scratch:SI 3 "=d"))
13890    (clobber (match_scratch:SI 4 "=c"))
13891    (clobber (reg:CC FLAGS_REG))]
13892   "!TARGET_64BIT && TARGET_GNU_TLS"
13893   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13894   [(set_attr "type" "multi")
13895    (set_attr "length" "11")])
13896
13897 (define_insn "*tls_local_dynamic_base_32_sun"
13898   [(set (match_operand:SI 0 "register_operand" "=a")
13899         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13900                     (match_operand:SI 2 "call_insn_operand" "")]
13901                    UNSPEC_TLS_LD_BASE))
13902    (clobber (match_scratch:SI 3 "=d"))
13903    (clobber (match_scratch:SI 4 "=c"))
13904    (clobber (reg:CC FLAGS_REG))]
13905   "!TARGET_64BIT && TARGET_SUN_TLS"
13906   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13907         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13908   [(set_attr "type" "multi")
13909    (set_attr "length" "13")])
13910
13911 (define_expand "tls_local_dynamic_base_32"
13912   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13913                    (unspec:SI [(match_dup 1) (match_dup 2)]
13914                               UNSPEC_TLS_LD_BASE))
13915               (clobber (match_scratch:SI 3 ""))
13916               (clobber (match_scratch:SI 4 ""))
13917               (clobber (reg:CC FLAGS_REG))])]
13918   ""
13919 {
13920   if (flag_pic)
13921     operands[1] = pic_offset_table_rtx;
13922   else
13923     {
13924       operands[1] = gen_reg_rtx (Pmode);
13925       emit_insn (gen_set_got (operands[1]));
13926     }
13927   operands[2] = ix86_tls_get_addr ();
13928 })
13929
13930 (define_insn "*tls_local_dynamic_base_64"
13931   [(set (match_operand:DI 0 "register_operand" "=a")
13932         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13933                       (match_operand:DI 2 "" "")))
13934    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13935   "TARGET_64BIT"
13936   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13937   [(set_attr "type" "multi")
13938    (set_attr "length" "12")])
13939
13940 (define_expand "tls_local_dynamic_base_64"
13941   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13942                    (call (mem:QI (match_dup 1)) (const_int 0)))
13943               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13944   ""
13945 {
13946   operands[1] = ix86_tls_get_addr ();
13947 })
13948
13949 ;; Local dynamic of a single variable is a lose.  Show combine how
13950 ;; to convert that back to global dynamic.
13951
13952 (define_insn_and_split "*tls_local_dynamic_32_once"
13953   [(set (match_operand:SI 0 "register_operand" "=a")
13954         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13955                              (match_operand:SI 2 "call_insn_operand" "")]
13956                             UNSPEC_TLS_LD_BASE)
13957                  (const:SI (unspec:SI
13958                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13959                             UNSPEC_DTPOFF))))
13960    (clobber (match_scratch:SI 4 "=d"))
13961    (clobber (match_scratch:SI 5 "=c"))
13962    (clobber (reg:CC FLAGS_REG))]
13963   ""
13964   "#"
13965   ""
13966   [(parallel [(set (match_dup 0)
13967                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13968                               UNSPEC_TLS_GD))
13969               (clobber (match_dup 4))
13970               (clobber (match_dup 5))
13971               (clobber (reg:CC FLAGS_REG))])]
13972   "")
13973
13974 ;; Load and add the thread base pointer from %gs:0.
13975
13976 (define_insn "*load_tp_si"
13977   [(set (match_operand:SI 0 "register_operand" "=r")
13978         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13979   "!TARGET_64BIT"
13980   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13981   [(set_attr "type" "imov")
13982    (set_attr "modrm" "0")
13983    (set_attr "length" "7")
13984    (set_attr "memory" "load")
13985    (set_attr "imm_disp" "false")])
13986
13987 (define_insn "*add_tp_si"
13988   [(set (match_operand:SI 0 "register_operand" "=r")
13989         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13990                  (match_operand:SI 1 "register_operand" "0")))
13991    (clobber (reg:CC FLAGS_REG))]
13992   "!TARGET_64BIT"
13993   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13994   [(set_attr "type" "alu")
13995    (set_attr "modrm" "0")
13996    (set_attr "length" "7")
13997    (set_attr "memory" "load")
13998    (set_attr "imm_disp" "false")])
13999
14000 (define_insn "*load_tp_di"
14001   [(set (match_operand:DI 0 "register_operand" "=r")
14002         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14003   "TARGET_64BIT"
14004   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14005   [(set_attr "type" "imov")
14006    (set_attr "modrm" "0")
14007    (set_attr "length" "7")
14008    (set_attr "memory" "load")
14009    (set_attr "imm_disp" "false")])
14010
14011 (define_insn "*add_tp_di"
14012   [(set (match_operand:DI 0 "register_operand" "=r")
14013         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14014                  (match_operand:DI 1 "register_operand" "0")))
14015    (clobber (reg:CC FLAGS_REG))]
14016   "TARGET_64BIT"
14017   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14018   [(set_attr "type" "alu")
14019    (set_attr "modrm" "0")
14020    (set_attr "length" "7")
14021    (set_attr "memory" "load")
14022    (set_attr "imm_disp" "false")])
14023 \f
14024 ;; These patterns match the binary 387 instructions for addM3, subM3,
14025 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14026 ;; SFmode.  The first is the normal insn, the second the same insn but
14027 ;; with one operand a conversion, and the third the same insn but with
14028 ;; the other operand a conversion.  The conversion may be SFmode or
14029 ;; SImode if the target mode DFmode, but only SImode if the target mode
14030 ;; is SFmode.
14031
14032 ;; Gcc is slightly more smart about handling normal two address instructions
14033 ;; so use special patterns for add and mull.
14034
14035 (define_insn "*fop_sf_comm_mixed"
14036   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14037         (match_operator:SF 3 "binary_fp_operator"
14038                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14039                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14040   "TARGET_MIX_SSE_I387
14041    && COMMUTATIVE_ARITH_P (operands[3])
14042    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14043   "* return output_387_binary_op (insn, operands);"
14044   [(set (attr "type") 
14045         (if_then_else (eq_attr "alternative" "1")
14046            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14047               (const_string "ssemul")
14048               (const_string "sseadd"))
14049            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14050               (const_string "fmul")
14051               (const_string "fop"))))
14052    (set_attr "mode" "SF")])
14053
14054 (define_insn "*fop_sf_comm_sse"
14055   [(set (match_operand:SF 0 "register_operand" "=x")
14056         (match_operator:SF 3 "binary_fp_operator"
14057                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14058                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14059   "TARGET_SSE_MATH
14060    && COMMUTATIVE_ARITH_P (operands[3])
14061    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14062   "* return output_387_binary_op (insn, operands);"
14063   [(set (attr "type") 
14064         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14065            (const_string "ssemul")
14066            (const_string "sseadd")))
14067    (set_attr "mode" "SF")])
14068
14069 (define_insn "*fop_sf_comm_i387"
14070   [(set (match_operand:SF 0 "register_operand" "=f")
14071         (match_operator:SF 3 "binary_fp_operator"
14072                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14073                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14074   "TARGET_80387
14075    && COMMUTATIVE_ARITH_P (operands[3])
14076    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14077   "* return output_387_binary_op (insn, operands);"
14078   [(set (attr "type") 
14079         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14080            (const_string "fmul")
14081            (const_string "fop")))
14082    (set_attr "mode" "SF")])
14083
14084 (define_insn "*fop_sf_1_mixed"
14085   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14086         (match_operator:SF 3 "binary_fp_operator"
14087                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14088                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14089   "TARGET_MIX_SSE_I387
14090    && !COMMUTATIVE_ARITH_P (operands[3])
14091    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14092   "* return output_387_binary_op (insn, operands);"
14093   [(set (attr "type") 
14094         (cond [(and (eq_attr "alternative" "2")
14095                     (match_operand:SF 3 "mult_operator" ""))
14096                  (const_string "ssemul")
14097                (and (eq_attr "alternative" "2")
14098                     (match_operand:SF 3 "div_operator" ""))
14099                  (const_string "ssediv")
14100                (eq_attr "alternative" "2")
14101                  (const_string "sseadd")
14102                (match_operand:SF 3 "mult_operator" "") 
14103                  (const_string "fmul")
14104                (match_operand:SF 3 "div_operator" "") 
14105                  (const_string "fdiv")
14106               ]
14107               (const_string "fop")))
14108    (set_attr "mode" "SF")])
14109
14110 (define_insn "*fop_sf_1_sse"
14111   [(set (match_operand:SF 0 "register_operand" "=x")
14112         (match_operator:SF 3 "binary_fp_operator"
14113                         [(match_operand:SF 1 "register_operand" "0")
14114                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14115   "TARGET_SSE_MATH
14116    && !COMMUTATIVE_ARITH_P (operands[3])"
14117   "* return output_387_binary_op (insn, operands);"
14118   [(set (attr "type") 
14119         (cond [(match_operand:SF 3 "mult_operator" "")
14120                  (const_string "ssemul")
14121                (match_operand:SF 3 "div_operator" "")
14122                  (const_string "ssediv")
14123               ]
14124               (const_string "sseadd")))
14125    (set_attr "mode" "SF")])
14126
14127 ;; This pattern is not fully shadowed by the pattern above.
14128 (define_insn "*fop_sf_1_i387"
14129   [(set (match_operand:SF 0 "register_operand" "=f,f")
14130         (match_operator:SF 3 "binary_fp_operator"
14131                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14132                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14133   "TARGET_80387 && !TARGET_SSE_MATH
14134    && !COMMUTATIVE_ARITH_P (operands[3])
14135    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14136   "* return output_387_binary_op (insn, operands);"
14137   [(set (attr "type") 
14138         (cond [(match_operand:SF 3 "mult_operator" "") 
14139                  (const_string "fmul")
14140                (match_operand:SF 3 "div_operator" "") 
14141                  (const_string "fdiv")
14142               ]
14143               (const_string "fop")))
14144    (set_attr "mode" "SF")])
14145
14146 ;; ??? Add SSE splitters for these!
14147 (define_insn "*fop_sf_2<mode>_i387"
14148   [(set (match_operand:SF 0 "register_operand" "=f,f")
14149         (match_operator:SF 3 "binary_fp_operator"
14150           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14151            (match_operand:SF 2 "register_operand" "0,0")]))]
14152   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14153   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14154   [(set (attr "type") 
14155         (cond [(match_operand:SF 3 "mult_operator" "") 
14156                  (const_string "fmul")
14157                (match_operand:SF 3 "div_operator" "") 
14158                  (const_string "fdiv")
14159               ]
14160               (const_string "fop")))
14161    (set_attr "fp_int_src" "true")
14162    (set_attr "mode" "<MODE>")])
14163
14164 (define_insn "*fop_sf_3<mode>_i387"
14165   [(set (match_operand:SF 0 "register_operand" "=f,f")
14166         (match_operator:SF 3 "binary_fp_operator"
14167           [(match_operand:SF 1 "register_operand" "0,0")
14168            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14169   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14170   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14171   [(set (attr "type") 
14172         (cond [(match_operand:SF 3 "mult_operator" "") 
14173                  (const_string "fmul")
14174                (match_operand:SF 3 "div_operator" "") 
14175                  (const_string "fdiv")
14176               ]
14177               (const_string "fop")))
14178    (set_attr "fp_int_src" "true")
14179    (set_attr "mode" "<MODE>")])
14180
14181 (define_insn "*fop_df_comm_mixed"
14182   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14183         (match_operator:DF 3 "binary_fp_operator"
14184                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14185                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14186   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14187    && COMMUTATIVE_ARITH_P (operands[3])
14188    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14189   "* return output_387_binary_op (insn, operands);"
14190   [(set (attr "type") 
14191         (if_then_else (eq_attr "alternative" "1")
14192            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14193               (const_string "ssemul")
14194               (const_string "sseadd"))
14195            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14196               (const_string "fmul")
14197               (const_string "fop"))))
14198    (set_attr "mode" "DF")])
14199
14200 (define_insn "*fop_df_comm_sse"
14201   [(set (match_operand:DF 0 "register_operand" "=Y")
14202         (match_operator:DF 3 "binary_fp_operator"
14203                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14204                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14205   "TARGET_SSE2 && TARGET_SSE_MATH
14206    && COMMUTATIVE_ARITH_P (operands[3])
14207    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14208   "* return output_387_binary_op (insn, operands);"
14209   [(set (attr "type") 
14210         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14211            (const_string "ssemul")
14212            (const_string "sseadd")))
14213    (set_attr "mode" "DF")])
14214
14215 (define_insn "*fop_df_comm_i387"
14216   [(set (match_operand:DF 0 "register_operand" "=f")
14217         (match_operator:DF 3 "binary_fp_operator"
14218                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14219                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14220   "TARGET_80387
14221    && COMMUTATIVE_ARITH_P (operands[3])
14222    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14223   "* return output_387_binary_op (insn, operands);"
14224   [(set (attr "type") 
14225         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14226            (const_string "fmul")
14227            (const_string "fop")))
14228    (set_attr "mode" "DF")])
14229
14230 (define_insn "*fop_df_1_mixed"
14231   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14232         (match_operator:DF 3 "binary_fp_operator"
14233                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14234                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14235   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14236    && !COMMUTATIVE_ARITH_P (operands[3])
14237    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14238   "* return output_387_binary_op (insn, operands);"
14239   [(set (attr "type") 
14240         (cond [(and (eq_attr "alternative" "2")
14241                     (match_operand:SF 3 "mult_operator" ""))
14242                  (const_string "ssemul")
14243                (and (eq_attr "alternative" "2")
14244                     (match_operand:SF 3 "div_operator" ""))
14245                  (const_string "ssediv")
14246                (eq_attr "alternative" "2")
14247                  (const_string "sseadd")
14248                (match_operand:DF 3 "mult_operator" "") 
14249                  (const_string "fmul")
14250                (match_operand:DF 3 "div_operator" "") 
14251                  (const_string "fdiv")
14252               ]
14253               (const_string "fop")))
14254    (set_attr "mode" "DF")])
14255
14256 (define_insn "*fop_df_1_sse"
14257   [(set (match_operand:DF 0 "register_operand" "=Y")
14258         (match_operator:DF 3 "binary_fp_operator"
14259                         [(match_operand:DF 1 "register_operand" "0")
14260                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14261   "TARGET_SSE2 && TARGET_SSE_MATH
14262    && !COMMUTATIVE_ARITH_P (operands[3])"
14263   "* return output_387_binary_op (insn, operands);"
14264   [(set_attr "mode" "DF")
14265    (set (attr "type") 
14266         (cond [(match_operand:SF 3 "mult_operator" "")
14267                  (const_string "ssemul")
14268                (match_operand:SF 3 "div_operator" "")
14269                  (const_string "ssediv")
14270               ]
14271               (const_string "sseadd")))])
14272
14273 ;; This pattern is not fully shadowed by the pattern above.
14274 (define_insn "*fop_df_1_i387"
14275   [(set (match_operand:DF 0 "register_operand" "=f,f")
14276         (match_operator:DF 3 "binary_fp_operator"
14277                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14278                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14279   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14280    && !COMMUTATIVE_ARITH_P (operands[3])
14281    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14282   "* return output_387_binary_op (insn, operands);"
14283   [(set (attr "type") 
14284         (cond [(match_operand:DF 3 "mult_operator" "") 
14285                  (const_string "fmul")
14286                (match_operand:DF 3 "div_operator" "")
14287                  (const_string "fdiv")
14288               ]
14289               (const_string "fop")))
14290    (set_attr "mode" "DF")])
14291
14292 ;; ??? Add SSE splitters for these!
14293 (define_insn "*fop_df_2<mode>_i387"
14294   [(set (match_operand:DF 0 "register_operand" "=f,f")
14295         (match_operator:DF 3 "binary_fp_operator"
14296            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14297             (match_operand:DF 2 "register_operand" "0,0")]))]
14298   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14299    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14300   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14301   [(set (attr "type") 
14302         (cond [(match_operand:DF 3 "mult_operator" "") 
14303                  (const_string "fmul")
14304                (match_operand:DF 3 "div_operator" "") 
14305                  (const_string "fdiv")
14306               ]
14307               (const_string "fop")))
14308    (set_attr "fp_int_src" "true")
14309    (set_attr "mode" "<MODE>")])
14310
14311 (define_insn "*fop_df_3<mode>_i387"
14312   [(set (match_operand:DF 0 "register_operand" "=f,f")
14313         (match_operator:DF 3 "binary_fp_operator"
14314            [(match_operand:DF 1 "register_operand" "0,0")
14315             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14316   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14317    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14318   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14319   [(set (attr "type") 
14320         (cond [(match_operand:DF 3 "mult_operator" "") 
14321                  (const_string "fmul")
14322                (match_operand:DF 3 "div_operator" "") 
14323                  (const_string "fdiv")
14324               ]
14325               (const_string "fop")))
14326    (set_attr "fp_int_src" "true")
14327    (set_attr "mode" "<MODE>")])
14328
14329 (define_insn "*fop_df_4_i387"
14330   [(set (match_operand:DF 0 "register_operand" "=f,f")
14331         (match_operator:DF 3 "binary_fp_operator"
14332            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14333             (match_operand:DF 2 "register_operand" "0,f")]))]
14334   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14335    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14336   "* return output_387_binary_op (insn, operands);"
14337   [(set (attr "type") 
14338         (cond [(match_operand:DF 3 "mult_operator" "") 
14339                  (const_string "fmul")
14340                (match_operand:DF 3 "div_operator" "") 
14341                  (const_string "fdiv")
14342               ]
14343               (const_string "fop")))
14344    (set_attr "mode" "SF")])
14345
14346 (define_insn "*fop_df_5_i387"
14347   [(set (match_operand:DF 0 "register_operand" "=f,f")
14348         (match_operator:DF 3 "binary_fp_operator"
14349           [(match_operand:DF 1 "register_operand" "0,f")
14350            (float_extend:DF
14351             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14352   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14353   "* return output_387_binary_op (insn, operands);"
14354   [(set (attr "type") 
14355         (cond [(match_operand:DF 3 "mult_operator" "") 
14356                  (const_string "fmul")
14357                (match_operand:DF 3 "div_operator" "") 
14358                  (const_string "fdiv")
14359               ]
14360               (const_string "fop")))
14361    (set_attr "mode" "SF")])
14362
14363 (define_insn "*fop_df_6_i387"
14364   [(set (match_operand:DF 0 "register_operand" "=f,f")
14365         (match_operator:DF 3 "binary_fp_operator"
14366           [(float_extend:DF
14367             (match_operand:SF 1 "register_operand" "0,f"))
14368            (float_extend:DF
14369             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14370   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14371   "* return output_387_binary_op (insn, operands);"
14372   [(set (attr "type") 
14373         (cond [(match_operand:DF 3 "mult_operator" "") 
14374                  (const_string "fmul")
14375                (match_operand:DF 3 "div_operator" "") 
14376                  (const_string "fdiv")
14377               ]
14378               (const_string "fop")))
14379    (set_attr "mode" "SF")])
14380
14381 (define_insn "*fop_xf_comm_i387"
14382   [(set (match_operand:XF 0 "register_operand" "=f")
14383         (match_operator:XF 3 "binary_fp_operator"
14384                         [(match_operand:XF 1 "register_operand" "%0")
14385                          (match_operand:XF 2 "register_operand" "f")]))]
14386   "TARGET_80387
14387    && COMMUTATIVE_ARITH_P (operands[3])"
14388   "* return output_387_binary_op (insn, operands);"
14389   [(set (attr "type") 
14390         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14391            (const_string "fmul")
14392            (const_string "fop")))
14393    (set_attr "mode" "XF")])
14394
14395 (define_insn "*fop_xf_1_i387"
14396   [(set (match_operand:XF 0 "register_operand" "=f,f")
14397         (match_operator:XF 3 "binary_fp_operator"
14398                         [(match_operand:XF 1 "register_operand" "0,f")
14399                          (match_operand:XF 2 "register_operand" "f,0")]))]
14400   "TARGET_80387
14401    && !COMMUTATIVE_ARITH_P (operands[3])"
14402   "* return output_387_binary_op (insn, operands);"
14403   [(set (attr "type") 
14404         (cond [(match_operand:XF 3 "mult_operator" "") 
14405                  (const_string "fmul")
14406                (match_operand:XF 3 "div_operator" "") 
14407                  (const_string "fdiv")
14408               ]
14409               (const_string "fop")))
14410    (set_attr "mode" "XF")])
14411
14412 (define_insn "*fop_xf_2<mode>_i387"
14413   [(set (match_operand:XF 0 "register_operand" "=f,f")
14414         (match_operator:XF 3 "binary_fp_operator"
14415            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14416             (match_operand:XF 2 "register_operand" "0,0")]))]
14417   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14418   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14419   [(set (attr "type") 
14420         (cond [(match_operand:XF 3 "mult_operator" "") 
14421                  (const_string "fmul")
14422                (match_operand:XF 3 "div_operator" "") 
14423                  (const_string "fdiv")
14424               ]
14425               (const_string "fop")))
14426    (set_attr "fp_int_src" "true")
14427    (set_attr "mode" "<MODE>")])
14428
14429 (define_insn "*fop_xf_3<mode>_i387"
14430   [(set (match_operand:XF 0 "register_operand" "=f,f")
14431         (match_operator:XF 3 "binary_fp_operator"
14432           [(match_operand:XF 1 "register_operand" "0,0")
14433            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14434   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14435   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14436   [(set (attr "type") 
14437         (cond [(match_operand:XF 3 "mult_operator" "") 
14438                  (const_string "fmul")
14439                (match_operand:XF 3 "div_operator" "") 
14440                  (const_string "fdiv")
14441               ]
14442               (const_string "fop")))
14443    (set_attr "fp_int_src" "true")
14444    (set_attr "mode" "<MODE>")])
14445
14446 (define_insn "*fop_xf_4_i387"
14447   [(set (match_operand:XF 0 "register_operand" "=f,f")
14448         (match_operator:XF 3 "binary_fp_operator"
14449            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14450             (match_operand:XF 2 "register_operand" "0,f")]))]
14451   "TARGET_80387"
14452   "* return output_387_binary_op (insn, operands);"
14453   [(set (attr "type") 
14454         (cond [(match_operand:XF 3 "mult_operator" "") 
14455                  (const_string "fmul")
14456                (match_operand:XF 3 "div_operator" "") 
14457                  (const_string "fdiv")
14458               ]
14459               (const_string "fop")))
14460    (set_attr "mode" "SF")])
14461
14462 (define_insn "*fop_xf_5_i387"
14463   [(set (match_operand:XF 0 "register_operand" "=f,f")
14464         (match_operator:XF 3 "binary_fp_operator"
14465           [(match_operand:XF 1 "register_operand" "0,f")
14466            (float_extend:XF
14467             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14468   "TARGET_80387"
14469   "* return output_387_binary_op (insn, operands);"
14470   [(set (attr "type") 
14471         (cond [(match_operand:XF 3 "mult_operator" "") 
14472                  (const_string "fmul")
14473                (match_operand:XF 3 "div_operator" "") 
14474                  (const_string "fdiv")
14475               ]
14476               (const_string "fop")))
14477    (set_attr "mode" "SF")])
14478
14479 (define_insn "*fop_xf_6_i387"
14480   [(set (match_operand:XF 0 "register_operand" "=f,f")
14481         (match_operator:XF 3 "binary_fp_operator"
14482           [(float_extend:XF
14483             (match_operand 1 "register_operand" "0,f"))
14484            (float_extend:XF
14485             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14486   "TARGET_80387"
14487   "* return output_387_binary_op (insn, operands);"
14488   [(set (attr "type") 
14489         (cond [(match_operand:XF 3 "mult_operator" "") 
14490                  (const_string "fmul")
14491                (match_operand:XF 3 "div_operator" "") 
14492                  (const_string "fdiv")
14493               ]
14494               (const_string "fop")))
14495    (set_attr "mode" "SF")])
14496
14497 (define_split
14498   [(set (match_operand 0 "register_operand" "")
14499         (match_operator 3 "binary_fp_operator"
14500            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14501             (match_operand 2 "register_operand" "")]))]
14502   "TARGET_80387 && reload_completed
14503    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14504   [(const_int 0)]
14505
14506   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14507   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14508   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14509                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14510                                           GET_MODE (operands[3]),
14511                                           operands[4],
14512                                           operands[2])));
14513   ix86_free_from_memory (GET_MODE (operands[1]));
14514   DONE;
14515 })
14516
14517 (define_split
14518   [(set (match_operand 0 "register_operand" "")
14519         (match_operator 3 "binary_fp_operator"
14520            [(match_operand 1 "register_operand" "")
14521             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14522   "TARGET_80387 && reload_completed
14523    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14524   [(const_int 0)]
14525 {
14526   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14527   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14528   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14529                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14530                                           GET_MODE (operands[3]),
14531                                           operands[1],
14532                                           operands[4])));
14533   ix86_free_from_memory (GET_MODE (operands[2]));
14534   DONE;
14535 })
14536 \f
14537 ;; FPU special functions.
14538
14539 (define_expand "sqrtsf2"
14540   [(set (match_operand:SF 0 "register_operand" "")
14541         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14542   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14543 {
14544   if (!TARGET_SSE_MATH)
14545     operands[1] = force_reg (SFmode, operands[1]);
14546 })
14547
14548 (define_insn "*sqrtsf2_mixed"
14549   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14550         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14551   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14552   "@
14553    fsqrt
14554    sqrtss\t{%1, %0|%0, %1}"
14555   [(set_attr "type" "fpspc,sse")
14556    (set_attr "mode" "SF,SF")
14557    (set_attr "athlon_decode" "direct,*")])
14558
14559 (define_insn "*sqrtsf2_sse"
14560   [(set (match_operand:SF 0 "register_operand" "=x")
14561         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14562   "TARGET_SSE_MATH"
14563   "sqrtss\t{%1, %0|%0, %1}"
14564   [(set_attr "type" "sse")
14565    (set_attr "mode" "SF")
14566    (set_attr "athlon_decode" "*")])
14567
14568 (define_insn "*sqrtsf2_i387"
14569   [(set (match_operand:SF 0 "register_operand" "=f")
14570         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14571   "TARGET_USE_FANCY_MATH_387"
14572   "fsqrt"
14573   [(set_attr "type" "fpspc")
14574    (set_attr "mode" "SF")
14575    (set_attr "athlon_decode" "direct")])
14576
14577 (define_expand "sqrtdf2"
14578   [(set (match_operand:DF 0 "register_operand" "")
14579         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14580   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14581 {
14582   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14583     operands[1] = force_reg (DFmode, operands[1]);
14584 })
14585
14586 (define_insn "*sqrtdf2_mixed"
14587   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14588         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14589   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14590   "@
14591    fsqrt
14592    sqrtsd\t{%1, %0|%0, %1}"
14593   [(set_attr "type" "fpspc,sse")
14594    (set_attr "mode" "DF,DF")
14595    (set_attr "athlon_decode" "direct,*")])
14596
14597 (define_insn "*sqrtdf2_sse"
14598   [(set (match_operand:DF 0 "register_operand" "=Y")
14599         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14600   "TARGET_SSE2 && TARGET_SSE_MATH"
14601   "sqrtsd\t{%1, %0|%0, %1}"
14602   [(set_attr "type" "sse")
14603    (set_attr "mode" "DF")
14604    (set_attr "athlon_decode" "*")])
14605
14606 (define_insn "*sqrtdf2_i387"
14607   [(set (match_operand:DF 0 "register_operand" "=f")
14608         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14609   "TARGET_USE_FANCY_MATH_387"
14610   "fsqrt"
14611   [(set_attr "type" "fpspc")
14612    (set_attr "mode" "DF")
14613    (set_attr "athlon_decode" "direct")])
14614
14615 (define_insn "*sqrtextendsfdf2_i387"
14616   [(set (match_operand:DF 0 "register_operand" "=f")
14617         (sqrt:DF (float_extend:DF
14618                   (match_operand:SF 1 "register_operand" "0"))))]
14619   "TARGET_USE_FANCY_MATH_387
14620    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14621   "fsqrt"
14622   [(set_attr "type" "fpspc")
14623    (set_attr "mode" "DF")
14624    (set_attr "athlon_decode" "direct")])
14625
14626 (define_insn "sqrtxf2"
14627   [(set (match_operand:XF 0 "register_operand" "=f")
14628         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14629   "TARGET_USE_FANCY_MATH_387 
14630    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14631   "fsqrt"
14632   [(set_attr "type" "fpspc")
14633    (set_attr "mode" "XF")
14634    (set_attr "athlon_decode" "direct")])
14635
14636 (define_insn "*sqrtextendsfxf2_i387"
14637   [(set (match_operand:XF 0 "register_operand" "=f")
14638         (sqrt:XF (float_extend:XF
14639                   (match_operand:SF 1 "register_operand" "0"))))]
14640   "TARGET_USE_FANCY_MATH_387"
14641   "fsqrt"
14642   [(set_attr "type" "fpspc")
14643    (set_attr "mode" "XF")
14644    (set_attr "athlon_decode" "direct")])
14645
14646 (define_insn "*sqrtextenddfxf2_i387"
14647   [(set (match_operand:XF 0 "register_operand" "=f")
14648         (sqrt:XF (float_extend:XF
14649                   (match_operand:DF 1 "register_operand" "0"))))]
14650   "TARGET_USE_FANCY_MATH_387"
14651   "fsqrt"
14652   [(set_attr "type" "fpspc")
14653    (set_attr "mode" "XF")
14654    (set_attr "athlon_decode" "direct")])
14655
14656 (define_insn "fpremxf4"
14657   [(set (match_operand:XF 0 "register_operand" "=f")
14658         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14659                     (match_operand:XF 3 "register_operand" "1")]
14660                    UNSPEC_FPREM_F))
14661    (set (match_operand:XF 1 "register_operand" "=u")
14662         (unspec:XF [(match_dup 2) (match_dup 3)]
14663                    UNSPEC_FPREM_U))
14664    (set (reg:CCFP FPSR_REG)
14665         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14666   "TARGET_USE_FANCY_MATH_387
14667    && flag_unsafe_math_optimizations"
14668   "fprem"
14669   [(set_attr "type" "fpspc")
14670    (set_attr "mode" "XF")])
14671
14672 (define_expand "fmodsf3"
14673   [(use (match_operand:SF 0 "register_operand" ""))
14674    (use (match_operand:SF 1 "register_operand" ""))
14675    (use (match_operand:SF 2 "register_operand" ""))]
14676   "TARGET_USE_FANCY_MATH_387
14677    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14678    && flag_unsafe_math_optimizations"
14679 {
14680   rtx label = gen_label_rtx ();
14681
14682   rtx op1 = gen_reg_rtx (XFmode);
14683   rtx op2 = gen_reg_rtx (XFmode);
14684
14685   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14686   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14687
14688   emit_label (label);
14689
14690   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14691   ix86_emit_fp_unordered_jump (label);
14692
14693   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14694   DONE;
14695 })
14696
14697 (define_expand "fmoddf3"
14698   [(use (match_operand:DF 0 "register_operand" ""))
14699    (use (match_operand:DF 1 "register_operand" ""))
14700    (use (match_operand:DF 2 "register_operand" ""))]
14701   "TARGET_USE_FANCY_MATH_387
14702    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14703    && flag_unsafe_math_optimizations"
14704 {
14705   rtx label = gen_label_rtx ();
14706
14707   rtx op1 = gen_reg_rtx (XFmode);
14708   rtx op2 = gen_reg_rtx (XFmode);
14709
14710   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14711   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14712
14713   emit_label (label);
14714
14715   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14716   ix86_emit_fp_unordered_jump (label);
14717
14718   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14719   DONE;
14720 })
14721
14722 (define_expand "fmodxf3"
14723   [(use (match_operand:XF 0 "register_operand" ""))
14724    (use (match_operand:XF 1 "register_operand" ""))
14725    (use (match_operand:XF 2 "register_operand" ""))]
14726   "TARGET_USE_FANCY_MATH_387
14727    && flag_unsafe_math_optimizations"
14728 {
14729   rtx label = gen_label_rtx ();
14730
14731   emit_label (label);
14732
14733   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14734                            operands[1], operands[2]));
14735   ix86_emit_fp_unordered_jump (label);
14736
14737   emit_move_insn (operands[0], operands[1]);
14738   DONE;
14739 })
14740
14741 (define_insn "fprem1xf4"
14742   [(set (match_operand:XF 0 "register_operand" "=f")
14743         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14744                     (match_operand:XF 3 "register_operand" "1")]
14745                    UNSPEC_FPREM1_F))
14746    (set (match_operand:XF 1 "register_operand" "=u")
14747         (unspec:XF [(match_dup 2) (match_dup 3)]
14748                    UNSPEC_FPREM1_U))
14749    (set (reg:CCFP FPSR_REG)
14750         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14751   "TARGET_USE_FANCY_MATH_387
14752    && flag_unsafe_math_optimizations"
14753   "fprem1"
14754   [(set_attr "type" "fpspc")
14755    (set_attr "mode" "XF")])
14756
14757 (define_expand "dremsf3"
14758   [(use (match_operand:SF 0 "register_operand" ""))
14759    (use (match_operand:SF 1 "register_operand" ""))
14760    (use (match_operand:SF 2 "register_operand" ""))]
14761   "TARGET_USE_FANCY_MATH_387
14762    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14763    && flag_unsafe_math_optimizations"
14764 {
14765   rtx label = gen_label_rtx ();
14766
14767   rtx op1 = gen_reg_rtx (XFmode);
14768   rtx op2 = gen_reg_rtx (XFmode);
14769
14770   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14771   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14772
14773   emit_label (label);
14774
14775   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14776   ix86_emit_fp_unordered_jump (label);
14777
14778   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14779   DONE;
14780 })
14781
14782 (define_expand "dremdf3"
14783   [(use (match_operand:DF 0 "register_operand" ""))
14784    (use (match_operand:DF 1 "register_operand" ""))
14785    (use (match_operand:DF 2 "register_operand" ""))]
14786   "TARGET_USE_FANCY_MATH_387
14787    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14788    && flag_unsafe_math_optimizations"
14789 {
14790   rtx label = gen_label_rtx ();
14791
14792   rtx op1 = gen_reg_rtx (XFmode);
14793   rtx op2 = gen_reg_rtx (XFmode);
14794
14795   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14796   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14797
14798   emit_label (label);
14799
14800   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14801   ix86_emit_fp_unordered_jump (label);
14802
14803   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14804   DONE;
14805 })
14806
14807 (define_expand "dremxf3"
14808   [(use (match_operand:XF 0 "register_operand" ""))
14809    (use (match_operand:XF 1 "register_operand" ""))
14810    (use (match_operand:XF 2 "register_operand" ""))]
14811   "TARGET_USE_FANCY_MATH_387
14812    && flag_unsafe_math_optimizations"
14813 {
14814   rtx label = gen_label_rtx ();
14815
14816   emit_label (label);
14817
14818   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14819                             operands[1], operands[2]));
14820   ix86_emit_fp_unordered_jump (label);
14821
14822   emit_move_insn (operands[0], operands[1]);
14823   DONE;
14824 })
14825
14826 (define_insn "*sindf2"
14827   [(set (match_operand:DF 0 "register_operand" "=f")
14828         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14829   "TARGET_USE_FANCY_MATH_387
14830    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14831    && flag_unsafe_math_optimizations"
14832   "fsin"
14833   [(set_attr "type" "fpspc")
14834    (set_attr "mode" "DF")])
14835
14836 (define_insn "*sinsf2"
14837   [(set (match_operand:SF 0 "register_operand" "=f")
14838         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14839   "TARGET_USE_FANCY_MATH_387
14840    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14841    && flag_unsafe_math_optimizations"
14842   "fsin"
14843   [(set_attr "type" "fpspc")
14844    (set_attr "mode" "SF")])
14845
14846 (define_insn "*sinextendsfdf2"
14847   [(set (match_operand:DF 0 "register_operand" "=f")
14848         (unspec:DF [(float_extend:DF
14849                      (match_operand:SF 1 "register_operand" "0"))]
14850                    UNSPEC_SIN))]
14851   "TARGET_USE_FANCY_MATH_387
14852    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14853    && flag_unsafe_math_optimizations"
14854   "fsin"
14855   [(set_attr "type" "fpspc")
14856    (set_attr "mode" "DF")])
14857
14858 (define_insn "*sinxf2"
14859   [(set (match_operand:XF 0 "register_operand" "=f")
14860         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14861   "TARGET_USE_FANCY_MATH_387
14862    && flag_unsafe_math_optimizations"
14863   "fsin"
14864   [(set_attr "type" "fpspc")
14865    (set_attr "mode" "XF")])
14866
14867 (define_insn "*cosdf2"
14868   [(set (match_operand:DF 0 "register_operand" "=f")
14869         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14870   "TARGET_USE_FANCY_MATH_387
14871    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14872    && flag_unsafe_math_optimizations"
14873   "fcos"
14874   [(set_attr "type" "fpspc")
14875    (set_attr "mode" "DF")])
14876
14877 (define_insn "*cossf2"
14878   [(set (match_operand:SF 0 "register_operand" "=f")
14879         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14880   "TARGET_USE_FANCY_MATH_387
14881    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14882    && flag_unsafe_math_optimizations"
14883   "fcos"
14884   [(set_attr "type" "fpspc")
14885    (set_attr "mode" "SF")])
14886
14887 (define_insn "*cosextendsfdf2"
14888   [(set (match_operand:DF 0 "register_operand" "=f")
14889         (unspec:DF [(float_extend:DF
14890                      (match_operand:SF 1 "register_operand" "0"))]
14891                    UNSPEC_COS))]
14892   "TARGET_USE_FANCY_MATH_387
14893    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14894    && flag_unsafe_math_optimizations"
14895   "fcos"
14896   [(set_attr "type" "fpspc")
14897    (set_attr "mode" "DF")])
14898
14899 (define_insn "*cosxf2"
14900   [(set (match_operand:XF 0 "register_operand" "=f")
14901         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14902   "TARGET_USE_FANCY_MATH_387
14903    && flag_unsafe_math_optimizations"
14904   "fcos"
14905   [(set_attr "type" "fpspc")
14906    (set_attr "mode" "XF")])
14907
14908 ;; With sincos pattern defined, sin and cos builtin function will be
14909 ;; expanded to sincos pattern with one of its outputs left unused. 
14910 ;; Cse pass  will detected, if two sincos patterns can be combined,
14911 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14912 ;; depending on the unused output.
14913
14914 (define_insn "sincosdf3"
14915   [(set (match_operand:DF 0 "register_operand" "=f")
14916         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14917                    UNSPEC_SINCOS_COS))
14918    (set (match_operand:DF 1 "register_operand" "=u")
14919         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14920   "TARGET_USE_FANCY_MATH_387
14921    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14922    && flag_unsafe_math_optimizations"
14923   "fsincos"
14924   [(set_attr "type" "fpspc")
14925    (set_attr "mode" "DF")])
14926
14927 (define_split
14928   [(set (match_operand:DF 0 "register_operand" "")
14929         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14930                    UNSPEC_SINCOS_COS))
14931    (set (match_operand:DF 1 "register_operand" "")
14932         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14933   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14934    && !reload_completed && !reload_in_progress"
14935   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14936   "")
14937
14938 (define_split
14939   [(set (match_operand:DF 0 "register_operand" "")
14940         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14941                    UNSPEC_SINCOS_COS))
14942    (set (match_operand:DF 1 "register_operand" "")
14943         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14944   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14945    && !reload_completed && !reload_in_progress"
14946   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14947   "")
14948
14949 (define_insn "sincossf3"
14950   [(set (match_operand:SF 0 "register_operand" "=f")
14951         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14952                    UNSPEC_SINCOS_COS))
14953    (set (match_operand:SF 1 "register_operand" "=u")
14954         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14955   "TARGET_USE_FANCY_MATH_387
14956    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14957    && flag_unsafe_math_optimizations"
14958   "fsincos"
14959   [(set_attr "type" "fpspc")
14960    (set_attr "mode" "SF")])
14961
14962 (define_split
14963   [(set (match_operand:SF 0 "register_operand" "")
14964         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14965                    UNSPEC_SINCOS_COS))
14966    (set (match_operand:SF 1 "register_operand" "")
14967         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14968   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14969    && !reload_completed && !reload_in_progress"
14970   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14971   "")
14972
14973 (define_split
14974   [(set (match_operand:SF 0 "register_operand" "")
14975         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14976                    UNSPEC_SINCOS_COS))
14977    (set (match_operand:SF 1 "register_operand" "")
14978         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14979   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14980    && !reload_completed && !reload_in_progress"
14981   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14982   "")
14983
14984 (define_insn "*sincosextendsfdf3"
14985   [(set (match_operand:DF 0 "register_operand" "=f")
14986         (unspec:DF [(float_extend:DF
14987                      (match_operand:SF 2 "register_operand" "0"))]
14988                    UNSPEC_SINCOS_COS))
14989    (set (match_operand:DF 1 "register_operand" "=u")
14990         (unspec:DF [(float_extend:DF
14991                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14992   "TARGET_USE_FANCY_MATH_387
14993    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14994    && flag_unsafe_math_optimizations"
14995   "fsincos"
14996   [(set_attr "type" "fpspc")
14997    (set_attr "mode" "DF")])
14998
14999 (define_split
15000   [(set (match_operand:DF 0 "register_operand" "")
15001         (unspec:DF [(float_extend:DF
15002                      (match_operand:SF 2 "register_operand" ""))]
15003                    UNSPEC_SINCOS_COS))
15004    (set (match_operand:DF 1 "register_operand" "")
15005         (unspec:DF [(float_extend:DF
15006                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15007   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15008    && !reload_completed && !reload_in_progress"
15009   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15010                                    (match_dup 2))] UNSPEC_SIN))]
15011   "")
15012
15013 (define_split
15014   [(set (match_operand:DF 0 "register_operand" "")
15015         (unspec:DF [(float_extend:DF
15016                      (match_operand:SF 2 "register_operand" ""))]
15017                    UNSPEC_SINCOS_COS))
15018    (set (match_operand:DF 1 "register_operand" "")
15019         (unspec:DF [(float_extend:DF
15020                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15021   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15022    && !reload_completed && !reload_in_progress"
15023   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15024                                    (match_dup 2))] UNSPEC_COS))]
15025   "")
15026
15027 (define_insn "sincosxf3"
15028   [(set (match_operand:XF 0 "register_operand" "=f")
15029         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15030                    UNSPEC_SINCOS_COS))
15031    (set (match_operand:XF 1 "register_operand" "=u")
15032         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15033   "TARGET_USE_FANCY_MATH_387
15034    && flag_unsafe_math_optimizations"
15035   "fsincos"
15036   [(set_attr "type" "fpspc")
15037    (set_attr "mode" "XF")])
15038
15039 (define_split
15040   [(set (match_operand:XF 0 "register_operand" "")
15041         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15042                    UNSPEC_SINCOS_COS))
15043    (set (match_operand:XF 1 "register_operand" "")
15044         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15045   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15046    && !reload_completed && !reload_in_progress"
15047   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15048   "")
15049
15050 (define_split
15051   [(set (match_operand:XF 0 "register_operand" "")
15052         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15053                    UNSPEC_SINCOS_COS))
15054    (set (match_operand:XF 1 "register_operand" "")
15055         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15056   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15057    && !reload_completed && !reload_in_progress"
15058   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15059   "")
15060
15061 (define_insn "*tandf3_1"
15062   [(set (match_operand:DF 0 "register_operand" "=f")
15063         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15064                    UNSPEC_TAN_ONE))
15065    (set (match_operand:DF 1 "register_operand" "=u")
15066         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15067   "TARGET_USE_FANCY_MATH_387
15068    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15069    && flag_unsafe_math_optimizations"
15070   "fptan"
15071   [(set_attr "type" "fpspc")
15072    (set_attr "mode" "DF")])
15073
15074 ;; optimize sequence: fptan
15075 ;;                    fstp    %st(0)
15076 ;;                    fld1
15077 ;; into fptan insn.
15078
15079 (define_peephole2
15080   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15081                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15082                              UNSPEC_TAN_ONE))
15083              (set (match_operand:DF 1 "register_operand" "")
15084                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15085    (set (match_dup 0)
15086         (match_operand:DF 3 "immediate_operand" ""))]
15087   "standard_80387_constant_p (operands[3]) == 2"
15088   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15089              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15090   "")
15091
15092 (define_expand "tandf2"
15093   [(parallel [(set (match_dup 2)
15094                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15095                               UNSPEC_TAN_ONE))
15096               (set (match_operand:DF 0 "register_operand" "")
15097                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15098   "TARGET_USE_FANCY_MATH_387
15099    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15100    && flag_unsafe_math_optimizations"
15101 {
15102   operands[2] = gen_reg_rtx (DFmode);
15103 })
15104
15105 (define_insn "*tansf3_1"
15106   [(set (match_operand:SF 0 "register_operand" "=f")
15107         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15108                    UNSPEC_TAN_ONE))
15109    (set (match_operand:SF 1 "register_operand" "=u")
15110         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15111   "TARGET_USE_FANCY_MATH_387
15112    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15113    && flag_unsafe_math_optimizations"
15114   "fptan"
15115   [(set_attr "type" "fpspc")
15116    (set_attr "mode" "SF")])
15117
15118 ;; optimize sequence: fptan
15119 ;;                    fstp    %st(0)
15120 ;;                    fld1
15121 ;; into fptan insn.
15122
15123 (define_peephole2
15124   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15125                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15126                              UNSPEC_TAN_ONE))
15127              (set (match_operand:SF 1 "register_operand" "")
15128                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15129    (set (match_dup 0)
15130         (match_operand:SF 3 "immediate_operand" ""))]
15131   "standard_80387_constant_p (operands[3]) == 2"
15132   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15133              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15134   "")
15135
15136 (define_expand "tansf2"
15137   [(parallel [(set (match_dup 2)
15138                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15139                               UNSPEC_TAN_ONE))
15140               (set (match_operand:SF 0 "register_operand" "")
15141                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15142   "TARGET_USE_FANCY_MATH_387
15143    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15144    && flag_unsafe_math_optimizations"
15145 {
15146   operands[2] = gen_reg_rtx (SFmode);
15147 })
15148
15149 (define_insn "*tanxf3_1"
15150   [(set (match_operand:XF 0 "register_operand" "=f")
15151         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15152                    UNSPEC_TAN_ONE))
15153    (set (match_operand:XF 1 "register_operand" "=u")
15154         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15155   "TARGET_USE_FANCY_MATH_387
15156    && flag_unsafe_math_optimizations"
15157   "fptan"
15158   [(set_attr "type" "fpspc")
15159    (set_attr "mode" "XF")])
15160
15161 ;; optimize sequence: fptan
15162 ;;                    fstp    %st(0)
15163 ;;                    fld1
15164 ;; into fptan insn.
15165
15166 (define_peephole2
15167   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15168                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15169                              UNSPEC_TAN_ONE))
15170              (set (match_operand:XF 1 "register_operand" "")
15171                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15172    (set (match_dup 0)
15173         (match_operand:XF 3 "immediate_operand" ""))]
15174   "standard_80387_constant_p (operands[3]) == 2"
15175   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15176              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15177   "")
15178
15179 (define_expand "tanxf2"
15180   [(parallel [(set (match_dup 2)
15181                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15182                               UNSPEC_TAN_ONE))
15183               (set (match_operand:XF 0 "register_operand" "")
15184                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15185   "TARGET_USE_FANCY_MATH_387
15186    && flag_unsafe_math_optimizations"
15187 {
15188   operands[2] = gen_reg_rtx (XFmode);
15189 })
15190
15191 (define_insn "atan2df3_1"
15192   [(set (match_operand:DF 0 "register_operand" "=f")
15193         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15194                     (match_operand:DF 1 "register_operand" "u")]
15195                    UNSPEC_FPATAN))
15196    (clobber (match_scratch:DF 3 "=1"))]
15197   "TARGET_USE_FANCY_MATH_387
15198    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15199    && flag_unsafe_math_optimizations"
15200   "fpatan"
15201   [(set_attr "type" "fpspc")
15202    (set_attr "mode" "DF")])
15203
15204 (define_expand "atan2df3"
15205   [(use (match_operand:DF 0 "register_operand" ""))
15206    (use (match_operand:DF 2 "register_operand" ""))
15207    (use (match_operand:DF 1 "register_operand" ""))]
15208   "TARGET_USE_FANCY_MATH_387
15209    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15210    && flag_unsafe_math_optimizations"
15211 {
15212   rtx copy = gen_reg_rtx (DFmode);
15213   emit_move_insn (copy, operands[1]);
15214   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15215   DONE;
15216 })
15217
15218 (define_expand "atandf2"
15219   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15220                    (unspec:DF [(match_dup 2)
15221                                (match_operand:DF 1 "register_operand" "")]
15222                     UNSPEC_FPATAN))
15223               (clobber (match_scratch:DF 3 ""))])]
15224   "TARGET_USE_FANCY_MATH_387
15225    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15226    && flag_unsafe_math_optimizations"
15227 {
15228   operands[2] = gen_reg_rtx (DFmode);
15229   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15230 })
15231
15232 (define_insn "atan2sf3_1"
15233   [(set (match_operand:SF 0 "register_operand" "=f")
15234         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15235                     (match_operand:SF 1 "register_operand" "u")]
15236                    UNSPEC_FPATAN))
15237    (clobber (match_scratch:SF 3 "=1"))]
15238   "TARGET_USE_FANCY_MATH_387
15239    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15240    && flag_unsafe_math_optimizations"
15241   "fpatan"
15242   [(set_attr "type" "fpspc")
15243    (set_attr "mode" "SF")])
15244
15245 (define_expand "atan2sf3"
15246   [(use (match_operand:SF 0 "register_operand" ""))
15247    (use (match_operand:SF 2 "register_operand" ""))
15248    (use (match_operand:SF 1 "register_operand" ""))]
15249   "TARGET_USE_FANCY_MATH_387
15250    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15251    && flag_unsafe_math_optimizations"
15252 {
15253   rtx copy = gen_reg_rtx (SFmode);
15254   emit_move_insn (copy, operands[1]);
15255   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15256   DONE;
15257 })
15258
15259 (define_expand "atansf2"
15260   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15261                    (unspec:SF [(match_dup 2)
15262                                (match_operand:SF 1 "register_operand" "")]
15263                     UNSPEC_FPATAN))
15264               (clobber (match_scratch:SF 3 ""))])]
15265   "TARGET_USE_FANCY_MATH_387
15266    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15267    && flag_unsafe_math_optimizations"
15268 {
15269   operands[2] = gen_reg_rtx (SFmode);
15270   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15271 })
15272
15273 (define_insn "atan2xf3_1"
15274   [(set (match_operand:XF 0 "register_operand" "=f")
15275         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15276                     (match_operand:XF 1 "register_operand" "u")]
15277                    UNSPEC_FPATAN))
15278    (clobber (match_scratch:XF 3 "=1"))]
15279   "TARGET_USE_FANCY_MATH_387
15280    && flag_unsafe_math_optimizations"
15281   "fpatan"
15282   [(set_attr "type" "fpspc")
15283    (set_attr "mode" "XF")])
15284
15285 (define_expand "atan2xf3"
15286   [(use (match_operand:XF 0 "register_operand" ""))
15287    (use (match_operand:XF 2 "register_operand" ""))
15288    (use (match_operand:XF 1 "register_operand" ""))]
15289   "TARGET_USE_FANCY_MATH_387
15290    && flag_unsafe_math_optimizations"
15291 {
15292   rtx copy = gen_reg_rtx (XFmode);
15293   emit_move_insn (copy, operands[1]);
15294   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15295   DONE;
15296 })
15297
15298 (define_expand "atanxf2"
15299   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15300                    (unspec:XF [(match_dup 2)
15301                                (match_operand:XF 1 "register_operand" "")]
15302                     UNSPEC_FPATAN))
15303               (clobber (match_scratch:XF 3 ""))])]
15304   "TARGET_USE_FANCY_MATH_387
15305    && flag_unsafe_math_optimizations"
15306 {
15307   operands[2] = gen_reg_rtx (XFmode);
15308   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15309 })
15310
15311 (define_expand "asindf2"
15312   [(set (match_dup 2)
15313         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15314    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15315    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15316    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15317    (parallel [(set (match_dup 7)
15318                    (unspec:XF [(match_dup 6) (match_dup 2)]
15319                               UNSPEC_FPATAN))
15320               (clobber (match_scratch:XF 8 ""))])
15321    (set (match_operand:DF 0 "register_operand" "")
15322         (float_truncate:DF (match_dup 7)))]
15323   "TARGET_USE_FANCY_MATH_387
15324    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15325    && flag_unsafe_math_optimizations"
15326 {
15327   int i;
15328
15329   for (i=2; i<8; i++)
15330     operands[i] = gen_reg_rtx (XFmode);
15331
15332   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15333 })
15334
15335 (define_expand "asinsf2"
15336   [(set (match_dup 2)
15337         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15338    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15339    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15340    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15341    (parallel [(set (match_dup 7)
15342                    (unspec:XF [(match_dup 6) (match_dup 2)]
15343                               UNSPEC_FPATAN))
15344               (clobber (match_scratch:XF 8 ""))])
15345    (set (match_operand:SF 0 "register_operand" "")
15346         (float_truncate:SF (match_dup 7)))]
15347   "TARGET_USE_FANCY_MATH_387
15348    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15349    && flag_unsafe_math_optimizations"
15350 {
15351   int i;
15352
15353   for (i=2; i<8; i++)
15354     operands[i] = gen_reg_rtx (XFmode);
15355
15356   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15357 })
15358
15359 (define_expand "asinxf2"
15360   [(set (match_dup 2)
15361         (mult:XF (match_operand:XF 1 "register_operand" "")
15362                  (match_dup 1)))
15363    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15364    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15365    (parallel [(set (match_operand:XF 0 "register_operand" "")
15366                    (unspec:XF [(match_dup 5) (match_dup 1)]
15367                               UNSPEC_FPATAN))
15368               (clobber (match_scratch:XF 6 ""))])]
15369   "TARGET_USE_FANCY_MATH_387
15370    && flag_unsafe_math_optimizations"
15371 {
15372   int i;
15373
15374   for (i=2; i<6; i++)
15375     operands[i] = gen_reg_rtx (XFmode);
15376
15377   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15378 })
15379
15380 (define_expand "acosdf2"
15381   [(set (match_dup 2)
15382         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15383    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15384    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15385    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15386    (parallel [(set (match_dup 7)
15387                    (unspec:XF [(match_dup 2) (match_dup 6)]
15388                               UNSPEC_FPATAN))
15389               (clobber (match_scratch:XF 8 ""))])
15390    (set (match_operand:DF 0 "register_operand" "")
15391         (float_truncate:DF (match_dup 7)))]
15392   "TARGET_USE_FANCY_MATH_387
15393    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15394    && flag_unsafe_math_optimizations"
15395 {
15396   int i;
15397
15398   for (i=2; i<8; i++)
15399     operands[i] = gen_reg_rtx (XFmode);
15400
15401   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15402 })
15403
15404 (define_expand "acossf2"
15405   [(set (match_dup 2)
15406         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15407    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15408    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15409    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15410    (parallel [(set (match_dup 7)
15411                    (unspec:XF [(match_dup 2) (match_dup 6)]
15412                               UNSPEC_FPATAN))
15413               (clobber (match_scratch:XF 8 ""))])
15414    (set (match_operand:SF 0 "register_operand" "")
15415         (float_truncate:SF (match_dup 7)))]
15416   "TARGET_USE_FANCY_MATH_387
15417    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15418    && flag_unsafe_math_optimizations"
15419 {
15420   int i;
15421
15422   for (i=2; i<8; i++)
15423     operands[i] = gen_reg_rtx (XFmode);
15424
15425   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15426 })
15427
15428 (define_expand "acosxf2"
15429   [(set (match_dup 2)
15430         (mult:XF (match_operand:XF 1 "register_operand" "")
15431                  (match_dup 1)))
15432    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15433    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15434    (parallel [(set (match_operand:XF 0 "register_operand" "")
15435                    (unspec:XF [(match_dup 1) (match_dup 5)]
15436                               UNSPEC_FPATAN))
15437               (clobber (match_scratch:XF 6 ""))])]
15438   "TARGET_USE_FANCY_MATH_387
15439    && flag_unsafe_math_optimizations"
15440 {
15441   int i;
15442
15443   for (i=2; i<6; i++)
15444     operands[i] = gen_reg_rtx (XFmode);
15445
15446   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15447 })
15448
15449 (define_insn "fyl2x_xf3"
15450   [(set (match_operand:XF 0 "register_operand" "=f")
15451         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15452                     (match_operand:XF 1 "register_operand" "u")]
15453                    UNSPEC_FYL2X))
15454    (clobber (match_scratch:XF 3 "=1"))]
15455   "TARGET_USE_FANCY_MATH_387
15456    && flag_unsafe_math_optimizations"
15457   "fyl2x"
15458   [(set_attr "type" "fpspc")
15459    (set_attr "mode" "XF")])
15460
15461 (define_expand "logsf2"
15462   [(set (match_dup 2)
15463         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15464    (parallel [(set (match_dup 4)
15465                    (unspec:XF [(match_dup 2)
15466                                (match_dup 3)] UNSPEC_FYL2X))
15467               (clobber (match_scratch:XF 5 ""))])
15468    (set (match_operand:SF 0 "register_operand" "")
15469         (float_truncate:SF (match_dup 4)))]
15470   "TARGET_USE_FANCY_MATH_387
15471    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15472    && flag_unsafe_math_optimizations"
15473 {
15474   rtx temp;
15475
15476   operands[2] = gen_reg_rtx (XFmode);
15477   operands[3] = gen_reg_rtx (XFmode);
15478   operands[4] = gen_reg_rtx (XFmode);
15479
15480   temp = standard_80387_constant_rtx (4); /* fldln2 */
15481   emit_move_insn (operands[3], temp);
15482 })
15483
15484 (define_expand "logdf2"
15485   [(set (match_dup 2)
15486         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15487    (parallel [(set (match_dup 4)
15488                    (unspec:XF [(match_dup 2)
15489                                (match_dup 3)] UNSPEC_FYL2X))
15490               (clobber (match_scratch:XF 5 ""))])
15491    (set (match_operand:DF 0 "register_operand" "")
15492         (float_truncate:DF (match_dup 4)))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15495    && flag_unsafe_math_optimizations"
15496 {
15497   rtx temp;
15498
15499   operands[2] = gen_reg_rtx (XFmode);
15500   operands[3] = gen_reg_rtx (XFmode);
15501   operands[4] = gen_reg_rtx (XFmode);
15502
15503   temp = standard_80387_constant_rtx (4); /* fldln2 */
15504   emit_move_insn (operands[3], temp);
15505 })
15506
15507 (define_expand "logxf2"
15508   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15509                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15510                                (match_dup 2)] UNSPEC_FYL2X))
15511               (clobber (match_scratch:XF 3 ""))])]
15512   "TARGET_USE_FANCY_MATH_387
15513    && flag_unsafe_math_optimizations"
15514 {
15515   rtx temp;
15516
15517   operands[2] = gen_reg_rtx (XFmode);
15518   temp = standard_80387_constant_rtx (4); /* fldln2 */
15519   emit_move_insn (operands[2], temp);
15520 })
15521
15522 (define_expand "log10sf2"
15523   [(set (match_dup 2)
15524         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15525    (parallel [(set (match_dup 4)
15526                    (unspec:XF [(match_dup 2)
15527                                (match_dup 3)] UNSPEC_FYL2X))
15528               (clobber (match_scratch:XF 5 ""))])
15529    (set (match_operand:SF 0 "register_operand" "")
15530         (float_truncate:SF (match_dup 4)))]
15531   "TARGET_USE_FANCY_MATH_387
15532    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15533    && flag_unsafe_math_optimizations"
15534 {
15535   rtx temp;
15536
15537   operands[2] = gen_reg_rtx (XFmode);
15538   operands[3] = gen_reg_rtx (XFmode);
15539   operands[4] = gen_reg_rtx (XFmode);
15540
15541   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15542   emit_move_insn (operands[3], temp);
15543 })
15544
15545 (define_expand "log10df2"
15546   [(set (match_dup 2)
15547         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15548    (parallel [(set (match_dup 4)
15549                    (unspec:XF [(match_dup 2)
15550                                (match_dup 3)] UNSPEC_FYL2X))
15551               (clobber (match_scratch:XF 5 ""))])
15552    (set (match_operand:DF 0 "register_operand" "")
15553         (float_truncate:DF (match_dup 4)))]
15554   "TARGET_USE_FANCY_MATH_387
15555    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15556    && flag_unsafe_math_optimizations"
15557 {
15558   rtx temp;
15559
15560   operands[2] = gen_reg_rtx (XFmode);
15561   operands[3] = gen_reg_rtx (XFmode);
15562   operands[4] = gen_reg_rtx (XFmode);
15563
15564   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15565   emit_move_insn (operands[3], temp);
15566 })
15567
15568 (define_expand "log10xf2"
15569   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15570                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15571                                (match_dup 2)] UNSPEC_FYL2X))
15572               (clobber (match_scratch:XF 3 ""))])]
15573   "TARGET_USE_FANCY_MATH_387
15574    && flag_unsafe_math_optimizations"
15575 {
15576   rtx temp;
15577
15578   operands[2] = gen_reg_rtx (XFmode);
15579   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15580   emit_move_insn (operands[2], temp);
15581 })
15582
15583 (define_expand "log2sf2"
15584   [(set (match_dup 2)
15585         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15586    (parallel [(set (match_dup 4)
15587                    (unspec:XF [(match_dup 2)
15588                                (match_dup 3)] UNSPEC_FYL2X))
15589               (clobber (match_scratch:XF 5 ""))])
15590    (set (match_operand:SF 0 "register_operand" "")
15591         (float_truncate:SF (match_dup 4)))]
15592   "TARGET_USE_FANCY_MATH_387
15593    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15594    && flag_unsafe_math_optimizations"
15595 {
15596   operands[2] = gen_reg_rtx (XFmode);
15597   operands[3] = gen_reg_rtx (XFmode);
15598   operands[4] = gen_reg_rtx (XFmode);
15599
15600   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15601 })
15602
15603 (define_expand "log2df2"
15604   [(set (match_dup 2)
15605         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15606    (parallel [(set (match_dup 4)
15607                    (unspec:XF [(match_dup 2)
15608                                (match_dup 3)] UNSPEC_FYL2X))
15609               (clobber (match_scratch:XF 5 ""))])
15610    (set (match_operand:DF 0 "register_operand" "")
15611         (float_truncate:DF (match_dup 4)))]
15612   "TARGET_USE_FANCY_MATH_387
15613    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15614    && flag_unsafe_math_optimizations"
15615 {
15616   operands[2] = gen_reg_rtx (XFmode);
15617   operands[3] = gen_reg_rtx (XFmode);
15618   operands[4] = gen_reg_rtx (XFmode);
15619
15620   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15621 })
15622
15623 (define_expand "log2xf2"
15624   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15625                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15626                                (match_dup 2)] UNSPEC_FYL2X))
15627               (clobber (match_scratch:XF 3 ""))])]
15628   "TARGET_USE_FANCY_MATH_387
15629    && flag_unsafe_math_optimizations"
15630 {
15631   operands[2] = gen_reg_rtx (XFmode);
15632   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15633 })
15634
15635 (define_insn "fyl2xp1_xf3"
15636   [(set (match_operand:XF 0 "register_operand" "=f")
15637         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15638                     (match_operand:XF 1 "register_operand" "u")]
15639                    UNSPEC_FYL2XP1))
15640    (clobber (match_scratch:XF 3 "=1"))]
15641   "TARGET_USE_FANCY_MATH_387
15642    && flag_unsafe_math_optimizations"
15643   "fyl2xp1"
15644   [(set_attr "type" "fpspc")
15645    (set_attr "mode" "XF")])
15646
15647 (define_expand "log1psf2"
15648   [(use (match_operand:SF 0 "register_operand" ""))
15649    (use (match_operand:SF 1 "register_operand" ""))]
15650   "TARGET_USE_FANCY_MATH_387
15651    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15652    && flag_unsafe_math_optimizations"
15653 {
15654   rtx op0 = gen_reg_rtx (XFmode);
15655   rtx op1 = gen_reg_rtx (XFmode);
15656
15657   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15658   ix86_emit_i387_log1p (op0, op1);
15659   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15660   DONE;
15661 })
15662
15663 (define_expand "log1pdf2"
15664   [(use (match_operand:DF 0 "register_operand" ""))
15665    (use (match_operand:DF 1 "register_operand" ""))]
15666   "TARGET_USE_FANCY_MATH_387
15667    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15668    && flag_unsafe_math_optimizations"
15669 {
15670   rtx op0 = gen_reg_rtx (XFmode);
15671   rtx op1 = gen_reg_rtx (XFmode);
15672
15673   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15674   ix86_emit_i387_log1p (op0, op1);
15675   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15676   DONE;
15677 })
15678
15679 (define_expand "log1pxf2"
15680   [(use (match_operand:XF 0 "register_operand" ""))
15681    (use (match_operand:XF 1 "register_operand" ""))]
15682   "TARGET_USE_FANCY_MATH_387
15683    && flag_unsafe_math_optimizations"
15684 {
15685   ix86_emit_i387_log1p (operands[0], operands[1]);
15686   DONE;
15687 })
15688
15689 (define_insn "*fxtractxf3"
15690   [(set (match_operand:XF 0 "register_operand" "=f")
15691         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15692                    UNSPEC_XTRACT_FRACT))
15693    (set (match_operand:XF 1 "register_operand" "=u")
15694         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15695   "TARGET_USE_FANCY_MATH_387
15696    && flag_unsafe_math_optimizations"
15697   "fxtract"
15698   [(set_attr "type" "fpspc")
15699    (set_attr "mode" "XF")])
15700
15701 (define_expand "logbsf2"
15702   [(set (match_dup 2)
15703         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15704    (parallel [(set (match_dup 3)
15705                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15706               (set (match_dup 4)
15707                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15708    (set (match_operand:SF 0 "register_operand" "")
15709         (float_truncate:SF (match_dup 4)))]
15710   "TARGET_USE_FANCY_MATH_387
15711    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15712    && flag_unsafe_math_optimizations"
15713 {
15714   operands[2] = gen_reg_rtx (XFmode);
15715   operands[3] = gen_reg_rtx (XFmode);
15716   operands[4] = gen_reg_rtx (XFmode);
15717 })
15718
15719 (define_expand "logbdf2"
15720   [(set (match_dup 2)
15721         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15722    (parallel [(set (match_dup 3)
15723                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15724               (set (match_dup 4)
15725                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15726    (set (match_operand:DF 0 "register_operand" "")
15727         (float_truncate:DF (match_dup 4)))]
15728   "TARGET_USE_FANCY_MATH_387
15729    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15730    && flag_unsafe_math_optimizations"
15731 {
15732   operands[2] = gen_reg_rtx (XFmode);
15733   operands[3] = gen_reg_rtx (XFmode);
15734   operands[4] = gen_reg_rtx (XFmode);
15735 })
15736
15737 (define_expand "logbxf2"
15738   [(parallel [(set (match_dup 2)
15739                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15740                               UNSPEC_XTRACT_FRACT))
15741               (set (match_operand:XF 0 "register_operand" "")
15742                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15743   "TARGET_USE_FANCY_MATH_387
15744    && flag_unsafe_math_optimizations"
15745 {
15746   operands[2] = gen_reg_rtx (XFmode);
15747 })
15748
15749 (define_expand "ilogbsi2"
15750   [(parallel [(set (match_dup 2)
15751                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15752                               UNSPEC_XTRACT_FRACT))
15753               (set (match_operand:XF 3 "register_operand" "")
15754                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15755    (parallel [(set (match_operand:SI 0 "register_operand" "")
15756                    (fix:SI (match_dup 3)))
15757               (clobber (reg:CC FLAGS_REG))])]
15758   "TARGET_USE_FANCY_MATH_387
15759    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15760    && flag_unsafe_math_optimizations"
15761 {
15762   operands[2] = gen_reg_rtx (XFmode);
15763   operands[3] = gen_reg_rtx (XFmode);
15764 })
15765
15766 (define_insn "*f2xm1xf2"
15767   [(set (match_operand:XF 0 "register_operand" "=f")
15768         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15769          UNSPEC_F2XM1))]
15770   "TARGET_USE_FANCY_MATH_387
15771    && flag_unsafe_math_optimizations"
15772   "f2xm1"
15773   [(set_attr "type" "fpspc")
15774    (set_attr "mode" "XF")])
15775
15776 (define_insn "*fscalexf4"
15777   [(set (match_operand:XF 0 "register_operand" "=f")
15778         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15779                     (match_operand:XF 3 "register_operand" "1")]
15780                    UNSPEC_FSCALE_FRACT))
15781    (set (match_operand:XF 1 "register_operand" "=u")
15782         (unspec:XF [(match_dup 2) (match_dup 3)]
15783                    UNSPEC_FSCALE_EXP))]
15784   "TARGET_USE_FANCY_MATH_387
15785    && flag_unsafe_math_optimizations"
15786   "fscale"
15787   [(set_attr "type" "fpspc")
15788    (set_attr "mode" "XF")])
15789
15790 (define_expand "expsf2"
15791   [(set (match_dup 2)
15792         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15793    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15794    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15795    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15796    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15797    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15798    (parallel [(set (match_dup 10)
15799                    (unspec:XF [(match_dup 9) (match_dup 5)]
15800                               UNSPEC_FSCALE_FRACT))
15801               (set (match_dup 11)
15802                    (unspec:XF [(match_dup 9) (match_dup 5)]
15803                               UNSPEC_FSCALE_EXP))])
15804    (set (match_operand:SF 0 "register_operand" "")
15805         (float_truncate:SF (match_dup 10)))]
15806   "TARGET_USE_FANCY_MATH_387
15807    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15808    && flag_unsafe_math_optimizations"
15809 {
15810   rtx temp;
15811   int i;
15812
15813   for (i=2; i<12; i++)
15814     operands[i] = gen_reg_rtx (XFmode);
15815   temp = standard_80387_constant_rtx (5); /* fldl2e */
15816   emit_move_insn (operands[3], temp);
15817   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15818 })
15819
15820 (define_expand "expdf2"
15821   [(set (match_dup 2)
15822         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15823    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15824    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15825    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15826    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15827    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15828    (parallel [(set (match_dup 10)
15829                    (unspec:XF [(match_dup 9) (match_dup 5)]
15830                               UNSPEC_FSCALE_FRACT))
15831               (set (match_dup 11)
15832                    (unspec:XF [(match_dup 9) (match_dup 5)]
15833                               UNSPEC_FSCALE_EXP))])
15834    (set (match_operand:DF 0 "register_operand" "")
15835         (float_truncate:DF (match_dup 10)))]
15836   "TARGET_USE_FANCY_MATH_387
15837    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15838    && flag_unsafe_math_optimizations"
15839 {
15840   rtx temp;
15841   int i;
15842
15843   for (i=2; i<12; i++)
15844     operands[i] = gen_reg_rtx (XFmode);
15845   temp = standard_80387_constant_rtx (5); /* fldl2e */
15846   emit_move_insn (operands[3], temp);
15847   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15848 })
15849
15850 (define_expand "expxf2"
15851   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15852                                (match_dup 2)))
15853    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15854    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15855    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15856    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15857    (parallel [(set (match_operand:XF 0 "register_operand" "")
15858                    (unspec:XF [(match_dup 8) (match_dup 4)]
15859                               UNSPEC_FSCALE_FRACT))
15860               (set (match_dup 9)
15861                    (unspec:XF [(match_dup 8) (match_dup 4)]
15862                               UNSPEC_FSCALE_EXP))])]
15863   "TARGET_USE_FANCY_MATH_387
15864    && flag_unsafe_math_optimizations"
15865 {
15866   rtx temp;
15867   int i;
15868
15869   for (i=2; i<10; i++)
15870     operands[i] = gen_reg_rtx (XFmode);
15871   temp = standard_80387_constant_rtx (5); /* fldl2e */
15872   emit_move_insn (operands[2], temp);
15873   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15874 })
15875
15876 (define_expand "exp10sf2"
15877   [(set (match_dup 2)
15878         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15879    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15880    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15881    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15882    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15883    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15884    (parallel [(set (match_dup 10)
15885                    (unspec:XF [(match_dup 9) (match_dup 5)]
15886                               UNSPEC_FSCALE_FRACT))
15887               (set (match_dup 11)
15888                    (unspec:XF [(match_dup 9) (match_dup 5)]
15889                               UNSPEC_FSCALE_EXP))])
15890    (set (match_operand:SF 0 "register_operand" "")
15891         (float_truncate:SF (match_dup 10)))]
15892   "TARGET_USE_FANCY_MATH_387
15893    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15894    && flag_unsafe_math_optimizations"
15895 {
15896   rtx temp;
15897   int i;
15898
15899   for (i=2; i<12; i++)
15900     operands[i] = gen_reg_rtx (XFmode);
15901   temp = standard_80387_constant_rtx (6); /* fldl2t */
15902   emit_move_insn (operands[3], temp);
15903   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15904 })
15905
15906 (define_expand "exp10df2"
15907   [(set (match_dup 2)
15908         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15909    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15910    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15911    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15912    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15913    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15914    (parallel [(set (match_dup 10)
15915                    (unspec:XF [(match_dup 9) (match_dup 5)]
15916                               UNSPEC_FSCALE_FRACT))
15917               (set (match_dup 11)
15918                    (unspec:XF [(match_dup 9) (match_dup 5)]
15919                               UNSPEC_FSCALE_EXP))])
15920    (set (match_operand:DF 0 "register_operand" "")
15921         (float_truncate:DF (match_dup 10)))]
15922   "TARGET_USE_FANCY_MATH_387
15923    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15924    && flag_unsafe_math_optimizations"
15925 {
15926   rtx temp;
15927   int i;
15928
15929   for (i=2; i<12; i++)
15930     operands[i] = gen_reg_rtx (XFmode);
15931   temp = standard_80387_constant_rtx (6); /* fldl2t */
15932   emit_move_insn (operands[3], temp);
15933   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15934 })
15935
15936 (define_expand "exp10xf2"
15937   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15938                                (match_dup 2)))
15939    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15940    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15941    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15942    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15943    (parallel [(set (match_operand:XF 0 "register_operand" "")
15944                    (unspec:XF [(match_dup 8) (match_dup 4)]
15945                               UNSPEC_FSCALE_FRACT))
15946               (set (match_dup 9)
15947                    (unspec:XF [(match_dup 8) (match_dup 4)]
15948                               UNSPEC_FSCALE_EXP))])]
15949   "TARGET_USE_FANCY_MATH_387
15950    && flag_unsafe_math_optimizations"
15951 {
15952   rtx temp;
15953   int i;
15954
15955   for (i=2; i<10; i++)
15956     operands[i] = gen_reg_rtx (XFmode);
15957   temp = standard_80387_constant_rtx (6); /* fldl2t */
15958   emit_move_insn (operands[2], temp);
15959   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15960 })
15961
15962 (define_expand "exp2sf2"
15963   [(set (match_dup 2)
15964         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15965    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15966    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15967    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15968    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15969    (parallel [(set (match_dup 8)
15970                    (unspec:XF [(match_dup 7) (match_dup 3)]
15971                               UNSPEC_FSCALE_FRACT))
15972               (set (match_dup 9)
15973                    (unspec:XF [(match_dup 7) (match_dup 3)]
15974                               UNSPEC_FSCALE_EXP))])
15975    (set (match_operand:SF 0 "register_operand" "")
15976         (float_truncate:SF (match_dup 8)))]
15977   "TARGET_USE_FANCY_MATH_387
15978    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15979    && flag_unsafe_math_optimizations"
15980 {
15981   int i;
15982
15983   for (i=2; i<10; i++)
15984     operands[i] = gen_reg_rtx (XFmode);
15985   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15986 })
15987
15988 (define_expand "exp2df2"
15989   [(set (match_dup 2)
15990         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15991    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15992    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15993    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15994    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15995    (parallel [(set (match_dup 8)
15996                    (unspec:XF [(match_dup 7) (match_dup 3)]
15997                               UNSPEC_FSCALE_FRACT))
15998               (set (match_dup 9)
15999                    (unspec:XF [(match_dup 7) (match_dup 3)]
16000                               UNSPEC_FSCALE_EXP))])
16001    (set (match_operand:DF 0 "register_operand" "")
16002         (float_truncate:DF (match_dup 8)))]
16003   "TARGET_USE_FANCY_MATH_387
16004    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16005    && flag_unsafe_math_optimizations"
16006 {
16007   int i;
16008
16009   for (i=2; i<10; i++)
16010     operands[i] = gen_reg_rtx (XFmode);
16011   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16012 })
16013
16014 (define_expand "exp2xf2"
16015   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16016    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16017    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16018    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16019    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16020    (parallel [(set (match_operand:XF 0 "register_operand" "")
16021                    (unspec:XF [(match_dup 7) (match_dup 3)]
16022                               UNSPEC_FSCALE_FRACT))
16023               (set (match_dup 8)
16024                    (unspec:XF [(match_dup 7) (match_dup 3)]
16025                               UNSPEC_FSCALE_EXP))])]
16026   "TARGET_USE_FANCY_MATH_387
16027    && flag_unsafe_math_optimizations"
16028 {
16029   int i;
16030
16031   for (i=2; i<9; i++)
16032     operands[i] = gen_reg_rtx (XFmode);
16033   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16034 })
16035
16036 (define_expand "expm1df2"
16037   [(set (match_dup 2)
16038         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16039    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16040    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16041    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16042    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16043    (parallel [(set (match_dup 8)
16044                    (unspec:XF [(match_dup 7) (match_dup 5)]
16045                               UNSPEC_FSCALE_FRACT))
16046                    (set (match_dup 9)
16047                    (unspec:XF [(match_dup 7) (match_dup 5)]
16048                               UNSPEC_FSCALE_EXP))])
16049    (parallel [(set (match_dup 11)
16050                    (unspec:XF [(match_dup 10) (match_dup 9)]
16051                               UNSPEC_FSCALE_FRACT))
16052               (set (match_dup 12)
16053                    (unspec:XF [(match_dup 10) (match_dup 9)]
16054                               UNSPEC_FSCALE_EXP))])
16055    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16056    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16057    (set (match_operand:DF 0 "register_operand" "")
16058         (float_truncate:DF (match_dup 14)))]
16059   "TARGET_USE_FANCY_MATH_387
16060    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16061    && flag_unsafe_math_optimizations"
16062 {
16063   rtx temp;
16064   int i;
16065
16066   for (i=2; i<15; i++)
16067     operands[i] = gen_reg_rtx (XFmode);
16068   temp = standard_80387_constant_rtx (5); /* fldl2e */
16069   emit_move_insn (operands[3], temp);
16070   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16071 })
16072
16073 (define_expand "expm1sf2"
16074   [(set (match_dup 2)
16075         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16076    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16077    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16078    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16079    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16080    (parallel [(set (match_dup 8)
16081                    (unspec:XF [(match_dup 7) (match_dup 5)]
16082                               UNSPEC_FSCALE_FRACT))
16083                    (set (match_dup 9)
16084                    (unspec:XF [(match_dup 7) (match_dup 5)]
16085                               UNSPEC_FSCALE_EXP))])
16086    (parallel [(set (match_dup 11)
16087                    (unspec:XF [(match_dup 10) (match_dup 9)]
16088                               UNSPEC_FSCALE_FRACT))
16089               (set (match_dup 12)
16090                    (unspec:XF [(match_dup 10) (match_dup 9)]
16091                               UNSPEC_FSCALE_EXP))])
16092    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16093    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16094    (set (match_operand:SF 0 "register_operand" "")
16095         (float_truncate:SF (match_dup 14)))]
16096   "TARGET_USE_FANCY_MATH_387
16097    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16098    && flag_unsafe_math_optimizations"
16099 {
16100   rtx temp;
16101   int i;
16102
16103   for (i=2; i<15; i++)
16104     operands[i] = gen_reg_rtx (XFmode);
16105   temp = standard_80387_constant_rtx (5); /* fldl2e */
16106   emit_move_insn (operands[3], temp);
16107   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16108 })
16109
16110 (define_expand "expm1xf2"
16111   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16112                                (match_dup 2)))
16113    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16114    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16115    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16116    (parallel [(set (match_dup 7)
16117                    (unspec:XF [(match_dup 6) (match_dup 4)]
16118                               UNSPEC_FSCALE_FRACT))
16119                    (set (match_dup 8)
16120                    (unspec:XF [(match_dup 6) (match_dup 4)]
16121                               UNSPEC_FSCALE_EXP))])
16122    (parallel [(set (match_dup 10)
16123                    (unspec:XF [(match_dup 9) (match_dup 8)]
16124                               UNSPEC_FSCALE_FRACT))
16125               (set (match_dup 11)
16126                    (unspec:XF [(match_dup 9) (match_dup 8)]
16127                               UNSPEC_FSCALE_EXP))])
16128    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16129    (set (match_operand:XF 0 "register_operand" "")
16130         (plus:XF (match_dup 12) (match_dup 7)))]
16131   "TARGET_USE_FANCY_MATH_387
16132    && flag_unsafe_math_optimizations"
16133 {
16134   rtx temp;
16135   int i;
16136
16137   for (i=2; i<13; i++)
16138     operands[i] = gen_reg_rtx (XFmode);
16139   temp = standard_80387_constant_rtx (5); /* fldl2e */
16140   emit_move_insn (operands[2], temp);
16141   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16142 })
16143
16144 (define_expand "ldexpdf3"
16145   [(set (match_dup 3)
16146         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16147    (set (match_dup 4)
16148         (float:XF (match_operand:SI 2 "register_operand" "")))
16149    (parallel [(set (match_dup 5)
16150                    (unspec:XF [(match_dup 3) (match_dup 4)]
16151                               UNSPEC_FSCALE_FRACT))
16152               (set (match_dup 6)
16153                    (unspec:XF [(match_dup 3) (match_dup 4)]
16154                               UNSPEC_FSCALE_EXP))])
16155    (set (match_operand:DF 0 "register_operand" "")
16156         (float_truncate:DF (match_dup 5)))]
16157   "TARGET_USE_FANCY_MATH_387
16158    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16159    && flag_unsafe_math_optimizations"
16160 {
16161   int i;
16162
16163   for (i=3; i<7; i++)
16164     operands[i] = gen_reg_rtx (XFmode);
16165 })
16166
16167 (define_expand "ldexpsf3"
16168   [(set (match_dup 3)
16169         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16170    (set (match_dup 4)
16171         (float:XF (match_operand:SI 2 "register_operand" "")))
16172    (parallel [(set (match_dup 5)
16173                    (unspec:XF [(match_dup 3) (match_dup 4)]
16174                               UNSPEC_FSCALE_FRACT))
16175               (set (match_dup 6)
16176                    (unspec:XF [(match_dup 3) (match_dup 4)]
16177                               UNSPEC_FSCALE_EXP))])
16178    (set (match_operand:SF 0 "register_operand" "")
16179         (float_truncate:SF (match_dup 5)))]
16180   "TARGET_USE_FANCY_MATH_387
16181    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16182    && flag_unsafe_math_optimizations"
16183 {
16184   int i;
16185
16186   for (i=3; i<7; i++)
16187     operands[i] = gen_reg_rtx (XFmode);
16188 })
16189
16190 (define_expand "ldexpxf3"
16191   [(set (match_dup 3)
16192         (float:XF (match_operand:SI 2 "register_operand" "")))
16193    (parallel [(set (match_operand:XF 0 " register_operand" "")
16194                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16195                                (match_dup 3)]
16196                               UNSPEC_FSCALE_FRACT))
16197               (set (match_dup 4)
16198                    (unspec:XF [(match_dup 1) (match_dup 3)]
16199                               UNSPEC_FSCALE_EXP))])]
16200   "TARGET_USE_FANCY_MATH_387
16201    && flag_unsafe_math_optimizations"
16202 {
16203   int i;
16204
16205   for (i=3; i<5; i++)
16206     operands[i] = gen_reg_rtx (XFmode);
16207 })
16208 \f
16209
16210 (define_insn "frndintxf2"
16211   [(set (match_operand:XF 0 "register_operand" "=f")
16212         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16213          UNSPEC_FRNDINT))]
16214   "TARGET_USE_FANCY_MATH_387
16215    && flag_unsafe_math_optimizations"
16216   "frndint"
16217   [(set_attr "type" "fpspc")
16218    (set_attr "mode" "XF")])
16219
16220 (define_expand "rintdf2"
16221   [(use (match_operand:DF 0 "register_operand" ""))
16222    (use (match_operand:DF 1 "register_operand" ""))]
16223   "TARGET_USE_FANCY_MATH_387
16224    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16225    && flag_unsafe_math_optimizations"
16226 {
16227   rtx op0 = gen_reg_rtx (XFmode);
16228   rtx op1 = gen_reg_rtx (XFmode);
16229
16230   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16231   emit_insn (gen_frndintxf2 (op0, op1));
16232
16233   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16234   DONE;
16235 })
16236
16237 (define_expand "rintsf2"
16238   [(use (match_operand:SF 0 "register_operand" ""))
16239    (use (match_operand:SF 1 "register_operand" ""))]
16240   "TARGET_USE_FANCY_MATH_387
16241    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16242    && flag_unsafe_math_optimizations"
16243 {
16244   rtx op0 = gen_reg_rtx (XFmode);
16245   rtx op1 = gen_reg_rtx (XFmode);
16246
16247   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16248   emit_insn (gen_frndintxf2 (op0, op1));
16249
16250   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16251   DONE;
16252 })
16253
16254 (define_expand "rintxf2"
16255   [(use (match_operand:XF 0 "register_operand" ""))
16256    (use (match_operand:XF 1 "register_operand" ""))]
16257   "TARGET_USE_FANCY_MATH_387
16258    && flag_unsafe_math_optimizations"
16259 {
16260   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16261   DONE;
16262 })
16263
16264 (define_insn "fistdi2"
16265   [(set (match_operand:DI 0 "memory_operand" "=m")
16266         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16267          UNSPEC_FIST))
16268    (clobber (match_scratch:XF 2 "=&1f"))]
16269   "TARGET_USE_FANCY_MATH_387
16270    && flag_unsafe_math_optimizations"
16271   "* return output_fix_trunc (insn, operands, 0);"
16272   [(set_attr "type" "fpspc")
16273    (set_attr "mode" "DI")])
16274
16275 (define_insn "fistdi2_with_temp"
16276   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16277         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16278          UNSPEC_FIST))
16279    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16280    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16281   "TARGET_USE_FANCY_MATH_387
16282    && flag_unsafe_math_optimizations"
16283   "#"
16284   [(set_attr "type" "fpspc")
16285    (set_attr "mode" "DI")])
16286
16287 (define_split 
16288   [(set (match_operand:DI 0 "register_operand" "")
16289         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16290          UNSPEC_FIST))
16291    (clobber (match_operand:DI 2 "memory_operand" ""))
16292    (clobber (match_scratch 3 ""))]
16293   "reload_completed"
16294   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16295               (clobber (match_dup 3))])
16296    (set (match_dup 0) (match_dup 2))]
16297   "")
16298
16299 (define_split 
16300   [(set (match_operand:DI 0 "memory_operand" "")
16301         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16302          UNSPEC_FIST))
16303    (clobber (match_operand:DI 2 "memory_operand" ""))
16304    (clobber (match_scratch 3 ""))]
16305   "reload_completed"
16306   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16307               (clobber (match_dup 3))])]
16308   "")
16309
16310 (define_insn "fist<mode>2"
16311   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16312         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16313          UNSPEC_FIST))]
16314   "TARGET_USE_FANCY_MATH_387
16315    && flag_unsafe_math_optimizations"
16316   "* return output_fix_trunc (insn, operands, 0);"
16317   [(set_attr "type" "fpspc")
16318    (set_attr "mode" "<MODE>")])
16319
16320 (define_insn "fist<mode>2_with_temp"
16321   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16322         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16323          UNSPEC_FIST))
16324    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16325   "TARGET_USE_FANCY_MATH_387
16326    && flag_unsafe_math_optimizations"
16327   "#"
16328   [(set_attr "type" "fpspc")
16329    (set_attr "mode" "<MODE>")])
16330
16331 (define_split 
16332   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16333         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16334          UNSPEC_FIST))
16335    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16336   "reload_completed"
16337   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16338                        UNSPEC_FIST))
16339    (set (match_dup 0) (match_dup 2))]
16340   "")
16341
16342 (define_split 
16343   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16344         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16345          UNSPEC_FIST))
16346    (clobber (match_scratch 2 ""))]
16347   "reload_completed"
16348   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16349                        UNSPEC_FIST))]
16350   "")
16351
16352 (define_expand "lrint<mode>2"
16353   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16354    (use (match_operand:XF 1 "register_operand" ""))]
16355   "TARGET_USE_FANCY_MATH_387
16356    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16357    && flag_unsafe_math_optimizations"
16358 {
16359   if (memory_operand (operands[0], VOIDmode))
16360     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16361   else
16362     {
16363       operands[2] = assign_386_stack_local (<MODE>mode, 0);
16364       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16365                                             operands[2]));
16366     }
16367   DONE;
16368 })
16369
16370 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16371 (define_insn_and_split "frndintxf2_floor"
16372   [(set (match_operand:XF 0 "register_operand" "=f")
16373         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16374          UNSPEC_FRNDINT_FLOOR))
16375    (clobber (reg:CC FLAGS_REG))]
16376   "TARGET_USE_FANCY_MATH_387
16377    && flag_unsafe_math_optimizations
16378    && !(reload_completed || reload_in_progress)"
16379   "#"
16380   "&& 1"
16381   [(const_int 0)]
16382 {
16383   ix86_optimize_mode_switching = 1;
16384
16385   operands[2] = assign_386_stack_local (HImode, 1);
16386   operands[3] = assign_386_stack_local (HImode, 2);
16387
16388   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16389                                         operands[2], operands[3]));
16390   DONE;
16391 }
16392   [(set_attr "type" "frndint")
16393    (set_attr "i387_cw" "floor")
16394    (set_attr "mode" "XF")])
16395
16396 (define_insn "frndintxf2_floor_i387"
16397   [(set (match_operand:XF 0 "register_operand" "=f")
16398         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16399          UNSPEC_FRNDINT_FLOOR))
16400    (use (match_operand:HI 2 "memory_operand" "m"))
16401    (use (match_operand:HI 3 "memory_operand" "m"))]
16402   "TARGET_USE_FANCY_MATH_387
16403    && flag_unsafe_math_optimizations"
16404   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16405   [(set_attr "type" "frndint")
16406    (set_attr "i387_cw" "floor")
16407    (set_attr "mode" "XF")])
16408
16409 (define_expand "floorxf2"
16410   [(use (match_operand:XF 0 "register_operand" ""))
16411    (use (match_operand:XF 1 "register_operand" ""))]
16412   "TARGET_USE_FANCY_MATH_387
16413    && flag_unsafe_math_optimizations"
16414 {
16415   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16416   DONE;
16417 })
16418
16419 (define_expand "floordf2"
16420   [(use (match_operand:DF 0 "register_operand" ""))
16421    (use (match_operand:DF 1 "register_operand" ""))]
16422   "TARGET_USE_FANCY_MATH_387
16423    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16424    && flag_unsafe_math_optimizations"
16425 {
16426   rtx op0 = gen_reg_rtx (XFmode);
16427   rtx op1 = gen_reg_rtx (XFmode);
16428
16429   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16430   emit_insn (gen_frndintxf2_floor (op0, op1));
16431
16432   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16433   DONE;
16434 })
16435
16436 (define_expand "floorsf2"
16437   [(use (match_operand:SF 0 "register_operand" ""))
16438    (use (match_operand:SF 1 "register_operand" ""))]
16439   "TARGET_USE_FANCY_MATH_387
16440    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16441    && flag_unsafe_math_optimizations"
16442 {
16443   rtx op0 = gen_reg_rtx (XFmode);
16444   rtx op1 = gen_reg_rtx (XFmode);
16445
16446   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16447   emit_insn (gen_frndintxf2_floor (op0, op1));
16448
16449   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16450   DONE;
16451 })
16452
16453 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16454 (define_insn_and_split "frndintxf2_ceil"
16455   [(set (match_operand:XF 0 "register_operand" "=f")
16456         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16457          UNSPEC_FRNDINT_CEIL))
16458    (clobber (reg:CC FLAGS_REG))]
16459   "TARGET_USE_FANCY_MATH_387
16460    && flag_unsafe_math_optimizations
16461    && !(reload_completed || reload_in_progress)"
16462   "#"
16463   "&& 1"
16464   [(const_int 0)]
16465 {
16466   ix86_optimize_mode_switching = 1;
16467
16468   operands[2] = assign_386_stack_local (HImode, 1);
16469   operands[3] = assign_386_stack_local (HImode, 2);
16470
16471   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16472                                        operands[2], operands[3]));
16473   DONE;
16474 }
16475   [(set_attr "type" "frndint")
16476    (set_attr "i387_cw" "ceil")
16477    (set_attr "mode" "XF")])
16478
16479 (define_insn "frndintxf2_ceil_i387"
16480   [(set (match_operand:XF 0 "register_operand" "=f")
16481         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16482          UNSPEC_FRNDINT_CEIL))
16483    (use (match_operand:HI 2 "memory_operand" "m"))
16484    (use (match_operand:HI 3 "memory_operand" "m"))]
16485   "TARGET_USE_FANCY_MATH_387
16486    && flag_unsafe_math_optimizations"
16487   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16488   [(set_attr "type" "frndint")
16489    (set_attr "i387_cw" "ceil")
16490    (set_attr "mode" "XF")])
16491
16492 (define_expand "ceilxf2"
16493   [(use (match_operand:XF 0 "register_operand" ""))
16494    (use (match_operand:XF 1 "register_operand" ""))]
16495   "TARGET_USE_FANCY_MATH_387
16496    && flag_unsafe_math_optimizations"
16497 {
16498   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16499   DONE;
16500 })
16501
16502 (define_expand "ceildf2"
16503   [(use (match_operand:DF 0 "register_operand" ""))
16504    (use (match_operand:DF 1 "register_operand" ""))]
16505   "TARGET_USE_FANCY_MATH_387
16506    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16507    && flag_unsafe_math_optimizations"
16508 {
16509   rtx op0 = gen_reg_rtx (XFmode);
16510   rtx op1 = gen_reg_rtx (XFmode);
16511
16512   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16513   emit_insn (gen_frndintxf2_ceil (op0, op1));
16514
16515   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16516   DONE;
16517 })
16518
16519 (define_expand "ceilsf2"
16520   [(use (match_operand:SF 0 "register_operand" ""))
16521    (use (match_operand:SF 1 "register_operand" ""))]
16522   "TARGET_USE_FANCY_MATH_387
16523    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16524    && flag_unsafe_math_optimizations"
16525 {
16526   rtx op0 = gen_reg_rtx (XFmode);
16527   rtx op1 = gen_reg_rtx (XFmode);
16528
16529   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16530   emit_insn (gen_frndintxf2_ceil (op0, op1));
16531
16532   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16533   DONE;
16534 })
16535
16536 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16537 (define_insn_and_split "frndintxf2_trunc"
16538   [(set (match_operand:XF 0 "register_operand" "=f")
16539         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16540          UNSPEC_FRNDINT_TRUNC))
16541    (clobber (reg:CC FLAGS_REG))]
16542   "TARGET_USE_FANCY_MATH_387
16543    && flag_unsafe_math_optimizations
16544    && !(reload_completed || reload_in_progress)"
16545   "#"
16546   "&& 1"
16547   [(const_int 0)]
16548 {
16549   ix86_optimize_mode_switching = 1;
16550
16551   operands[2] = assign_386_stack_local (HImode, 1);
16552   operands[3] = assign_386_stack_local (HImode, 2);
16553
16554   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16555                                         operands[2], operands[3]));
16556   DONE;
16557 }
16558   [(set_attr "type" "frndint")
16559    (set_attr "i387_cw" "trunc")
16560    (set_attr "mode" "XF")])
16561
16562 (define_insn "frndintxf2_trunc_i387"
16563   [(set (match_operand:XF 0 "register_operand" "=f")
16564         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16565          UNSPEC_FRNDINT_TRUNC))
16566    (use (match_operand:HI 2 "memory_operand" "m"))
16567    (use (match_operand:HI 3 "memory_operand" "m"))]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16570   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16571   [(set_attr "type" "frndint")
16572    (set_attr "i387_cw" "trunc")
16573    (set_attr "mode" "XF")])
16574
16575 (define_expand "btruncxf2"
16576   [(use (match_operand:XF 0 "register_operand" ""))
16577    (use (match_operand:XF 1 "register_operand" ""))]
16578   "TARGET_USE_FANCY_MATH_387
16579    && flag_unsafe_math_optimizations"
16580 {
16581   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16582   DONE;
16583 })
16584
16585 (define_expand "btruncdf2"
16586   [(use (match_operand:DF 0 "register_operand" ""))
16587    (use (match_operand:DF 1 "register_operand" ""))]
16588   "TARGET_USE_FANCY_MATH_387
16589    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16590    && flag_unsafe_math_optimizations"
16591 {
16592   rtx op0 = gen_reg_rtx (XFmode);
16593   rtx op1 = gen_reg_rtx (XFmode);
16594
16595   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16596   emit_insn (gen_frndintxf2_trunc (op0, op1));
16597
16598   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16599   DONE;
16600 })
16601
16602 (define_expand "btruncsf2"
16603   [(use (match_operand:SF 0 "register_operand" ""))
16604    (use (match_operand:SF 1 "register_operand" ""))]
16605   "TARGET_USE_FANCY_MATH_387
16606    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16607    && flag_unsafe_math_optimizations"
16608 {
16609   rtx op0 = gen_reg_rtx (XFmode);
16610   rtx op1 = gen_reg_rtx (XFmode);
16611
16612   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16613   emit_insn (gen_frndintxf2_trunc (op0, op1));
16614
16615   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16616   DONE;
16617 })
16618
16619 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16620 (define_insn_and_split "frndintxf2_mask_pm"
16621   [(set (match_operand:XF 0 "register_operand" "=f")
16622         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16623          UNSPEC_FRNDINT_MASK_PM))
16624    (clobber (reg:CC FLAGS_REG))]
16625   "TARGET_USE_FANCY_MATH_387
16626    && flag_unsafe_math_optimizations
16627    && !(reload_completed || reload_in_progress)"
16628   "#"
16629   "&& 1"
16630   [(const_int 0)]
16631 {
16632   ix86_optimize_mode_switching = 1;
16633
16634   operands[2] = assign_386_stack_local (HImode, 1);
16635   operands[3] = assign_386_stack_local (HImode, 2);
16636
16637   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16638                                           operands[2], operands[3]));
16639   DONE;
16640 }
16641   [(set_attr "type" "frndint")
16642    (set_attr "i387_cw" "mask_pm")
16643    (set_attr "mode" "XF")])
16644
16645 (define_insn "frndintxf2_mask_pm_i387"
16646   [(set (match_operand:XF 0 "register_operand" "=f")
16647         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16648          UNSPEC_FRNDINT_MASK_PM))
16649    (use (match_operand:HI 2 "memory_operand" "m"))
16650    (use (match_operand:HI 3 "memory_operand" "m"))]
16651   "TARGET_USE_FANCY_MATH_387
16652    && flag_unsafe_math_optimizations"
16653   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16654   [(set_attr "type" "frndint")
16655    (set_attr "i387_cw" "mask_pm")
16656    (set_attr "mode" "XF")])
16657
16658 (define_expand "nearbyintxf2"
16659   [(use (match_operand:XF 0 "register_operand" ""))
16660    (use (match_operand:XF 1 "register_operand" ""))]
16661   "TARGET_USE_FANCY_MATH_387
16662    && flag_unsafe_math_optimizations"
16663 {
16664   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16665
16666   DONE;
16667 })
16668
16669 (define_expand "nearbyintdf2"
16670   [(use (match_operand:DF 0 "register_operand" ""))
16671    (use (match_operand:DF 1 "register_operand" ""))]
16672   "TARGET_USE_FANCY_MATH_387
16673    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16674    && flag_unsafe_math_optimizations"
16675 {
16676   rtx op0 = gen_reg_rtx (XFmode);
16677   rtx op1 = gen_reg_rtx (XFmode);
16678
16679   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16680   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16681
16682   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16683   DONE;
16684 })
16685
16686 (define_expand "nearbyintsf2"
16687   [(use (match_operand:SF 0 "register_operand" ""))
16688    (use (match_operand:SF 1 "register_operand" ""))]
16689   "TARGET_USE_FANCY_MATH_387
16690    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16691    && flag_unsafe_math_optimizations"
16692 {
16693   rtx op0 = gen_reg_rtx (XFmode);
16694   rtx op1 = gen_reg_rtx (XFmode);
16695
16696   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16697   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16698
16699   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16700   DONE;
16701 })
16702
16703 \f
16704 ;; Block operation instructions
16705
16706 (define_insn "cld"
16707  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16708  ""
16709  "cld"
16710   [(set_attr "type" "cld")])
16711
16712 (define_expand "movmemsi"
16713   [(use (match_operand:BLK 0 "memory_operand" ""))
16714    (use (match_operand:BLK 1 "memory_operand" ""))
16715    (use (match_operand:SI 2 "nonmemory_operand" ""))
16716    (use (match_operand:SI 3 "const_int_operand" ""))]
16717   "! optimize_size"
16718 {
16719  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16720    DONE;
16721  else
16722    FAIL;
16723 })
16724
16725 (define_expand "movmemdi"
16726   [(use (match_operand:BLK 0 "memory_operand" ""))
16727    (use (match_operand:BLK 1 "memory_operand" ""))
16728    (use (match_operand:DI 2 "nonmemory_operand" ""))
16729    (use (match_operand:DI 3 "const_int_operand" ""))]
16730   "TARGET_64BIT"
16731 {
16732  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16733    DONE;
16734  else
16735    FAIL;
16736 })
16737
16738 ;; Most CPUs don't like single string operations
16739 ;; Handle this case here to simplify previous expander.
16740
16741 (define_expand "strmov"
16742   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16743    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16744    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16745               (clobber (reg:CC FLAGS_REG))])
16746    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16747               (clobber (reg:CC FLAGS_REG))])]
16748   ""
16749 {
16750   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16751
16752   /* If .md ever supports :P for Pmode, these can be directly
16753      in the pattern above.  */
16754   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16755   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16756
16757   if (TARGET_SINGLE_STRINGOP || optimize_size)
16758     {
16759       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16760                                       operands[2], operands[3],
16761                                       operands[5], operands[6]));
16762       DONE;
16763     }
16764
16765   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16766 })
16767
16768 (define_expand "strmov_singleop"
16769   [(parallel [(set (match_operand 1 "memory_operand" "")
16770                    (match_operand 3 "memory_operand" ""))
16771               (set (match_operand 0 "register_operand" "")
16772                    (match_operand 4 "" ""))
16773               (set (match_operand 2 "register_operand" "")
16774                    (match_operand 5 "" ""))
16775               (use (reg:SI DIRFLAG_REG))])]
16776   "TARGET_SINGLE_STRINGOP || optimize_size"
16777   "")
16778
16779 (define_insn "*strmovdi_rex_1"
16780   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16781         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16782    (set (match_operand:DI 0 "register_operand" "=D")
16783         (plus:DI (match_dup 2)
16784                  (const_int 8)))
16785    (set (match_operand:DI 1 "register_operand" "=S")
16786         (plus:DI (match_dup 3)
16787                  (const_int 8)))
16788    (use (reg:SI DIRFLAG_REG))]
16789   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16790   "movsq"
16791   [(set_attr "type" "str")
16792    (set_attr "mode" "DI")
16793    (set_attr "memory" "both")])
16794
16795 (define_insn "*strmovsi_1"
16796   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16797         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16798    (set (match_operand:SI 0 "register_operand" "=D")
16799         (plus:SI (match_dup 2)
16800                  (const_int 4)))
16801    (set (match_operand:SI 1 "register_operand" "=S")
16802         (plus:SI (match_dup 3)
16803                  (const_int 4)))
16804    (use (reg:SI DIRFLAG_REG))]
16805   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16806   "{movsl|movsd}"
16807   [(set_attr "type" "str")
16808    (set_attr "mode" "SI")
16809    (set_attr "memory" "both")])
16810
16811 (define_insn "*strmovsi_rex_1"
16812   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16813         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16814    (set (match_operand:DI 0 "register_operand" "=D")
16815         (plus:DI (match_dup 2)
16816                  (const_int 4)))
16817    (set (match_operand:DI 1 "register_operand" "=S")
16818         (plus:DI (match_dup 3)
16819                  (const_int 4)))
16820    (use (reg:SI DIRFLAG_REG))]
16821   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16822   "{movsl|movsd}"
16823   [(set_attr "type" "str")
16824    (set_attr "mode" "SI")
16825    (set_attr "memory" "both")])
16826
16827 (define_insn "*strmovhi_1"
16828   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16829         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16830    (set (match_operand:SI 0 "register_operand" "=D")
16831         (plus:SI (match_dup 2)
16832                  (const_int 2)))
16833    (set (match_operand:SI 1 "register_operand" "=S")
16834         (plus:SI (match_dup 3)
16835                  (const_int 2)))
16836    (use (reg:SI DIRFLAG_REG))]
16837   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16838   "movsw"
16839   [(set_attr "type" "str")
16840    (set_attr "memory" "both")
16841    (set_attr "mode" "HI")])
16842
16843 (define_insn "*strmovhi_rex_1"
16844   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16845         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16846    (set (match_operand:DI 0 "register_operand" "=D")
16847         (plus:DI (match_dup 2)
16848                  (const_int 2)))
16849    (set (match_operand:DI 1 "register_operand" "=S")
16850         (plus:DI (match_dup 3)
16851                  (const_int 2)))
16852    (use (reg:SI DIRFLAG_REG))]
16853   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16854   "movsw"
16855   [(set_attr "type" "str")
16856    (set_attr "memory" "both")
16857    (set_attr "mode" "HI")])
16858
16859 (define_insn "*strmovqi_1"
16860   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16861         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16862    (set (match_operand:SI 0 "register_operand" "=D")
16863         (plus:SI (match_dup 2)
16864                  (const_int 1)))
16865    (set (match_operand:SI 1 "register_operand" "=S")
16866         (plus:SI (match_dup 3)
16867                  (const_int 1)))
16868    (use (reg:SI DIRFLAG_REG))]
16869   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16870   "movsb"
16871   [(set_attr "type" "str")
16872    (set_attr "memory" "both")
16873    (set_attr "mode" "QI")])
16874
16875 (define_insn "*strmovqi_rex_1"
16876   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16877         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16878    (set (match_operand:DI 0 "register_operand" "=D")
16879         (plus:DI (match_dup 2)
16880                  (const_int 1)))
16881    (set (match_operand:DI 1 "register_operand" "=S")
16882         (plus:DI (match_dup 3)
16883                  (const_int 1)))
16884    (use (reg:SI DIRFLAG_REG))]
16885   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16886   "movsb"
16887   [(set_attr "type" "str")
16888    (set_attr "memory" "both")
16889    (set_attr "mode" "QI")])
16890
16891 (define_expand "rep_mov"
16892   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16893               (set (match_operand 0 "register_operand" "")
16894                    (match_operand 5 "" ""))
16895               (set (match_operand 2 "register_operand" "")
16896                    (match_operand 6 "" ""))
16897               (set (match_operand 1 "memory_operand" "")
16898                    (match_operand 3 "memory_operand" ""))
16899               (use (match_dup 4))
16900               (use (reg:SI DIRFLAG_REG))])]
16901   ""
16902   "")
16903
16904 (define_insn "*rep_movdi_rex64"
16905   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16906    (set (match_operand:DI 0 "register_operand" "=D") 
16907         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16908                             (const_int 3))
16909                  (match_operand:DI 3 "register_operand" "0")))
16910    (set (match_operand:DI 1 "register_operand" "=S") 
16911         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16912                  (match_operand:DI 4 "register_operand" "1")))
16913    (set (mem:BLK (match_dup 3))
16914         (mem:BLK (match_dup 4)))
16915    (use (match_dup 5))
16916    (use (reg:SI DIRFLAG_REG))]
16917   "TARGET_64BIT"
16918   "{rep\;movsq|rep movsq}"
16919   [(set_attr "type" "str")
16920    (set_attr "prefix_rep" "1")
16921    (set_attr "memory" "both")
16922    (set_attr "mode" "DI")])
16923
16924 (define_insn "*rep_movsi"
16925   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16926    (set (match_operand:SI 0 "register_operand" "=D") 
16927         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16928                             (const_int 2))
16929                  (match_operand:SI 3 "register_operand" "0")))
16930    (set (match_operand:SI 1 "register_operand" "=S") 
16931         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16932                  (match_operand:SI 4 "register_operand" "1")))
16933    (set (mem:BLK (match_dup 3))
16934         (mem:BLK (match_dup 4)))
16935    (use (match_dup 5))
16936    (use (reg:SI DIRFLAG_REG))]
16937   "!TARGET_64BIT"
16938   "{rep\;movsl|rep movsd}"
16939   [(set_attr "type" "str")
16940    (set_attr "prefix_rep" "1")
16941    (set_attr "memory" "both")
16942    (set_attr "mode" "SI")])
16943
16944 (define_insn "*rep_movsi_rex64"
16945   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16946    (set (match_operand:DI 0 "register_operand" "=D") 
16947         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16948                             (const_int 2))
16949                  (match_operand:DI 3 "register_operand" "0")))
16950    (set (match_operand:DI 1 "register_operand" "=S") 
16951         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16952                  (match_operand:DI 4 "register_operand" "1")))
16953    (set (mem:BLK (match_dup 3))
16954         (mem:BLK (match_dup 4)))
16955    (use (match_dup 5))
16956    (use (reg:SI DIRFLAG_REG))]
16957   "TARGET_64BIT"
16958   "{rep\;movsl|rep movsd}"
16959   [(set_attr "type" "str")
16960    (set_attr "prefix_rep" "1")
16961    (set_attr "memory" "both")
16962    (set_attr "mode" "SI")])
16963
16964 (define_insn "*rep_movqi"
16965   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16966    (set (match_operand:SI 0 "register_operand" "=D") 
16967         (plus:SI (match_operand:SI 3 "register_operand" "0")
16968                  (match_operand:SI 5 "register_operand" "2")))
16969    (set (match_operand:SI 1 "register_operand" "=S") 
16970         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16971    (set (mem:BLK (match_dup 3))
16972         (mem:BLK (match_dup 4)))
16973    (use (match_dup 5))
16974    (use (reg:SI DIRFLAG_REG))]
16975   "!TARGET_64BIT"
16976   "{rep\;movsb|rep movsb}"
16977   [(set_attr "type" "str")
16978    (set_attr "prefix_rep" "1")
16979    (set_attr "memory" "both")
16980    (set_attr "mode" "SI")])
16981
16982 (define_insn "*rep_movqi_rex64"
16983   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16984    (set (match_operand:DI 0 "register_operand" "=D") 
16985         (plus:DI (match_operand:DI 3 "register_operand" "0")
16986                  (match_operand:DI 5 "register_operand" "2")))
16987    (set (match_operand:DI 1 "register_operand" "=S") 
16988         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16989    (set (mem:BLK (match_dup 3))
16990         (mem:BLK (match_dup 4)))
16991    (use (match_dup 5))
16992    (use (reg:SI DIRFLAG_REG))]
16993   "TARGET_64BIT"
16994   "{rep\;movsb|rep movsb}"
16995   [(set_attr "type" "str")
16996    (set_attr "prefix_rep" "1")
16997    (set_attr "memory" "both")
16998    (set_attr "mode" "SI")])
16999
17000 (define_expand "clrmemsi"
17001    [(use (match_operand:BLK 0 "memory_operand" ""))
17002     (use (match_operand:SI 1 "nonmemory_operand" ""))
17003     (use (match_operand 2 "const_int_operand" ""))]
17004   ""
17005 {
17006  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17007    DONE;
17008  else
17009    FAIL;
17010 })
17011
17012 (define_expand "clrmemdi"
17013    [(use (match_operand:BLK 0 "memory_operand" ""))
17014     (use (match_operand:DI 1 "nonmemory_operand" ""))
17015     (use (match_operand 2 "const_int_operand" ""))]
17016   "TARGET_64BIT"
17017 {
17018  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17019    DONE;
17020  else
17021    FAIL;
17022 })
17023
17024 ;; Most CPUs don't like single string operations
17025 ;; Handle this case here to simplify previous expander.
17026
17027 (define_expand "strset"
17028   [(set (match_operand 1 "memory_operand" "")
17029         (match_operand 2 "register_operand" ""))
17030    (parallel [(set (match_operand 0 "register_operand" "")
17031                    (match_dup 3))
17032               (clobber (reg:CC FLAGS_REG))])]
17033   ""
17034 {
17035   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17036     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17037
17038   /* If .md ever supports :P for Pmode, this can be directly
17039      in the pattern above.  */
17040   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17041                               GEN_INT (GET_MODE_SIZE (GET_MODE
17042                                                       (operands[2]))));
17043   if (TARGET_SINGLE_STRINGOP || optimize_size)
17044     {
17045       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17046                                       operands[3]));
17047       DONE;
17048     }
17049 })
17050
17051 (define_expand "strset_singleop"
17052   [(parallel [(set (match_operand 1 "memory_operand" "")
17053                    (match_operand 2 "register_operand" ""))
17054               (set (match_operand 0 "register_operand" "")
17055                    (match_operand 3 "" ""))
17056               (use (reg:SI DIRFLAG_REG))])]
17057   "TARGET_SINGLE_STRINGOP || optimize_size"
17058   "")
17059
17060 (define_insn "*strsetdi_rex_1"
17061   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17062         (match_operand:DI 2 "register_operand" "a"))
17063    (set (match_operand:DI 0 "register_operand" "=D")
17064         (plus:DI (match_dup 1)
17065                  (const_int 8)))
17066    (use (reg:SI DIRFLAG_REG))]
17067   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17068   "stosq"
17069   [(set_attr "type" "str")
17070    (set_attr "memory" "store")
17071    (set_attr "mode" "DI")])
17072
17073 (define_insn "*strsetsi_1"
17074   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17075         (match_operand:SI 2 "register_operand" "a"))
17076    (set (match_operand:SI 0 "register_operand" "=D")
17077         (plus:SI (match_dup 1)
17078                  (const_int 4)))
17079    (use (reg:SI DIRFLAG_REG))]
17080   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17081   "{stosl|stosd}"
17082   [(set_attr "type" "str")
17083    (set_attr "memory" "store")
17084    (set_attr "mode" "SI")])
17085
17086 (define_insn "*strsetsi_rex_1"
17087   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17088         (match_operand:SI 2 "register_operand" "a"))
17089    (set (match_operand:DI 0 "register_operand" "=D")
17090         (plus:DI (match_dup 1)
17091                  (const_int 4)))
17092    (use (reg:SI DIRFLAG_REG))]
17093   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17094   "{stosl|stosd}"
17095   [(set_attr "type" "str")
17096    (set_attr "memory" "store")
17097    (set_attr "mode" "SI")])
17098
17099 (define_insn "*strsethi_1"
17100   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17101         (match_operand:HI 2 "register_operand" "a"))
17102    (set (match_operand:SI 0 "register_operand" "=D")
17103         (plus:SI (match_dup 1)
17104                  (const_int 2)))
17105    (use (reg:SI DIRFLAG_REG))]
17106   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17107   "stosw"
17108   [(set_attr "type" "str")
17109    (set_attr "memory" "store")
17110    (set_attr "mode" "HI")])
17111
17112 (define_insn "*strsethi_rex_1"
17113   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17114         (match_operand:HI 2 "register_operand" "a"))
17115    (set (match_operand:DI 0 "register_operand" "=D")
17116         (plus:DI (match_dup 1)
17117                  (const_int 2)))
17118    (use (reg:SI DIRFLAG_REG))]
17119   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17120   "stosw"
17121   [(set_attr "type" "str")
17122    (set_attr "memory" "store")
17123    (set_attr "mode" "HI")])
17124
17125 (define_insn "*strsetqi_1"
17126   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17127         (match_operand:QI 2 "register_operand" "a"))
17128    (set (match_operand:SI 0 "register_operand" "=D")
17129         (plus:SI (match_dup 1)
17130                  (const_int 1)))
17131    (use (reg:SI DIRFLAG_REG))]
17132   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17133   "stosb"
17134   [(set_attr "type" "str")
17135    (set_attr "memory" "store")
17136    (set_attr "mode" "QI")])
17137
17138 (define_insn "*strsetqi_rex_1"
17139   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17140         (match_operand:QI 2 "register_operand" "a"))
17141    (set (match_operand:DI 0 "register_operand" "=D")
17142         (plus:DI (match_dup 1)
17143                  (const_int 1)))
17144    (use (reg:SI DIRFLAG_REG))]
17145   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17146   "stosb"
17147   [(set_attr "type" "str")
17148    (set_attr "memory" "store")
17149    (set_attr "mode" "QI")])
17150
17151 (define_expand "rep_stos"
17152   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17153               (set (match_operand 0 "register_operand" "")
17154                    (match_operand 4 "" ""))
17155               (set (match_operand 2 "memory_operand" "") (const_int 0))
17156               (use (match_operand 3 "register_operand" ""))
17157               (use (match_dup 1))
17158               (use (reg:SI DIRFLAG_REG))])]
17159   ""
17160   "")
17161
17162 (define_insn "*rep_stosdi_rex64"
17163   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17164    (set (match_operand:DI 0 "register_operand" "=D") 
17165         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17166                             (const_int 3))
17167                  (match_operand:DI 3 "register_operand" "0")))
17168    (set (mem:BLK (match_dup 3))
17169         (const_int 0))
17170    (use (match_operand:DI 2 "register_operand" "a"))
17171    (use (match_dup 4))
17172    (use (reg:SI DIRFLAG_REG))]
17173   "TARGET_64BIT"
17174   "{rep\;stosq|rep stosq}"
17175   [(set_attr "type" "str")
17176    (set_attr "prefix_rep" "1")
17177    (set_attr "memory" "store")
17178    (set_attr "mode" "DI")])
17179
17180 (define_insn "*rep_stossi"
17181   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17182    (set (match_operand:SI 0 "register_operand" "=D") 
17183         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17184                             (const_int 2))
17185                  (match_operand:SI 3 "register_operand" "0")))
17186    (set (mem:BLK (match_dup 3))
17187         (const_int 0))
17188    (use (match_operand:SI 2 "register_operand" "a"))
17189    (use (match_dup 4))
17190    (use (reg:SI DIRFLAG_REG))]
17191   "!TARGET_64BIT"
17192   "{rep\;stosl|rep stosd}"
17193   [(set_attr "type" "str")
17194    (set_attr "prefix_rep" "1")
17195    (set_attr "memory" "store")
17196    (set_attr "mode" "SI")])
17197
17198 (define_insn "*rep_stossi_rex64"
17199   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17200    (set (match_operand:DI 0 "register_operand" "=D") 
17201         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17202                             (const_int 2))
17203                  (match_operand:DI 3 "register_operand" "0")))
17204    (set (mem:BLK (match_dup 3))
17205         (const_int 0))
17206    (use (match_operand:SI 2 "register_operand" "a"))
17207    (use (match_dup 4))
17208    (use (reg:SI DIRFLAG_REG))]
17209   "TARGET_64BIT"
17210   "{rep\;stosl|rep stosd}"
17211   [(set_attr "type" "str")
17212    (set_attr "prefix_rep" "1")
17213    (set_attr "memory" "store")
17214    (set_attr "mode" "SI")])
17215
17216 (define_insn "*rep_stosqi"
17217   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17218    (set (match_operand:SI 0 "register_operand" "=D") 
17219         (plus:SI (match_operand:SI 3 "register_operand" "0")
17220                  (match_operand:SI 4 "register_operand" "1")))
17221    (set (mem:BLK (match_dup 3))
17222         (const_int 0))
17223    (use (match_operand:QI 2 "register_operand" "a"))
17224    (use (match_dup 4))
17225    (use (reg:SI DIRFLAG_REG))]
17226   "!TARGET_64BIT"
17227   "{rep\;stosb|rep stosb}"
17228   [(set_attr "type" "str")
17229    (set_attr "prefix_rep" "1")
17230    (set_attr "memory" "store")
17231    (set_attr "mode" "QI")])
17232
17233 (define_insn "*rep_stosqi_rex64"
17234   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17235    (set (match_operand:DI 0 "register_operand" "=D") 
17236         (plus:DI (match_operand:DI 3 "register_operand" "0")
17237                  (match_operand:DI 4 "register_operand" "1")))
17238    (set (mem:BLK (match_dup 3))
17239         (const_int 0))
17240    (use (match_operand:QI 2 "register_operand" "a"))
17241    (use (match_dup 4))
17242    (use (reg:SI DIRFLAG_REG))]
17243   "TARGET_64BIT"
17244   "{rep\;stosb|rep stosb}"
17245   [(set_attr "type" "str")
17246    (set_attr "prefix_rep" "1")
17247    (set_attr "memory" "store")
17248    (set_attr "mode" "QI")])
17249
17250 (define_expand "cmpstrsi"
17251   [(set (match_operand:SI 0 "register_operand" "")
17252         (compare:SI (match_operand:BLK 1 "general_operand" "")
17253                     (match_operand:BLK 2 "general_operand" "")))
17254    (use (match_operand 3 "general_operand" ""))
17255    (use (match_operand 4 "immediate_operand" ""))]
17256   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17257 {
17258   rtx addr1, addr2, out, outlow, count, countreg, align;
17259
17260   /* Can't use this if the user has appropriated esi or edi.  */
17261   if (global_regs[4] || global_regs[5])
17262     FAIL;
17263
17264   out = operands[0];
17265   if (GET_CODE (out) != REG)
17266     out = gen_reg_rtx (SImode);
17267
17268   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17269   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17270   if (addr1 != XEXP (operands[1], 0))
17271     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17272   if (addr2 != XEXP (operands[2], 0))
17273     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17274
17275   count = operands[3];
17276   countreg = ix86_zero_extend_to_Pmode (count);
17277
17278   /* %%% Iff we are testing strict equality, we can use known alignment
17279      to good advantage.  This may be possible with combine, particularly
17280      once cc0 is dead.  */
17281   align = operands[4];
17282
17283   emit_insn (gen_cld ());
17284   if (GET_CODE (count) == CONST_INT)
17285     {
17286       if (INTVAL (count) == 0)
17287         {
17288           emit_move_insn (operands[0], const0_rtx);
17289           DONE;
17290         }
17291       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17292                                     operands[1], operands[2]));
17293     }
17294   else
17295     {
17296       if (TARGET_64BIT)
17297         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17298       else
17299         emit_insn (gen_cmpsi_1 (countreg, countreg));
17300       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17301                                  operands[1], operands[2]));
17302     }
17303
17304   outlow = gen_lowpart (QImode, out);
17305   emit_insn (gen_cmpintqi (outlow));
17306   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17307
17308   if (operands[0] != out)
17309     emit_move_insn (operands[0], out);
17310
17311   DONE;
17312 })
17313
17314 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17315
17316 (define_expand "cmpintqi"
17317   [(set (match_dup 1)
17318         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17319    (set (match_dup 2)
17320         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17321    (parallel [(set (match_operand:QI 0 "register_operand" "")
17322                    (minus:QI (match_dup 1)
17323                              (match_dup 2)))
17324               (clobber (reg:CC FLAGS_REG))])]
17325   ""
17326   "operands[1] = gen_reg_rtx (QImode);
17327    operands[2] = gen_reg_rtx (QImode);")
17328
17329 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17330 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17331
17332 (define_expand "cmpstrqi_nz_1"
17333   [(parallel [(set (reg:CC FLAGS_REG)
17334                    (compare:CC (match_operand 4 "memory_operand" "")
17335                                (match_operand 5 "memory_operand" "")))
17336               (use (match_operand 2 "register_operand" ""))
17337               (use (match_operand:SI 3 "immediate_operand" ""))
17338               (use (reg:SI DIRFLAG_REG))
17339               (clobber (match_operand 0 "register_operand" ""))
17340               (clobber (match_operand 1 "register_operand" ""))
17341               (clobber (match_dup 2))])]
17342   ""
17343   "")
17344
17345 (define_insn "*cmpstrqi_nz_1"
17346   [(set (reg:CC FLAGS_REG)
17347         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17348                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17349    (use (match_operand:SI 6 "register_operand" "2"))
17350    (use (match_operand:SI 3 "immediate_operand" "i"))
17351    (use (reg:SI DIRFLAG_REG))
17352    (clobber (match_operand:SI 0 "register_operand" "=S"))
17353    (clobber (match_operand:SI 1 "register_operand" "=D"))
17354    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17355   "!TARGET_64BIT"
17356   "repz{\;| }cmpsb"
17357   [(set_attr "type" "str")
17358    (set_attr "mode" "QI")
17359    (set_attr "prefix_rep" "1")])
17360
17361 (define_insn "*cmpstrqi_nz_rex_1"
17362   [(set (reg:CC FLAGS_REG)
17363         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17364                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17365    (use (match_operand:DI 6 "register_operand" "2"))
17366    (use (match_operand:SI 3 "immediate_operand" "i"))
17367    (use (reg:SI DIRFLAG_REG))
17368    (clobber (match_operand:DI 0 "register_operand" "=S"))
17369    (clobber (match_operand:DI 1 "register_operand" "=D"))
17370    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17371   "TARGET_64BIT"
17372   "repz{\;| }cmpsb"
17373   [(set_attr "type" "str")
17374    (set_attr "mode" "QI")
17375    (set_attr "prefix_rep" "1")])
17376
17377 ;; The same, but the count is not known to not be zero.
17378
17379 (define_expand "cmpstrqi_1"
17380   [(parallel [(set (reg:CC FLAGS_REG)
17381                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17382                                      (const_int 0))
17383                   (compare:CC (match_operand 4 "memory_operand" "")
17384                               (match_operand 5 "memory_operand" ""))
17385                   (const_int 0)))
17386               (use (match_operand:SI 3 "immediate_operand" ""))
17387               (use (reg:CC FLAGS_REG))
17388               (use (reg:SI DIRFLAG_REG))
17389               (clobber (match_operand 0 "register_operand" ""))
17390               (clobber (match_operand 1 "register_operand" ""))
17391               (clobber (match_dup 2))])]
17392   ""
17393   "")
17394
17395 (define_insn "*cmpstrqi_1"
17396   [(set (reg:CC FLAGS_REG)
17397         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17398                              (const_int 0))
17399           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17400                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17401           (const_int 0)))
17402    (use (match_operand:SI 3 "immediate_operand" "i"))
17403    (use (reg:CC FLAGS_REG))
17404    (use (reg:SI DIRFLAG_REG))
17405    (clobber (match_operand:SI 0 "register_operand" "=S"))
17406    (clobber (match_operand:SI 1 "register_operand" "=D"))
17407    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17408   "!TARGET_64BIT"
17409   "repz{\;| }cmpsb"
17410   [(set_attr "type" "str")
17411    (set_attr "mode" "QI")
17412    (set_attr "prefix_rep" "1")])
17413
17414 (define_insn "*cmpstrqi_rex_1"
17415   [(set (reg:CC FLAGS_REG)
17416         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17417                              (const_int 0))
17418           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17419                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17420           (const_int 0)))
17421    (use (match_operand:SI 3 "immediate_operand" "i"))
17422    (use (reg:CC FLAGS_REG))
17423    (use (reg:SI DIRFLAG_REG))
17424    (clobber (match_operand:DI 0 "register_operand" "=S"))
17425    (clobber (match_operand:DI 1 "register_operand" "=D"))
17426    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17427   "TARGET_64BIT"
17428   "repz{\;| }cmpsb"
17429   [(set_attr "type" "str")
17430    (set_attr "mode" "QI")
17431    (set_attr "prefix_rep" "1")])
17432
17433 (define_expand "strlensi"
17434   [(set (match_operand:SI 0 "register_operand" "")
17435         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17436                     (match_operand:QI 2 "immediate_operand" "")
17437                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17438   ""
17439 {
17440  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17441    DONE;
17442  else
17443    FAIL;
17444 })
17445
17446 (define_expand "strlendi"
17447   [(set (match_operand:DI 0 "register_operand" "")
17448         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17449                     (match_operand:QI 2 "immediate_operand" "")
17450                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17451   ""
17452 {
17453  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17454    DONE;
17455  else
17456    FAIL;
17457 })
17458
17459 (define_expand "strlenqi_1"
17460   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17461               (use (reg:SI DIRFLAG_REG))
17462               (clobber (match_operand 1 "register_operand" ""))
17463               (clobber (reg:CC FLAGS_REG))])]
17464   ""
17465   "")
17466
17467 (define_insn "*strlenqi_1"
17468   [(set (match_operand:SI 0 "register_operand" "=&c")
17469         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17470                     (match_operand:QI 2 "register_operand" "a")
17471                     (match_operand:SI 3 "immediate_operand" "i")
17472                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17473    (use (reg:SI DIRFLAG_REG))
17474    (clobber (match_operand:SI 1 "register_operand" "=D"))
17475    (clobber (reg:CC FLAGS_REG))]
17476   "!TARGET_64BIT"
17477   "repnz{\;| }scasb"
17478   [(set_attr "type" "str")
17479    (set_attr "mode" "QI")
17480    (set_attr "prefix_rep" "1")])
17481
17482 (define_insn "*strlenqi_rex_1"
17483   [(set (match_operand:DI 0 "register_operand" "=&c")
17484         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17485                     (match_operand:QI 2 "register_operand" "a")
17486                     (match_operand:DI 3 "immediate_operand" "i")
17487                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17488    (use (reg:SI DIRFLAG_REG))
17489    (clobber (match_operand:DI 1 "register_operand" "=D"))
17490    (clobber (reg:CC FLAGS_REG))]
17491   "TARGET_64BIT"
17492   "repnz{\;| }scasb"
17493   [(set_attr "type" "str")
17494    (set_attr "mode" "QI")
17495    (set_attr "prefix_rep" "1")])
17496
17497 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17498 ;; handled in combine, but it is not currently up to the task.
17499 ;; When used for their truth value, the cmpstr* expanders generate
17500 ;; code like this:
17501 ;;
17502 ;;   repz cmpsb
17503 ;;   seta       %al
17504 ;;   setb       %dl
17505 ;;   cmpb       %al, %dl
17506 ;;   jcc        label
17507 ;;
17508 ;; The intermediate three instructions are unnecessary.
17509
17510 ;; This one handles cmpstr*_nz_1...
17511 (define_peephole2
17512   [(parallel[
17513      (set (reg:CC FLAGS_REG)
17514           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17515                       (mem:BLK (match_operand 5 "register_operand" ""))))
17516      (use (match_operand 6 "register_operand" ""))
17517      (use (match_operand:SI 3 "immediate_operand" ""))
17518      (use (reg:SI DIRFLAG_REG))
17519      (clobber (match_operand 0 "register_operand" ""))
17520      (clobber (match_operand 1 "register_operand" ""))
17521      (clobber (match_operand 2 "register_operand" ""))])
17522    (set (match_operand:QI 7 "register_operand" "")
17523         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17524    (set (match_operand:QI 8 "register_operand" "")
17525         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17526    (set (reg FLAGS_REG)
17527         (compare (match_dup 7) (match_dup 8)))
17528   ]
17529   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17530   [(parallel[
17531      (set (reg:CC FLAGS_REG)
17532           (compare:CC (mem:BLK (match_dup 4))
17533                       (mem:BLK (match_dup 5))))
17534      (use (match_dup 6))
17535      (use (match_dup 3))
17536      (use (reg:SI DIRFLAG_REG))
17537      (clobber (match_dup 0))
17538      (clobber (match_dup 1))
17539      (clobber (match_dup 2))])]
17540   "")
17541
17542 ;; ...and this one handles cmpstr*_1.
17543 (define_peephole2
17544   [(parallel[
17545      (set (reg:CC FLAGS_REG)
17546           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17547                                (const_int 0))
17548             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17549                         (mem:BLK (match_operand 5 "register_operand" "")))
17550             (const_int 0)))
17551      (use (match_operand:SI 3 "immediate_operand" ""))
17552      (use (reg:CC FLAGS_REG))
17553      (use (reg:SI DIRFLAG_REG))
17554      (clobber (match_operand 0 "register_operand" ""))
17555      (clobber (match_operand 1 "register_operand" ""))
17556      (clobber (match_operand 2 "register_operand" ""))])
17557    (set (match_operand:QI 7 "register_operand" "")
17558         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17559    (set (match_operand:QI 8 "register_operand" "")
17560         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17561    (set (reg FLAGS_REG)
17562         (compare (match_dup 7) (match_dup 8)))
17563   ]
17564   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17565   [(parallel[
17566      (set (reg:CC FLAGS_REG)
17567           (if_then_else:CC (ne (match_dup 6)
17568                                (const_int 0))
17569             (compare:CC (mem:BLK (match_dup 4))
17570                         (mem:BLK (match_dup 5)))
17571             (const_int 0)))
17572      (use (match_dup 3))
17573      (use (reg:CC FLAGS_REG))
17574      (use (reg:SI DIRFLAG_REG))
17575      (clobber (match_dup 0))
17576      (clobber (match_dup 1))
17577      (clobber (match_dup 2))])]
17578   "")
17579
17580
17581 \f
17582 ;; Conditional move instructions.
17583
17584 (define_expand "movdicc"
17585   [(set (match_operand:DI 0 "register_operand" "")
17586         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17587                          (match_operand:DI 2 "general_operand" "")
17588                          (match_operand:DI 3 "general_operand" "")))]
17589   "TARGET_64BIT"
17590   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17591
17592 (define_insn "x86_movdicc_0_m1_rex64"
17593   [(set (match_operand:DI 0 "register_operand" "=r")
17594         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17595           (const_int -1)
17596           (const_int 0)))
17597    (clobber (reg:CC FLAGS_REG))]
17598   "TARGET_64BIT"
17599   "sbb{q}\t%0, %0"
17600   ; Since we don't have the proper number of operands for an alu insn,
17601   ; fill in all the blanks.
17602   [(set_attr "type" "alu")
17603    (set_attr "pent_pair" "pu")
17604    (set_attr "memory" "none")
17605    (set_attr "imm_disp" "false")
17606    (set_attr "mode" "DI")
17607    (set_attr "length_immediate" "0")])
17608
17609 (define_insn "*movdicc_c_rex64"
17610   [(set (match_operand:DI 0 "register_operand" "=r,r")
17611         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17612                                 [(reg FLAGS_REG) (const_int 0)])
17613                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17614                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17615   "TARGET_64BIT && TARGET_CMOVE
17616    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17617   "@
17618    cmov%O2%C1\t{%2, %0|%0, %2}
17619    cmov%O2%c1\t{%3, %0|%0, %3}"
17620   [(set_attr "type" "icmov")
17621    (set_attr "mode" "DI")])
17622
17623 (define_expand "movsicc"
17624   [(set (match_operand:SI 0 "register_operand" "")
17625         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17626                          (match_operand:SI 2 "general_operand" "")
17627                          (match_operand:SI 3 "general_operand" "")))]
17628   ""
17629   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17630
17631 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17632 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17633 ;; So just document what we're doing explicitly.
17634
17635 (define_insn "x86_movsicc_0_m1"
17636   [(set (match_operand:SI 0 "register_operand" "=r")
17637         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17638           (const_int -1)
17639           (const_int 0)))
17640    (clobber (reg:CC FLAGS_REG))]
17641   ""
17642   "sbb{l}\t%0, %0"
17643   ; Since we don't have the proper number of operands for an alu insn,
17644   ; fill in all the blanks.
17645   [(set_attr "type" "alu")
17646    (set_attr "pent_pair" "pu")
17647    (set_attr "memory" "none")
17648    (set_attr "imm_disp" "false")
17649    (set_attr "mode" "SI")
17650    (set_attr "length_immediate" "0")])
17651
17652 (define_insn "*movsicc_noc"
17653   [(set (match_operand:SI 0 "register_operand" "=r,r")
17654         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17655                                 [(reg FLAGS_REG) (const_int 0)])
17656                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17657                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17658   "TARGET_CMOVE
17659    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17660   "@
17661    cmov%O2%C1\t{%2, %0|%0, %2}
17662    cmov%O2%c1\t{%3, %0|%0, %3}"
17663   [(set_attr "type" "icmov")
17664    (set_attr "mode" "SI")])
17665
17666 (define_expand "movhicc"
17667   [(set (match_operand:HI 0 "register_operand" "")
17668         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17669                          (match_operand:HI 2 "general_operand" "")
17670                          (match_operand:HI 3 "general_operand" "")))]
17671   "TARGET_HIMODE_MATH"
17672   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17673
17674 (define_insn "*movhicc_noc"
17675   [(set (match_operand:HI 0 "register_operand" "=r,r")
17676         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17677                                 [(reg FLAGS_REG) (const_int 0)])
17678                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17679                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17680   "TARGET_CMOVE
17681    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17682   "@
17683    cmov%O2%C1\t{%2, %0|%0, %2}
17684    cmov%O2%c1\t{%3, %0|%0, %3}"
17685   [(set_attr "type" "icmov")
17686    (set_attr "mode" "HI")])
17687
17688 (define_expand "movqicc"
17689   [(set (match_operand:QI 0 "register_operand" "")
17690         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17691                          (match_operand:QI 2 "general_operand" "")
17692                          (match_operand:QI 3 "general_operand" "")))]
17693   "TARGET_QIMODE_MATH"
17694   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17695
17696 (define_insn_and_split "*movqicc_noc"
17697   [(set (match_operand:QI 0 "register_operand" "=r,r")
17698         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17699                                 [(match_operand 4 "flags_reg_operand" "")
17700                                  (const_int 0)])
17701                       (match_operand:QI 2 "register_operand" "r,0")
17702                       (match_operand:QI 3 "register_operand" "0,r")))]
17703   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17704   "#"
17705   "&& reload_completed"
17706   [(set (match_dup 0)
17707         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17708                       (match_dup 2)
17709                       (match_dup 3)))]
17710   "operands[0] = gen_lowpart (SImode, operands[0]);
17711    operands[2] = gen_lowpart (SImode, operands[2]);
17712    operands[3] = gen_lowpart (SImode, operands[3]);"
17713   [(set_attr "type" "icmov")
17714    (set_attr "mode" "SI")])
17715
17716 (define_expand "movsfcc"
17717   [(set (match_operand:SF 0 "register_operand" "")
17718         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17719                          (match_operand:SF 2 "register_operand" "")
17720                          (match_operand:SF 3 "register_operand" "")))]
17721   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17722   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17723
17724 ;; These versions of min/max are aware of the instruction's behavior
17725 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17726 ;; should have used the smin/smax expanders in the first place.
17727 (define_insn "*movsfcc_1_sse_min"
17728   [(set (match_operand:SF 0 "register_operand" "=x")
17729         (if_then_else:SF
17730           (lt:SF (match_operand:SF 1 "register_operand" "0")
17731                  (match_operand:SF 2 "nonimmediate_operand" "xm"))
17732           (match_dup 1)
17733           (match_dup 2)))]
17734   "TARGET_SSE_MATH"
17735   "minss\t{%2, %0|%0, %2}"
17736   [(set_attr "type" "sseadd")
17737    (set_attr "mode" "SF")])
17738
17739 (define_insn "*movsfcc_1_sse_max"
17740   [(set (match_operand:SF 0 "register_operand" "=x")
17741         (if_then_else:SF
17742           (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17743                  (match_operand:SF 1 "nonimmediate_operand" "0"))
17744           (match_dup 1)
17745           (match_dup 2)))]
17746   "TARGET_SSE_MATH"
17747   "maxss\t{%2, %0|%0, %2}"
17748   [(set_attr "type" "sseadd")
17749    (set_attr "mode" "SF")])
17750
17751 (define_insn_and_split "*movsfcc_1_sse"
17752   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17753         (if_then_else:SF
17754           (match_operator:SF 4 "sse_comparison_operator"
17755             [(match_operand:SF 5 "register_operand" "0,0,0")
17756              (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17757           (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
17758           (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17759    (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
17760   "TARGET_SSE_MATH"
17761   "#"
17762   "&& reload_completed"
17763   [(const_int 0)]
17764 {
17765   ix86_split_sse_movcc (operands);
17766   DONE;
17767 })
17768
17769 (define_insn "*movsfcc_1_387"
17770   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17771         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17772                                 [(reg FLAGS_REG) (const_int 0)])
17773                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17774                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17775   "TARGET_80387 && TARGET_CMOVE
17776    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17777   "@
17778    fcmov%F1\t{%2, %0|%0, %2}
17779    fcmov%f1\t{%3, %0|%0, %3}
17780    cmov%O2%C1\t{%2, %0|%0, %2}
17781    cmov%O2%c1\t{%3, %0|%0, %3}"
17782   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17783    (set_attr "mode" "SF,SF,SI,SI")])
17784
17785 (define_expand "movdfcc"
17786   [(set (match_operand:DF 0 "register_operand" "")
17787         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17788                          (match_operand:DF 2 "register_operand" "")
17789                          (match_operand:DF 3 "register_operand" "")))]
17790   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17791   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17792
17793 ;; These versions of min/max are aware of the instruction's behavior
17794 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17795 ;; should have used the smin/smax expanders in the first place.
17796 (define_insn "*movdfcc_1_sse_min"
17797   [(set (match_operand:DF 0 "register_operand" "=x")
17798         (if_then_else:DF
17799           (lt:DF (match_operand:DF 1 "register_operand" "0")
17800                  (match_operand:DF 2 "nonimmediate_operand" "xm"))
17801           (match_dup 1)
17802           (match_dup 2)))]
17803   "TARGET_SSE2 && TARGET_SSE_MATH"
17804   "minsd\t{%2, %0|%0, %2}"
17805   [(set_attr "type" "sseadd")
17806    (set_attr "mode" "DF")])
17807
17808 (define_insn "*movdfcc_1_sse_max"
17809   [(set (match_operand:DF 0 "register_operand" "=x")
17810         (if_then_else:DF
17811           (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17812                  (match_operand:DF 1 "nonimmediate_operand" "0"))
17813           (match_dup 1)
17814           (match_dup 2)))]
17815   "TARGET_SSE2 && TARGET_SSE_MATH"
17816   "maxsd\t{%2, %0|%0, %2}"
17817   [(set_attr "type" "sseadd")
17818    (set_attr "mode" "DF")])
17819
17820 (define_insn_and_split "*movdfcc_1_sse"
17821   [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17822         (if_then_else:DF
17823           (match_operator:DF 4 "sse_comparison_operator"
17824             [(match_operand:DF 5 "register_operand" "0,0,0")
17825              (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17826           (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
17827           (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17828    (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
17829   "TARGET_SSE2 && TARGET_SSE_MATH"
17830   "#"
17831   "&& reload_completed"
17832   [(const_int 0)]
17833 {
17834   ix86_split_sse_movcc (operands);
17835   DONE;
17836 })
17837
17838 (define_insn "*movdfcc_1"
17839   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17840         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17841                                 [(reg FLAGS_REG) (const_int 0)])
17842                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17843                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17844   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17845    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17846   "@
17847    fcmov%F1\t{%2, %0|%0, %2}
17848    fcmov%f1\t{%3, %0|%0, %3}
17849    #
17850    #"
17851   [(set_attr "type" "fcmov,fcmov,multi,multi")
17852    (set_attr "mode" "DF")])
17853
17854 (define_insn "*movdfcc_1_rex64"
17855   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17856         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17857                                 [(reg FLAGS_REG) (const_int 0)])
17858                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17859                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17860   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17861    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17862   "@
17863    fcmov%F1\t{%2, %0|%0, %2}
17864    fcmov%f1\t{%3, %0|%0, %3}
17865    cmov%O2%C1\t{%2, %0|%0, %2}
17866    cmov%O2%c1\t{%3, %0|%0, %3}"
17867   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17868    (set_attr "mode" "DF")])
17869
17870 (define_split
17871   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17872         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17873                                 [(match_operand 4 "flags_reg_operand" "")
17874                                  (const_int 0)])
17875                       (match_operand:DF 2 "nonimmediate_operand" "")
17876                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17877   "!TARGET_64BIT && reload_completed"
17878   [(set (match_dup 2)
17879         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17880                       (match_dup 5)
17881                       (match_dup 7)))
17882    (set (match_dup 3)
17883         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17884                       (match_dup 6)
17885                       (match_dup 8)))]
17886   "split_di (operands+2, 1, operands+5, operands+6);
17887    split_di (operands+3, 1, operands+7, operands+8);
17888    split_di (operands, 1, operands+2, operands+3);")
17889
17890 (define_expand "movxfcc"
17891   [(set (match_operand:XF 0 "register_operand" "")
17892         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17893                          (match_operand:XF 2 "register_operand" "")
17894                          (match_operand:XF 3 "register_operand" "")))]
17895   "TARGET_80387 && TARGET_CMOVE"
17896   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17897
17898 (define_insn "*movxfcc_1"
17899   [(set (match_operand:XF 0 "register_operand" "=f,f")
17900         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17901                                 [(reg FLAGS_REG) (const_int 0)])
17902                       (match_operand:XF 2 "register_operand" "f,0")
17903                       (match_operand:XF 3 "register_operand" "0,f")))]
17904   "TARGET_80387 && TARGET_CMOVE"
17905   "@
17906    fcmov%F1\t{%2, %0|%0, %2}
17907    fcmov%f1\t{%3, %0|%0, %3}"
17908   [(set_attr "type" "fcmov")
17909    (set_attr "mode" "XF")])
17910
17911 ;; These versions of the min/max patterns are intentionally ignorant of
17912 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17913 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17914 ;; are undefined in this condition, we're certain this is correct.
17915
17916 (define_insn "sminsf3"
17917   [(set (match_operand:SF 0 "register_operand" "=x")
17918         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17919                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17920   "TARGET_SSE_MATH"
17921   "minss\t{%2, %0|%0, %2}"
17922   [(set_attr "type" "sseadd")
17923    (set_attr "mode" "SF")])
17924
17925 (define_insn "smaxsf3"
17926   [(set (match_operand:SF 0 "register_operand" "=x")
17927         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17928                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17929   "TARGET_SSE_MATH"
17930   "maxss\t{%2, %0|%0, %2}"
17931   [(set_attr "type" "sseadd")
17932    (set_attr "mode" "SF")])
17933
17934 (define_insn "smindf3"
17935   [(set (match_operand:DF 0 "register_operand" "=x")
17936         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17937                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17938   "TARGET_SSE2 && TARGET_SSE_MATH"
17939   "minsd\t{%2, %0|%0, %2}"
17940   [(set_attr "type" "sseadd")
17941    (set_attr "mode" "DF")])
17942
17943 (define_insn "smaxdf3"
17944   [(set (match_operand:DF 0 "register_operand" "=x")
17945         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17946                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17947   "TARGET_SSE2 && TARGET_SSE_MATH"
17948   "maxsd\t{%2, %0|%0, %2}"
17949   [(set_attr "type" "sseadd")
17950    (set_attr "mode" "DF")])
17951
17952 ;; Conditional addition patterns
17953 (define_expand "addqicc"
17954   [(match_operand:QI 0 "register_operand" "")
17955    (match_operand 1 "comparison_operator" "")
17956    (match_operand:QI 2 "register_operand" "")
17957    (match_operand:QI 3 "const_int_operand" "")]
17958   ""
17959   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17960
17961 (define_expand "addhicc"
17962   [(match_operand:HI 0 "register_operand" "")
17963    (match_operand 1 "comparison_operator" "")
17964    (match_operand:HI 2 "register_operand" "")
17965    (match_operand:HI 3 "const_int_operand" "")]
17966   ""
17967   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17968
17969 (define_expand "addsicc"
17970   [(match_operand:SI 0 "register_operand" "")
17971    (match_operand 1 "comparison_operator" "")
17972    (match_operand:SI 2 "register_operand" "")
17973    (match_operand:SI 3 "const_int_operand" "")]
17974   ""
17975   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17976
17977 (define_expand "adddicc"
17978   [(match_operand:DI 0 "register_operand" "")
17979    (match_operand 1 "comparison_operator" "")
17980    (match_operand:DI 2 "register_operand" "")
17981    (match_operand:DI 3 "const_int_operand" "")]
17982   "TARGET_64BIT"
17983   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17984
17985 \f
17986 ;; Misc patterns (?)
17987
17988 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17989 ;; Otherwise there will be nothing to keep
17990 ;; 
17991 ;; [(set (reg ebp) (reg esp))]
17992 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17993 ;;  (clobber (eflags)]
17994 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17995 ;;
17996 ;; in proper program order.
17997 (define_insn "pro_epilogue_adjust_stack_1"
17998   [(set (match_operand:SI 0 "register_operand" "=r,r")
17999         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18000                  (match_operand:SI 2 "immediate_operand" "i,i")))
18001    (clobber (reg:CC FLAGS_REG))
18002    (clobber (mem:BLK (scratch)))]
18003   "!TARGET_64BIT"
18004 {
18005   switch (get_attr_type (insn))
18006     {
18007     case TYPE_IMOV:
18008       return "mov{l}\t{%1, %0|%0, %1}";
18009
18010     case TYPE_ALU:
18011       if (GET_CODE (operands[2]) == CONST_INT
18012           && (INTVAL (operands[2]) == 128
18013               || (INTVAL (operands[2]) < 0
18014                   && INTVAL (operands[2]) != -128)))
18015         {
18016           operands[2] = GEN_INT (-INTVAL (operands[2]));
18017           return "sub{l}\t{%2, %0|%0, %2}";
18018         }
18019       return "add{l}\t{%2, %0|%0, %2}";
18020
18021     case TYPE_LEA:
18022       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18023       return "lea{l}\t{%a2, %0|%0, %a2}";
18024
18025     default:
18026       abort ();
18027     }
18028 }
18029   [(set (attr "type")
18030         (cond [(eq_attr "alternative" "0")
18031                  (const_string "alu")
18032                (match_operand:SI 2 "const0_operand" "")
18033                  (const_string "imov")
18034               ]
18035               (const_string "lea")))
18036    (set_attr "mode" "SI")])
18037
18038 (define_insn "pro_epilogue_adjust_stack_rex64"
18039   [(set (match_operand:DI 0 "register_operand" "=r,r")
18040         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18041                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18042    (clobber (reg:CC FLAGS_REG))
18043    (clobber (mem:BLK (scratch)))]
18044   "TARGET_64BIT"
18045 {
18046   switch (get_attr_type (insn))
18047     {
18048     case TYPE_IMOV:
18049       return "mov{q}\t{%1, %0|%0, %1}";
18050
18051     case TYPE_ALU:
18052       if (GET_CODE (operands[2]) == CONST_INT
18053           /* Avoid overflows.  */
18054           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18055           && (INTVAL (operands[2]) == 128
18056               || (INTVAL (operands[2]) < 0
18057                   && INTVAL (operands[2]) != -128)))
18058         {
18059           operands[2] = GEN_INT (-INTVAL (operands[2]));
18060           return "sub{q}\t{%2, %0|%0, %2}";
18061         }
18062       return "add{q}\t{%2, %0|%0, %2}";
18063
18064     case TYPE_LEA:
18065       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18066       return "lea{q}\t{%a2, %0|%0, %a2}";
18067
18068     default:
18069       abort ();
18070     }
18071 }
18072   [(set (attr "type")
18073         (cond [(eq_attr "alternative" "0")
18074                  (const_string "alu")
18075                (match_operand:DI 2 "const0_operand" "")
18076                  (const_string "imov")
18077               ]
18078               (const_string "lea")))
18079    (set_attr "mode" "DI")])
18080
18081 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18082   [(set (match_operand:DI 0 "register_operand" "=r,r")
18083         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18084                  (match_operand:DI 3 "immediate_operand" "i,i")))
18085    (use (match_operand:DI 2 "register_operand" "r,r"))
18086    (clobber (reg:CC FLAGS_REG))
18087    (clobber (mem:BLK (scratch)))]
18088   "TARGET_64BIT"
18089 {
18090   switch (get_attr_type (insn))
18091     {
18092     case TYPE_ALU:
18093       return "add{q}\t{%2, %0|%0, %2}";
18094
18095     case TYPE_LEA:
18096       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18097       return "lea{q}\t{%a2, %0|%0, %a2}";
18098
18099     default:
18100       abort ();
18101     }
18102 }
18103   [(set_attr "type" "alu,lea")
18104    (set_attr "mode" "DI")])
18105
18106 (define_expand "allocate_stack_worker"
18107   [(match_operand:SI 0 "register_operand" "")]
18108   "TARGET_STACK_PROBE"
18109 {
18110   if (reload_completed)
18111     {
18112       if (TARGET_64BIT)
18113         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18114       else
18115         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18116     }
18117   else
18118     {
18119       if (TARGET_64BIT)
18120         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18121       else
18122         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18123     }
18124   DONE;
18125 })
18126
18127 (define_insn "allocate_stack_worker_1"
18128   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18129     UNSPECV_STACK_PROBE)
18130    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18131    (clobber (match_scratch:SI 1 "=0"))
18132    (clobber (reg:CC FLAGS_REG))]
18133   "!TARGET_64BIT && TARGET_STACK_PROBE"
18134   "call\t__alloca"
18135   [(set_attr "type" "multi")
18136    (set_attr "length" "5")])
18137
18138 (define_expand "allocate_stack_worker_postreload"
18139   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18140                                     UNSPECV_STACK_PROBE)
18141               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18142               (clobber (match_dup 0))
18143               (clobber (reg:CC FLAGS_REG))])]
18144   ""
18145   "")
18146
18147 (define_insn "allocate_stack_worker_rex64"
18148   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18149     UNSPECV_STACK_PROBE)
18150    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18151    (clobber (match_scratch:DI 1 "=0"))
18152    (clobber (reg:CC FLAGS_REG))]
18153   "TARGET_64BIT && TARGET_STACK_PROBE"
18154   "call\t__alloca"
18155   [(set_attr "type" "multi")
18156    (set_attr "length" "5")])
18157
18158 (define_expand "allocate_stack_worker_rex64_postreload"
18159   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18160                                     UNSPECV_STACK_PROBE)
18161               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18162               (clobber (match_dup 0))
18163               (clobber (reg:CC FLAGS_REG))])]
18164   ""
18165   "")
18166
18167 (define_expand "allocate_stack"
18168   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18169                    (minus:SI (reg:SI SP_REG)
18170                              (match_operand:SI 1 "general_operand" "")))
18171               (clobber (reg:CC FLAGS_REG))])
18172    (parallel [(set (reg:SI SP_REG)
18173                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18174               (clobber (reg:CC FLAGS_REG))])]
18175   "TARGET_STACK_PROBE"
18176 {
18177 #ifdef CHECK_STACK_LIMIT
18178   if (GET_CODE (operands[1]) == CONST_INT
18179       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18180     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18181                            operands[1]));
18182   else 
18183 #endif
18184     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18185                                                             operands[1])));
18186
18187   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18188   DONE;
18189 })
18190
18191 (define_expand "builtin_setjmp_receiver"
18192   [(label_ref (match_operand 0 "" ""))]
18193   "!TARGET_64BIT && flag_pic"
18194 {
18195   emit_insn (gen_set_got (pic_offset_table_rtx));
18196   DONE;
18197 })
18198 \f
18199 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18200
18201 (define_split
18202   [(set (match_operand 0 "register_operand" "")
18203         (match_operator 3 "promotable_binary_operator"
18204            [(match_operand 1 "register_operand" "")
18205             (match_operand 2 "aligned_operand" "")]))
18206    (clobber (reg:CC FLAGS_REG))]
18207   "! TARGET_PARTIAL_REG_STALL && reload_completed
18208    && ((GET_MODE (operands[0]) == HImode 
18209         && ((!optimize_size && !TARGET_FAST_PREFIX)
18210             || GET_CODE (operands[2]) != CONST_INT
18211             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18212        || (GET_MODE (operands[0]) == QImode 
18213            && (TARGET_PROMOTE_QImode || optimize_size)))"
18214   [(parallel [(set (match_dup 0)
18215                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18216               (clobber (reg:CC FLAGS_REG))])]
18217   "operands[0] = gen_lowpart (SImode, operands[0]);
18218    operands[1] = gen_lowpart (SImode, operands[1]);
18219    if (GET_CODE (operands[3]) != ASHIFT)
18220      operands[2] = gen_lowpart (SImode, operands[2]);
18221    PUT_MODE (operands[3], SImode);")
18222
18223 ; Promote the QImode tests, as i386 has encoding of the AND
18224 ; instruction with 32-bit sign-extended immediate and thus the
18225 ; instruction size is unchanged, except in the %eax case for
18226 ; which it is increased by one byte, hence the ! optimize_size.
18227 (define_split
18228   [(set (match_operand 0 "flags_reg_operand" "")
18229         (match_operator 2 "compare_operator"
18230           [(and (match_operand 3 "aligned_operand" "")
18231                 (match_operand 4 "const_int_operand" ""))
18232            (const_int 0)]))
18233    (set (match_operand 1 "register_operand" "")
18234         (and (match_dup 3) (match_dup 4)))]
18235   "! TARGET_PARTIAL_REG_STALL && reload_completed
18236    /* Ensure that the operand will remain sign-extended immediate.  */
18237    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18238    && ! optimize_size
18239    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18240        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18241   [(parallel [(set (match_dup 0)
18242                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18243                                     (const_int 0)]))
18244               (set (match_dup 1)
18245                    (and:SI (match_dup 3) (match_dup 4)))])]
18246 {
18247   operands[4]
18248     = gen_int_mode (INTVAL (operands[4])
18249                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18250   operands[1] = gen_lowpart (SImode, operands[1]);
18251   operands[3] = gen_lowpart (SImode, operands[3]);
18252 })
18253
18254 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18255 ; the TEST instruction with 32-bit sign-extended immediate and thus
18256 ; the instruction size would at least double, which is not what we
18257 ; want even with ! optimize_size.
18258 (define_split
18259   [(set (match_operand 0 "flags_reg_operand" "")
18260         (match_operator 1 "compare_operator"
18261           [(and (match_operand:HI 2 "aligned_operand" "")
18262                 (match_operand:HI 3 "const_int_operand" ""))
18263            (const_int 0)]))]
18264   "! TARGET_PARTIAL_REG_STALL && reload_completed
18265    /* Ensure that the operand will remain sign-extended immediate.  */
18266    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18267    && ! TARGET_FAST_PREFIX
18268    && ! optimize_size"
18269   [(set (match_dup 0)
18270         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18271                          (const_int 0)]))]
18272 {
18273   operands[3]
18274     = gen_int_mode (INTVAL (operands[3])
18275                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18276   operands[2] = gen_lowpart (SImode, operands[2]);
18277 })
18278
18279 (define_split
18280   [(set (match_operand 0 "register_operand" "")
18281         (neg (match_operand 1 "register_operand" "")))
18282    (clobber (reg:CC FLAGS_REG))]
18283   "! TARGET_PARTIAL_REG_STALL && reload_completed
18284    && (GET_MODE (operands[0]) == HImode
18285        || (GET_MODE (operands[0]) == QImode 
18286            && (TARGET_PROMOTE_QImode || optimize_size)))"
18287   [(parallel [(set (match_dup 0)
18288                    (neg:SI (match_dup 1)))
18289               (clobber (reg:CC FLAGS_REG))])]
18290   "operands[0] = gen_lowpart (SImode, operands[0]);
18291    operands[1] = gen_lowpart (SImode, operands[1]);")
18292
18293 (define_split
18294   [(set (match_operand 0 "register_operand" "")
18295         (not (match_operand 1 "register_operand" "")))]
18296   "! TARGET_PARTIAL_REG_STALL && reload_completed
18297    && (GET_MODE (operands[0]) == HImode
18298        || (GET_MODE (operands[0]) == QImode 
18299            && (TARGET_PROMOTE_QImode || optimize_size)))"
18300   [(set (match_dup 0)
18301         (not:SI (match_dup 1)))]
18302   "operands[0] = gen_lowpart (SImode, operands[0]);
18303    operands[1] = gen_lowpart (SImode, operands[1]);")
18304
18305 (define_split 
18306   [(set (match_operand 0 "register_operand" "")
18307         (if_then_else (match_operator 1 "comparison_operator" 
18308                                 [(reg FLAGS_REG) (const_int 0)])
18309                       (match_operand 2 "register_operand" "")
18310                       (match_operand 3 "register_operand" "")))]
18311   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18312    && (GET_MODE (operands[0]) == HImode
18313        || (GET_MODE (operands[0]) == QImode 
18314            && (TARGET_PROMOTE_QImode || optimize_size)))"
18315   [(set (match_dup 0)
18316         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18317   "operands[0] = gen_lowpart (SImode, operands[0]);
18318    operands[2] = gen_lowpart (SImode, operands[2]);
18319    operands[3] = gen_lowpart (SImode, operands[3]);")
18320                         
18321 \f
18322 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18323 ;; transform a complex memory operation into two memory to register operations.
18324
18325 ;; Don't push memory operands
18326 (define_peephole2
18327   [(set (match_operand:SI 0 "push_operand" "")
18328         (match_operand:SI 1 "memory_operand" ""))
18329    (match_scratch:SI 2 "r")]
18330   "! optimize_size && ! TARGET_PUSH_MEMORY"
18331   [(set (match_dup 2) (match_dup 1))
18332    (set (match_dup 0) (match_dup 2))]
18333   "")
18334
18335 (define_peephole2
18336   [(set (match_operand:DI 0 "push_operand" "")
18337         (match_operand:DI 1 "memory_operand" ""))
18338    (match_scratch:DI 2 "r")]
18339   "! optimize_size && ! TARGET_PUSH_MEMORY"
18340   [(set (match_dup 2) (match_dup 1))
18341    (set (match_dup 0) (match_dup 2))]
18342   "")
18343
18344 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18345 ;; SImode pushes.
18346 (define_peephole2
18347   [(set (match_operand:SF 0 "push_operand" "")
18348         (match_operand:SF 1 "memory_operand" ""))
18349    (match_scratch:SF 2 "r")]
18350   "! optimize_size && ! TARGET_PUSH_MEMORY"
18351   [(set (match_dup 2) (match_dup 1))
18352    (set (match_dup 0) (match_dup 2))]
18353   "")
18354
18355 (define_peephole2
18356   [(set (match_operand:HI 0 "push_operand" "")
18357         (match_operand:HI 1 "memory_operand" ""))
18358    (match_scratch:HI 2 "r")]
18359   "! optimize_size && ! TARGET_PUSH_MEMORY"
18360   [(set (match_dup 2) (match_dup 1))
18361    (set (match_dup 0) (match_dup 2))]
18362   "")
18363
18364 (define_peephole2
18365   [(set (match_operand:QI 0 "push_operand" "")
18366         (match_operand:QI 1 "memory_operand" ""))
18367    (match_scratch:QI 2 "q")]
18368   "! optimize_size && ! TARGET_PUSH_MEMORY"
18369   [(set (match_dup 2) (match_dup 1))
18370    (set (match_dup 0) (match_dup 2))]
18371   "")
18372
18373 ;; Don't move an immediate directly to memory when the instruction
18374 ;; gets too big.
18375 (define_peephole2
18376   [(match_scratch:SI 1 "r")
18377    (set (match_operand:SI 0 "memory_operand" "")
18378         (const_int 0))]
18379   "! optimize_size
18380    && ! TARGET_USE_MOV0
18381    && TARGET_SPLIT_LONG_MOVES
18382    && get_attr_length (insn) >= ix86_cost->large_insn
18383    && peep2_regno_dead_p (0, FLAGS_REG)"
18384   [(parallel [(set (match_dup 1) (const_int 0))
18385               (clobber (reg:CC FLAGS_REG))])
18386    (set (match_dup 0) (match_dup 1))]
18387   "")
18388
18389 (define_peephole2
18390   [(match_scratch:HI 1 "r")
18391    (set (match_operand:HI 0 "memory_operand" "")
18392         (const_int 0))]
18393   "! optimize_size
18394    && ! TARGET_USE_MOV0
18395    && TARGET_SPLIT_LONG_MOVES
18396    && get_attr_length (insn) >= ix86_cost->large_insn
18397    && peep2_regno_dead_p (0, FLAGS_REG)"
18398   [(parallel [(set (match_dup 2) (const_int 0))
18399               (clobber (reg:CC FLAGS_REG))])
18400    (set (match_dup 0) (match_dup 1))]
18401   "operands[2] = gen_lowpart (SImode, operands[1]);")
18402
18403 (define_peephole2
18404   [(match_scratch:QI 1 "q")
18405    (set (match_operand:QI 0 "memory_operand" "")
18406         (const_int 0))]
18407   "! optimize_size
18408    && ! TARGET_USE_MOV0
18409    && TARGET_SPLIT_LONG_MOVES
18410    && get_attr_length (insn) >= ix86_cost->large_insn
18411    && peep2_regno_dead_p (0, FLAGS_REG)"
18412   [(parallel [(set (match_dup 2) (const_int 0))
18413               (clobber (reg:CC FLAGS_REG))])
18414    (set (match_dup 0) (match_dup 1))]
18415   "operands[2] = gen_lowpart (SImode, operands[1]);")
18416
18417 (define_peephole2
18418   [(match_scratch:SI 2 "r")
18419    (set (match_operand:SI 0 "memory_operand" "")
18420         (match_operand:SI 1 "immediate_operand" ""))]
18421   "! optimize_size
18422    && get_attr_length (insn) >= ix86_cost->large_insn
18423    && TARGET_SPLIT_LONG_MOVES"
18424   [(set (match_dup 2) (match_dup 1))
18425    (set (match_dup 0) (match_dup 2))]
18426   "")
18427
18428 (define_peephole2
18429   [(match_scratch:HI 2 "r")
18430    (set (match_operand:HI 0 "memory_operand" "")
18431         (match_operand:HI 1 "immediate_operand" ""))]
18432   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18433   && TARGET_SPLIT_LONG_MOVES"
18434   [(set (match_dup 2) (match_dup 1))
18435    (set (match_dup 0) (match_dup 2))]
18436   "")
18437
18438 (define_peephole2
18439   [(match_scratch:QI 2 "q")
18440    (set (match_operand:QI 0 "memory_operand" "")
18441         (match_operand:QI 1 "immediate_operand" ""))]
18442   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18443   && TARGET_SPLIT_LONG_MOVES"
18444   [(set (match_dup 2) (match_dup 1))
18445    (set (match_dup 0) (match_dup 2))]
18446   "")
18447
18448 ;; Don't compare memory with zero, load and use a test instead.
18449 (define_peephole2
18450   [(set (match_operand 0 "flags_reg_operand" "")
18451         (match_operator 1 "compare_operator"
18452           [(match_operand:SI 2 "memory_operand" "")
18453            (const_int 0)]))
18454    (match_scratch:SI 3 "r")]
18455   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18456   [(set (match_dup 3) (match_dup 2))
18457    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18458   "")
18459
18460 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18461 ;; Don't split NOTs with a displacement operand, because resulting XOR
18462 ;; will not be pairable anyway.
18463 ;;
18464 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18465 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18466 ;; so this split helps here as well.
18467 ;;
18468 ;; Note: Can't do this as a regular split because we can't get proper
18469 ;; lifetime information then.
18470
18471 (define_peephole2
18472   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18473         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18474   "!optimize_size
18475    && peep2_regno_dead_p (0, FLAGS_REG)
18476    && ((TARGET_PENTIUM 
18477         && (GET_CODE (operands[0]) != MEM
18478             || !memory_displacement_operand (operands[0], SImode)))
18479        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18480   [(parallel [(set (match_dup 0)
18481                    (xor:SI (match_dup 1) (const_int -1)))
18482               (clobber (reg:CC FLAGS_REG))])]
18483   "")
18484
18485 (define_peephole2
18486   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18487         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18488   "!optimize_size
18489    && peep2_regno_dead_p (0, FLAGS_REG)
18490    && ((TARGET_PENTIUM 
18491         && (GET_CODE (operands[0]) != MEM
18492             || !memory_displacement_operand (operands[0], HImode)))
18493        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18494   [(parallel [(set (match_dup 0)
18495                    (xor:HI (match_dup 1) (const_int -1)))
18496               (clobber (reg:CC FLAGS_REG))])]
18497   "")
18498
18499 (define_peephole2
18500   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18501         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18502   "!optimize_size
18503    && peep2_regno_dead_p (0, FLAGS_REG)
18504    && ((TARGET_PENTIUM 
18505         && (GET_CODE (operands[0]) != MEM
18506             || !memory_displacement_operand (operands[0], QImode)))
18507        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18508   [(parallel [(set (match_dup 0)
18509                    (xor:QI (match_dup 1) (const_int -1)))
18510               (clobber (reg:CC FLAGS_REG))])]
18511   "")
18512
18513 ;; Non pairable "test imm, reg" instructions can be translated to
18514 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18515 ;; byte opcode instead of two, have a short form for byte operands),
18516 ;; so do it for other CPUs as well.  Given that the value was dead,
18517 ;; this should not create any new dependencies.  Pass on the sub-word
18518 ;; versions if we're concerned about partial register stalls.
18519
18520 (define_peephole2
18521   [(set (match_operand 0 "flags_reg_operand" "")
18522         (match_operator 1 "compare_operator"
18523           [(and:SI (match_operand:SI 2 "register_operand" "")
18524                    (match_operand:SI 3 "immediate_operand" ""))
18525            (const_int 0)]))]
18526   "ix86_match_ccmode (insn, CCNOmode)
18527    && (true_regnum (operands[2]) != 0
18528        || (GET_CODE (operands[3]) == CONST_INT
18529            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18530    && peep2_reg_dead_p (1, operands[2])"
18531   [(parallel
18532      [(set (match_dup 0)
18533            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18534                             (const_int 0)]))
18535       (set (match_dup 2)
18536            (and:SI (match_dup 2) (match_dup 3)))])]
18537   "")
18538
18539 ;; We don't need to handle HImode case, because it will be promoted to SImode
18540 ;; on ! TARGET_PARTIAL_REG_STALL
18541
18542 (define_peephole2
18543   [(set (match_operand 0 "flags_reg_operand" "")
18544         (match_operator 1 "compare_operator"
18545           [(and:QI (match_operand:QI 2 "register_operand" "")
18546                    (match_operand:QI 3 "immediate_operand" ""))
18547            (const_int 0)]))]
18548   "! TARGET_PARTIAL_REG_STALL
18549    && ix86_match_ccmode (insn, CCNOmode)
18550    && true_regnum (operands[2]) != 0
18551    && peep2_reg_dead_p (1, operands[2])"
18552   [(parallel
18553      [(set (match_dup 0)
18554            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18555                             (const_int 0)]))
18556       (set (match_dup 2)
18557            (and:QI (match_dup 2) (match_dup 3)))])]
18558   "")
18559
18560 (define_peephole2
18561   [(set (match_operand 0 "flags_reg_operand" "")
18562         (match_operator 1 "compare_operator"
18563           [(and:SI
18564              (zero_extract:SI
18565                (match_operand 2 "ext_register_operand" "")
18566                (const_int 8)
18567                (const_int 8))
18568              (match_operand 3 "const_int_operand" ""))
18569            (const_int 0)]))]
18570   "! TARGET_PARTIAL_REG_STALL
18571    && ix86_match_ccmode (insn, CCNOmode)
18572    && true_regnum (operands[2]) != 0
18573    && peep2_reg_dead_p (1, operands[2])"
18574   [(parallel [(set (match_dup 0)
18575                    (match_op_dup 1
18576                      [(and:SI
18577                         (zero_extract:SI
18578                           (match_dup 2)
18579                           (const_int 8)
18580                           (const_int 8))
18581                         (match_dup 3))
18582                       (const_int 0)]))
18583               (set (zero_extract:SI (match_dup 2)
18584                                     (const_int 8)
18585                                     (const_int 8))
18586                    (and:SI 
18587                      (zero_extract:SI
18588                        (match_dup 2)
18589                        (const_int 8)
18590                        (const_int 8))
18591                      (match_dup 3)))])]
18592   "")
18593
18594 ;; Don't do logical operations with memory inputs.
18595 (define_peephole2
18596   [(match_scratch:SI 2 "r")
18597    (parallel [(set (match_operand:SI 0 "register_operand" "")
18598                    (match_operator:SI 3 "arith_or_logical_operator"
18599                      [(match_dup 0)
18600                       (match_operand:SI 1 "memory_operand" "")]))
18601               (clobber (reg:CC FLAGS_REG))])]
18602   "! optimize_size && ! TARGET_READ_MODIFY"
18603   [(set (match_dup 2) (match_dup 1))
18604    (parallel [(set (match_dup 0)
18605                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18606               (clobber (reg:CC FLAGS_REG))])]
18607   "")
18608
18609 (define_peephole2
18610   [(match_scratch:SI 2 "r")
18611    (parallel [(set (match_operand:SI 0 "register_operand" "")
18612                    (match_operator:SI 3 "arith_or_logical_operator"
18613                      [(match_operand:SI 1 "memory_operand" "")
18614                       (match_dup 0)]))
18615               (clobber (reg:CC FLAGS_REG))])]
18616   "! optimize_size && ! TARGET_READ_MODIFY"
18617   [(set (match_dup 2) (match_dup 1))
18618    (parallel [(set (match_dup 0)
18619                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18620               (clobber (reg:CC FLAGS_REG))])]
18621   "")
18622
18623 ; Don't do logical operations with memory outputs
18624 ;
18625 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18626 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18627 ; the same decoder scheduling characteristics as the original.
18628
18629 (define_peephole2
18630   [(match_scratch:SI 2 "r")
18631    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18632                    (match_operator:SI 3 "arith_or_logical_operator"
18633                      [(match_dup 0)
18634                       (match_operand:SI 1 "nonmemory_operand" "")]))
18635               (clobber (reg:CC FLAGS_REG))])]
18636   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18637   [(set (match_dup 2) (match_dup 0))
18638    (parallel [(set (match_dup 2)
18639                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18640               (clobber (reg:CC FLAGS_REG))])
18641    (set (match_dup 0) (match_dup 2))]
18642   "")
18643
18644 (define_peephole2
18645   [(match_scratch:SI 2 "r")
18646    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18647                    (match_operator:SI 3 "arith_or_logical_operator"
18648                      [(match_operand:SI 1 "nonmemory_operand" "")
18649                       (match_dup 0)]))
18650               (clobber (reg:CC FLAGS_REG))])]
18651   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18652   [(set (match_dup 2) (match_dup 0))
18653    (parallel [(set (match_dup 2)
18654                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18655               (clobber (reg:CC FLAGS_REG))])
18656    (set (match_dup 0) (match_dup 2))]
18657   "")
18658
18659 ;; Attempt to always use XOR for zeroing registers.
18660 (define_peephole2
18661   [(set (match_operand 0 "register_operand" "")
18662         (match_operand 1 "const0_operand" ""))]
18663   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18664    && (! TARGET_USE_MOV0 || optimize_size)
18665    && GENERAL_REG_P (operands[0])
18666    && peep2_regno_dead_p (0, FLAGS_REG)"
18667   [(parallel [(set (match_dup 0) (const_int 0))
18668               (clobber (reg:CC FLAGS_REG))])]
18669 {
18670   operands[0] = gen_lowpart (word_mode, operands[0]);
18671 })
18672
18673 (define_peephole2
18674   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18675         (const_int 0))]
18676   "(GET_MODE (operands[0]) == QImode
18677     || GET_MODE (operands[0]) == HImode)
18678    && (! TARGET_USE_MOV0 || optimize_size)
18679    && peep2_regno_dead_p (0, FLAGS_REG)"
18680   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18681               (clobber (reg:CC FLAGS_REG))])])
18682
18683 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18684 (define_peephole2
18685   [(set (match_operand 0 "register_operand" "")
18686         (const_int -1))]
18687   "(GET_MODE (operands[0]) == HImode
18688     || GET_MODE (operands[0]) == SImode 
18689     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18690    && (optimize_size || TARGET_PENTIUM)
18691    && peep2_regno_dead_p (0, FLAGS_REG)"
18692   [(parallel [(set (match_dup 0) (const_int -1))
18693               (clobber (reg:CC FLAGS_REG))])]
18694   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18695                               operands[0]);")
18696
18697 ;; Attempt to convert simple leas to adds. These can be created by
18698 ;; move expanders.
18699 (define_peephole2
18700   [(set (match_operand:SI 0 "register_operand" "")
18701         (plus:SI (match_dup 0)
18702                  (match_operand:SI 1 "nonmemory_operand" "")))]
18703   "peep2_regno_dead_p (0, FLAGS_REG)"
18704   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18705               (clobber (reg:CC FLAGS_REG))])]
18706   "")
18707
18708 (define_peephole2
18709   [(set (match_operand:SI 0 "register_operand" "")
18710         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18711                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18712   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18713   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18714               (clobber (reg:CC FLAGS_REG))])]
18715   "operands[2] = gen_lowpart (SImode, operands[2]);")
18716
18717 (define_peephole2
18718   [(set (match_operand:DI 0 "register_operand" "")
18719         (plus:DI (match_dup 0)
18720                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18721   "peep2_regno_dead_p (0, FLAGS_REG)"
18722   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18723               (clobber (reg:CC FLAGS_REG))])]
18724   "")
18725
18726 (define_peephole2
18727   [(set (match_operand:SI 0 "register_operand" "")
18728         (mult:SI (match_dup 0)
18729                  (match_operand:SI 1 "const_int_operand" "")))]
18730   "exact_log2 (INTVAL (operands[1])) >= 0
18731    && peep2_regno_dead_p (0, FLAGS_REG)"
18732   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18733               (clobber (reg:CC FLAGS_REG))])]
18734   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18735
18736 (define_peephole2
18737   [(set (match_operand:DI 0 "register_operand" "")
18738         (mult:DI (match_dup 0)
18739                  (match_operand:DI 1 "const_int_operand" "")))]
18740   "exact_log2 (INTVAL (operands[1])) >= 0
18741    && peep2_regno_dead_p (0, FLAGS_REG)"
18742   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18743               (clobber (reg:CC FLAGS_REG))])]
18744   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18745
18746 (define_peephole2
18747   [(set (match_operand:SI 0 "register_operand" "")
18748         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18749                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18750   "exact_log2 (INTVAL (operands[2])) >= 0
18751    && REGNO (operands[0]) == REGNO (operands[1])
18752    && peep2_regno_dead_p (0, FLAGS_REG)"
18753   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18754               (clobber (reg:CC FLAGS_REG))])]
18755   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18756
18757 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18758 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18759 ;; many CPUs it is also faster, since special hardware to avoid esp
18760 ;; dependencies is present.
18761
18762 ;; While some of these conversions may be done using splitters, we use peepholes
18763 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18764
18765 ;; Convert prologue esp subtractions to push.
18766 ;; We need register to push.  In order to keep verify_flow_info happy we have
18767 ;; two choices
18768 ;; - use scratch and clobber it in order to avoid dependencies
18769 ;; - use already live register
18770 ;; We can't use the second way right now, since there is no reliable way how to
18771 ;; verify that given register is live.  First choice will also most likely in
18772 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18773 ;; call clobbered registers are dead.  We may want to use base pointer as an
18774 ;; alternative when no register is available later.
18775
18776 (define_peephole2
18777   [(match_scratch:SI 0 "r")
18778    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18779               (clobber (reg:CC FLAGS_REG))
18780               (clobber (mem:BLK (scratch)))])]
18781   "optimize_size || !TARGET_SUB_ESP_4"
18782   [(clobber (match_dup 0))
18783    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18784               (clobber (mem:BLK (scratch)))])])
18785
18786 (define_peephole2
18787   [(match_scratch:SI 0 "r")
18788    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18789               (clobber (reg:CC FLAGS_REG))
18790               (clobber (mem:BLK (scratch)))])]
18791   "optimize_size || !TARGET_SUB_ESP_8"
18792   [(clobber (match_dup 0))
18793    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18794    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18795               (clobber (mem:BLK (scratch)))])])
18796
18797 ;; Convert esp subtractions to push.
18798 (define_peephole2
18799   [(match_scratch:SI 0 "r")
18800    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18801               (clobber (reg:CC FLAGS_REG))])]
18802   "optimize_size || !TARGET_SUB_ESP_4"
18803   [(clobber (match_dup 0))
18804    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18805
18806 (define_peephole2
18807   [(match_scratch:SI 0 "r")
18808    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18809               (clobber (reg:CC FLAGS_REG))])]
18810   "optimize_size || !TARGET_SUB_ESP_8"
18811   [(clobber (match_dup 0))
18812    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18813    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18814
18815 ;; Convert epilogue deallocator to pop.
18816 (define_peephole2
18817   [(match_scratch:SI 0 "r")
18818    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18819               (clobber (reg:CC FLAGS_REG))
18820               (clobber (mem:BLK (scratch)))])]
18821   "optimize_size || !TARGET_ADD_ESP_4"
18822   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18823               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18824               (clobber (mem:BLK (scratch)))])]
18825   "")
18826
18827 ;; Two pops case is tricky, since pop causes dependency on destination register.
18828 ;; We use two registers if available.
18829 (define_peephole2
18830   [(match_scratch:SI 0 "r")
18831    (match_scratch:SI 1 "r")
18832    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18833               (clobber (reg:CC FLAGS_REG))
18834               (clobber (mem:BLK (scratch)))])]
18835   "optimize_size || !TARGET_ADD_ESP_8"
18836   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18837               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18838               (clobber (mem:BLK (scratch)))])
18839    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18840               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18841   "")
18842
18843 (define_peephole2
18844   [(match_scratch:SI 0 "r")
18845    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18846               (clobber (reg:CC FLAGS_REG))
18847               (clobber (mem:BLK (scratch)))])]
18848   "optimize_size"
18849   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18850               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18851               (clobber (mem:BLK (scratch)))])
18852    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18853               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18854   "")
18855
18856 ;; Convert esp additions to pop.
18857 (define_peephole2
18858   [(match_scratch:SI 0 "r")
18859    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18860               (clobber (reg:CC FLAGS_REG))])]
18861   ""
18862   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18863               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18864   "")
18865
18866 ;; Two pops case is tricky, since pop causes dependency on destination register.
18867 ;; We use two registers if available.
18868 (define_peephole2
18869   [(match_scratch:SI 0 "r")
18870    (match_scratch:SI 1 "r")
18871    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18872               (clobber (reg:CC FLAGS_REG))])]
18873   ""
18874   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18875               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18876    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18877               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18878   "")
18879
18880 (define_peephole2
18881   [(match_scratch:SI 0 "r")
18882    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18883               (clobber (reg:CC FLAGS_REG))])]
18884   "optimize_size"
18885   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18886               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18887    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18888               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18889   "")
18890 \f
18891 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18892 ;; required and register dies.  Similarly for 128 to plus -128.
18893 (define_peephole2
18894   [(set (match_operand 0 "flags_reg_operand" "")
18895         (match_operator 1 "compare_operator"
18896           [(match_operand 2 "register_operand" "")
18897            (match_operand 3 "const_int_operand" "")]))]
18898   "(INTVAL (operands[3]) == -1
18899     || INTVAL (operands[3]) == 1
18900     || INTVAL (operands[3]) == 128)
18901    && ix86_match_ccmode (insn, CCGCmode)
18902    && peep2_reg_dead_p (1, operands[2])"
18903   [(parallel [(set (match_dup 0)
18904                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18905               (clobber (match_dup 2))])]
18906   "")
18907 \f
18908 (define_peephole2
18909   [(match_scratch:DI 0 "r")
18910    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18911               (clobber (reg:CC FLAGS_REG))
18912               (clobber (mem:BLK (scratch)))])]
18913   "optimize_size || !TARGET_SUB_ESP_4"
18914   [(clobber (match_dup 0))
18915    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18916               (clobber (mem:BLK (scratch)))])])
18917
18918 (define_peephole2
18919   [(match_scratch:DI 0 "r")
18920    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18921               (clobber (reg:CC FLAGS_REG))
18922               (clobber (mem:BLK (scratch)))])]
18923   "optimize_size || !TARGET_SUB_ESP_8"
18924   [(clobber (match_dup 0))
18925    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18926    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18927               (clobber (mem:BLK (scratch)))])])
18928
18929 ;; Convert esp subtractions to push.
18930 (define_peephole2
18931   [(match_scratch:DI 0 "r")
18932    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18933               (clobber (reg:CC FLAGS_REG))])]
18934   "optimize_size || !TARGET_SUB_ESP_4"
18935   [(clobber (match_dup 0))
18936    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18937
18938 (define_peephole2
18939   [(match_scratch:DI 0 "r")
18940    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18941               (clobber (reg:CC FLAGS_REG))])]
18942   "optimize_size || !TARGET_SUB_ESP_8"
18943   [(clobber (match_dup 0))
18944    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18945    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18946
18947 ;; Convert epilogue deallocator to pop.
18948 (define_peephole2
18949   [(match_scratch:DI 0 "r")
18950    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18951               (clobber (reg:CC FLAGS_REG))
18952               (clobber (mem:BLK (scratch)))])]
18953   "optimize_size || !TARGET_ADD_ESP_4"
18954   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18955               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18956               (clobber (mem:BLK (scratch)))])]
18957   "")
18958
18959 ;; Two pops case is tricky, since pop causes dependency on destination register.
18960 ;; We use two registers if available.
18961 (define_peephole2
18962   [(match_scratch:DI 0 "r")
18963    (match_scratch:DI 1 "r")
18964    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18965               (clobber (reg:CC FLAGS_REG))
18966               (clobber (mem:BLK (scratch)))])]
18967   "optimize_size || !TARGET_ADD_ESP_8"
18968   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18969               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18970               (clobber (mem:BLK (scratch)))])
18971    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18972               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18973   "")
18974
18975 (define_peephole2
18976   [(match_scratch:DI 0 "r")
18977    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18978               (clobber (reg:CC FLAGS_REG))
18979               (clobber (mem:BLK (scratch)))])]
18980   "optimize_size"
18981   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18982               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18983               (clobber (mem:BLK (scratch)))])
18984    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18985               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18986   "")
18987
18988 ;; Convert esp additions to pop.
18989 (define_peephole2
18990   [(match_scratch:DI 0 "r")
18991    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18992               (clobber (reg:CC FLAGS_REG))])]
18993   ""
18994   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18995               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18996   "")
18997
18998 ;; Two pops case is tricky, since pop causes dependency on destination register.
18999 ;; We use two registers if available.
19000 (define_peephole2
19001   [(match_scratch:DI 0 "r")
19002    (match_scratch:DI 1 "r")
19003    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19004               (clobber (reg:CC FLAGS_REG))])]
19005   ""
19006   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19007               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19008    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19009               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19010   "")
19011
19012 (define_peephole2
19013   [(match_scratch:DI 0 "r")
19014    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19015               (clobber (reg:CC FLAGS_REG))])]
19016   "optimize_size"
19017   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19018               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19019    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19020               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19021   "")
19022 \f
19023 ;; Convert imul by three, five and nine into lea
19024 (define_peephole2
19025   [(parallel
19026     [(set (match_operand:SI 0 "register_operand" "")
19027           (mult:SI (match_operand:SI 1 "register_operand" "")
19028                    (match_operand:SI 2 "const_int_operand" "")))
19029      (clobber (reg:CC FLAGS_REG))])]
19030   "INTVAL (operands[2]) == 3
19031    || INTVAL (operands[2]) == 5
19032    || INTVAL (operands[2]) == 9"
19033   [(set (match_dup 0)
19034         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19035                  (match_dup 1)))]
19036   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19037
19038 (define_peephole2
19039   [(parallel
19040     [(set (match_operand:SI 0 "register_operand" "")
19041           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19042                    (match_operand:SI 2 "const_int_operand" "")))
19043      (clobber (reg:CC FLAGS_REG))])]
19044   "!optimize_size 
19045    && (INTVAL (operands[2]) == 3
19046        || INTVAL (operands[2]) == 5
19047        || INTVAL (operands[2]) == 9)"
19048   [(set (match_dup 0) (match_dup 1))
19049    (set (match_dup 0)
19050         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19051                  (match_dup 0)))]
19052   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19053
19054 (define_peephole2
19055   [(parallel
19056     [(set (match_operand:DI 0 "register_operand" "")
19057           (mult:DI (match_operand:DI 1 "register_operand" "")
19058                    (match_operand:DI 2 "const_int_operand" "")))
19059      (clobber (reg:CC FLAGS_REG))])]
19060   "TARGET_64BIT
19061    && (INTVAL (operands[2]) == 3
19062        || INTVAL (operands[2]) == 5
19063        || INTVAL (operands[2]) == 9)"
19064   [(set (match_dup 0)
19065         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19066                  (match_dup 1)))]
19067   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19068
19069 (define_peephole2
19070   [(parallel
19071     [(set (match_operand:DI 0 "register_operand" "")
19072           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19073                    (match_operand:DI 2 "const_int_operand" "")))
19074      (clobber (reg:CC FLAGS_REG))])]
19075   "TARGET_64BIT
19076    && !optimize_size 
19077    && (INTVAL (operands[2]) == 3
19078        || INTVAL (operands[2]) == 5
19079        || INTVAL (operands[2]) == 9)"
19080   [(set (match_dup 0) (match_dup 1))
19081    (set (match_dup 0)
19082         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19083                  (match_dup 0)))]
19084   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19085
19086 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19087 ;; imul $32bit_imm, reg, reg is direct decoded.
19088 (define_peephole2
19089   [(match_scratch:DI 3 "r")
19090    (parallel [(set (match_operand:DI 0 "register_operand" "")
19091                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19092                             (match_operand:DI 2 "immediate_operand" "")))
19093               (clobber (reg:CC FLAGS_REG))])]
19094   "TARGET_K8 && !optimize_size
19095    && (GET_CODE (operands[2]) != CONST_INT
19096        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19097   [(set (match_dup 3) (match_dup 1))
19098    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19099               (clobber (reg:CC FLAGS_REG))])]
19100 "")
19101
19102 (define_peephole2
19103   [(match_scratch:SI 3 "r")
19104    (parallel [(set (match_operand:SI 0 "register_operand" "")
19105                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19106                             (match_operand:SI 2 "immediate_operand" "")))
19107               (clobber (reg:CC FLAGS_REG))])]
19108   "TARGET_K8 && !optimize_size
19109    && (GET_CODE (operands[2]) != CONST_INT
19110        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19111   [(set (match_dup 3) (match_dup 1))
19112    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19113               (clobber (reg:CC FLAGS_REG))])]
19114 "")
19115
19116 (define_peephole2
19117   [(match_scratch:SI 3 "r")
19118    (parallel [(set (match_operand:DI 0 "register_operand" "")
19119                    (zero_extend:DI
19120                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19121                               (match_operand:SI 2 "immediate_operand" ""))))
19122               (clobber (reg:CC FLAGS_REG))])]
19123   "TARGET_K8 && !optimize_size
19124    && (GET_CODE (operands[2]) != CONST_INT
19125        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19126   [(set (match_dup 3) (match_dup 1))
19127    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19128               (clobber (reg:CC FLAGS_REG))])]
19129 "")
19130
19131 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19132 ;; Convert it into imul reg, reg
19133 ;; It would be better to force assembler to encode instruction using long
19134 ;; immediate, but there is apparently no way to do so.
19135 (define_peephole2
19136   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19137                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19138                             (match_operand:DI 2 "const_int_operand" "")))
19139               (clobber (reg:CC FLAGS_REG))])
19140    (match_scratch:DI 3 "r")]
19141   "TARGET_K8 && !optimize_size
19142    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19143   [(set (match_dup 3) (match_dup 2))
19144    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19145               (clobber (reg:CC FLAGS_REG))])]
19146 {
19147   if (!rtx_equal_p (operands[0], operands[1]))
19148     emit_move_insn (operands[0], operands[1]);
19149 })
19150
19151 (define_peephole2
19152   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19153                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19154                             (match_operand:SI 2 "const_int_operand" "")))
19155               (clobber (reg:CC FLAGS_REG))])
19156    (match_scratch:SI 3 "r")]
19157   "TARGET_K8 && !optimize_size
19158    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19159   [(set (match_dup 3) (match_dup 2))
19160    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19161               (clobber (reg:CC FLAGS_REG))])]
19162 {
19163   if (!rtx_equal_p (operands[0], operands[1]))
19164     emit_move_insn (operands[0], operands[1]);
19165 })
19166
19167 (define_peephole2
19168   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19169                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19170                             (match_operand:HI 2 "immediate_operand" "")))
19171               (clobber (reg:CC FLAGS_REG))])
19172    (match_scratch:HI 3 "r")]
19173   "TARGET_K8 && !optimize_size"
19174   [(set (match_dup 3) (match_dup 2))
19175    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19176               (clobber (reg:CC FLAGS_REG))])]
19177 {
19178   if (!rtx_equal_p (operands[0], operands[1]))
19179     emit_move_insn (operands[0], operands[1]);
19180 })
19181 \f
19182 ;; Call-value patterns last so that the wildcard operand does not
19183 ;; disrupt insn-recog's switch tables.
19184
19185 (define_insn "*call_value_pop_0"
19186   [(set (match_operand 0 "" "")
19187         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19188               (match_operand:SI 2 "" "")))
19189    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19190                             (match_operand:SI 3 "immediate_operand" "")))]
19191   "!TARGET_64BIT"
19192 {
19193   if (SIBLING_CALL_P (insn))
19194     return "jmp\t%P1";
19195   else
19196     return "call\t%P1";
19197 }
19198   [(set_attr "type" "callv")])
19199
19200 (define_insn "*call_value_pop_1"
19201   [(set (match_operand 0 "" "")
19202         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19203               (match_operand:SI 2 "" "")))
19204    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19205                             (match_operand:SI 3 "immediate_operand" "i")))]
19206   "!TARGET_64BIT"
19207 {
19208   if (constant_call_address_operand (operands[1], Pmode))
19209     {
19210       if (SIBLING_CALL_P (insn))
19211         return "jmp\t%P1";
19212       else
19213         return "call\t%P1";
19214     }
19215   if (SIBLING_CALL_P (insn))
19216     return "jmp\t%A1";
19217   else
19218     return "call\t%A1";
19219 }
19220   [(set_attr "type" "callv")])
19221
19222 (define_insn "*call_value_0"
19223   [(set (match_operand 0 "" "")
19224         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19225               (match_operand:SI 2 "" "")))]
19226   "!TARGET_64BIT"
19227 {
19228   if (SIBLING_CALL_P (insn))
19229     return "jmp\t%P1";
19230   else
19231     return "call\t%P1";
19232 }
19233   [(set_attr "type" "callv")])
19234
19235 (define_insn "*call_value_0_rex64"
19236   [(set (match_operand 0 "" "")
19237         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19238               (match_operand:DI 2 "const_int_operand" "")))]
19239   "TARGET_64BIT"
19240 {
19241   if (SIBLING_CALL_P (insn))
19242     return "jmp\t%P1";
19243   else
19244     return "call\t%P1";
19245 }
19246   [(set_attr "type" "callv")])
19247
19248 (define_insn "*call_value_1"
19249   [(set (match_operand 0 "" "")
19250         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19251               (match_operand:SI 2 "" "")))]
19252   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19253 {
19254   if (constant_call_address_operand (operands[1], Pmode))
19255     return "call\t%P1";
19256   return "call\t%A1";
19257 }
19258   [(set_attr "type" "callv")])
19259
19260 (define_insn "*sibcall_value_1"
19261   [(set (match_operand 0 "" "")
19262         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19263               (match_operand:SI 2 "" "")))]
19264   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19265 {
19266   if (constant_call_address_operand (operands[1], Pmode))
19267     return "jmp\t%P1";
19268   return "jmp\t%A1";
19269 }
19270   [(set_attr "type" "callv")])
19271
19272 (define_insn "*call_value_1_rex64"
19273   [(set (match_operand 0 "" "")
19274         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19275               (match_operand:DI 2 "" "")))]
19276   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19277 {
19278   if (constant_call_address_operand (operands[1], Pmode))
19279     return "call\t%P1";
19280   return "call\t%A1";
19281 }
19282   [(set_attr "type" "callv")])
19283
19284 (define_insn "*sibcall_value_1_rex64"
19285   [(set (match_operand 0 "" "")
19286         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19287               (match_operand:DI 2 "" "")))]
19288   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19289   "jmp\t%P1"
19290   [(set_attr "type" "callv")])
19291
19292 (define_insn "*sibcall_value_1_rex64_v"
19293   [(set (match_operand 0 "" "")
19294         (call (mem:QI (reg:DI 40))
19295               (match_operand:DI 1 "" "")))]
19296   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19297   "jmp\t*%%r11"
19298   [(set_attr "type" "callv")])
19299 \f
19300 (define_insn "trap"
19301   [(trap_if (const_int 1) (const_int 5))]
19302   ""
19303   "int\t$5")
19304
19305 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19306 ;;; for the sake of bounds checking.  By emitting bounds checks as
19307 ;;; conditional traps rather than as conditional jumps around
19308 ;;; unconditional traps we avoid introducing spurious basic-block
19309 ;;; boundaries and facilitate elimination of redundant checks.  In
19310 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19311 ;;; interrupt 5.
19312 ;;; 
19313 ;;; FIXME: Static branch prediction rules for ix86 are such that
19314 ;;; forward conditional branches predict as untaken.  As implemented
19315 ;;; below, pseudo conditional traps violate that rule.  We should use
19316 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19317 ;;; section loaded at the end of the text segment and branch forward
19318 ;;; there on bounds-failure, and then jump back immediately (in case
19319 ;;; the system chooses to ignore bounds violations, or to report
19320 ;;; violations and continue execution).
19321
19322 (define_expand "conditional_trap"
19323   [(trap_if (match_operator 0 "comparison_operator"
19324              [(match_dup 2) (const_int 0)])
19325             (match_operand 1 "const_int_operand" ""))]
19326   ""
19327 {
19328   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19329                               ix86_expand_compare (GET_CODE (operands[0]),
19330                                                    NULL, NULL),
19331                               operands[1]));
19332   DONE;
19333 })
19334
19335 (define_insn "*conditional_trap_1"
19336   [(trap_if (match_operator 0 "comparison_operator"
19337              [(reg FLAGS_REG) (const_int 0)])
19338             (match_operand 1 "const_int_operand" ""))]
19339   ""
19340 {
19341   operands[2] = gen_label_rtx ();
19342   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19343   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19344                              CODE_LABEL_NUMBER (operands[2]));
19345   RET;
19346 })
19347
19348 (define_expand "sse_prologue_save"
19349   [(parallel [(set (match_operand:BLK 0 "" "")
19350                    (unspec:BLK [(reg:DI 21)
19351                                 (reg:DI 22)
19352                                 (reg:DI 23)
19353                                 (reg:DI 24)
19354                                 (reg:DI 25)
19355                                 (reg:DI 26)
19356                                 (reg:DI 27)
19357                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19358               (use (match_operand:DI 1 "register_operand" ""))
19359               (use (match_operand:DI 2 "immediate_operand" ""))
19360               (use (label_ref:DI (match_operand 3 "" "")))])]
19361   "TARGET_64BIT"
19362   "")
19363
19364 (define_insn "*sse_prologue_save_insn"
19365   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19366                           (match_operand:DI 4 "const_int_operand" "n")))
19367         (unspec:BLK [(reg:DI 21)
19368                      (reg:DI 22)
19369                      (reg:DI 23)
19370                      (reg:DI 24)
19371                      (reg:DI 25)
19372                      (reg:DI 26)
19373                      (reg:DI 27)
19374                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19375    (use (match_operand:DI 1 "register_operand" "r"))
19376    (use (match_operand:DI 2 "const_int_operand" "i"))
19377    (use (label_ref:DI (match_operand 3 "" "X")))]
19378   "TARGET_64BIT
19379    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19380    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19381   "*
19382 {
19383   int i;
19384   operands[0] = gen_rtx_MEM (Pmode,
19385                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19386   output_asm_insn (\"jmp\\t%A1\", operands);
19387   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19388     {
19389       operands[4] = adjust_address (operands[0], DImode, i*16);
19390       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19391       PUT_MODE (operands[4], TImode);
19392       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19393         output_asm_insn (\"rex\", operands);
19394       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19395     }
19396   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19397                              CODE_LABEL_NUMBER (operands[3]));
19398   RET;
19399 }
19400   "
19401   [(set_attr "type" "other")
19402    (set_attr "length_immediate" "0")
19403    (set_attr "length_address" "0")
19404    (set_attr "length" "135")
19405    (set_attr "memory" "store")
19406    (set_attr "modrm" "0")
19407    (set_attr "mode" "DI")])
19408
19409 (define_expand "prefetch"
19410   [(prefetch (match_operand 0 "address_operand" "")
19411              (match_operand:SI 1 "const_int_operand" "")
19412              (match_operand:SI 2 "const_int_operand" ""))]
19413   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19414 {
19415   int rw = INTVAL (operands[1]);
19416   int locality = INTVAL (operands[2]);
19417
19418   if (rw != 0 && rw != 1)
19419     abort ();
19420   if (locality < 0 || locality > 3)
19421     abort ();
19422   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19423     abort ();
19424
19425   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19426      supported by SSE counterpart or the SSE prefetch is not available
19427      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19428      of locality.  */
19429   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19430     operands[2] = GEN_INT (3);
19431   else
19432     operands[1] = const0_rtx;
19433 })
19434
19435 (define_insn "*prefetch_sse"
19436   [(prefetch (match_operand:SI 0 "address_operand" "p")
19437              (const_int 0)
19438              (match_operand:SI 1 "const_int_operand" ""))]
19439   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19440 {
19441   static const char * const patterns[4] = {
19442    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19443   };
19444
19445   int locality = INTVAL (operands[1]);
19446   if (locality < 0 || locality > 3)
19447     abort ();
19448
19449   return patterns[locality];  
19450 }
19451   [(set_attr "type" "sse")
19452    (set_attr "memory" "none")])
19453
19454 (define_insn "*prefetch_sse_rex"
19455   [(prefetch (match_operand:DI 0 "address_operand" "p")
19456              (const_int 0)
19457              (match_operand:SI 1 "const_int_operand" ""))]
19458   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19459 {
19460   static const char * const patterns[4] = {
19461    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19462   };
19463
19464   int locality = INTVAL (operands[1]);
19465   if (locality < 0 || locality > 3)
19466     abort ();
19467
19468   return patterns[locality];  
19469 }
19470   [(set_attr "type" "sse")
19471    (set_attr "memory" "none")])
19472
19473 (define_insn "*prefetch_3dnow"
19474   [(prefetch (match_operand:SI 0 "address_operand" "p")
19475              (match_operand:SI 1 "const_int_operand" "n")
19476              (const_int 3))]
19477   "TARGET_3DNOW && !TARGET_64BIT"
19478 {
19479   if (INTVAL (operands[1]) == 0)
19480     return "prefetch\t%a0";
19481   else
19482     return "prefetchw\t%a0";
19483 }
19484   [(set_attr "type" "mmx")
19485    (set_attr "memory" "none")])
19486
19487 (define_insn "*prefetch_3dnow_rex"
19488   [(prefetch (match_operand:DI 0 "address_operand" "p")
19489              (match_operand:SI 1 "const_int_operand" "n")
19490              (const_int 3))]
19491   "TARGET_3DNOW && TARGET_64BIT"
19492 {
19493   if (INTVAL (operands[1]) == 0)
19494     return "prefetch\t%a0";
19495   else
19496     return "prefetchw\t%a0";
19497 }
19498   [(set_attr "type" "mmx")
19499    (set_attr "memory" "none")])
19500
19501 (include "sse.md")
19502 (include "mmx.md")