OSDN Git Service

* config/i386/i386.md (call_pop): Check operands[0],
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 ;; Free Software Foundation, Inc.
4 ;; Mostly by William Schelter.
5 ;;
6 ;; This file is part of GNU CC.
7 ;;
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA. */
22 ;;
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
25 ;;
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;;
28 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
29 ;; updates for most instructions.
30 ;;
31 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
32 ;; constraint letters.
33 ;;
34 ;; The special asm out single letter directives following a '%' are:
35 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;;     operands[1].
37 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
38 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
39 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
40 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
41 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
42 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
43 ;; 'J' Print the appropriate jump operand.
44 ;;
45 ;; 'b' Print the QImode name of the register for the indicated operand.
46 ;;     %b0 would print %al if operands[0] is reg 0.
47 ;; 'w' Likewise, print the HImode name of the register.
48 ;; 'k' Likewise, print the SImode name of the register.
49 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
50 ;; 'y' Print "st(0)" instead of "st" as a register.
51 ;;
52 ;; UNSPEC usage:
53 ;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
54 ;;    operand 0 is the memory address to scan.
55 ;;    operand 1 is a register containing the value to scan for.  The mode
56 ;;       of the scas opcode will be the same as the mode of this operand.
57 ;;    operand 2 is the known alignment of operand 0.
58 ;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
59 ;;    operand 0 is the argument for `sin'.
60 ;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
61 ;;    operand 0 is the argument for `cos'.
62 ;; 3  This is part of a `stack probe' operation.  The mode of the UNSPEC is 
63 ;;    always SImode.  operand 0 is the size of the stack allocation.
64 ;; 4  This is the source of a fake SET of the frame pointer which is used to
65 ;;    prevent insns referencing it being scheduled across the initial
66 ;;    decrement of the stack pointer.
67 ;; 5  This is a `bsf' operation.
68 ;; 6  This is the @GOT offset of a PIC address.
69 ;; 7  This is the @GOTOFF offset of a PIC address.
70 ;; 8  This is a reference to a symbol's @PLT address.
71 ;; 9  This is an `fnstsw' operation.
72 ;; 10 This is a `sahf' operation.
73 ;; 11 This is a `fstcw' operation
74 ;;
75 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
76 ;; from i386.c.
77
78 \f
79 ;; Processor type.  This attribute must exactly match the processor_type
80 ;; enumeration in i386.h.
81 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon"
82   (const (symbol_ref "ix86_cpu")))
83
84 ;; A basic instruction type.  Refinements due to arguments to be
85 ;; provided in other attributes.
86 (define_attr "type"
87   "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld"
88   (const_string "other"))
89
90 ;; Main data type used by the insn
91 (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF"
92   (const_string "unknown"))
93
94 ;; Set for i387 operations.
95 (define_attr "i387" ""
96   (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch")
97     (const_int 1)
98     (const_int 0)))
99
100 ;; The (bounding maximum) length of an instruction immediate.
101 (define_attr "length_immediate" ""
102   (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv")
103            (const_int 0)
104          (eq_attr "i387" "1")
105            (const_int 0)
106          (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
107            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
108          (eq_attr "type" "imov,test")
109            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
110          (eq_attr "type" "call")
111            (if_then_else (match_operand 0 "constant_call_address_operand" "")
112              (const_int 4)
113              (const_int 0))
114          (eq_attr "type" "callv")
115            (if_then_else (match_operand 1 "constant_call_address_operand" "")
116              (const_int 4)
117              (const_int 0))
118          (eq_attr "type" "ibr")
119            (if_then_else (and (ge (minus (match_dup 0) (pc))
120                                   (const_int -128))
121                               (lt (minus (match_dup 0) (pc))
122                                   (const_int 124)))
123              (const_int 1)
124              (const_int 4))
125          ]
126          (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
127
128 ;; The (bounding maximum) length of an instruction address.
129 (define_attr "length_address" ""
130   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
131            (const_int 0)
132          (and (eq_attr "type" "call")
133               (match_operand 1 "constant_call_address_operand" ""))
134              (const_int 0)
135          (and (eq_attr "type" "callv")
136               (match_operand 1 "constant_call_address_operand" ""))
137              (const_int 0)
138          ]
139          (symbol_ref "ix86_attr_length_address_default (insn)")))
140
141 ;; Set when length prefix is used.
142 (define_attr "prefix_data16" ""
143   (if_then_else (eq_attr "mode" "HI")
144     (const_int 1)
145     (const_int 0)))
146
147 ;; Set when string REP prefix is used.
148 (define_attr "prefix_rep" "" (const_int 0))
149
150 ;; Set when 0f opcode prefix is used.
151 (define_attr "prefix_0f" ""
152   (if_then_else (eq_attr "type" "imovx,setcc,icmov")
153     (const_int 1)
154     (const_int 0)))
155
156 ;; Set when modrm byte is used.
157 (define_attr "modrm" ""
158   (cond [(eq_attr "type" "str,cld")
159            (const_int 0)
160          (eq_attr "i387" "1")
161            (const_int 0)
162          (and (eq_attr "type" "incdec")
163               (ior (match_operand:SI 1 "register_operand" "")
164                    (match_operand:HI 1 "register_operand" "")))
165            (const_int 0)
166          (and (eq_attr "type" "push")
167               (not (match_operand 1 "memory_operand" "")))
168            (const_int 0)
169          (and (eq_attr "type" "pop")
170               (not (match_operand 0 "memory_operand" "")))
171            (const_int 0)
172          (and (eq_attr "type" "imov")
173               (and (match_operand 0 "register_operand" "")
174                    (match_operand 1 "immediate_operand" "")))
175            (const_int 0)
176          ]
177          (const_int 1)))
178
179 ;; The (bounding maximum) length of an instruction in bytes.
180 (define_attr "length" ""
181   (cond [(eq_attr "type" "other,multi")
182            (const_int 16)
183          ]
184          (plus (plus (attr "modrm")
185                      (plus (attr "prefix_0f")
186                            (plus (attr "i387")
187                                  (const_int 1))))
188                (plus (attr "prefix_rep")
189                      (plus (attr "prefix_data16")
190                            (plus (attr "length_immediate")
191                                  (attr "length_address")))))))
192
193 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
194 ;; `store' if there is a simple memory reference therein, or `unknown'
195 ;; if the instruction is complex.
196
197 (define_attr "memory" "none,load,store,both,unknown"
198   (cond [(eq_attr "type" "other,multi,str")
199            (const_string "unknown")
200          (eq_attr "type" "lea,fcmov,fpspc,cld")
201            (const_string "none")
202          (eq_attr "type" "push")
203            (if_then_else (match_operand 1 "memory_operand" "")
204              (const_string "both")
205              (const_string "store"))
206          (eq_attr "type" "pop,setcc")
207            (if_then_else (match_operand 0 "memory_operand" "")
208              (const_string "both")
209              (const_string "load"))
210          (eq_attr "type" "icmp,test")
211            (if_then_else (ior (match_operand 0 "memory_operand" "")
212                               (match_operand 1 "memory_operand" ""))
213              (const_string "load")
214              (const_string "none"))
215          (eq_attr "type" "ibr")
216            (if_then_else (match_operand 0 "memory_operand" "")
217              (const_string "load")
218              (const_string "none"))
219          (eq_attr "type" "call")
220            (if_then_else (match_operand 0 "constant_call_address_operand" "")
221              (const_string "none")
222              (const_string "load"))
223          (eq_attr "type" "callv")
224            (if_then_else (match_operand 1 "constant_call_address_operand" "")
225              (const_string "none")
226              (const_string "load"))
227          (and (eq_attr "type" "alu1,negnot")
228               (match_operand 1 "memory_operand" ""))
229            (const_string "both")
230          (and (match_operand 0 "memory_operand" "")
231               (match_operand 1 "memory_operand" ""))
232            (const_string "both")
233          (match_operand 0 "memory_operand" "")
234            (const_string "store")
235          (match_operand 1 "memory_operand" "")
236            (const_string "load")
237          (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp")
238               (match_operand 2 "memory_operand" ""))
239            (const_string "load")
240          (and (eq_attr "type" "icmov")
241               (match_operand 3 "memory_operand" ""))
242            (const_string "load")
243         ]
244         (const_string "none")))
245
246 ;; Indicates if an instruction has both an immediate and a displacement.
247
248 (define_attr "imm_disp" "false,true,unknown"
249   (cond [(eq_attr "type" "other,multi")
250            (const_string "unknown")
251          (and (eq_attr "type" "icmp,test,imov")
252               (and (match_operand 0 "memory_displacement_operand" "")
253                    (match_operand 1 "immediate_operand" "")))
254            (const_string "true")
255          (and (eq_attr "type" "alu,ishift,imul,idiv")
256               (and (match_operand 0 "memory_displacement_operand" "")
257                    (match_operand 2 "immediate_operand" "")))
258            (const_string "true")
259         ]
260         (const_string "false")))
261
262 ;; Indicates if an FP operation has an integer source.
263
264 (define_attr "fp_int_src" "false,true"
265   (const_string "false"))
266
267 ;; Describe a user's asm statement.
268 (define_asm_attributes
269   [(set_attr "length" "128")
270    (set_attr "type" "multi")])
271 \f
272 ;; Pentium Scheduling
273 ;;
274 ;; The Pentium is an in-order core with two integer pipelines.
275
276 ;; True for insns that behave like prefixed insns on the Pentium.
277 (define_attr "pent_prefix" "false,true"
278   (if_then_else (ior (eq_attr "prefix_0f" "1")
279                      (ior (eq_attr "prefix_data16" "1")
280                           (eq_attr "prefix_rep" "1")))
281     (const_string "true")
282     (const_string "false")))
283
284 ;; Categorize how an instruction slots.
285
286 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
287 ;; while MMX Pentium can slot it on either U or V.  Model non-MMX Pentium
288 ;; rules, because it results in noticeably better code on non-MMX Pentium
289 ;; and doesn't hurt much on MMX.  (Prefixed instructions are not very
290 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
291
292 (define_attr "pent_pair" "uv,pu,pv,np"
293   (cond [(eq_attr "imm_disp" "true")
294            (const_string "np")
295          (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
296               (and (eq_attr "type" "pop,push")
297                    (eq_attr "memory" "!both")))
298            (if_then_else (eq_attr "pent_prefix" "true")
299              (const_string "pu")
300              (const_string "uv"))
301          (eq_attr "type" "ibr")
302            (const_string "pv")
303          (and (eq_attr "type" "ishift")
304               (match_operand 2 "const_int_operand" ""))
305            (const_string "pu")
306          (and (eq_attr "type" "call")
307               (match_operand 0 "constant_call_address_operand" ""))
308            (const_string "pv")
309          (and (eq_attr "type" "callv")
310               (match_operand 1 "constant_call_address_operand" ""))
311            (const_string "pv")
312         ]
313         (const_string "np")))
314
315 ;; Rough readiness numbers.  Fine tuning happens in i386.c.
316 ;;
317 ;; u    describes pipe U
318 ;; v    describes pipe V
319 ;; uv   describes either pipe U or V for those that can issue to either
320 ;; np   describes not paring
321 ;; fpu  describes fpu
322 ;; fpm  describes fp insns of different types are not pipelined.
323 ;;
324 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
325
326 (define_function_unit "pent_np" 1 0
327   (and (eq_attr "cpu" "pentium")
328        (eq_attr "type" "imul"))
329   11 11)
330
331 (define_function_unit "pent_mul" 1 1
332   (and (eq_attr "cpu" "pentium")
333        (eq_attr "type" "imul"))
334   11 11)
335
336 ;; Rep movs takes minimally 12 cycles.
337 (define_function_unit "pent_np" 1 0
338   (and (eq_attr "cpu" "pentium")
339        (eq_attr "type" "str"))
340   12 12)
341
342 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
343 (define_function_unit "pent_np" 1 0
344   (and (eq_attr "cpu" "pentium")
345        (eq_attr "type" "idiv"))
346   46 46)
347
348 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
349 ; 3 cycles for XFmode.  Stores takes 2 cycles for SF/DF and 3 for XF.
350 ; fldz and fld1 takes 2 cycles.  Only reg-reg moves are pairable.
351 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
352 ; like normal fp operation and fist takes 6 cycles.
353
354 (define_function_unit "fpu" 1 0
355   (and (eq_attr "cpu" "pentium")
356        (and (eq_attr "type" "fmov")
357             (ior (and (eq_attr "memory" "store")
358                       (match_operand:XF 0 "memory_operand" ""))
359                  (and (eq_attr "memory" "load")
360                       (match_operand:XF 1 "memory_operand" "")))))
361   3 3)
362
363 (define_function_unit "pent_np" 1 0
364   (and (eq_attr "cpu" "pentium")
365        (and (eq_attr "type" "fmov")
366             (ior (and (eq_attr "memory" "store")
367                       (match_operand:XF 0 "memory_operand" ""))
368                  (and (eq_attr "memory" "load")
369                       (match_operand:XF 1 "memory_operand" "")))))
370   3 3)
371
372 (define_function_unit "fpu" 1 0
373   (and (eq_attr "cpu" "pentium")
374        (and (eq_attr "type" "fmov")
375             (ior (match_operand 1 "immediate_operand" "")
376                  (eq_attr "memory" "store"))))
377   2 2)
378
379 (define_function_unit "pent_np" 1 0
380   (and (eq_attr "cpu" "pentium")
381        (and (eq_attr "type" "fmov")
382             (ior (match_operand 1 "immediate_operand" "")
383                  (eq_attr "memory" "store"))))
384   2 2)
385
386 (define_function_unit "pent_np" 1 0
387   (and (eq_attr "cpu" "pentium")
388        (eq_attr "type" "cld"))
389   2 2)
390
391 (define_function_unit "fpu" 1 0
392   (and (eq_attr "cpu" "pentium")
393        (and (eq_attr "type" "fmov")
394             (eq_attr "memory" "none,load")))
395   1 1)
396
397 ; Read/Modify/Write instructions usually take 3 cycles.
398 (define_function_unit "pent_u" 1 0
399   (and (eq_attr "cpu" "pentium")
400        (and (eq_attr "type" "alu,alu1,ishift")
401             (and (eq_attr "pent_pair" "pu")
402                  (eq_attr "memory" "both"))))
403   3 3)
404
405 (define_function_unit "pent_uv" 2 0
406   (and (eq_attr "cpu" "pentium")
407        (and (eq_attr "type" "alu,alu1,ishift")
408             (and (eq_attr "pent_pair" "!np")
409                  (eq_attr "memory" "both"))))
410   3 3)
411
412 (define_function_unit "pent_np" 1 0
413   (and (eq_attr "cpu" "pentium")
414        (and (eq_attr "type" "alu,alu1,negnot,ishift")
415             (and (eq_attr "pent_pair" "np")
416                  (eq_attr "memory" "both"))))
417   3 3)
418
419 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
420 (define_function_unit "pent_u" 1 0
421   (and (eq_attr "cpu" "pentium")
422        (and (eq_attr "type" "alu,ishift")
423             (and (eq_attr "pent_pair" "pu")
424                  (eq_attr "memory" "load,store"))))
425   2 2)
426
427 (define_function_unit "pent_uv" 2 0
428   (and (eq_attr "cpu" "pentium")
429        (and (eq_attr "type" "alu,ishift")
430             (and (eq_attr "pent_pair" "!np")
431                  (eq_attr "memory" "load,store"))))
432   2 2)
433
434 (define_function_unit "pent_np" 1 0
435   (and (eq_attr "cpu" "pentium")
436        (and (eq_attr "type" "alu,ishift")
437             (and (eq_attr "pent_pair" "np")
438                  (eq_attr "memory" "load,store"))))
439   2 2)
440
441 ; Insns w/o memory operands and move instructions usually take one cycle.
442 (define_function_unit "pent_u" 1 0
443   (and (eq_attr "cpu" "pentium")
444        (eq_attr "pent_pair" "pu"))
445   1 1)
446
447 (define_function_unit "pent_v" 1 0
448   (and (eq_attr "cpu" "pentium")
449        (eq_attr "pent_pair" "pv"))
450   1 1)
451
452 (define_function_unit "pent_uv" 2 0
453   (and (eq_attr "cpu" "pentium")
454        (eq_attr "pent_pair" "!np"))
455   1 1)
456
457 (define_function_unit "pent_np" 1 0
458   (and (eq_attr "cpu" "pentium")
459        (eq_attr "pent_pair" "np"))
460   1 1)
461
462 ; Pairable insns only conflict with other non-pairable insns.
463 (define_function_unit "pent_np" 1 0
464   (and (eq_attr "cpu" "pentium")
465        (and (eq_attr "type" "alu,alu1,ishift")
466             (and (eq_attr "pent_pair" "!np")
467                  (eq_attr "memory" "both"))))
468   3 3
469   [(eq_attr "pent_pair" "np")])
470
471 (define_function_unit "pent_np" 1 0
472   (and (eq_attr "cpu" "pentium")
473        (and (eq_attr "type" "alu,alu1,ishift")
474             (and (eq_attr "pent_pair" "!np")
475                  (eq_attr "memory" "load,store"))))
476   2 2
477   [(eq_attr "pent_pair" "np")])
478
479 (define_function_unit "pent_np" 1 0
480   (and (eq_attr "cpu" "pentium")
481        (eq_attr "pent_pair" "!np"))
482   1 1
483   [(eq_attr "pent_pair" "np")])
484
485 ; Floating point instructions usually blocks cycle longer when combined with
486 ; integer instructions, because of the inpaired fxch instruction.
487 (define_function_unit "pent_np" 1 0
488   (and (eq_attr "cpu" "pentium")
489        (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
490   2 2
491   [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
492
493 (define_function_unit "fpu" 1 0
494   (and (eq_attr "cpu" "pentium")
495        (eq_attr "type" "fcmp,fxch,fsgn"))
496   1 1)
497
498 ; Addition takes 3 cycles; assume other random cruft does as well.
499 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
500 (define_function_unit "fpu" 1 0
501   (and (eq_attr "cpu" "pentium")
502        (eq_attr "type" "fop,fop1"))
503   3 1)
504
505 ; Multiplication takes 3 cycles and is only half pipelined.
506 (define_function_unit "fpu" 1 0
507   (and (eq_attr "cpu" "pentium")
508        (eq_attr "type" "fmul"))
509   3 1)
510
511 (define_function_unit "pent_mul" 1 1
512   (and (eq_attr "cpu" "pentium")
513        (eq_attr "type" "fmul"))
514   2 2)
515
516 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles. 
517 ; They can overlap with integer insns.  Only the last two cycles can overlap
518 ; with other fp insns.  Only fsin/fcos can overlap with multiplies.
519 ; Only last two cycles of fsin/fcos can overlap with other instructions.
520 (define_function_unit "fpu" 1 0
521   (and (eq_attr "cpu" "pentium")
522        (eq_attr "type" "fdiv"))
523   39 37)
524
525 (define_function_unit "pent_mul" 1 1
526   (and (eq_attr "cpu" "pentium")
527        (eq_attr "type" "fdiv"))
528   39 39)
529
530 (define_function_unit "fpu" 1 0
531   (and (eq_attr "cpu" "pentium")
532        (eq_attr "type" "fpspc"))
533   70 68)
534
535 (define_function_unit "pent_mul" 1 1
536   (and (eq_attr "cpu" "pentium")
537        (eq_attr "type" "fpspc"))
538   70 70)
539 \f
540 ;; Pentium Pro/PII Scheduling
541 ;;
542 ;; The PPro has an out-of-order core, but the instruction decoders are
543 ;; naturally in-order and asymmetric.  We get best performance by scheduling
544 ;; for the decoders, for in doing so we give the oo execution unit the 
545 ;; most choices.
546
547 ;; Categorize how many uops an ia32 instruction evaluates to:
548 ;;   one --  an instruction with 1 uop can be decoded by any of the
549 ;;           three decoders.
550 ;;   few --  an instruction with 1 to 4 uops can be decoded only by 
551 ;;           decoder 0.
552 ;;   many -- a complex instruction may take an unspecified number of
553 ;;           cycles to decode in decoder 0.
554
555 (define_attr "ppro_uops" "one,few,many"
556   (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
557            (const_string "many")
558          (eq_attr "type" "icmov,fcmov,str,cld")
559            (const_string "few")
560          (eq_attr "type" "imov")
561            (if_then_else (eq_attr "memory" "store,both")
562              (const_string "few")
563              (const_string "one"))
564          (eq_attr "memory" "!none")
565            (const_string "few")
566         ]
567         (const_string "one")))
568
569 ;; Rough readiness numbers.  Fine tuning happens in i386.c.
570 ;;
571 ;; p0   describes port 0.
572 ;; p01  describes ports 0 and 1 as a pair; alu insns can issue to either.
573 ;; p2   describes port 2 for loads.
574 ;; p34  describes ports 3 and 4 for stores.
575 ;; fpu  describes the fpu accessed via port 0. 
576 ;;      ??? It is less than clear if there are separate fadd and fmul units
577 ;;      that could operate in parallel.
578 ;;
579 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
580
581 (define_function_unit "ppro_p0" 1 0
582   (and (eq_attr "cpu" "pentiumpro")
583        (eq_attr "type" "ishift,lea,ibr,cld"))
584   1 1)
585
586 (define_function_unit "ppro_p0" 1 0
587   (and (eq_attr "cpu" "pentiumpro")
588        (eq_attr "type" "imul"))
589   4 1)
590
591 ;; ??? Does the divider lock out the pipe while it works,
592 ;; or is there a disconnected unit?
593 (define_function_unit "ppro_p0" 1 0
594   (and (eq_attr "cpu" "pentiumpro")
595        (eq_attr "type" "idiv"))
596   17 17)
597
598 (define_function_unit "ppro_p0" 1 0
599   (and (eq_attr "cpu" "pentiumpro")
600        (eq_attr "type" "fop,fop1,fsgn"))
601   3 1)
602
603 (define_function_unit "ppro_p0" 1 0
604   (and (eq_attr "cpu" "pentiumpro")
605        (eq_attr "type" "fcmov"))
606   2 1)
607
608 (define_function_unit "ppro_p0" 1 0
609   (and (eq_attr "cpu" "pentiumpro")
610        (eq_attr "type" "fcmp"))
611   1 1)
612
613 (define_function_unit "ppro_p0" 1 0
614   (and (eq_attr "cpu" "pentiumpro")
615        (eq_attr "type" "fmov"))
616   1 1)
617
618 (define_function_unit "ppro_p0" 1 0
619   (and (eq_attr "cpu" "pentiumpro")
620        (eq_attr "type" "fmul"))
621   5 1)
622
623 (define_function_unit "ppro_p0" 1 0
624   (and (eq_attr "cpu" "pentiumpro")
625        (eq_attr "type" "fdiv,fpspc"))
626   56 1)
627
628 (define_function_unit "ppro_p01" 2 0
629   (and (eq_attr "cpu" "pentiumpro")
630        (eq_attr "type" "!imov,fmov"))
631   1 1)
632
633 (define_function_unit "ppro_p01" 2 0
634   (and (and (eq_attr "cpu" "pentiumpro")
635             (eq_attr "type" "imov,fmov"))
636        (eq_attr "memory" "none"))
637   1 1)
638
639 (define_function_unit "ppro_p2" 1 0
640   (and (eq_attr "cpu" "pentiumpro")
641        (ior (eq_attr "type" "pop")
642             (eq_attr "memory" "load,both")))
643   3 1)
644
645 (define_function_unit "ppro_p34" 1 0
646   (and (eq_attr "cpu" "pentiumpro")
647        (ior (eq_attr "type" "push")
648             (eq_attr "memory" "store,both")))
649   1 1)
650
651 (define_function_unit "fpu" 1 0
652   (and (eq_attr "cpu" "pentiumpro")
653        (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
654   1 1)
655
656 (define_function_unit "fpu" 1 0
657   (and (eq_attr "cpu" "pentiumpro")
658        (eq_attr "type" "fmul"))
659   5 2)
660
661 (define_function_unit "fpu" 1 0
662   (and (eq_attr "cpu" "pentiumpro")
663        (eq_attr "type" "fdiv,fpspc"))
664   56 56)
665
666 ;; imul uses the fpu.  ??? does it have the same throughput as fmul?
667 (define_function_unit "fpu" 1 0
668   (and (eq_attr "cpu" "pentiumpro")
669        (eq_attr "type" "imul"))
670   4 1)
671 \f
672 ;; AMD K6/K6-2 Scheduling
673 ;;
674 ;; The K6 has similar architecture to PPro.  Important difference is, that
675 ;; there are only two decoders and they seems to be much slower than execution
676 ;; units.  So we have to pay much more attention to proper decoding for
677 ;; schedulers.  We share most of scheduler code for PPro in i386.c
678 ;;
679 ;; The fp unit is not pipelined and do one operation per two cycles including
680 ;; the FXCH.
681 ;;
682 ;; alu    describes both ALU units (ALU-X and ALU-Y).
683 ;; alux   describes X alu unit
684 ;; fpu    describes FPU unit
685 ;; load   describes load unit.
686 ;; branch describes branch unit.
687 ;; store  decsribes store unit.  This unit is not modelled completely and only
688 ;;        used to model lea operation.  Otherwise it lie outside of the critical
689 ;;        path.
690 ;;
691 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
692
693 ;; The decoder specification is in the PPro section above!
694
695 ;; Shift instructions and certain arithmetic are issued only to X pipe.
696 (define_function_unit "k6_alux" 1 0
697   (and (eq_attr "cpu" "k6")
698        (eq_attr "type" "ishift,alu1,negnot,cld"))
699   1 1)
700
701 ;; The QI mode arithmetic is issued to X pipe only.
702 (define_function_unit "k6_alux" 1 0
703   (and (eq_attr "cpu" "k6")
704        (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
705             (match_operand:QI 0 "general_operand" "")))
706   1 1)
707
708 (define_function_unit "k6_alu" 2 0
709   (and (eq_attr "cpu" "k6")
710        (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
711   1 1)
712
713 (define_function_unit "k6_alu" 2 0
714   (and (eq_attr "cpu" "k6")
715        (and (eq_attr "type" "imov")
716             (eq_attr "memory" "none")))
717   1 1)
718
719 (define_function_unit "k6_branch" 1 0
720   (and (eq_attr "cpu" "k6")
721        (eq_attr "type" "call,callv,ibr"))
722   1 1)
723
724 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
725 (define_function_unit "k6_load" 1 0
726   (and (eq_attr "cpu" "k6")
727        (ior (eq_attr "type" "pop")
728             (eq_attr "memory" "load,both")))
729   1 1)
730
731 (define_function_unit "k6_load" 1 0
732   (and (eq_attr "cpu" "k6")
733        (and (eq_attr "type" "str")
734             (eq_attr "memory" "load,both")))
735   10 10)
736
737 ;; Lea have two instructions, so latency is probably 2
738 (define_function_unit "k6_store" 1 0
739   (and (eq_attr "cpu" "k6")
740        (eq_attr "type" "lea"))
741   2 1)
742
743 (define_function_unit "k6_store" 1 0
744   (and (eq_attr "cpu" "k6")
745        (eq_attr "type" "str"))
746   10 10)
747
748 (define_function_unit "k6_store" 1 0
749   (and (eq_attr "cpu" "k6")
750        (ior (eq_attr "type" "push")
751             (eq_attr "memory" "store,both")))
752   1 1)
753
754 (define_function_unit "k6_fpu" 1 1
755   (and (eq_attr "cpu" "k6")
756        (eq_attr "type" "fop,fop1,fmov,fcmp"))
757   2 2)
758
759 (define_function_unit "k6_fpu" 1 1
760   (and (eq_attr "cpu" "k6")
761        (eq_attr "type" "fmul"))
762   2 2)
763
764 ;; ??? Guess
765 (define_function_unit "k6_fpu" 1 1
766   (and (eq_attr "cpu" "k6")
767        (eq_attr "type" "fdiv,fpspc"))
768   56 56)
769
770 (define_function_unit "k6_alu" 2 0
771   (and (eq_attr "cpu" "k6")
772        (eq_attr "type" "imul"))
773   2 2)
774
775 (define_function_unit "k6_alux" 1 0
776   (and (eq_attr "cpu" "k6")
777        (eq_attr "type" "imul"))
778   2 2)
779
780 ;; ??? Guess
781 (define_function_unit "k6_alu" 2 0
782   (and (eq_attr "cpu" "k6")
783        (eq_attr "type" "idiv"))
784   17 17)
785
786 (define_function_unit "k6_alux" 1 0
787   (and (eq_attr "cpu" "k6")
788        (eq_attr "type" "idiv"))
789   17 17)
790 \f
791 ;; AMD Athlon Scheduling
792 ;;
793 ;; The Athlon does contain three pipelined FP units, three integer units and
794 ;; three address generation units. 
795 ;;
796 ;; The predecode logic is determining boundaries of instructions in the 64
797 ;; byte cache line. So the cache line straddling problem of K6 might be issue
798 ;; here as well, but it is not noted in the documentation.
799 ;;
800 ;; Three DirectPath instructions decoders and only one VectorPath decoder
801 ;; is available. They can decode three DirectPath instructions or one VectorPath
802 ;; instruction per cycle.
803 ;; Decoded macro instructions are then passed to 72 entry instruction control
804 ;; unit, that passes
805 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
806 ;;
807 ;; The load/store queue unit is not attached to the schedulers but
808 ;; communicates with all the execution units seperately instead.
809
810 (define_attr "athlon_decode" "direct,vector"
811   (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
812            (const_string "vector")
813          (and (eq_attr "type" "push")
814               (match_operand 1 "memory_operand" ""))
815            (const_string "vector")
816          (and (eq_attr "type" "fmov")
817               (ior (match_operand:XF 0 "memory_operand" "")
818                    (match_operand:XF 1 "memory_operand" "")))
819            (const_string "vector")]
820         (const_string "direct")))
821
822 (define_function_unit "athlon_vectordec" 1 0
823   (and (eq_attr "cpu" "athlon")
824        (eq_attr "athlon_decode" "vector"))
825   1 1)
826
827 (define_function_unit "athlon_directdec" 3 0
828   (and (eq_attr "cpu" "athlon")
829        (eq_attr "athlon_decode" "direct"))
830   1 1)
831
832 (define_function_unit "athlon_vectordec" 1 0
833   (and (eq_attr "cpu" "athlon")
834        (eq_attr "athlon_decode" "direct"))
835   1 1 [(eq_attr "athlon_decode" "vector")])
836
837 (define_function_unit "athlon_ieu" 3 0
838   (and (eq_attr "cpu" "athlon")
839        (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
840   1 1)
841
842 (define_function_unit "athlon_ieu" 3 0
843   (and (eq_attr "cpu" "athlon")
844        (eq_attr "type" "str"))
845   15 15)
846
847 (define_function_unit "athlon_ieu" 3 0
848   (and (eq_attr "cpu" "athlon")
849        (eq_attr "type" "imul"))
850   5 0)
851
852 (define_function_unit "athlon_ieu" 3 0
853   (and (eq_attr "cpu" "athlon")
854        (eq_attr "type" "idiv"))
855   42 0)
856
857 (define_function_unit "athlon_muldiv" 1 0
858   (and (eq_attr "cpu" "athlon")
859        (eq_attr "type" "imul"))
860   5 0)
861
862 (define_function_unit "athlon_muldiv" 1 0
863   (and (eq_attr "cpu" "athlon")
864        (eq_attr "type" "idiv"))
865   42 42)
866
867 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
868   (cond [(eq_attr "type" "fop,fop1,fcmp")
869            (const_string "add")
870          (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
871            (const_string "mul")
872          (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
873            (const_string "store")
874          (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
875            (const_string "any")
876          (and (eq_attr "type" "fmov")
877               (ior (match_operand:SI 1 "register_operand" "")
878                    (match_operand 1 "immediate_operand" "")))
879            (const_string "store")
880          (eq_attr "type" "fmov")
881            (const_string "muladd")]
882         (const_string "none")))
883
884 ;; We use latencies 1 for definitions.  This is OK to model colisions
885 ;; in execution units.  The real latencies are modeled in the "fp" pipeline.
886
887 ;; fsin, fcos: 96-192
888 ;; fsincos: 107-211
889 ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
890 (define_function_unit "athlon_fp" 3 0
891   (and (eq_attr "cpu" "athlon")
892        (eq_attr "type" "fpspc"))
893   100 1)
894
895 ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
896 (define_function_unit "athlon_fp" 3 0
897   (and (eq_attr "cpu" "athlon")
898        (eq_attr "type" "fdiv"))
899   24 1)
900
901 (define_function_unit "athlon_fp" 3 0
902   (and (eq_attr "cpu" "athlon")
903        (eq_attr "type" "fop,fop1,fmul"))
904   4 1)
905
906 ;; XFmode loads are slow.
907 ;; XFmode store is slow too (8 cycles), but we don't need to model it, because
908 ;; there are no dependent instructions.
909
910 (define_function_unit "athlon_fp" 3 0
911   (and (eq_attr "cpu" "athlon")
912        (and (eq_attr "type" "fmov")
913             (match_operand:XF 1 "memory_operand" "")))
914   10 1)
915
916 (define_function_unit "athlon_fp" 3 0
917   (and (eq_attr "cpu" "athlon")
918        (eq_attr "type" "fmov,fsgn"))
919   2 1)
920
921 ;; fcmp and ftst instructions
922 (define_function_unit "athlon_fp" 3 0
923   (and (eq_attr "cpu" "athlon")
924        (and (eq_attr "type" "fcmp")
925             (eq_attr "athlon_decode" "direct")))
926   3 1)
927
928 ;; fcmpi instructions.
929 (define_function_unit "athlon_fp" 3 0
930   (and (eq_attr "cpu" "athlon")
931        (and (eq_attr "type" "fcmp")
932             (eq_attr "athlon_decode" "vector")))
933   3 1)
934
935 (define_function_unit "athlon_fp" 3 0
936   (and (eq_attr "cpu" "athlon")
937        (eq_attr "type" "fcmov"))
938   7 1)
939
940 (define_function_unit "athlon_fp_mul" 1 0
941   (and (eq_attr "cpu" "athlon")
942        (eq_attr "athlon_fpunits" "mul"))
943   1 1)
944
945 (define_function_unit "athlon_fp_add" 1 0
946   (and (eq_attr "cpu" "athlon")
947        (eq_attr "athlon_fpunits" "add"))
948   1 1)
949
950 (define_function_unit "athlon_fp_muladd" 2 0
951   (and (eq_attr "cpu" "athlon")
952        (eq_attr "athlon_fpunits" "muladd,mul,add"))
953   1 1)
954
955 (define_function_unit "athlon_fp_store" 1 0
956   (and (eq_attr "cpu" "athlon")
957        (eq_attr "athlon_fpunits" "store"))
958   1 1)
959
960 ;; We don't need to model the Adress Generation Unit, since we don't model
961 ;; the re-order buffer yet and thus we never schedule more than three operations
962 ;; at time.  Later we may want to experiment with MD_SCHED macros modeling the
963 ;; decoders independently on the functional units.
964
965 ;(define_function_unit "athlon_agu" 3 0
966 ;  (and (eq_attr "cpu" "athlon")
967 ;       (and (eq_attr "memory" "!none")
968 ;            (eq_attr "athlon_fpunits" "none")))
969 ;  1 1)
970
971 ;; Model load unit to avoid too long sequences of loads.  We don't need to
972 ;; model store queue, since it is hardly going to be bottleneck.
973
974 (define_function_unit "athlon_load" 2 0
975   (and (eq_attr "cpu" "athlon")
976        (eq_attr "memory" "load,both"))
977   1 1)
978
979 \f
980 ;; Compare instructions.
981
982 ;; All compare insns have expanders that save the operands away without
983 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
984 ;; after the cmp) will actually emit the cmpM.
985
986 (define_expand "cmpdi"
987   [(set (reg:CC 17)
988         (compare:CC (match_operand:DI 0 "general_operand" "")
989                     (match_operand:DI 1 "general_operand" "")))]
990   ""
991   "
992 {
993   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
994       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
995     operands[0] = force_reg (DImode, operands[0]);
996   ix86_compare_op0 = operands[0];
997   ix86_compare_op1 = operands[1];
998   DONE;
999 }")
1000
1001 (define_expand "cmpsi"
1002   [(set (reg:CC 17)
1003         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1004                     (match_operand:SI 1 "general_operand" "")))]
1005   ""
1006   "
1007 {
1008   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1009       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1010     operands[0] = force_reg (SImode, operands[0]);
1011   ix86_compare_op0 = operands[0];
1012   ix86_compare_op1 = operands[1];
1013   DONE;
1014 }")
1015
1016 (define_expand "cmphi"
1017   [(set (reg:CC 17)
1018         (compare:CC (match_operand:HI 0 "general_operand" "")
1019                     (match_operand:HI 1 "general_operand" "")))]
1020   ""
1021   "
1022 {
1023   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1024       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1025     operands[0] = force_reg (HImode, operands[0]);
1026   ix86_compare_op0 = operands[0];
1027   ix86_compare_op1 = operands[1];
1028   DONE;
1029 }")
1030
1031 (define_expand "cmpqi"
1032   [(set (reg:CC 17)
1033         (compare:CC (match_operand:QI 0 "general_operand" "")
1034                     (match_operand:QI 1 "general_operand" "")))]
1035   "TARGET_QIMODE_MATH"
1036   "
1037 {
1038   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1039       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1040     operands[0] = force_reg (QImode, operands[0]);
1041   ix86_compare_op0 = operands[0];
1042   ix86_compare_op1 = operands[1];
1043   DONE;
1044 }")
1045
1046 (define_insn "cmpsi_ccz_1"
1047   [(set (reg:CCZ 17)
1048         (compare:CCZ (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1049                      (match_operand:SI 1 "const0_operand" "n,n")))]
1050   ""
1051   "@
1052    test{l}\\t{%0, %0|%0, %0}
1053    cmp{l}\\t{%1, %0|%0, %1}"
1054   [(set_attr "type" "test,icmp")
1055    (set_attr "length_immediate" "0,1")
1056    (set_attr "mode" "SI")])
1057
1058 (define_insn "cmpsi_ccno_1"
1059   [(set (reg:CCNO 17)
1060         (compare:CCNO (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1061                       (match_operand:SI 1 "const0_operand" "n,n")))]
1062   ""
1063   "@
1064    test{l}\\t{%0, %0|%0, %0}
1065    cmp{l}\\t{%1, %0|%0, %1}"
1066   [(set_attr "type" "test,icmp")
1067    (set_attr "length_immediate" "0,1")
1068    (set_attr "mode" "SI")])
1069
1070 (define_insn "cmpsi_1"
1071   [(set (reg:CC 17)
1072         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1073                     (match_operand:SI 1 "general_operand" "ri,mr")))]
1074   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1075   "cmp{l}\\t{%1, %0|%0, %1}"
1076   [(set_attr "type" "icmp")
1077    (set_attr "mode" "SI")])
1078
1079 (define_insn "*cmphi_0"
1080   [(set (reg 17)
1081         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1082                  (match_operand:HI 1 "const0_operand" "n,n")))]
1083   "ix86_match_ccmode (insn, CCNOmode)"
1084   "@
1085    test{w}\\t{%0, %0|%0, %0}
1086    cmp{w}\\t{%1, %0|%0, %1}"
1087   [(set_attr "type" "test,icmp")
1088    (set_attr "length_immediate" "0,1")
1089    (set_attr "mode" "HI")])
1090
1091 (define_insn "*cmphi_1"
1092   [(set (reg:CC 17)
1093         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1094                     (match_operand:HI 1 "general_operand" "ri,mr")))]
1095   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1096   "cmp{w}\\t{%1, %0|%0, %1}"
1097   [(set_attr "type" "icmp")
1098    (set_attr "mode" "HI")])
1099
1100 (define_insn "cmpqi_ccz_1"
1101   [(set (reg:CCZ 17)
1102         (compare:CCZ (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1103                      (match_operand:QI 1 "const0_operand" "n,n")))]
1104   ""
1105   "@
1106    test{b}\\t{%0, %0|%0, %0}
1107    cmp{b}\\t{$0, %0|%0, 0}"
1108   [(set_attr "type" "test,icmp")
1109    (set_attr "length_immediate" "0,1")
1110    (set_attr "mode" "QI")])
1111
1112 (define_insn "*cmpqi_ccno_1"
1113   [(set (reg:CCNO 17)
1114         (compare:CCNO (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1115                       (match_operand:QI 1 "const0_operand" "n,n")))]
1116   ""
1117   "@
1118    test{b}\\t{%0, %0|%0, %0}
1119    cmp{b}\\t{$0, %0|%0, 0}"
1120   [(set_attr "type" "test,icmp")
1121    (set_attr "length_immediate" "0,1")
1122    (set_attr "mode" "QI")])
1123
1124 (define_insn "*cmpqi_1"
1125   [(set (reg:CC 17)
1126         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1127                     (match_operand:QI 1 "general_operand" "qi,mq")))]
1128   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1129   "cmp{b}\\t{%1, %0|%0, %1}"
1130   [(set_attr "type" "icmp")
1131    (set_attr "mode" "QI")])
1132
1133 (define_insn "*cmpqi_ext_1"
1134   [(set (reg:CC 17)
1135         (compare:CC
1136           (match_operand:QI 0 "general_operand" "qm")
1137           (subreg:QI
1138             (zero_extract:SI
1139               (match_operand 1 "ext_register_operand" "q")
1140               (const_int 8)
1141               (const_int 8)) 0)))]
1142   ""
1143   "cmp{b}\\t{%h1, %0|%0, %h1}"
1144   [(set_attr "type" "icmp")
1145    (set_attr "mode" "QI")])
1146
1147 (define_insn "*cmpqi_ext_2"
1148   [(set (reg 17)
1149         (compare
1150           (subreg:QI
1151             (zero_extract:SI
1152               (match_operand 0 "ext_register_operand" "q")
1153               (const_int 8)
1154               (const_int 8)) 0)
1155           (match_operand:QI 1 "const0_operand" "n")))]
1156   "ix86_match_ccmode (insn, CCNOmode)"
1157   "test{b}\\t%h0, %h0"
1158   [(set_attr "type" "test")
1159    (set_attr "length_immediate" "0")
1160    (set_attr "mode" "QI")])
1161
1162 (define_insn "cmpqi_ext_3"
1163   [(set (reg:CC 17)
1164         (compare:CC
1165           (subreg:QI
1166             (zero_extract:SI
1167               (match_operand 0 "ext_register_operand" "q")
1168               (const_int 8)
1169               (const_int 8)) 0)
1170           (match_operand:QI 1 "general_operand" "qmn")))]
1171   ""
1172   "cmp{b}\\t{%1, %h0|%h0, %1}"
1173   [(set_attr "type" "icmp")
1174    (set_attr "mode" "QI")])
1175
1176 (define_insn "*cmpqi_ext_4"
1177   [(set (reg:CC 17)
1178         (compare:CC
1179           (subreg:QI
1180             (zero_extract:SI
1181               (match_operand 0 "ext_register_operand" "q")
1182               (const_int 8)
1183               (const_int 8)) 0)
1184           (subreg:QI
1185             (zero_extract:SI
1186               (match_operand 1 "ext_register_operand" "q")
1187               (const_int 8)
1188               (const_int 8)) 0)))]
1189   ""
1190   "cmp{b}\\t{%h1, %h0|%h0, %h1}"
1191   [(set_attr "type" "icmp")
1192    (set_attr "mode" "QI")])
1193
1194 ;; These implement float point compares.
1195 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1196 ;; which would allow mix and match FP modes on the compares.  Which is what
1197 ;; the old patterns did, but with many more of them.
1198
1199 (define_expand "cmpxf"
1200   [(set (reg:CC 17)
1201         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1202                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1203   "TARGET_80387"
1204   "
1205 {
1206   ix86_compare_op0 = operands[0];
1207   ix86_compare_op1 = operands[1];
1208   DONE;
1209 }")
1210
1211 (define_expand "cmpdf"
1212   [(set (reg:CC 17)
1213         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1214                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1215   "TARGET_80387"
1216   "
1217 {
1218   ix86_compare_op0 = operands[0];
1219   ix86_compare_op1 = operands[1];
1220   DONE;
1221 }")
1222
1223 (define_expand "cmpsf"
1224   [(set (reg:CC 17)
1225         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1226                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1227   "TARGET_80387"
1228   "
1229 {
1230   ix86_compare_op0 = operands[0];
1231   ix86_compare_op1 = operands[1];
1232   DONE;
1233 }")
1234
1235 ;; FP compares, step 1:
1236 ;; Set the FP condition codes.
1237 ;;
1238 ;; CCFPmode     compare with exceptions
1239 ;; CCFPUmode    compare with no exceptions
1240
1241 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1242 ;; and that fp moves clobber the condition codes, and that there is
1243 ;; currently no way to describe this fact to reg-stack.  So there are
1244 ;; no splitters yet for this.
1245
1246 ;; %%% YIKES!  This scheme does not retain a strong connection between 
1247 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1248 ;; work!  Only allow tos/mem with tos in op 0.
1249 ;;
1250 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
1251 ;; things aren't as bad as they sound...
1252
1253 (define_insn "*cmpfp_0"
1254   [(set (match_operand:HI 0 "register_operand" "=a")
1255         (unspec:HI
1256           [(compare:CCFP (match_operand 1 "register_operand" "f")
1257                          (match_operand 2 "const0_operand" "X"))] 9))]
1258   "TARGET_80387
1259    && FLOAT_MODE_P (GET_MODE (operands[1]))
1260    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261   "*
1262 {
1263   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1264     return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\";
1265   else
1266     return \"ftst\;fnstsw\\t%0\";
1267 }"
1268   [(set_attr "type" "multi")
1269    (set_attr "mode" "unknownfp")])
1270
1271 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1272 ;; used to manage the reg stack popping would not be preserved.
1273
1274 (define_insn "*cmpfp_2_sf"
1275   [(set (reg:CCFP 18)
1276         (compare:CCFP
1277           (match_operand:SF 0 "register_operand" "f")
1278           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1279   "TARGET_80387"
1280   "* return output_fp_compare (insn, operands, 0, 0);"
1281   [(set_attr "type" "fcmp")
1282    (set_attr "mode" "SF")])
1283
1284 (define_insn "*cmpfp_2_sf_1"
1285   [(set (match_operand:HI 0 "register_operand" "=a")
1286         (unspec:HI
1287           [(compare:CCFP
1288              (match_operand:SF 1 "register_operand" "f")
1289              (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1290   "TARGET_80387"
1291   "* return output_fp_compare (insn, operands, 2, 0);"
1292   [(set_attr "type" "fcmp")
1293    (set_attr "mode" "SF")])
1294
1295 (define_insn "*cmpfp_2_df"
1296   [(set (reg:CCFP 18)
1297         (compare:CCFP
1298           (match_operand:DF 0 "register_operand" "f")
1299           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1300   "TARGET_80387"
1301   "* return output_fp_compare (insn, operands, 0, 0);"
1302   [(set_attr "type" "fcmp")
1303    (set_attr "mode" "DF")])
1304
1305 (define_insn "*cmpfp_2_df_1"
1306   [(set (match_operand:HI 0 "register_operand" "=a")
1307         (unspec:HI
1308           [(compare:CCFP
1309              (match_operand:DF 1 "register_operand" "f")
1310              (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1311   "TARGET_80387"
1312   "* return output_fp_compare (insn, operands, 2, 0);"
1313   [(set_attr "type" "multi")
1314    (set_attr "mode" "DF")])
1315
1316 (define_insn "*cmpfp_2_xf"
1317   [(set (reg:CCFP 18)
1318         (compare:CCFP
1319           (match_operand:XF 0 "register_operand" "f")
1320           (match_operand:XF 1 "register_operand" "f")))]
1321   "TARGET_80387"
1322   "* return output_fp_compare (insn, operands, 0, 0);"
1323   [(set_attr "type" "fcmp")
1324    (set_attr "mode" "XF")])
1325
1326 (define_insn "*cmpfp_2_xf_1"
1327   [(set (match_operand:HI 0 "register_operand" "=a")
1328         (unspec:HI
1329           [(compare:CCFP
1330              (match_operand:XF 1 "register_operand" "f")
1331              (match_operand:XF 2 "register_operand" "f"))] 9))]
1332   "TARGET_80387"
1333   "* return output_fp_compare (insn, operands, 2, 0);"
1334   [(set_attr "type" "multi")
1335    (set_attr "mode" "XF")])
1336
1337 (define_insn "*cmpfp_2u"
1338   [(set (reg:CCFPU 18)
1339         (compare:CCFPU
1340           (match_operand 0 "register_operand" "f")
1341           (match_operand 1 "register_operand" "f")))]
1342   "TARGET_80387
1343    && FLOAT_MODE_P (GET_MODE (operands[0]))
1344    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1345   "* return output_fp_compare (insn, operands, 0, 1);"
1346   [(set_attr "type" "fcmp")
1347    (set_attr "mode" "unknownfp")])
1348
1349 (define_insn "*cmpfp_2u_1"
1350   [(set (match_operand:HI 0 "register_operand" "=a")
1351         (unspec:HI
1352           [(compare:CCFPU
1353              (match_operand 1 "register_operand" "f")
1354              (match_operand 2 "register_operand" "f"))] 9))]
1355   "TARGET_80387
1356    && FLOAT_MODE_P (GET_MODE (operands[1]))
1357    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1358   "* return output_fp_compare (insn, operands, 2, 1);"
1359   [(set_attr "type" "multi")
1360    (set_attr "mode" "unknownfp")])
1361
1362 ;; Patterns to match the SImode-in-memory ficom instructions.
1363 ;;
1364 ;; %%% Play games with accepting gp registers, as otherwise we have to
1365 ;; force them to memory during rtl generation, which is no good.  We
1366 ;; can get rid of this once we teach reload to do memory input reloads 
1367 ;; via pushes.
1368
1369 (define_insn "*ficom_1"
1370   [(set (reg:CCFP 18)
1371         (compare:CCFP
1372           (match_operand 0 "register_operand" "f,f")
1373           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1374   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1375    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1376   "#")
1377
1378 ;; Split the not-really-implemented gp register case into a
1379 ;; push-op-pop sequence.
1380 ;;
1381 ;; %%% This is most efficient, but am I gonna get in trouble
1382 ;; for separating cc0_setter and cc0_user?
1383
1384 (define_split
1385   [(set (reg:CCFP 18)
1386         (compare:CCFP
1387           (match_operand:SF 0 "register_operand" "")
1388           (float (match_operand:SI 1 "register_operand" ""))))]
1389   "0 && TARGET_80387 && reload_completed"
1390   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1391    (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1392    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1393               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1394   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1395    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1396
1397 ;; FP compares, step 2
1398 ;; Move the fpsw to ax.
1399
1400 (define_insn "x86_fnstsw_1"
1401   [(set (match_operand:HI 0 "register_operand" "=a")
1402         (unspec:HI [(reg 18)] 9))]
1403   "TARGET_80387"
1404   "fnstsw\\t%0"
1405   [(set_attr "length" "2")
1406    (set_attr "mode" "SI")
1407    (set_attr "i387" "1")
1408    (set_attr "ppro_uops" "few")])
1409
1410 ;; FP compares, step 3
1411 ;; Get ax into flags, general case.
1412
1413 (define_insn "x86_sahf_1"
1414   [(set (reg:CC 17)
1415         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1416   ""
1417   "sahf"
1418   [(set_attr "length" "1")
1419    (set_attr "athlon_decode" "vector")
1420    (set_attr "mode" "SI")
1421    (set_attr "ppro_uops" "one")])
1422
1423 ;; Pentium Pro can do steps 1 through 3 in one go.
1424
1425 (define_insn "*cmpfp_i"
1426   [(set (reg:CCFP 17)
1427         (compare:CCFP (match_operand 0 "register_operand" "f")
1428                       (match_operand 1 "register_operand" "f")))]
1429   "TARGET_80387 && TARGET_CMOVE
1430    && FLOAT_MODE_P (GET_MODE (operands[0]))
1431    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1432   "* return output_fp_compare (insn, operands, 1, 0);"
1433   [(set_attr "type" "fcmp")
1434    (set_attr "mode" "unknownfp")
1435    (set_attr "athlon_decode" "vector")])
1436
1437 (define_insn "*cmpfp_iu"
1438   [(set (reg:CCFPU 17)
1439         (compare:CCFPU (match_operand 0 "register_operand" "f")
1440                        (match_operand 1 "register_operand" "f")))]
1441   "TARGET_80387 && TARGET_CMOVE
1442    && FLOAT_MODE_P (GET_MODE (operands[0]))
1443    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1444   "* return output_fp_compare (insn, operands, 1, 1);"
1445   [(set_attr "type" "fcmp")
1446    (set_attr "mode" "unknownfp")
1447    (set_attr "athlon_decode" "vector")])
1448 \f
1449 ;; Move instructions.
1450
1451 ;; General case of fullword move.
1452
1453 (define_expand "movsi"
1454   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1455         (match_operand:SI 1 "general_operand" ""))]
1456   ""
1457   "ix86_expand_move (SImode, operands); DONE;")
1458
1459 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1460 ;; general_operand.
1461 ;;
1462 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1463 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1464 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1465 ;; targets without our curiosities, and it is just as easy to represent
1466 ;; this differently.
1467
1468 (define_insn "pushsi2"
1469   [(set (match_operand:SI 0 "push_operand" "=<")
1470         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1471   ""
1472   "push{l}\\t%1"
1473   [(set_attr "type" "push")
1474    (set_attr "mode" "SI")])
1475
1476 (define_insn "*pushsi2_prologue"
1477   [(set (match_operand:SI 0 "push_operand" "=<")
1478         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1479    (set (reg:SI 6) (reg:SI 6))]
1480   ""
1481   "push{l}\\t%1"
1482   [(set_attr "type" "push")
1483    (set_attr "mode" "SI")])
1484
1485 (define_insn "*popsi1_epilogue"
1486   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1487         (mem:SI (reg:SI 7)))
1488    (set (reg:SI 7)
1489         (plus:SI (reg:SI 7) (const_int 4)))
1490    (set (reg:SI 6) (reg:SI 6))]
1491   ""
1492   "pop{l}\\t%0"
1493   [(set_attr "type" "pop")
1494    (set_attr "mode" "SI")])
1495
1496 (define_insn "popsi1"
1497   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1498         (mem:SI (reg:SI 7)))
1499    (set (reg:SI 7)
1500         (plus:SI (reg:SI 7) (const_int 4)))]
1501   ""
1502   "pop{l}\\t%0"
1503   [(set_attr "type" "pop")
1504    (set_attr "mode" "SI")])
1505
1506 (define_insn "*movsi_xor"
1507   [(set (match_operand:SI 0 "register_operand" "=r")
1508         (match_operand:SI 1 "const0_operand" "i"))
1509    (clobber (reg:CC 17))]
1510   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1511   "xor{l}\\t{%0, %0|%0, %0}"
1512   [(set_attr "type" "alu1")
1513    (set_attr "mode" "SI")
1514    (set_attr "length_immediate" "0")])
1515
1516 (define_insn "*movsi_or"
1517   [(set (match_operand:SI 0 "register_operand" "=r")
1518         (match_operand:SI 1 "immediate_operand" "i"))
1519    (clobber (reg:CC 17))]
1520   "reload_completed && GET_CODE (operands[1]) == CONST_INT
1521    && INTVAL (operands[1]) == -1
1522    && (TARGET_PENTIUM || optimize_size)"
1523   "*
1524 {
1525   operands[1] = constm1_rtx;
1526   return \"or{l}\\t{%1, %0|%1, %0}\";
1527 }"
1528   [(set_attr "type" "alu1")
1529    (set_attr "mode" "SI")
1530    (set_attr "length_immediate" "1")])
1531
1532 (define_insn "*movsi_1"
1533   [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m")
1534         (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin"))]
1535   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1536   "*
1537 {
1538   switch (get_attr_type (insn))
1539     {
1540     case TYPE_LEA:
1541       return \"lea{l}\\t{%1, %0|%0, %1}\";
1542     default:
1543       if (flag_pic && SYMBOLIC_CONST (operands[1]))
1544         abort();
1545       return \"mov{l}\\t{%1, %0|%0, %1}\";
1546     }
1547 }"
1548   [(set (attr "type")
1549      (cond [(and (ne (symbol_ref "flag_pic") (const_int 0))
1550                  (match_operand:SI 1 "symbolic_operand" ""))
1551               (const_string "lea")
1552            ]
1553            (const_string "imov")))
1554    (set_attr "modrm" "0,*,0,*")
1555    (set_attr "mode" "SI")])
1556
1557 (define_insn "*swapsi"
1558   [(set (match_operand:SI 0 "register_operand" "+r")
1559         (match_operand:SI 1 "register_operand" "+r"))
1560    (set (match_dup 1)
1561         (match_dup 0))]
1562   ""
1563   "xchg{l}\\t%1, %0"
1564   [(set_attr "type" "imov")
1565    (set_attr "pent_pair" "np")
1566    (set_attr "athlon_decode" "vector")
1567    (set_attr "mode" "SI")
1568    (set_attr "modrm" "0")
1569    (set_attr "ppro_uops" "few")])
1570
1571 (define_expand "movhi"
1572   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1573         (match_operand:HI 1 "general_operand" ""))]
1574   ""
1575   "ix86_expand_move (HImode, operands); DONE;")
1576
1577 (define_insn "pushhi2"
1578   [(set (match_operand:HI 0 "push_operand" "=<,<")
1579         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1580   ""
1581   "@
1582    push{w}\\t{|WORD PTR }%1
1583    push{w}\\t%1"
1584   [(set_attr "type" "push")
1585    (set_attr "mode" "HI")])
1586
1587 (define_insn "pophi1"
1588   [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m")
1589         (mem:HI (reg:SI 7)))
1590    (set (reg:SI 7)
1591         (plus:SI (reg:SI 7) (const_int 2)))]
1592   ""
1593   "pop{w}\\t%0"
1594   [(set_attr "type" "pop")
1595    (set_attr "mode" "HI")])
1596
1597 (define_insn "*movhi_1"
1598   [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1599         (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1600   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1601   "*
1602 {
1603   switch (get_attr_type (insn))
1604     {
1605     case TYPE_IMOVX:
1606       /* movzwl is faster than movw on p2 due to partial word stalls,
1607          though not as fast as an aligned movl.  */
1608       return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
1609     default:
1610       if (get_attr_mode (insn) == MODE_SI)
1611         return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1612       else
1613         return \"mov{w}\\t{%1, %0|%0, %1}\";
1614     }
1615 }"
1616   [(set (attr "type")
1617      (cond [(and (eq_attr "alternative" "0,1")
1618                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1619                           (const_int 0))
1620                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1621                           (const_int 0))))
1622               (const_string "imov")
1623             (and (eq_attr "alternative" "2,3,4")
1624                  (match_operand:HI 1 "aligned_operand" ""))
1625               (const_string "imov")
1626             (and (ne (symbol_ref "TARGET_MOVX")
1627                      (const_int 0))
1628                  (eq_attr "alternative" "0,1,3,4"))
1629               (const_string "imovx")
1630            ]
1631            (const_string "imov")))
1632     (set (attr "mode")
1633       (cond [(eq_attr "type" "imovx")
1634                (const_string "SI")
1635              (and (eq_attr "alternative" "2,3,4")
1636                   (match_operand:HI 1 "aligned_operand" ""))
1637                (const_string "SI")
1638              (and (eq_attr "alternative" "0,1")
1639                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1640                            (const_int 0))
1641                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1642                            (const_int 0))))
1643                (const_string "SI")
1644             ]
1645             (const_string "HI")))
1646    (set_attr "modrm" "0,*,*,0,*,*")])
1647
1648 (define_insn "*swaphi_1"
1649   [(set (match_operand:HI 0 "register_operand" "+r")
1650         (match_operand:HI 1 "register_operand" "+r"))
1651    (set (match_dup 1)
1652         (match_dup 0))]
1653   "TARGET_PARTIAL_REG_STALL"
1654   "xchg{w}\\t%1, %0"
1655   [(set_attr "type" "imov")
1656    (set_attr "pent_pair" "np")
1657    (set_attr "mode" "HI")
1658    (set_attr "modrm" "0")
1659    (set_attr "ppro_uops" "few")])
1660
1661 (define_insn "*swaphi_2"
1662   [(set (match_operand:HI 0 "register_operand" "+r")
1663         (match_operand:HI 1 "register_operand" "+r"))
1664    (set (match_dup 1)
1665         (match_dup 0))]
1666   "! TARGET_PARTIAL_REG_STALL"
1667   "xchg{l}\\t%k1, %k0"
1668   [(set_attr "type" "imov")
1669    (set_attr "pent_pair" "np")
1670    (set_attr "mode" "SI")
1671    (set_attr "modrm" "0")
1672    (set_attr "ppro_uops" "few")])
1673
1674 (define_expand "movstricthi"
1675   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1676         (match_operand:HI 1 "general_operand" ""))]
1677   "! TARGET_PARTIAL_REG_STALL"
1678   "
1679 {
1680   /* Don't generate memory->memory moves, go through a register */
1681   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1682     operands[1] = force_reg (HImode, operands[1]);
1683 }")
1684
1685 (define_insn "*movstricthi_1"
1686   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1687         (match_operand:HI 1 "general_operand" "rn,m"))]
1688   "! TARGET_PARTIAL_REG_STALL
1689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1690   "mov{w}\\t{%1, %0|%0, %1}"
1691   [(set_attr "type" "imov")
1692    (set_attr "mode" "HI")])
1693
1694 (define_insn "*movstricthi_xor"
1695   [(set (strict_low_part (match_operand:HI 0 "register_operand" "=r"))
1696         (match_operand:HI 1 "const0_operand" "i"))
1697    (clobber (reg:CC 17))]
1698   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1699   "xor{w}\\t{%0, %0|%0, %0}"
1700   [(set_attr "type" "alu1")
1701    (set_attr "mode" "HI")
1702    (set_attr "length_immediate" "0")])
1703
1704 (define_expand "movqi"
1705   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1706         (match_operand:QI 1 "general_operand" ""))]
1707   ""
1708   "ix86_expand_move (QImode, operands); DONE;")
1709
1710 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1711 ;; "push a byte".  But actually we use pushw, which has the effect
1712 ;; of rounding the amount pushed up to a halfword.
1713
1714 (define_insn "pushqi2"
1715   [(set (match_operand:QI 0 "push_operand" "=<,<")
1716         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1717   ""
1718   "@
1719    push{w}\\t{|word ptr }%1
1720    push{w}\\t%w1"
1721   [(set_attr "type" "push")
1722    (set_attr "mode" "HI")])
1723
1724 (define_insn "popqi1"
1725   [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m")
1726         (mem:QI (reg:SI 7)))
1727    (set (reg:SI 7)
1728         (plus:SI (reg:SI 7) (const_int 2)))]
1729   ""
1730   "pop{w}\\t%0"
1731   [(set_attr "type" "pop")
1732    (set_attr "mode" "HI")])
1733
1734 ;; Situation is quite tricky about when to choose full sized (SImode) move
1735 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1736 ;; partial register dependency machines (such as AMD Athlon), where QImode
1737 ;; moves issue extra dependency and for partial register stalls machines
1738 ;; that don't use QImode patterns (and QImode move cause stall on the next
1739 ;; instruction).
1740 ;;
1741 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1742 ;; register stall machines with, where we use QImode instructions, since
1743 ;; partial register stall can be caused there.  Then we use movzx.
1744 (define_insn "*movqi_1"
1745   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1746         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1747   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1748   "*
1749 {
1750   switch (get_attr_type (insn))
1751     {
1752     case TYPE_IMOVX:
1753       if (!QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1754         abort ();
1755       return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
1756     default:
1757       if (get_attr_mode (insn) == MODE_SI)
1758         return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1759       else
1760         return \"mov{b}\\t{%1, %0|%0, %1}\";
1761     }
1762 }"
1763   [(set (attr "type")
1764      (cond [(and (eq_attr "alternative" "3")
1765                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1766                           (const_int 0))
1767                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1768                           (const_int 0))))
1769               (const_string "imov")
1770             (eq_attr "alternative" "3,5")
1771               (const_string "imovx")
1772             (and (ne (symbol_ref "TARGET_MOVX")
1773                      (const_int 0))
1774                  (eq_attr "alternative" "2"))
1775               (const_string "imovx")
1776            ]
1777            (const_string "imov")))
1778    (set (attr "mode")
1779       (cond [(eq_attr "alternative" "3,4,5")
1780                (const_string "SI")
1781              (eq_attr "alternative" "6")
1782                (const_string "QI")
1783              (eq_attr "type" "imovx")
1784                (const_string "SI")
1785              (and (eq_attr "type" "imov")
1786                   (and (eq_attr "alternative" "0,1,2")
1787                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1788                            (const_int 0))))
1789                (const_string "SI")
1790              ;; Avoid partial register stalls when not using QImode arithmetic
1791              (and (eq_attr "type" "imov")
1792                   (and (eq_attr "alternative" "0,1,2")
1793                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1794                                 (const_int 0))
1795                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1796                                 (const_int 0)))))
1797                (const_string "SI")
1798            ]
1799            (const_string "QI")))])
1800
1801 (define_expand "reload_outqi"
1802   [(parallel [(match_operand:QI 0 "" "=m")
1803               (match_operand:QI 1 "register_operand" "r")
1804               (match_operand:QI 2 "register_operand" "=&q")])]
1805   ""
1806   "
1807 {
1808   rtx op0, op1, op2;
1809   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1810
1811   if (reg_overlap_mentioned_p (op2, op0))
1812     abort ();
1813   if (! q_regs_operand (op1, QImode))
1814     {
1815       emit_insn (gen_movqi (op2, op1));
1816       op1 = op2;
1817     }
1818   emit_insn (gen_movqi (op0, op1));
1819   DONE;
1820 }")
1821
1822 (define_insn "*swapqi"
1823   [(set (match_operand:QI 0 "register_operand" "+r")
1824         (match_operand:QI 1 "register_operand" "+r"))
1825    (set (match_dup 1)
1826         (match_dup 0))]
1827   ""
1828   "xchg{b}\\t%1, %0"
1829   [(set_attr "type" "imov")
1830    (set_attr "pent_pair" "np")
1831    (set_attr "mode" "QI")
1832    (set_attr "modrm" "0")
1833    (set_attr "ppro_uops" "few")])
1834
1835 (define_expand "movstrictqi"
1836   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1837         (match_operand:QI 1 "general_operand" ""))]
1838   "! TARGET_PARTIAL_REG_STALL"
1839   "
1840 {
1841   /* Don't generate memory->memory moves, go through a register */
1842   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1843     operands[1] = force_reg (QImode, operands[1]);
1844 }")
1845
1846 (define_insn "*movstrictqi_1"
1847   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1848         (match_operand:QI 1 "general_operand" "*qn,m"))]
1849   "! TARGET_PARTIAL_REG_STALL
1850    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1851   "mov{b}\\t{%1, %0|%0, %1}"
1852   [(set_attr "type" "imov")
1853    (set_attr "mode" "QI")])
1854
1855 (define_insn "*movstrictqi_xor"
1856   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1857         (match_operand:QI 1 "const0_operand" "i"))
1858    (clobber (reg:CC 17))]
1859   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1860   "xor{b}\\t{%0, %0|%0, %0}"
1861   [(set_attr "type" "alu1")
1862    (set_attr "mode" "QI")
1863    (set_attr "length_immediate" "0")])
1864
1865 (define_insn "*movsi_extv_1"
1866   [(set (match_operand:SI 0 "register_operand" "=r")
1867         (sign_extract:SI (match_operand:SI 1 "register_operand" "q")
1868                          (const_int 8)
1869                          (const_int 8)))]
1870   ""
1871   "movs{bl|x}\\t{%h1, %0|%0, %h1}"
1872   [(set_attr "type" "imovx")
1873    (set_attr "mode" "SI")])
1874
1875 (define_insn "*movhi_extv_1"
1876   [(set (match_operand:HI 0 "register_operand" "=r")
1877         (sign_extract:HI (match_operand:SI 1 "register_operand" "q")
1878                          (const_int 8)
1879                          (const_int 8)))]
1880   ""
1881   "movs{bl|x}\\t{%h1, %k0|%k0, %h1}"
1882   [(set_attr "type" "imovx")
1883    (set_attr "mode" "SI")])
1884
1885 (define_insn "*movqi_extv_1"
1886   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1887         (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q")
1888                          (const_int 8)
1889                          (const_int 8)))]
1890   ""
1891   "*
1892 {
1893   switch (get_attr_type (insn))
1894     {
1895     case TYPE_IMOVX:
1896       return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1897     default:
1898       return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1899     }
1900 }"
1901   [(set (attr "type")
1902      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1903                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1904                              (ne (symbol_ref "TARGET_MOVX")
1905                                  (const_int 0))))
1906         (const_string "imovx")
1907         (const_string "imov")))
1908    (set (attr "mode")
1909      (if_then_else (eq_attr "type" "imovx")
1910         (const_string "SI")
1911         (const_string "QI")))])
1912
1913 (define_insn "*movsi_extzv_1"
1914   [(set (match_operand:SI 0 "register_operand" "=r")
1915         (zero_extract:SI (match_operand 1 "ext_register_operand" "q")
1916                          (const_int 8)
1917                          (const_int 8)))]
1918   ""
1919   "movz{bl|x}\\t{%h1, %0|%0, %h1}"
1920   [(set_attr "type" "imovx")
1921    (set_attr "mode" "SI")])
1922
1923 (define_insn "*movqi_extzv_1"
1924   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1925         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "q,q")
1926                                     (const_int 8)
1927                                     (const_int 8)) 0))]
1928   ""
1929   "*
1930 {
1931   switch (get_attr_type (insn))
1932     {
1933     case TYPE_IMOVX:
1934       return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1935     default:
1936       return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1937     }
1938 }"
1939   [(set (attr "type")
1940      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1941                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1942                              (ne (symbol_ref "TARGET_MOVX")
1943                                  (const_int 0))))
1944         (const_string "imovx")
1945         (const_string "imov")))
1946    (set (attr "mode")
1947      (if_then_else (eq_attr "type" "imovx")
1948         (const_string "SI")
1949         (const_string "QI")))])
1950
1951 (define_insn "*movsi_insv_1"
1952   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
1953                          (const_int 8)
1954                          (const_int 8))
1955         (match_operand:SI 1 "nonimmediate_operand" "qm"))]
1956   ""
1957   "mov{b}\\t{%b1, %h0|%h0, %b1}"
1958   [(set_attr "type" "imov")
1959    (set_attr "mode" "QI")])
1960
1961 (define_insn "*movqi_insv_2"
1962   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
1963                          (const_int 8)
1964                          (const_int 8))
1965         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "q")
1966                              (const_int 8))
1967                 (const_int 255)))]
1968   ""
1969   "mov{b}\\t{%h1, %h0|%h0, %h1}"
1970   [(set_attr "type" "imov")
1971    (set_attr "mode" "QI")])
1972
1973 (define_expand "movdi"
1974   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1975         (match_operand:DI 1 "general_operand" ""))]
1976   ""
1977   "ix86_expand_move (DImode, operands); DONE;")
1978
1979 (define_insn "*pushdi"
1980   [(set (match_operand:DI 0 "push_operand" "=<")
1981         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1982   ""
1983   "#")
1984
1985 (define_insn "*movdi_2"
1986   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
1987         (match_operand:DI 1 "general_operand" "riFo,riF"))]
1988   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1989   "#")
1990
1991 (define_split
1992   [(set (match_operand:DI 0 "push_operand" "")
1993         (match_operand:DI 1 "general_operand" ""))]
1994   "reload_completed"
1995   [(const_int 0)]
1996   "if (!ix86_split_long_move (operands)) abort (); DONE;")
1997
1998 ;; %%% This multiword shite has got to go.
1999 (define_split
2000   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2001         (match_operand:DI 1 "general_operand" ""))]
2002   "reload_completed"
2003   [(set (match_dup 2) (match_dup 5))
2004    (set (match_dup 3) (match_dup 6))]
2005   "if (ix86_split_long_move (operands)) DONE;")
2006   
2007 (define_expand "movsf"
2008   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2009         (match_operand:SF 1 "general_operand" ""))]
2010   ""
2011   "ix86_expand_move (SFmode, operands); DONE;")
2012
2013 (define_insn "*pushsf"
2014   [(set (match_operand:SF 0 "push_operand" "=<,<")
2015         (match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
2016   ""
2017   "*
2018 {
2019   switch (which_alternative)
2020     {
2021     case 0:
2022       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2023       operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2024       operands[2] = stack_pointer_rtx;
2025       operands[3] = GEN_INT (4);
2026       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2027         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2028       else
2029         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2030
2031     case 1:
2032       return \"push{l}\\t%1\";
2033
2034     default:
2035       abort ();
2036     }
2037 }"
2038   [(set_attr "type" "multi,push")
2039    (set_attr "mode" "SF,SI")])
2040
2041 (define_split
2042   [(set (match_operand:SF 0 "push_operand" "")
2043         (match_operand:SF 1 "memory_operand" ""))]
2044   "reload_completed
2045    && GET_CODE (operands[1]) == MEM
2046    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2047    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2048   [(set (match_dup 0)
2049         (match_dup 1))]
2050   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2051
2052
2053 ;; %%% Kill this when call knows how to work this out.
2054 (define_split
2055   [(set (match_operand:SF 0 "push_operand" "")
2056         (match_operand:SF 1 "register_operand" ""))]
2057   "FP_REGNO_P (REGNO (operands[1]))"
2058   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2059    (set (mem:SF (reg:SI 7)) (match_dup 1))])
2060
2061 (define_insn "*movsf_1"
2062   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
2063         (match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
2064   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2065    && (reload_in_progress || reload_completed
2066        || GET_CODE (operands[1]) != CONST_DOUBLE
2067        || memory_operand (operands[0], SFmode))" 
2068   "*
2069 {
2070   switch (which_alternative)
2071     {
2072     case 0:
2073       if (REG_P (operands[1])
2074           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2075         return \"fstp\\t%y0\";
2076       else if (STACK_TOP_P (operands[0]))
2077         return \"fld%z1\\t%y1\";
2078       else
2079         return \"fst\\t%y0\";
2080
2081     case 1:
2082       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2083         return \"fstp%z0\\t%y0\";
2084       else
2085         return \"fst%z0\\t%y0\";
2086
2087     case 2:
2088       switch (standard_80387_constant_p (operands[1]))
2089         {
2090         case 1:
2091           return \"fldz\";
2092         case 2:
2093           return \"fld1\";
2094         }
2095       abort();
2096
2097     case 3:
2098     case 4:
2099       return \"mov{l}\\t{%1, %0|%0, %1}\";
2100
2101     default:
2102       abort();
2103     }
2104 }"
2105   [(set_attr "type" "fmov,fmov,fmov,imov,imov")
2106    (set_attr "mode" "SF,SF,SF,SI,SI")])
2107
2108 (define_split
2109   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2110         (match_operand:SF 1 "memory_operand" ""))]
2111   "reload_completed
2112    && GET_CODE (operands[1]) == MEM
2113    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2114    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2115    && (!(FP_REG_P (operands[0]) || 
2116          (GET_CODE (operands[0]) == SUBREG
2117           && FP_REG_P (SUBREG_REG (operands[0]))))
2118        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2119   [(set (match_dup 0)
2120         (match_dup 1))]
2121   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2122
2123 (define_insn "swapsf"
2124   [(set (match_operand:SF 0 "register_operand" "+f")
2125         (match_operand:SF 1 "register_operand" "+f"))
2126    (set (match_dup 1)
2127         (match_dup 0))]
2128   ""
2129   "*
2130 {
2131   if (STACK_TOP_P (operands[0]))
2132     return \"fxch\\t%1\";
2133   else
2134     return \"fxch\\t%0\";
2135 }"
2136   [(set_attr "type" "fxch")
2137    (set_attr "mode" "SF")])
2138
2139 (define_expand "movdf"
2140   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2141         (match_operand:DF 1 "general_operand" ""))]
2142   ""
2143   "ix86_expand_move (DFmode, operands); DONE;")
2144
2145 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2146 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2147 ;; On the average, pushdf using integers can be still shorter.  Allow this
2148 ;; pattern for optimize_size too.
2149
2150 (define_insn "*pushdf_nointeger"
2151   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2152         (match_operand:DF 1 "general_no_elim_operand" "f,Fo#f,*r#f"))]
2153   "!TARGET_INTEGER_DFMODE_MOVES"
2154   "*
2155 {
2156   switch (which_alternative)
2157     {
2158     case 0:
2159       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2160       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2161       operands[2] = stack_pointer_rtx;
2162       operands[3] = GEN_INT (8);
2163       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2164         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2165       else
2166         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2167
2168     case 1:
2169     case 2:
2170       return \"#\";
2171
2172     default:
2173       abort ();
2174     }
2175 }"
2176   [(set_attr "type" "multi")
2177    (set_attr "mode" "DF,SI,SI")])
2178
2179 (define_insn "*pushdf_integer"
2180   [(set (match_operand:DF 0 "push_operand" "=<,<")
2181         (match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2182   "TARGET_INTEGER_DFMODE_MOVES"
2183   "*
2184 {
2185   switch (which_alternative)
2186     {
2187     case 0:
2188       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2189       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2190       operands[2] = stack_pointer_rtx;
2191       operands[3] = GEN_INT (8);
2192       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2193         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2194       else
2195         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2196
2197     case 1:
2198       return \"#\";
2199
2200     default:
2201       abort ();
2202     }
2203 }"
2204   [(set_attr "type" "multi")
2205    (set_attr "mode" "DF,SI")])
2206
2207 ;; %%% Kill this when call knows how to work this out.
2208 (define_split
2209   [(set (match_operand:DF 0 "push_operand" "")
2210         (match_operand:DF 1 "register_operand" ""))]
2211   "reload_completed && FP_REGNO_P (REGNO (operands[1]))"
2212   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2213    (set (mem:DF (reg:SI 7)) (match_dup 1))]
2214   "")
2215
2216 (define_split
2217   [(set (match_operand:DF 0 "push_operand" "")
2218         (match_operand:DF 1 "general_operand" ""))]
2219   "reload_completed"
2220   [(const_int 0)]
2221   "if (!ix86_split_long_move (operands)) abort (); DONE;")
2222
2223 ;; Moving is usually shorter when only FP registers are used. This separate
2224 ;; movdf pattern avoids the use of integer registers for FP operations
2225 ;; when optimizing for size.
2226
2227 (define_insn "*movdf_nointeger"
2228   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2229         (match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2230   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2231    && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2232    && (reload_in_progress || reload_completed
2233        || GET_CODE (operands[1]) != CONST_DOUBLE
2234        || memory_operand (operands[0], DFmode))" 
2235   "*
2236 {
2237   switch (which_alternative)
2238     {
2239     case 0:
2240       if (REG_P (operands[1])
2241           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2242         return \"fstp\\t%y0\";
2243       else if (STACK_TOP_P (operands[0]))
2244         return \"fld%z1\\t%y1\";
2245       else
2246         return \"fst\\t%y0\";
2247
2248     case 1:
2249       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2250         return \"fstp%z0\\t%y0\";
2251       else
2252         return \"fst%z0\\t%y0\";
2253
2254     case 2:
2255       switch (standard_80387_constant_p (operands[1]))
2256         {
2257         case 1:
2258           return \"fldz\";
2259         case 2:
2260           return \"fld1\";
2261         }
2262       abort();
2263
2264     case 3:
2265     case 4:
2266       return \"#\";
2267
2268     default:
2269       abort();
2270     }
2271 }"
2272   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2273    (set_attr "mode" "DF,DF,DF,SI,SI")])
2274
2275 (define_insn "*movdf_integer"
2276   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2277         (match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2278   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2279    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2280    && (reload_in_progress || reload_completed
2281        || GET_CODE (operands[1]) != CONST_DOUBLE
2282        || memory_operand (operands[0], DFmode))" 
2283   "*
2284 {
2285   switch (which_alternative)
2286     {
2287     case 0:
2288       if (REG_P (operands[1])
2289           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2290         return \"fstp\\t%y0\";
2291       else if (STACK_TOP_P (operands[0]))
2292         return \"fld%z1\\t%y1\";
2293       else
2294         return \"fst\\t%y0\";
2295
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return \"fstp%z0\\t%y0\";
2299       else
2300         return \"fst%z0\\t%y0\";
2301
2302     case 2:
2303       switch (standard_80387_constant_p (operands[1]))
2304         {
2305         case 1:
2306           return \"fldz\";
2307         case 2:
2308           return \"fld1\";
2309         }
2310       abort();
2311
2312     case 3:
2313     case 4:
2314       return \"#\";
2315
2316     default:
2317       abort();
2318     }
2319 }"
2320   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2321    (set_attr "mode" "DF,DF,DF,SI,SI")])
2322
2323 (define_split
2324   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2325         (match_operand:DF 1 "general_operand" ""))]
2326   "reload_completed
2327    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2328    && ! (FP_REG_P (operands[0]) || 
2329          (GET_CODE (operands[0]) == SUBREG
2330           && FP_REG_P (SUBREG_REG (operands[0]))))
2331    && ! (FP_REG_P (operands[1]) || 
2332          (GET_CODE (operands[1]) == SUBREG
2333           && FP_REG_P (SUBREG_REG (operands[1]))))"
2334   [(set (match_dup 2) (match_dup 5))
2335    (set (match_dup 3) (match_dup 6))]
2336   "if (ix86_split_long_move (operands)) DONE;")
2337
2338 (define_split
2339   [(set (match_operand:DF 0 "register_operand" "")
2340         (match_operand:DF 1 "memory_operand" ""))]
2341   "reload_completed
2342    && GET_CODE (operands[1]) == MEM
2343    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2344    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2345    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2346   [(set (match_dup 0)
2347         (match_dup 1))]
2348   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2349
2350 (define_insn "swapdf"
2351   [(set (match_operand:DF 0 "register_operand" "+f")
2352         (match_operand:DF 1 "register_operand" "+f"))
2353    (set (match_dup 1)
2354         (match_dup 0))]
2355   ""
2356   "*
2357 {
2358   if (STACK_TOP_P (operands[0]))
2359     return \"fxch\\t%1\";
2360   else
2361     return \"fxch\\t%0\";
2362 }"
2363   [(set_attr "type" "fxch")
2364    (set_attr "mode" "DF")])
2365
2366 (define_expand "movxf"
2367   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2368         (match_operand:XF 1 "general_operand" ""))]
2369   ""
2370   "ix86_expand_move (XFmode, operands); DONE;")
2371
2372 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2373 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2374 ;; Pushing using integer instructions is longer except for constants
2375 ;; and direct memory references.
2376 ;; (assuming that any given constant is pushed only once, but this ought to be
2377 ;;  handled elsewhere).
2378
2379 (define_insn "*pushxf_nointeger"
2380   [(set (match_operand:XF 0 "push_operand" "=<,<,<")
2381         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2382   "optimize_size"
2383   "*
2384 {
2385   switch (which_alternative)
2386     {
2387     case 0:
2388       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2389       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2390       operands[2] = stack_pointer_rtx;
2391       operands[3] = GEN_INT (12);
2392       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2393         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2394       else
2395         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2396
2397     case 1:
2398     case 2:
2399       return \"#\";
2400
2401     default:
2402       abort ();
2403     }
2404 }"
2405   [(set_attr "type" "multi")
2406    (set_attr "mode" "XF,SI,SI")])
2407
2408 (define_insn "*pushxf_integer"
2409   [(set (match_operand:XF 0 "push_operand" "=<,<")
2410         (match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2411   "!optimize_size"
2412   "*
2413 {
2414   switch (which_alternative)
2415     {
2416     case 0:
2417       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2418       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2419       operands[2] = stack_pointer_rtx;
2420       operands[3] = GEN_INT (12);
2421       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2422         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2423       else
2424         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2425
2426     case 1:
2427       return \"#\";
2428
2429     default:
2430       abort ();
2431     }
2432 }"
2433   [(set_attr "type" "multi")
2434    (set_attr "mode" "XF,SI")])
2435
2436 (define_split
2437   [(set (match_operand:XF 0 "push_operand" "")
2438         (match_operand:XF 1 "general_operand" ""))]
2439   "reload_completed
2440    && (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
2441   [(const_int 0)]
2442   "if (!ix86_split_long_move (operands)) abort (); DONE;")
2443
2444 (define_split
2445   [(set (match_operand:XF 0 "push_operand" "")
2446         (match_operand:XF 1 "register_operand" ""))]
2447   "FP_REGNO_P (REGNO (operands[1]))"
2448   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2449    (set (mem:XF (reg:SI 7)) (match_dup 1))])
2450
2451 ;; Do not use integer registers when optimizing for size
2452 (define_insn "*movxf_nointeger"
2453   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2454         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2455   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2456    && optimize_size
2457    && (reload_in_progress || reload_completed
2458        || GET_CODE (operands[1]) != CONST_DOUBLE
2459        || memory_operand (operands[0], XFmode))" 
2460   "*
2461 {
2462   switch (which_alternative)
2463     {
2464     case 0:
2465       if (REG_P (operands[1])
2466           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2467         return \"fstp\\t%y0\";
2468       else if (STACK_TOP_P (operands[0]))
2469         return \"fld%z1\\t%y1\";
2470       else
2471         return \"fst\\t%y0\";
2472
2473     case 1:
2474       /* There is no non-popping store to memory for XFmode.  So if
2475          we need one, follow the store with a load.  */
2476       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2477         return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2478       else
2479         return \"fstp%z0\\t%y0\";
2480
2481     case 2:
2482       switch (standard_80387_constant_p (operands[1]))
2483         {
2484         case 1:
2485           return \"fldz\";
2486         case 2:
2487           return \"fld1\";
2488         }
2489       break;
2490
2491     case 3: case 4:
2492       return \"#\";
2493     }
2494   abort();
2495 }"
2496   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2497    (set_attr "mode" "XF,XF,XF,SI,SI")])
2498
2499 (define_insn "*movxf_integer"
2500   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2501         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2502   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2503    && !optimize_size
2504    && (reload_in_progress || reload_completed
2505        || GET_CODE (operands[1]) != CONST_DOUBLE
2506        || memory_operand (operands[0], XFmode))" 
2507   "*
2508 {
2509   switch (which_alternative)
2510     {
2511     case 0:
2512       if (REG_P (operands[1])
2513           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2514         return \"fstp\\t%y0\";
2515       else if (STACK_TOP_P (operands[0]))
2516         return \"fld%z1\\t%y1\";
2517       else
2518         return \"fst\\t%y0\";
2519
2520     case 1:
2521       /* There is no non-popping store to memory for XFmode.  So if
2522          we need one, follow the store with a load.  */
2523       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2524         return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2525       else
2526         return \"fstp%z0\\t%y0\";
2527
2528     case 2:
2529       switch (standard_80387_constant_p (operands[1]))
2530         {
2531         case 1:
2532           return \"fldz\";
2533         case 2:
2534           return \"fld1\";
2535         }
2536       break;
2537
2538     case 3: case 4:
2539       return \"#\";
2540     }
2541   abort();
2542 }"
2543   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2544    (set_attr "mode" "XF,XF,XF,SI,SI")])
2545
2546 (define_split
2547   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2548         (match_operand:XF 1 "general_operand" ""))]
2549   "reload_completed
2550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2551    && ! (FP_REG_P (operands[0]) || 
2552          (GET_CODE (operands[0]) == SUBREG
2553           && FP_REG_P (SUBREG_REG (operands[0]))))
2554    && ! (FP_REG_P (operands[1]) || 
2555          (GET_CODE (operands[1]) == SUBREG
2556           && FP_REG_P (SUBREG_REG (operands[1]))))"
2557   [(set (match_dup 2) (match_dup 5))
2558    (set (match_dup 3) (match_dup 6))
2559    (set (match_dup 4) (match_dup 7))]
2560   "if (ix86_split_long_move (operands)) DONE;")
2561
2562 (define_split
2563   [(set (match_operand:XF 0 "register_operand" "")
2564         (match_operand:XF 1 "memory_operand" ""))]
2565   "reload_completed
2566    && GET_CODE (operands[1]) == MEM
2567    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2568    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2569    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2570   [(set (match_dup 0)
2571         (match_dup 1))]
2572   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2573
2574 (define_insn "swapxf"
2575   [(set (match_operand:XF 0 "register_operand" "+f")
2576         (match_operand:XF 1 "register_operand" "+f"))
2577    (set (match_dup 1)
2578         (match_dup 0))]
2579   ""
2580   "*
2581 {
2582   if (STACK_TOP_P (operands[0]))
2583     return \"fxch\\t%1\";
2584   else
2585     return \"fxch\\t%0\";
2586 }"
2587   [(set_attr "type" "fxch")
2588    (set_attr "mode" "XF")])
2589 \f
2590 ;; Zero extension instructions
2591
2592 (define_expand "zero_extendhisi2"
2593   [(set (match_operand:SI 0 "register_operand" "")
2594      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2595   ""
2596   "
2597 {
2598   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2599     {
2600       operands[1] = force_reg (HImode, operands[1]);
2601       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2602       DONE;
2603     }
2604 }")
2605
2606 (define_insn "zero_extendhisi2_and"
2607   [(set (match_operand:SI 0 "register_operand" "=r")
2608      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2609    (clobber (reg:CC 17))]
2610   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2611   "#"
2612   [(set_attr "type" "alu1")
2613    (set_attr "mode" "SI")])
2614
2615 (define_split
2616   [(set (match_operand:SI 0 "register_operand" "")
2617         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2618    (clobber (reg:CC 17))]
2619   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2620   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2621               (clobber (reg:CC 17))])]
2622   "")
2623
2624 (define_insn "*zero_extendhisi2_movzwl"
2625   [(set (match_operand:SI 0 "register_operand" "=r")
2626      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2627   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2628   "movz{wl|x}\\t{%1, %0|%0, %1}"
2629   [(set_attr "type" "imovx")
2630    (set_attr "mode" "SI")])
2631
2632 (define_expand "zero_extendqihi2"
2633   [(parallel
2634     [(set (match_operand:HI 0 "register_operand" "")
2635        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2636      (clobber (reg:CC 17))])]
2637   ""
2638   "")
2639
2640 (define_insn "*zero_extendqihi2_and"
2641   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2642      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2643    (clobber (reg:CC 17))]
2644   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2645   "#"
2646   [(set_attr "type" "alu1")
2647    (set_attr "mode" "HI")])
2648
2649 (define_insn "*zero_extendqihi2_movzbw_and"
2650   [(set (match_operand:HI 0 "register_operand" "=r,r")
2651      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2652    (clobber (reg:CC 17))]
2653   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2654   "#"
2655   [(set_attr "type" "imovx,alu1")
2656    (set_attr "mode" "HI")])
2657
2658 (define_insn "*zero_extendqihi2_movzbw"
2659   [(set (match_operand:HI 0 "register_operand" "=r")
2660      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2661   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2662   "movz{bw|x}\\t{%1, %0|%0, %1}"
2663   [(set_attr "type" "imovx")
2664    (set_attr "mode" "HI")])
2665
2666 ;; For the movzbw case strip only the clobber
2667 (define_split
2668   [(set (match_operand:HI 0 "register_operand" "")
2669         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2670    (clobber (reg:CC 17))]
2671   "reload_completed 
2672    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2673    && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2674   [(set (match_operand:HI 0 "register_operand" "")
2675         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2676
2677 ;; When source and destination does not overlap, clear destination
2678 ;; first and then do the movb
2679 (define_split
2680   [(set (match_operand:HI 0 "register_operand" "")
2681         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2682    (clobber (reg:CC 17))]
2683   "reload_completed
2684    && QI_REG_P (operands[0])
2685    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2686    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2687   [(set (match_dup 0) (const_int 0))
2688    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2689   "operands[2] = gen_lowpart (QImode, operands[0]);")
2690
2691 ;; Rest is handled by single and.
2692 (define_split
2693   [(set (match_operand:HI 0 "register_operand" "")
2694         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2695    (clobber (reg:CC 17))]
2696   "reload_completed
2697    && true_regnum (operands[0]) == true_regnum (operands[1])"
2698   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2699               (clobber (reg:CC 17))])]
2700   "")
2701
2702 (define_expand "zero_extendqisi2"
2703   [(parallel
2704     [(set (match_operand:SI 0 "register_operand" "")
2705        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2706      (clobber (reg:CC 17))])]
2707   ""
2708   "")
2709
2710 (define_insn "*zero_extendqisi2_and"
2711   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2712      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2713    (clobber (reg:CC 17))]
2714   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2715   "#"
2716   [(set_attr "type" "alu1")
2717    (set_attr "mode" "SI")])
2718
2719 (define_insn "*zero_extendqisi2_movzbw_and"
2720   [(set (match_operand:SI 0 "register_operand" "=r,r")
2721      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2722    (clobber (reg:CC 17))]
2723   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2724   "#"
2725   [(set_attr "type" "imovx,alu1")
2726    (set_attr "mode" "SI")])
2727
2728 (define_insn "*zero_extendqisi2_movzbw"
2729   [(set (match_operand:SI 0 "register_operand" "=r")
2730      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2731   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2732   "movz{bl|x}\\t{%1, %0|%0, %1}"
2733   [(set_attr "type" "imovx")
2734    (set_attr "mode" "SI")])
2735
2736 ;; For the movzbl case strip only the clobber
2737 (define_split
2738   [(set (match_operand:SI 0 "register_operand" "")
2739         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2740    (clobber (reg:CC 17))]
2741   "reload_completed 
2742    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2743    && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2744   [(set (match_dup 0)
2745         (zero_extend:SI (match_dup 1)))])
2746
2747 ;; When source and destination does not overlap, clear destination
2748 ;; first and then do the movb
2749 (define_split
2750   [(set (match_operand:SI 0 "register_operand" "")
2751         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2752    (clobber (reg:CC 17))]
2753   "reload_completed
2754    && QI_REG_P (operands[0])
2755    && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
2756    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2757    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2758   [(set (match_dup 0) (const_int 0))
2759    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2760   "operands[2] = gen_lowpart (QImode, operands[0]);")
2761
2762 ;; Rest is handled by single and.
2763 (define_split
2764   [(set (match_operand:SI 0 "register_operand" "")
2765         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
2766    (clobber (reg:CC 17))]
2767   "reload_completed
2768    && true_regnum (operands[0]) == true_regnum (operands[1])"
2769   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
2770               (clobber (reg:CC 17))])]
2771   "")
2772
2773 ;; %%% Kill me once multi-word ops are sane.
2774 (define_insn "zero_extendsidi2"
2775   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
2776         (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))
2777    (clobber (reg:CC 17))]
2778   ""
2779   "#"
2780   [(set_attr "mode" "SI")])
2781
2782 (define_split 
2783   [(set (match_operand:DI 0 "register_operand" "")
2784         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2785    (clobber (reg:CC 17))]
2786   "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
2787   [(set (match_dup 4) (const_int 0))]
2788   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2789
2790 (define_split 
2791   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2792         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
2793    (clobber (reg:CC 17))]
2794   "reload_completed"
2795   [(set (match_dup 3) (match_dup 1))
2796    (set (match_dup 4) (const_int 0))]
2797   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2798 \f
2799 ;; Sign extension instructions
2800
2801 (define_insn "extendsidi2"
2802   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
2803         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
2804    (clobber (reg:CC 17))
2805    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
2806   ""
2807   "#")
2808
2809 ;; Extend to memory case when source register does die.
2810 (define_split 
2811   [(set (match_operand:DI 0 "memory_operand" "")
2812         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2813    (clobber (reg:CC 17))
2814    (clobber (match_operand:SI 2 "register_operand" ""))]
2815   "(reload_completed
2816     && dead_or_set_p (insn, operands[1])
2817     && !reg_mentioned_p (operands[1], operands[0]))"
2818   [(set (match_dup 3) (match_dup 1))
2819    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
2820               (clobber (reg:CC 17))])
2821    (set (match_dup 4) (match_dup 1))]
2822   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2823
2824 ;; Extend to memory case when source register does not die.
2825 (define_split 
2826   [(set (match_operand:DI 0 "memory_operand" "")
2827         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2828    (clobber (reg:CC 17))
2829    (clobber (match_operand:SI 2 "register_operand" ""))]
2830   "reload_completed"
2831   [(const_int 0)]
2832   "
2833 {
2834   split_di (&operands[0], 1, &operands[3], &operands[4]);
2835
2836   emit_move_insn (operands[3], operands[1]);
2837
2838   /* Generate a cltd if possible and doing so it profitable.  */
2839   if (true_regnum (operands[1]) == 0
2840       && true_regnum (operands[2]) == 1
2841       && (optimize_size || TARGET_USE_CLTD))
2842     {
2843       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
2844     }
2845   else
2846     {
2847       emit_move_insn (operands[2], operands[1]);
2848       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
2849     }
2850   emit_move_insn (operands[4], operands[2]);
2851   DONE;
2852 }")
2853
2854 ;; Extend to register case.  Optimize case where source and destination
2855 ;; registers match and cases where we can use cltd.
2856 (define_split 
2857   [(set (match_operand:DI 0 "register_operand" "")
2858         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2859    (clobber (reg:CC 17))
2860    (clobber (match_scratch:SI 2 ""))]
2861   "reload_completed"
2862   [(const_int 0)]
2863   "
2864 {
2865   split_di (&operands[0], 1, &operands[3], &operands[4]);
2866
2867   if (true_regnum (operands[3]) != true_regnum (operands[1]))
2868     emit_move_insn (operands[3], operands[1]);
2869
2870   /* Generate a cltd if possible and doing so it profitable.  */
2871   if (true_regnum (operands[3]) == 0
2872       && (optimize_size || TARGET_USE_CLTD))
2873     {
2874       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
2875       DONE;
2876     }
2877
2878   if (true_regnum (operands[4]) != true_regnum (operands[1]))
2879     emit_move_insn (operands[4], operands[1]);
2880
2881   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
2882   DONE;
2883 }")
2884
2885 (define_insn "extendhisi2"
2886   [(set (match_operand:SI 0 "register_operand" "=*a,r")
2887         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
2888   ""
2889   "*
2890 {
2891   switch (get_attr_prefix_0f (insn))
2892     {
2893     case 0:
2894       return \"{cwtl|cwde}\";
2895     default:
2896       return \"movs{wl|x}\\t{%1,%0|%0, %1}\";
2897     }
2898 }"
2899   [(set_attr "type" "imovx")
2900    (set_attr "mode" "SI")
2901    (set (attr "prefix_0f")
2902      ;; movsx is short decodable while cwtl is vector decoded.
2903      (if_then_else (and (eq_attr "cpu" "!k6")
2904                         (eq_attr "alternative" "0"))
2905         (const_string "0")
2906         (const_string "1")))
2907    (set (attr "modrm")
2908      (if_then_else (eq_attr "prefix_0f" "0")
2909         (const_string "0")
2910         (const_string "1")))])
2911
2912 (define_insn "extendqihi2"
2913   [(set (match_operand:HI 0 "register_operand" "=*a,r")
2914         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
2915   ""
2916   "*
2917 {
2918   switch (get_attr_prefix_0f (insn))
2919     {
2920     case 0:
2921       return \"{cbtw|cbw}\";
2922     default:
2923       return \"movs{bw|x}\\t{%1,%0|%0, %1}\";
2924     }
2925 }"
2926   [(set_attr "type" "imovx")
2927    (set_attr "mode" "HI")
2928    (set (attr "prefix_0f")
2929      ;; movsx is short decodable while cwtl is vector decoded.
2930      (if_then_else (and (eq_attr "cpu" "!k6")
2931                         (eq_attr "alternative" "0"))
2932         (const_string "0")
2933         (const_string "1")))
2934    (set (attr "modrm")
2935      (if_then_else (eq_attr "prefix_0f" "0")
2936         (const_string "0")
2937         (const_string "1")))])
2938
2939 (define_insn "extendqisi2"
2940   [(set (match_operand:SI 0 "register_operand" "=r")
2941         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2942   ""
2943   "movs{bl|x}\\t{%1,%0|%0, %1}"
2944    [(set_attr "type" "imovx")
2945     (set_attr "mode" "SI")])
2946 \f
2947 ;; Conversions between float and double.
2948
2949 ;; These are all no-ops in the model used for the 80387.  So just
2950 ;; emit moves.
2951
2952 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
2953 (define_insn "*dummy_extendsfdf2"
2954   [(set (match_operand:DF 0 "push_operand" "=<")
2955         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f")))]
2956   "0"
2957   "#")
2958
2959 (define_split
2960   [(set (match_operand:DF 0 "push_operand" "")
2961         (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
2962   "FP_REGNO_P (REGNO (operands[1]))"
2963   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2964    (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
2965
2966 (define_insn "*dummy_extendsfxf2"
2967   [(set (match_operand:XF 0 "push_operand" "=<")
2968         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
2969   "0"
2970   "#")
2971
2972 (define_split
2973   [(set (match_operand:XF 0 "push_operand" "")
2974         (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
2975   "FP_REGNO_P (REGNO (operands[1]))"
2976   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2977    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2978
2979 (define_insn "*dummy_extenddfxf2"
2980   [(set (match_operand:XF 0 "push_operand" "=<")
2981         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
2982   "0"
2983   "#")
2984
2985 (define_split
2986   [(set (match_operand:XF 0 "push_operand" "")
2987         (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
2988   "FP_REGNO_P (REGNO (operands[1]))"
2989   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2990    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2991
2992 (define_expand "extendsfdf2"
2993   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2994         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
2995   "TARGET_80387"
2996   "
2997 {
2998   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2999     operands[1] = force_reg (SFmode, operands[1]);
3000 }")
3001
3002 (define_insn "*extendsfdf2_1"
3003   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3004         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3005   "TARGET_80387
3006    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3007   "*
3008 {
3009   switch (which_alternative)
3010     {
3011     case 0:
3012       if (REG_P (operands[1])
3013           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3014         return \"fstp\\t%y0\";
3015       else if (STACK_TOP_P (operands[0]))
3016         return \"fld%z1\\t%y1\";
3017       else
3018         return \"fst\\t%y0\";
3019
3020     case 1:
3021       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3022         return \"fstp%z0\\t%y0\";
3023
3024       else
3025         return \"fst%z0\\t%y0\";
3026
3027     default:
3028       abort ();
3029     }
3030 }"
3031   [(set_attr "type" "fmov")
3032    (set_attr "mode" "SF,XF")])
3033
3034 (define_expand "extendsfxf2"
3035   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3036         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
3037   "TARGET_80387"
3038   "
3039 {
3040   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3041     operands[1] = force_reg (SFmode, operands[1]);
3042 }")
3043
3044 (define_insn "*extendsfxf2_1"
3045   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3046         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3047   "TARGET_80387
3048    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3049   "*
3050 {
3051   switch (which_alternative)
3052     {
3053     case 0:
3054       if (REG_P (operands[1])
3055           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3056         return \"fstp\\t%y0\";
3057       else if (STACK_TOP_P (operands[0]))
3058         return \"fld%z1\\t%y1\";
3059       else
3060         return \"fst\\t%y0\";
3061
3062     case 1:
3063       /* There is no non-popping store to memory for XFmode.  So if
3064          we need one, follow the store with a load.  */
3065       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3066         return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3067       else
3068         return \"fstp%z0\\t%y0\";
3069
3070     default:
3071       abort ();
3072     }
3073 }"
3074   [(set_attr "type" "fmov")
3075    (set_attr "mode" "SF,XF")])
3076
3077 (define_expand "extenddfxf2"
3078   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3079         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
3080   "TARGET_80387"
3081   "
3082 {
3083   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3084     operands[1] = force_reg (DFmode, operands[1]);
3085 }")
3086
3087 (define_insn "*extenddfxf2_1"
3088   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3089         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3090   "TARGET_80387
3091    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3092   "*
3093 {
3094   switch (which_alternative)
3095     {
3096     case 0:
3097       if (REG_P (operands[1])
3098           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3099         return \"fstp\\t%y0\";
3100       else if (STACK_TOP_P (operands[0]))
3101         return \"fld%z1\\t%y1\";
3102       else
3103         return \"fst\\t%y0\";
3104
3105     case 1:
3106       /* There is no non-popping store to memory for XFmode.  So if
3107          we need one, follow the store with a load.  */
3108       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3109         return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3110       else
3111         return \"fstp%z0\\t%y0\";
3112
3113     default:
3114       abort ();
3115     }
3116 }"
3117   [(set_attr "type" "fmov")
3118    (set_attr "mode" "DF,XF")])
3119
3120 ;; %%% This seems bad bad news.
3121 ;; This cannot output into an f-reg because there is no way to be sure
3122 ;; of truncating in that case.  Otherwise this is just like a simple move
3123 ;; insn.  So we pretend we can output to a reg in order to get better
3124 ;; register preferencing, but we really use a stack slot.
3125
3126 (define_expand "truncdfsf2"
3127   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3128                    (float_truncate:SF
3129                     (match_operand:DF 1 "register_operand" "")))
3130               (clobber (match_dup 2))])]
3131   "TARGET_80387"
3132   "operands[2] = assign_386_stack_local (SFmode, 0);")
3133
3134 (define_insn "*truncdfsf2_1"
3135   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3136         (float_truncate:SF
3137          (match_operand:DF 1 "register_operand" "f,0")))
3138    (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3139   "TARGET_80387"
3140   "*
3141 {
3142   switch (which_alternative)
3143     {
3144     case 0:
3145       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3146         return \"fstp%z0\\t%y0\";
3147       else
3148         return \"fst%z0\\t%y0\";
3149     case 1:
3150       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3151     }
3152   abort ();
3153 }"
3154   [(set_attr "type" "fmov,multi")
3155    (set_attr "mode" "SF")])
3156
3157 (define_insn "*truncdfsf2_2"
3158   [(set (match_operand:SF 0 "memory_operand" "=m")
3159         (float_truncate:SF
3160          (match_operand:DF 1 "register_operand" "f")))]
3161   "TARGET_80387"
3162   "*
3163 {
3164   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3165     return \"fstp%z0\\t%y0\";
3166   else
3167     return \"fst%z0\\t%y0\";
3168 }"
3169   [(set_attr "type" "fmov")
3170    (set_attr "mode" "SF")])
3171
3172 (define_split
3173   [(set (match_operand:SF 0 "memory_operand" "")
3174         (float_truncate:SF
3175          (match_operand:DF 1 "register_operand" "")))
3176    (clobber (match_operand:SF 2 "memory_operand" ""))]
3177   "TARGET_80387"
3178   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3179   "")
3180
3181 (define_split
3182   [(set (match_operand:SF 0 "register_operand" "")
3183         (float_truncate:SF
3184          (match_operand:DF 1 "register_operand" "")))
3185    (clobber (match_operand:SF 2 "memory_operand" ""))]
3186   "TARGET_80387 && reload_completed"
3187   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3188    (set (match_dup 0) (match_dup 2))]
3189   "")
3190
3191 (define_expand "truncxfsf2"
3192   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3193                    (float_truncate:SF
3194                     (match_operand:XF 1 "register_operand" "")))
3195               (clobber (match_dup 2))])]
3196   "TARGET_80387"
3197   "operands[2] = assign_386_stack_local (SFmode, 0);")
3198
3199 (define_insn "*truncxfsf2_1"
3200   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3201         (float_truncate:SF
3202          (match_operand:XF 1 "register_operand" "f,0")))
3203    (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3204   "TARGET_80387"
3205   "*
3206 {
3207   switch (which_alternative)
3208     {
3209     case 0:
3210       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3211         return \"fstp%z0\\t%y0\";
3212       else
3213         return \"fst%z0\\t%y0\";
3214     case 1:
3215       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3216     }
3217   abort ();
3218 }"
3219   [(set_attr "type" "fmov,multi")
3220    (set_attr "mode" "SF")])
3221
3222 (define_insn "*truncxfsf2_2"
3223   [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
3224         (float_truncate:SF
3225          (match_operand:XF 1 "register_operand" "f")))]
3226   "TARGET_80387"
3227   "*
3228 {
3229   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3230     return \"fstp%z0\\t%y0\";
3231   else
3232     return \"fst%z0\\t%y0\";
3233 }"
3234   [(set_attr "type" "fmov")
3235    (set_attr "mode" "SF")])
3236
3237 (define_split
3238   [(set (match_operand:SF 0 "memory_operand" "")
3239         (float_truncate:SF
3240          (match_operand:XF 1 "register_operand" "")))
3241    (clobber (match_operand:SF 2 "memory_operand" ""))]
3242   "TARGET_80387"
3243   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3244   "")
3245
3246 (define_split
3247   [(set (match_operand:SF 0 "register_operand" "")
3248         (float_truncate:SF
3249          (match_operand:XF 1 "register_operand" "")))
3250    (clobber (match_operand:SF 2 "memory_operand" ""))]
3251   "TARGET_80387 && reload_completed"
3252   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3253    (set (match_dup 0) (match_dup 2))]
3254   "")
3255
3256 (define_expand "truncxfdf2"
3257   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3258                    (float_truncate:DF
3259                     (match_operand:XF 1 "register_operand" "")))
3260               (clobber (match_dup 2))])]
3261   "TARGET_80387"
3262   "operands[2] = assign_386_stack_local (DFmode, 0);")
3263
3264 (define_insn "*truncxfdf2_1"
3265   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3266         (float_truncate:DF
3267          (match_operand:XF 1 "register_operand" "f,0")))
3268    (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3269   "TARGET_80387"
3270   "*
3271 {
3272   switch (which_alternative)
3273     {
3274     case 0:
3275       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3276         return \"fstp%z0\\t%y0\";
3277       else
3278         return \"fst%z0\\t%y0\";
3279     case 1:
3280       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3281     }
3282   abort ();
3283 }"
3284   [(set_attr "type" "fmov,multi")
3285    (set_attr "mode" "DF")])
3286
3287 (define_insn "*truncxfdf2_2"
3288   [(set (match_operand:DF 0 "memory_operand" "=m")
3289         (float_truncate:DF
3290           (match_operand:XF 1 "register_operand" "f")))]
3291   "TARGET_80387"
3292   "*
3293 {
3294   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3295     return \"fstp%z0\\t%y0\";
3296   else
3297     return \"fst%z0\\t%y0\";
3298 }"
3299   [(set_attr "type" "fmov")
3300    (set_attr "mode" "DF")])
3301
3302 (define_split
3303   [(set (match_operand:DF 0 "memory_operand" "")
3304         (float_truncate:DF
3305          (match_operand:XF 1 "register_operand" "")))
3306    (clobber (match_operand:DF 2 "memory_operand" ""))]
3307   "TARGET_80387"
3308   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3309   "")
3310
3311 (define_split
3312   [(set (match_operand:DF 0 "register_operand" "")
3313         (float_truncate:DF
3314          (match_operand:XF 1 "register_operand" "")))
3315    (clobber (match_operand:DF 2 "memory_operand" ""))]
3316   "TARGET_80387 && reload_completed"
3317   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3318    (set (match_dup 0) (match_dup 2))]
3319   "")
3320
3321 \f
3322 ;; %%% Break up all these bad boys.
3323
3324 ;; Signed conversion to DImode.
3325
3326 (define_expand "fix_truncxfdi2"
3327   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3328                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3329               (clobber (match_dup 2))
3330               (clobber (match_dup 3))
3331               (clobber (match_scratch:SI 4 ""))
3332               (clobber (match_scratch:XF 5 ""))])]
3333   "TARGET_80387"
3334   "operands[2] = assign_386_stack_local (SImode, 0);
3335    operands[3] = assign_386_stack_local (DImode, 1);")
3336
3337 (define_expand "fix_truncdfdi2"
3338   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3339                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3340               (clobber (match_dup 2))
3341               (clobber (match_dup 3))
3342               (clobber (match_scratch:SI 4 ""))
3343               (clobber (match_scratch:DF 5 ""))])]
3344   "TARGET_80387"
3345   "operands[2] = assign_386_stack_local (SImode, 0);
3346    operands[3] = assign_386_stack_local (DImode, 1);")
3347
3348 (define_expand "fix_truncsfdi2"
3349   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3350                    (fix:DI (match_operand:SF 1 "register_operand" "")))
3351               (clobber (match_dup 2))
3352               (clobber (match_dup 3))
3353               (clobber (match_scratch:SI 4 ""))
3354               (clobber (match_scratch:SF 5 ""))])]
3355   "TARGET_80387"
3356   "operands[2] = assign_386_stack_local (SImode, 0);
3357    operands[3] = assign_386_stack_local (DImode, 1);")
3358
3359 (define_insn "*fix_truncdi_1"
3360   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
3361         (fix:DI (match_operand 1 "register_operand" "f,f")))
3362    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3363    (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
3364    (clobber (match_scratch:SI 4 "=&r,&r"))
3365    (clobber (match_scratch 5 "=&f,&f"))]
3366   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3367   "* return output_fix_trunc (insn, operands);"
3368   [(set_attr "type" "multi")])
3369
3370 (define_split 
3371   [(set (match_operand:DI 0 "register_operand" "")
3372         (fix:DI (match_operand 1 "register_operand" "")))
3373    (clobber (match_operand:SI 2 "memory_operand" ""))
3374    (clobber (match_operand:DI 3 "memory_operand" ""))
3375    (clobber (match_scratch:SI 4 ""))
3376    (clobber (match_scratch 5 ""))]
3377   "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
3378   [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
3379               (clobber (match_dup 2))
3380               (clobber (match_dup 3))
3381               (clobber (match_dup 4))
3382               (clobber (match_dup 5))])
3383    (set (match_dup 0) (match_dup 3))]
3384   "")
3385
3386 ;; Signed conversion to SImode.
3387
3388 (define_expand "fix_truncxfsi2"
3389   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3390                    (fix:SI (match_operand:XF 1 "register_operand" "")))
3391               (clobber (match_dup 2))
3392               (clobber (match_dup 3))
3393               (clobber (match_scratch:SI 4 ""))])]
3394   "TARGET_80387"
3395   "operands[2] = assign_386_stack_local (SImode, 0);
3396    operands[3] = assign_386_stack_local (SImode, 1);")
3397
3398 (define_expand "fix_truncdfsi2"
3399   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3400                    (fix:SI (match_operand:DF 1 "register_operand" "")))
3401               (clobber (match_dup 2))
3402               (clobber (match_dup 3))
3403               (clobber (match_scratch:SI 4 ""))])]
3404   "TARGET_80387"
3405   "operands[2] = assign_386_stack_local (SImode, 0);
3406    operands[3] = assign_386_stack_local (SImode, 1);")
3407
3408 (define_expand "fix_truncsfsi2"
3409   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3410                    (fix:SI (match_operand:SF 1 "register_operand" "")))
3411               (clobber (match_dup 2))
3412               (clobber (match_dup 3))
3413               (clobber (match_scratch:SI 4 ""))])]
3414   "TARGET_80387"
3415   "operands[2] = assign_386_stack_local (SImode, 0);
3416    operands[3] = assign_386_stack_local (SImode, 1);")
3417
3418 (define_insn "*fix_truncsi_1"
3419   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
3420         (fix:SI (match_operand 1 "register_operand" "f,f")))
3421    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3422    (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
3423    (clobber (match_scratch:SI 4 "=&r,r"))]
3424   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3425   "* return output_fix_trunc (insn, operands);"
3426   [(set_attr "type" "multi")])
3427
3428 (define_split 
3429   [(set (match_operand:SI 0 "register_operand" "")
3430         (fix:SI (match_operand 1 "register_operand" "")))
3431    (clobber (match_operand:SI 2 "memory_operand" ""))
3432    (clobber (match_operand:SI 3 "memory_operand" ""))
3433    (clobber (match_scratch:SI 4 ""))]
3434   "reload_completed"
3435   [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
3436               (clobber (match_dup 2))
3437               (clobber (match_dup 3))
3438               (clobber (match_dup 4))])
3439    (set (match_dup 0) (match_dup 3))]
3440   "")
3441
3442 ;; Signed conversion to HImode.
3443
3444 (define_expand "fix_truncxfhi2"
3445   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3446                    (fix:HI (match_operand:XF 1 "register_operand" "")))
3447               (clobber (match_dup 2))
3448               (clobber (match_dup 3))
3449               (clobber (match_scratch:SI 4 ""))])]
3450   "TARGET_80387"
3451   "operands[2] = assign_386_stack_local (SImode, 0);
3452    operands[3] = assign_386_stack_local (HImode, 1);")
3453
3454 (define_expand "fix_truncdfhi2"
3455   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3456                    (fix:HI (match_operand:DF 1 "register_operand" "")))
3457               (clobber (match_dup 2))
3458               (clobber (match_dup 3))
3459               (clobber (match_scratch:SI 4 ""))])]
3460   "TARGET_80387"
3461   "operands[2] = assign_386_stack_local (SImode, 0);
3462    operands[3] = assign_386_stack_local (HImode, 1);")
3463
3464 (define_expand "fix_truncsfhi2"
3465   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3466                    (fix:HI (match_operand:SF 1 "register_operand" "")))
3467               (clobber (match_dup 2))
3468               (clobber (match_dup 3))
3469               (clobber (match_scratch:SI 4 ""))])]
3470   "TARGET_80387"
3471   "operands[2] = assign_386_stack_local (SImode, 0);
3472    operands[3] = assign_386_stack_local (HImode, 1);")
3473
3474 (define_insn "*fix_trunchi_1"
3475   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
3476         (fix:HI (match_operand 1 "register_operand" "f,f")))
3477    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3478    (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
3479    (clobber (match_scratch:SI 4 "=&r,r"))]
3480   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3481   "* return output_fix_trunc (insn, operands);"
3482   [(set_attr "type" "multi")])
3483
3484 (define_split 
3485   [(set (match_operand:HI 0 "register_operand" "")
3486         (fix:HI (match_operand 1 "register_operand" "")))
3487    (clobber (match_operand:SI 2 "memory_operand" ""))
3488    (clobber (match_operand:HI 3 "memory_operand" ""))
3489    (clobber (match_scratch:SI 4 ""))]
3490   "reload_completed"
3491   [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
3492               (clobber (match_dup 2))
3493               (clobber (match_dup 3))
3494               (clobber (match_dup 4))])
3495    (set (match_dup 0) (match_dup 3))]
3496   "")
3497
3498 ;; %% Not used yet.
3499 (define_insn "x86_fnstcw_1"
3500   [(set (match_operand:HI 0 "memory_operand" "=m")
3501         (unspec:HI [(reg:HI 18)] 11))]
3502   "TARGET_80387"
3503   "fnstcw\\t%0"
3504   [(set_attr "length" "2")
3505    (set_attr "mode" "HI")
3506    (set_attr "i387" "1")
3507    (set_attr "ppro_uops" "few")])
3508
3509 (define_insn "x86_fldcw_1"
3510   [(set (reg:HI 18)
3511         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
3512   "TARGET_80387"
3513   "fldcw\\t%0"
3514   [(set_attr "length" "2")
3515    (set_attr "mode" "HI")
3516    (set_attr "i387" "1")
3517    (set_attr "athlon_decode" "vector")
3518    (set_attr "ppro_uops" "few")])
3519 \f
3520 ;; Conversion between fixed point and floating point.
3521
3522 ;; Even though we only accept memory inputs, the backend _really_
3523 ;; wants to be able to do this between registers.
3524
3525 (define_insn "floathisf2"
3526   [(set (match_operand:SF 0 "register_operand" "=f,f")
3527         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3528   "TARGET_80387"
3529   "@
3530    fild%z1\\t%1
3531    #"
3532   [(set_attr "type" "fmov,multi")
3533    (set_attr "mode" "SF")
3534    (set_attr "fp_int_src" "true")])
3535
3536 (define_insn "floatsisf2"
3537   [(set (match_operand:SF 0 "register_operand" "=f,f")
3538         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3539   "TARGET_80387"
3540   "@
3541    fild%z1\\t%1
3542    #"
3543   [(set_attr "type" "fmov,multi")
3544    (set_attr "mode" "SF")
3545    (set_attr "fp_int_src" "true")])
3546
3547 (define_insn "floatdisf2"
3548   [(set (match_operand:SF 0 "register_operand" "=f,f")
3549         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3550   "TARGET_80387"
3551   "@
3552    fild%z1\\t%1
3553    #"
3554   [(set_attr "type" "fmov,multi")
3555    (set_attr "mode" "SF")
3556    (set_attr "fp_int_src" "true")])
3557
3558 (define_insn "floathidf2"
3559   [(set (match_operand:DF 0 "register_operand" "=f,f")
3560         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3561   "TARGET_80387"
3562   "@
3563    fild%z1\\t%1
3564    #"
3565   [(set_attr "type" "fmov,multi")
3566    (set_attr "mode" "DF")
3567    (set_attr "fp_int_src" "true")])
3568
3569 (define_insn "floatsidf2"
3570   [(set (match_operand:DF 0 "register_operand" "=f,f")
3571         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3572   "TARGET_80387"
3573   "@
3574    fild%z1\\t%1
3575    #"
3576   [(set_attr "type" "fmov,multi")
3577    (set_attr "mode" "DF")
3578    (set_attr "fp_int_src" "true")])
3579
3580 (define_insn "floatdidf2"
3581   [(set (match_operand:DF 0 "register_operand" "=f,f")
3582         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3583   "TARGET_80387"
3584   "@
3585    fild%z1\\t%1
3586    #"
3587   [(set_attr "type" "fmov,multi")
3588    (set_attr "mode" "DF")
3589    (set_attr "fp_int_src" "true")])
3590
3591 (define_insn "floathixf2"
3592   [(set (match_operand:XF 0 "register_operand" "=f,f")
3593         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3594   "TARGET_80387"
3595   "@
3596    fild%z1\\t%1
3597    #"
3598   [(set_attr "type" "fmov,multi")
3599    (set_attr "mode" "XF")
3600    (set_attr "fp_int_src" "true")])
3601
3602 (define_insn "floatsixf2"
3603   [(set (match_operand:XF 0 "register_operand" "=f,f")
3604         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3605   "TARGET_80387"
3606   "@
3607    fild%z1\\t%1
3608    #"
3609   [(set_attr "type" "fmov,multi")
3610    (set_attr "mode" "XF")
3611    (set_attr "fp_int_src" "true")])
3612
3613 (define_insn "floatdixf2"
3614   [(set (match_operand:XF 0 "register_operand" "=f,f")
3615         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3616   "TARGET_80387"
3617   "@
3618    fild%z1\\t%1
3619    #"
3620   [(set_attr "type" "fmov,multi")
3621    (set_attr "mode" "XF")
3622    (set_attr "fp_int_src" "true")])
3623
3624 ;; %%% Kill these when reload knows how to do it.
3625 (define_split
3626   [(set (match_operand 0 "register_operand" "")
3627         (float (match_operand:HI 1 "register_operand" "")))]
3628   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3629   [(set (mem:HI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3630    (set (match_dup 0) (match_dup 2))
3631    (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 2)))]
3632   "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3633                                 gen_rtx_MEM (HImode, stack_pointer_rtx));")
3634
3635 (define_split
3636   [(set (match_operand 0 "register_operand" "")
3637         (float (match_operand:SI 1 "register_operand" "")))]
3638   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3639   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3640    (set (match_dup 0) (match_dup 2))
3641    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
3642               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
3643   "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3644                                 gen_rtx_MEM (SImode, stack_pointer_rtx));")
3645
3646 (define_split
3647   [(set (match_operand 0 "register_operand" "")
3648         (float (match_operand:DI 1 "nonmemory_operand" "")))]
3649   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3650   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
3651    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3652    (set (match_dup 0) (match_dup 3))
3653    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
3654               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
3655    (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
3656               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
3657   "split_di (operands+1, 1, operands+1, operands+2);
3658    operands[3] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3659                                 gen_rtx_MEM (DImode, stack_pointer_rtx));")
3660 \f
3661 ;; Add instructions
3662
3663 ;; %%% define_expand from the very first?
3664 ;; %%% splits for addsidi3
3665 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3666 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
3667 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
3668
3669 (define_insn "adddi3"
3670   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3671         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
3672                  (match_operand:DI 2 "general_operand" "roiF,riF")))
3673    (clobber (reg:CC 17))]
3674   ""
3675   "#")
3676
3677 (define_split
3678   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3679         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
3680                  (match_operand:DI 2 "general_operand" "")))
3681    (clobber (reg:CC 17))]
3682   "reload_completed"
3683   [(parallel [(set (reg:CC 17) (plus:CC (match_dup 1) (match_dup 2)))
3684               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
3685    (parallel [(set (match_dup 3)
3686                    (plus:SI (match_dup 4)
3687                    (plus:SI (match_dup 5)
3688                             (ltu:SI (reg:CC 17) (const_int 0)))))
3689               (clobber (reg:CC 17))])]
3690   "split_di (operands+0, 1, operands+0, operands+3);
3691    split_di (operands+1, 1, operands+1, operands+4);
3692    split_di (operands+2, 1, operands+2, operands+5);")
3693
3694 (define_insn "*addsi3_cc"
3695   [(set (reg:CC 17) (plus:CC (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3696                     (match_operand:SI 2 "general_operand" "ri,rm")))
3697    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3698         (plus:SI (match_dup 1) (match_dup 2)))]
3699   "ix86_binary_operator_ok (PLUS, SImode, operands)"
3700   "add{l}\\t{%2, %0|%0, %2}"
3701   [(set_attr "type" "alu")
3702    (set_attr "mode" "SI")])
3703
3704 (define_insn "addqi3_cc"
3705   [(set (reg:CC 17) (plus:CC (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3706                     (match_operand:QI 2 "general_operand" "qi,qm")))
3707    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3708         (plus:QI (match_dup 1) (match_dup 2)))]
3709   "ix86_binary_operator_ok (PLUS, QImode, operands)"
3710   "add{b}\\t{%2, %0|%0, %2}"
3711   [(set_attr "type" "alu")
3712    (set_attr "mode" "QI")])
3713
3714 (define_insn "*addsi3_carry"
3715   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3716           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3717             (plus:SI (match_operand:SI 2 "general_operand" "ri,rm")
3718               (ltu:SI (reg:CC 17) (const_int 0)))))
3719    (clobber (reg:CC 17))]
3720   "ix86_binary_operator_ok (PLUS, SImode, operands)"
3721   "adc{l}\\t{%2, %0|%0, %2}"
3722   [(set_attr "type" "alu")
3723    (set_attr "pent_pair" "pu")
3724    (set_attr "mode" "SI")
3725    (set_attr "ppro_uops" "few")])
3726
3727 (define_expand "addsi3"
3728   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3729                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3730                             (match_operand:SI 2 "general_operand" "")))
3731               (clobber (reg:CC 17))])]
3732   ""
3733   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
3734
3735 (define_insn "*lea_0"
3736   [(set (match_operand:SI 0 "register_operand" "=r")
3737         (match_operand:SI 1 "address_operand" "p"))]
3738   ""
3739   "lea{l}\\t{%a1, %0|%0, %a1}"
3740   [(set_attr "type" "lea")
3741    (set_attr "mode" "SI")])
3742
3743 (define_insn "*addsi_1"
3744   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3745         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3746                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
3747    (clobber (reg:CC 17))]
3748   "ix86_binary_operator_ok (PLUS, SImode, operands)"
3749   "*
3750 {
3751   switch (get_attr_type (insn))
3752     {
3753     case TYPE_LEA:
3754       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
3755       return \"lea{l}\\t{%a2, %0|%0, %a2}\";
3756
3757     case TYPE_INCDEC:
3758       if (! rtx_equal_p (operands[0], operands[1]))
3759         abort ();
3760       if (operands[2] == const1_rtx)
3761         return \"inc{l}\\t%0\";
3762       else if (operands[2] == constm1_rtx)
3763         return \"dec{l}\\t%0\";
3764       else
3765         abort();
3766
3767     default:
3768       if (! rtx_equal_p (operands[0], operands[1]))
3769         abort ();
3770
3771       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3772          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3773       if (GET_CODE (operands[2]) == CONST_INT
3774           && (INTVAL (operands[2]) == 128
3775               || (INTVAL (operands[2]) < 0
3776                   && INTVAL (operands[2]) != -128)))
3777         {
3778           operands[2] = GEN_INT (-INTVAL (operands[2]));
3779           return \"sub{l}\\t{%2, %0|%0, %2}\";
3780         }
3781       return \"add{l}\\t{%2, %0|%0, %2}\";
3782     }
3783 }"
3784   [(set (attr "type")
3785      (cond [(eq_attr "alternative" "2")
3786               (const_string "lea")
3787             ; Current assemblers are broken and do not allow @GOTOFF in
3788             ; ought but a memory context.
3789             (match_operand:SI 2 "pic_symbolic_operand" "")
3790               (const_string "lea")
3791             (match_operand:SI 2 "incdec_operand" "")
3792               (const_string "incdec")
3793            ]
3794            (const_string "alu")))
3795    (set_attr "mode" "SI")])
3796
3797 ;; Convert lea to the lea pattern to avoid flags dependency.
3798 (define_split
3799   [(set (match_operand:SI 0 "register_operand" "")
3800         (plus:SI (match_operand:SI 1 "register_operand" "")
3801                  (match_operand:SI 2 "nonmemory_operand" "")))
3802    (clobber (reg:CC 17))]
3803   "reload_completed
3804    && true_regnum (operands[0]) != true_regnum (operands[1])"
3805   [(set (match_dup 0)
3806         (plus:SI (match_dup 1)
3807                  (match_dup 2)))]
3808   "")
3809
3810 (define_insn "*addsi_2"
3811   [(set (reg 17)
3812         (compare
3813           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3814                    (match_operand:SI 2 "general_operand" "rmni,rni"))
3815           (const_int 0)))                       
3816    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
3817         (plus:SI (match_dup 1) (match_dup 2)))]
3818   "ix86_match_ccmode (insn, CCNOmode)
3819    && ix86_binary_operator_ok (PLUS, SImode, operands)
3820    /* Current assemblers are broken and do not allow @GOTOFF in
3821       ought but a memory context. */
3822    && ! pic_symbolic_operand (operands[2], VOIDmode)"
3823   "*
3824 {
3825   switch (get_attr_type (insn))
3826     {
3827     case TYPE_INCDEC:
3828       if (! rtx_equal_p (operands[0], operands[1]))
3829         abort ();
3830       if (operands[2] == const1_rtx)
3831         return \"inc{l}\\t%0\";
3832       else if (operands[2] == constm1_rtx)
3833         return \"dec{l}\\t%0\";
3834       else
3835         abort();
3836
3837     default:
3838       if (! rtx_equal_p (operands[0], operands[1]))
3839         abort ();
3840       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3841          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3842       if (GET_CODE (operands[2]) == CONST_INT
3843           && (INTVAL (operands[2]) == 128
3844               || (INTVAL (operands[2]) < 0
3845                   && INTVAL (operands[2]) != -128)))
3846         {
3847           operands[2] = GEN_INT (-INTVAL (operands[2]));
3848           return \"sub{l}\\t{%2, %0|%0, %2}\";
3849         }
3850       return \"add{l}\\t{%2, %0|%0, %2}\";
3851     }
3852 }"
3853   [(set (attr "type")
3854      (if_then_else (match_operand:SI 2 "incdec_operand" "")
3855         (const_string "incdec")
3856         (const_string "alu")))
3857    (set_attr "mode" "SI")])
3858
3859 (define_insn "*addsi_3"
3860   [(set (reg:CC 17)
3861         (compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3862                              (match_operand:SI 2 "general_operand" "rmni,rni"))
3863                     (const_int 0)))                     
3864    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
3865         (plus:SI (match_dup 1) (match_dup 2)))]
3866   "ix86_binary_operator_ok (PLUS, SImode, operands)
3867    /* Current assemblers are broken and do not allow @GOTOFF in
3868       ought but a memory context. */
3869    && ! pic_symbolic_operand (operands[2], VOIDmode)"
3870   "add{l}\\t{%2, %0|%0, %2}"
3871   [(set_attr "type" "alu")
3872    (set_attr "mode" "SI")])
3873
3874 (define_expand "addhi3"
3875   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3876                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3877                             (match_operand:HI 2 "general_operand" "")))
3878               (clobber (reg:CC 17))])]
3879   "TARGET_HIMODE_MATH"
3880   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
3881
3882 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
3883 ;; type optimizations enabled by define-splits.  This is not important
3884 ;; for PII, and in fact harmful because of partial register stalls.
3885
3886 (define_insn "*addhi_1"
3887   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3888         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3889                  (match_operand:HI 2 "general_operand" "ri,rm")))
3890    (clobber (reg:CC 17))]
3891   "ix86_binary_operator_ok (PLUS, HImode, operands)"
3892   "*
3893 {
3894   switch (get_attr_type (insn))
3895     {
3896     case TYPE_INCDEC:
3897       if (operands[2] == const1_rtx)
3898         return \"inc{w}\\t%0\";
3899       else if (operands[2] == constm1_rtx
3900                || (GET_CODE (operands[2]) == CONST_INT
3901                    && INTVAL (operands[2]) == 65535))
3902         return \"dec{w}\\t%0\";
3903       abort();
3904
3905     default:
3906       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3907          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3908       if (GET_CODE (operands[2]) == CONST_INT
3909           && (INTVAL (operands[2]) == 128
3910               || (INTVAL (operands[2]) < 0
3911                   && INTVAL (operands[2]) != -128)))
3912         {
3913           operands[2] = GEN_INT (-INTVAL (operands[2]));
3914           return \"sub{w}\\t{%2, %0|%0, %2}\";
3915         }
3916       return \"add{w}\\t{%2, %0|%0, %2}\";
3917     }
3918 }"
3919   [(set (attr "type")
3920      (if_then_else (match_operand:HI 2 "incdec_operand" "")
3921         (const_string "incdec")
3922         (const_string "alu")))
3923    (set_attr "mode" "HI")])
3924
3925 (define_insn "*addhi_2"
3926   [(set (reg 17)
3927         (compare
3928           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3929                    (match_operand:HI 2 "general_operand" "rmni,rni"))
3930           (const_int 0)))                       
3931    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
3932         (plus:HI (match_dup 1) (match_dup 2)))]
3933   "ix86_match_ccmode (insn, CCNOmode)
3934    && ix86_binary_operator_ok (PLUS, HImode, operands)"
3935   "*
3936 {
3937   switch (get_attr_type (insn))
3938     {
3939     case TYPE_INCDEC:
3940       if (operands[2] == const1_rtx)
3941         return \"inc{w}\\t%0\";
3942       else if (operands[2] == constm1_rtx
3943                || (GET_CODE (operands[2]) == CONST_INT
3944                    && INTVAL (operands[2]) == 65535))
3945         return \"dec{w}\\t%0\";
3946       abort();
3947
3948     default:
3949       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3950          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3951       if (GET_CODE (operands[2]) == CONST_INT
3952           && (INTVAL (operands[2]) == 128
3953               || (INTVAL (operands[2]) < 0
3954                   && INTVAL (operands[2]) != -128)))
3955         {
3956           operands[2] = GEN_INT (-INTVAL (operands[2]));
3957           return \"sub{w}\\t{%2, %0|%0, %2}\";
3958         }
3959       return \"add{w}\\t{%2, %0|%0, %2}\";
3960     }
3961 }"
3962   [(set (attr "type")
3963      (if_then_else (match_operand:HI 2 "incdec_operand" "")
3964         (const_string "incdec")
3965         (const_string "alu")))
3966    (set_attr "mode" "HI")])
3967
3968 (define_insn "*addhi_3"
3969   [(set (reg:CC 17)
3970         (compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3971                              (match_operand:HI 2 "general_operand" "rmni,rni"))
3972                     (const_int 0)))                     
3973    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
3974         (plus:HI (match_dup 1) (match_dup 2)))]
3975   "ix86_binary_operator_ok (PLUS, HImode, operands)"
3976   "add{w}\\t{%2, %0|%0, %2}"
3977   [(set_attr "type" "alu")
3978    (set_attr "mode" "HI")])
3979
3980 (define_expand "addqi3"
3981   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
3982                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
3983                             (match_operand:QI 2 "general_operand" "")))
3984               (clobber (reg:CC 17))])]
3985   "TARGET_QIMODE_MATH"
3986   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
3987
3988 ;; %%% Potential partial reg stall on alternative 2.  What to do?
3989 (define_insn "*addqi_1"
3990   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
3991         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
3992                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
3993    (clobber (reg:CC 17))]
3994   "ix86_binary_operator_ok (PLUS, QImode, operands)"
3995   "*
3996 {
3997   int widen = (which_alternative == 2);
3998   switch (get_attr_type (insn))
3999     {
4000     case TYPE_INCDEC:
4001       if (operands[2] == const1_rtx)
4002         return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
4003       else if (operands[2] == constm1_rtx
4004                || (GET_CODE (operands[2]) == CONST_INT
4005                    && INTVAL (operands[2]) == 255))
4006         return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
4007       abort();
4008
4009     default:
4010       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4011          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4012       if (GET_CODE (operands[2]) == CONST_INT
4013           && (INTVAL (operands[2]) == 128
4014               || (INTVAL (operands[2]) < 0
4015                   && INTVAL (operands[2]) != -128)))
4016         {
4017           operands[2] = GEN_INT (-INTVAL (operands[2]));
4018           if (widen)
4019             return \"sub{l}\\t{%2, %k0|%k0, %2}\";
4020           else
4021             return \"sub{b}\\t{%2, %0|%0, %2}\";
4022         }
4023       if (widen)
4024         return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
4025       else
4026         return \"add{b}\\t{%2, %0|%0, %2}\";
4027     }
4028 }"
4029   [(set (attr "type")
4030      (if_then_else (match_operand:QI 2 "incdec_operand" "")
4031         (const_string "incdec")
4032         (const_string "alu")))
4033    (set_attr "mode" "QI,QI,SI")])
4034
4035 (define_insn "*addqi_2"
4036   [(set (reg 17)
4037         (compare
4038           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4039                    (match_operand:QI 2 "general_operand" "qmni,qni"))
4040           (const_int 0)))
4041    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
4042         (plus:QI (match_dup 1) (match_dup 2)))]
4043   "ix86_match_ccmode (insn, CCNOmode)
4044    && ix86_binary_operator_ok (PLUS, QImode, operands)"
4045   "*
4046 {
4047   switch (get_attr_type (insn))
4048     {
4049     case TYPE_INCDEC:
4050       if (operands[2] == const1_rtx)
4051         return \"inc{b}\\t%0\";
4052       else if (operands[2] == constm1_rtx
4053                || (GET_CODE (operands[2]) == CONST_INT
4054                    && INTVAL (operands[2]) == 255))
4055         return \"dec{b}\\t%0\";
4056       abort();
4057
4058     default:
4059       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
4060       if (GET_CODE (operands[2]) == CONST_INT
4061           && INTVAL (operands[2]) < 0)
4062         {
4063           operands[2] = GEN_INT (-INTVAL (operands[2]));
4064           return \"sub{b}\\t{%2, %0|%0, %2}\";
4065         }
4066       return \"add{b}\\t{%2, %0|%0, %2}\";
4067     }
4068 }"
4069   [(set (attr "type")
4070      (if_then_else (match_operand:QI 2 "incdec_operand" "")
4071         (const_string "incdec")
4072         (const_string "alu")))
4073    (set_attr "mode" "QI")])
4074
4075 (define_insn "*addqi_3"
4076   [(set (reg:CC 17)
4077         (compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4078                              (match_operand:QI 2 "general_operand" "qmni,qni"))
4079                     (const_int 0)))                     
4080    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
4081         (plus:QI (match_dup 1) (match_dup 2)))]
4082   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4083   "add{b}\\t{%2, %0|%0, %2}"
4084   [(set_attr "type" "alu")
4085    (set_attr "mode" "QI")])
4086
4087
4088 (define_insn "addqi_ext_1"
4089   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4090                          (const_int 8)
4091                          (const_int 8))
4092         (plus:SI
4093           (zero_extract:SI
4094             (match_operand 1 "ext_register_operand" "0")
4095             (const_int 8)
4096             (const_int 8))
4097           (match_operand:QI 2 "general_operand" "qmn")))
4098    (clobber (reg:CC 17))]
4099   ""
4100   "*
4101 {
4102   switch (get_attr_type (insn))
4103     {
4104     case TYPE_INCDEC:
4105       if (operands[2] == const1_rtx)
4106         return \"inc{b}\\t%h0\";
4107       else if (operands[2] == constm1_rtx
4108                || (GET_CODE (operands[2]) == CONST_INT
4109                    && INTVAL (operands[2]) == 255))
4110         return \"dec{b}\\t%h0\";
4111       abort();
4112
4113     default:
4114       return \"add{b}\\t{%2, %h0|%h0, %2}\";
4115     }
4116 }"
4117   [(set (attr "type")
4118      (if_then_else (match_operand:QI 2 "incdec_operand" "")
4119         (const_string "incdec")
4120         (const_string "alu")))
4121    (set_attr "mode" "QI")])
4122
4123 (define_insn "*addqi_ext_2"
4124   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4125                          (const_int 8)
4126                          (const_int 8))
4127         (plus:SI
4128           (zero_extract:SI
4129             (match_operand 1 "ext_register_operand" "%0")
4130             (const_int 8)
4131             (const_int 8))
4132           (zero_extract:SI
4133             (match_operand 2 "ext_register_operand" "q")
4134             (const_int 8)
4135             (const_int 8))))
4136    (clobber (reg:CC 17))]
4137   ""
4138   "add{b}\\t{%h2, %h0|%h0, %h2}"
4139   [(set_attr "type" "alu")
4140    (set_attr "mode" "QI")])
4141
4142 ;; The patterns that match these are at the end of this file.
4143
4144 (define_expand "addxf3"
4145   [(set (match_operand:XF 0 "register_operand" "")
4146         (plus:XF (match_operand:XF 1 "register_operand" "")
4147                  (match_operand:XF 2 "register_operand" "")))]
4148   "TARGET_80387"
4149   "")
4150
4151 (define_expand "adddf3"
4152   [(set (match_operand:DF 0 "register_operand" "")
4153         (plus:DF (match_operand:DF 1 "register_operand" "")
4154                  (match_operand:DF 2 "nonimmediate_operand" "")))]
4155   "TARGET_80387"
4156   "")
4157
4158 (define_expand "addsf3"
4159   [(set (match_operand:SF 0 "register_operand" "")
4160         (plus:SF (match_operand:SF 1 "register_operand" "")
4161                  (match_operand:SF 2 "nonimmediate_operand" "")))]
4162   "TARGET_80387"
4163   "")
4164 \f
4165 ;; Subtract instructions
4166
4167 ;; %%% define_expand from the very first?
4168 ;; %%% splits for subsidi3
4169
4170 (define_insn "subdi3"
4171   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4172         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
4173                   (match_operand:DI 2 "general_operand" "roiF,riF")))
4174    (clobber (reg:CC 17))]
4175   ""
4176   "#")
4177
4178 (define_split
4179   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4180         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4181                   (match_operand:DI 2 "general_operand" "")))
4182    (clobber (reg:CC 17))]
4183   "reload_completed"
4184   [(parallel [(set (reg:CC 17) (minus:CC (match_dup 1) (match_dup 2)))
4185               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
4186    (parallel [(set (match_dup 3)
4187                    (minus:SI (match_dup 4)
4188                              (plus:SI (match_dup 5)
4189                              (ltu:SI (reg:CC 17) (const_int 0)))))
4190               (clobber (reg:CC 17))])]
4191   "split_di (operands+0, 1, operands+0, operands+3);
4192    split_di (operands+1, 1, operands+1, operands+4);
4193    split_di (operands+2, 1, operands+2, operands+5);")
4194
4195 (define_insn "*subsi3_cc"
4196   [(set (reg:CC 17) (minus:CC (match_operand:SI 1 "nonimmediate_operand" "0,0")
4197                               (match_operand:SI 2 "general_operand" "ri,rm")))
4198    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4199         (minus:SI (match_dup 1) (match_dup 2)))]
4200   "ix86_binary_operator_ok (MINUS, SImode, operands)"
4201   "sub{l}\\t{%2, %0|%0, %2}"
4202   [(set_attr "type" "alu")
4203    (set_attr "mode" "SI")])
4204
4205 (define_insn "subsi3_carry"
4206   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4207           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4208             (plus:SI (match_operand:SI 2 "general_operand" "ri,rm")
4209               (ltu:SI (reg:CC 17) (const_int 0)))))
4210    (clobber (reg:CC 17))]
4211   "ix86_binary_operator_ok (MINUS, SImode, operands)"
4212   "sbb{l}\\t{%2, %0|%0, %2}"
4213   [(set_attr "type" "alu")
4214    (set_attr "pent_pair" "pu")
4215    (set_attr "ppro_uops" "few")
4216    (set_attr "mode" "SI")])
4217
4218 (define_expand "subsi3"
4219   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4220                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4221                              (match_operand:SI 2 "general_operand" "")))
4222               (clobber (reg:CC 17))])]
4223   ""
4224   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
4225
4226 (define_insn "*subsi_1"
4227   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4228         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4229                   (match_operand:SI 2 "general_operand" "ri,rm")))
4230    (clobber (reg:CC 17))]
4231   "ix86_binary_operator_ok (MINUS, SImode, operands)"
4232   "sub{l}\\t{%2, %0|%0, %2}"
4233   [(set_attr "type" "alu")
4234    (set_attr "mode" "SI")])
4235
4236 (define_insn "*subsi_2"
4237   [(set (reg 17)
4238         (compare
4239           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4240                     (match_operand:SI 2 "general_operand" "ri,rm"))
4241           (const_int 0)))
4242    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4243         (minus:SI (match_dup 1) (match_dup 2)))]
4244   "ix86_match_ccmode (insn, CCmode)
4245    && ix86_binary_operator_ok (MINUS, SImode, operands)"
4246   "sub{l}\\t{%2, %0|%0, %2}"
4247   [(set_attr "type" "alu")
4248    (set_attr "mode" "SI")])
4249
4250 (define_expand "subhi3"
4251   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4252                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
4253                              (match_operand:HI 2 "general_operand" "")))
4254               (clobber (reg:CC 17))])]
4255   "TARGET_HIMODE_MATH"
4256   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
4257
4258 (define_insn "*subhi_1"
4259   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4260         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
4261                   (match_operand:HI 2 "general_operand" "ri,rm")))
4262    (clobber (reg:CC 17))]
4263   "ix86_binary_operator_ok (MINUS, HImode, operands)"
4264   "sub{w}\\t{%2, %0|%0, %2}"
4265   [(set_attr "type" "alu")
4266    (set_attr "mode" "HI")])
4267
4268 (define_insn "*subhi_2"
4269   [(set (reg 17)
4270         (compare
4271           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
4272                     (match_operand:HI 2 "general_operand" "ri,rm"))
4273           (const_int 0)))
4274    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4275         (minus:HI (match_dup 1) (match_dup 2)))]
4276   "ix86_match_ccmode (insn, CCmode)
4277    && ix86_binary_operator_ok (MINUS, HImode, operands)"
4278   "sub{w}\\t{%2, %0|%0, %2}"
4279   [(set_attr "type" "alu")
4280    (set_attr "mode" "HI")])
4281
4282 (define_expand "subqi3"
4283   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
4284                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
4285                              (match_operand:QI 2 "general_operand" "")))
4286               (clobber (reg:CC 17))])]
4287   "TARGET_QIMODE_MATH"
4288   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
4289
4290 (define_insn "*subqi_1"
4291   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4292         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
4293                   (match_operand:QI 2 "general_operand" "qn,qmn")))
4294    (clobber (reg:CC 17))]
4295   "ix86_binary_operator_ok (MINUS, QImode, operands)"
4296   "sub{b}\\t{%2, %0|%0, %2}"
4297   [(set_attr "type" "alu")
4298    (set_attr "mode" "QI")])
4299
4300 (define_insn "*subqi_2"
4301   [(set (reg 17)
4302         (compare
4303           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
4304                     (match_operand:QI 2 "general_operand" "qi,qm"))
4305           (const_int 0)))
4306    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
4307         (minus:HI (match_dup 1) (match_dup 2)))]
4308   "ix86_match_ccmode (insn, CCmode)
4309    && ix86_binary_operator_ok (MINUS, QImode, operands)"
4310   "sub{b}\\t{%2, %0|%0, %2}"
4311   [(set_attr "type" "alu")
4312    (set_attr "mode" "QI")])
4313
4314 ;; The patterns that match these are at the end of this file.
4315
4316 (define_expand "subxf3"
4317   [(set (match_operand:XF 0 "register_operand" "")
4318         (minus:XF (match_operand:XF 1 "register_operand" "")
4319                   (match_operand:XF 2 "register_operand" "")))]
4320   "TARGET_80387"
4321   "")
4322
4323 (define_expand "subdf3"
4324   [(set (match_operand:DF 0 "register_operand" "")
4325         (minus:DF (match_operand:DF 1 "register_operand" "")
4326                   (match_operand:DF 2 "nonimmediate_operand" "")))]
4327   "TARGET_80387"
4328   "")
4329
4330 (define_expand "subsf3"
4331   [(set (match_operand:SF 0 "register_operand" "")
4332         (minus:SF (match_operand:SF 1 "register_operand" "")
4333                   (match_operand:SF 2 "nonimmediate_operand" "")))]
4334   "TARGET_80387"
4335   "")
4336 \f
4337 ;; Multiply instructions
4338
4339 (define_expand "mulsi3"
4340   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4341                    (mult:SI (match_operand:SI 1 "register_operand" "")
4342                             (match_operand:SI 2 "general_operand" "")))
4343               (clobber (reg:CC 17))])]
4344   ""
4345   "")
4346
4347 (define_insn "*mulsi3_1"
4348   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4349         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
4350                  (match_operand:SI 2 "general_operand" "K,i,mr")))
4351    (clobber (reg:CC 17))]
4352   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
4353   ; For the {r,0,i} alternative (i.e., register <- register * immediate),
4354   ; there are two ways of writing the exact same machine instruction
4355   ; in assembly language.  One, for example, is:
4356   ;
4357   ;   imul $12, %eax
4358   ;
4359   ; while the other is:
4360   ;
4361   ;   imul $12, %eax, %eax
4362   ;
4363   ; The first is simply short-hand for the latter.  But, some assemblers,
4364   ; like the SCO OSR5 COFF assembler, don't handle the first form.
4365   "@
4366    imul{l}\\t{%2, %1, %0|%0, %1, %2}
4367    imul{l}\\t{%2, %1, %0|%0, %1, %2}
4368    imul{l}\\t{%2, %0|%0, %2}"
4369   [(set_attr "type" "imul")
4370    (set_attr "prefix_0f" "0,0,1")
4371    (set_attr "mode" "SI")])
4372
4373 (define_expand "mulhi3"
4374   [(parallel [(set (match_operand:HI 0 "register_operand" "")
4375                    (mult:HI (match_operand:HI 1 "register_operand" "")
4376                             (match_operand:HI 2 "general_operand" "")))
4377               (clobber (reg:CC 17))])]
4378   "TARGET_HIMODE_MATH"
4379   "")
4380
4381 (define_insn "*mulhi3_1"
4382   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
4383         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
4384                  (match_operand:HI 2 "general_operand" "K,i,mr")))
4385    (clobber (reg:CC 17))]
4386   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
4387   ; %%% There was a note about "Assembler has weird restrictions",
4388   ; concerning alternative 1 when op1 == op0.  True?
4389   "@
4390    imul{w}\\t{%2, %1, %0|%0, %1, %2}
4391    imul{w}\\t{%2, %1, %0|%0, %1, %2}
4392    imul{w}\\t{%2, %0|%0, %2}"
4393   [(set_attr "type" "imul")
4394    (set_attr "prefix_0f" "0,0,1")
4395    (set_attr "mode" "HI")])
4396
4397 (define_insn "mulqi3"
4398   [(set (match_operand:QI 0 "register_operand" "=a")
4399         (mult:QI (match_operand:QI 1 "register_operand" "%0")
4400                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
4401    (clobber (reg:CC 17))]
4402   "TARGET_QIMODE_MATH"
4403   "mul{b}\\t%2"
4404   [(set_attr "type" "imul")
4405    (set_attr "length_immediate" "0")
4406    (set_attr "mode" "QI")])
4407
4408 (define_insn "umulqihi3"
4409   [(set (match_operand:HI 0 "register_operand" "=a")
4410         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4411                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
4412    (clobber (reg:CC 17))]
4413   "TARGET_QIMODE_MATH"
4414   "mul{b}\\t%2"
4415   [(set_attr "type" "imul")
4416    (set_attr "length_immediate" "0")
4417    (set_attr "mode" "QI")])
4418
4419 (define_insn "mulqihi3"
4420   [(set (match_operand:HI 0 "register_operand" "=a")
4421         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4422                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
4423    (clobber (reg:CC 17))]
4424   "TARGET_QIMODE_MATH"
4425   "imul{b}\\t%2"
4426   [(set_attr "type" "imul")
4427    (set_attr "length_immediate" "0")
4428    (set_attr "mode" "QI")])
4429
4430 (define_insn "umulsidi3"
4431   [(set (match_operand:DI 0 "register_operand" "=A")
4432         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4433                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
4434    (clobber (reg:CC 17))]
4435   ""
4436   "mul{l}\\t%2"
4437   [(set_attr "type" "imul")
4438    (set_attr "ppro_uops" "few")
4439    (set_attr "length_immediate" "0")
4440    (set_attr "mode" "SI")])
4441
4442 (define_insn "mulsidi3"
4443   [(set (match_operand:DI 0 "register_operand" "=A")
4444         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4445                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
4446    (clobber (reg:CC 17))]
4447   ""
4448   "imul{l}\\t%2"
4449   [(set_attr "type" "imul")
4450    (set_attr "length_immediate" "0")
4451    (set_attr "mode" "SI")])
4452
4453 (define_insn "umulsi3_highpart"
4454   [(set (match_operand:SI 0 "register_operand" "=d")
4455         (truncate:SI
4456           (lshiftrt:DI
4457             (mult:DI (zero_extend:DI
4458                        (match_operand:SI 1 "register_operand" "%a"))
4459                      (zero_extend:DI
4460                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
4461             (const_int 32))))
4462    (clobber (match_scratch:SI 3 "=a"))
4463    (clobber (reg:CC 17))]
4464   ""
4465   "mul{l}\\t%2"
4466   [(set_attr "type" "imul")
4467    (set_attr "ppro_uops" "few")
4468    (set_attr "length_immediate" "0")
4469    (set_attr "mode" "SI")])
4470
4471 (define_insn "smulsi3_highpart"
4472   [(set (match_operand:SI 0 "register_operand" "=d")
4473         (truncate:SI
4474           (lshiftrt:DI
4475             (mult:DI (sign_extend:DI
4476                        (match_operand:SI 1 "register_operand" "%a"))
4477                      (sign_extend:DI
4478                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
4479             (const_int 32))))
4480    (clobber (match_scratch:SI 3 "=a"))
4481    (clobber (reg:CC 17))]
4482   ""
4483   "imul{l}\\t%2"
4484   [(set_attr "type" "imul")
4485    (set_attr "ppro_uops" "few")
4486    (set_attr "mode" "SI")])
4487
4488 ;; The patterns that match these are at the end of this file.
4489
4490 (define_expand "mulxf3"
4491   [(set (match_operand:XF 0 "register_operand" "")
4492         (mult:XF (match_operand:XF 1 "register_operand" "")
4493                  (match_operand:XF 2 "register_operand" "")))]
4494   "TARGET_80387"
4495   "")
4496
4497 (define_expand "muldf3"
4498   [(set (match_operand:DF 0 "register_operand" "")
4499         (mult:DF (match_operand:DF 1 "register_operand" "")
4500                  (match_operand:DF 2 "nonimmediate_operand" "")))]
4501   "TARGET_80387"
4502   "")
4503
4504 (define_expand "mulsf3"
4505   [(set (match_operand:SF 0 "register_operand" "")
4506         (mult:SF (match_operand:SF 1 "register_operand" "")
4507                  (match_operand:SF 2 "nonimmediate_operand" "")))]
4508   "TARGET_80387"
4509   "")
4510 \f
4511 ;; Divide instructions
4512
4513 (define_insn "divqi3"
4514   [(set (match_operand:QI 0 "register_operand" "=a")
4515         (div:QI (match_operand:HI 1 "register_operand" "0")
4516                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
4517    (clobber (reg:CC 17))]
4518   "TARGET_QIMODE_MATH"
4519   "idiv{b}\\t%2"
4520   [(set_attr "type" "idiv")
4521    (set_attr "mode" "QI")
4522    (set_attr "ppro_uops" "few")])
4523
4524 (define_insn "udivqi3"
4525   [(set (match_operand:QI 0 "register_operand" "=a")
4526         (udiv:QI (match_operand:HI 1 "register_operand" "0")
4527                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
4528    (clobber (reg:CC 17))]
4529   "TARGET_QIMODE_MATH"
4530   "div{b}\\t%2"
4531   [(set_attr "type" "idiv")
4532    (set_attr "mode" "QI")
4533    (set_attr "ppro_uops" "few")])
4534
4535 ;; The patterns that match these are at the end of this file.
4536
4537 (define_expand "divxf3"
4538   [(set (match_operand:XF 0 "register_operand" "")
4539         (div:XF (match_operand:XF 1 "register_operand" "")
4540                 (match_operand:XF 2 "register_operand" "")))]
4541   "TARGET_80387"
4542   "")
4543
4544 (define_expand "divdf3"
4545   [(set (match_operand:DF 0 "register_operand" "")
4546         (div:DF (match_operand:DF 1 "register_operand" "")
4547                 (match_operand:DF 2 "nonimmediate_operand" "")))]
4548    "TARGET_80387"
4549    "")
4550  
4551 (define_expand "divsf3"
4552   [(set (match_operand:SF 0 "register_operand" "")
4553         (div:SF (match_operand:SF 1 "register_operand" "")
4554                 (match_operand:SF 2 "nonimmediate_operand" "")))]
4555   "TARGET_80387"
4556   "")
4557 \f
4558 ;; Remainder instructions.
4559 (define_expand "divmodsi4"
4560   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4561                    (div:SI (match_operand:SI 1 "register_operand" "")
4562                            (match_operand:SI 2 "nonimmediate_operand" "")))
4563               (set (match_operand:SI 3 "register_operand" "")
4564                    (mod:SI (match_dup 1) (match_dup 2)))
4565               (clobber (reg:CC 17))])]
4566   ""
4567   "")
4568
4569 ;; Allow to come the parameter in eax or edx to avoid extra moves.
4570 ;; Penalize eax case sligthly because it results in worse scheduling
4571 ;; of code.
4572 (define_insn "*divmodsi4_nocltd"
4573   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
4574         (div:SI (match_operand:SI 2 "register_operand" "1,0")
4575                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
4576    (set (match_operand:SI 1 "register_operand" "=&d,&d")
4577         (mod:SI (match_dup 2) (match_dup 3)))
4578    (clobber (reg:CC 17))]
4579   "!optimize_size && !TARGET_USE_CLTD"
4580   "#"
4581   [(set_attr "type" "multi")])
4582
4583 (define_insn "*divmodsi4_cltd"
4584   [(set (match_operand:SI 0 "register_operand" "=a")
4585         (div:SI (match_operand:SI 2 "register_operand" "a")
4586                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
4587    (set (match_operand:SI 1 "register_operand" "=&d")
4588         (mod:SI (match_dup 2) (match_dup 3)))
4589    (clobber (reg:CC 17))]
4590   "optimize_size || TARGET_USE_CLTD"
4591   "#"
4592   [(set_attr "type" "multi")])
4593
4594 (define_insn "*divmodsi_noext"
4595   [(set (match_operand:SI 0 "register_operand" "=a")
4596         (div:SI (match_operand:SI 1 "register_operand" "0")
4597                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4598    (set (match_operand:SI 3 "register_operand" "=d")
4599         (mod:SI (match_dup 1) (match_dup 2)))
4600    (use (match_operand:SI 4 "register_operand" "3"))
4601    (clobber (reg:CC 17))]
4602   ""
4603   "idiv{l}\\t%2"
4604   [(set_attr "type" "idiv")
4605    (set_attr "mode" "SI")
4606    (set_attr "ppro_uops" "few")])
4607
4608 (define_split
4609   [(set (match_operand:SI 0 "register_operand" "")
4610         (div:SI (match_operand:SI 1 "register_operand" "")
4611                 (match_operand:SI 2 "nonimmediate_operand" "")))
4612    (set (match_operand:SI 3 "register_operand" "")
4613         (mod:SI (match_dup 1) (match_dup 2)))
4614    (clobber (reg:CC 17))]
4615   "reload_completed"
4616   [(parallel [(set (match_dup 3)
4617                    (ashiftrt:SI (match_dup 4) (const_int 31)))
4618               (clobber (reg:CC 17))])
4619    (parallel [(set (match_dup 0)
4620                    (div:SI (reg:SI 0) (match_dup 2)))
4621               (set (match_dup 3)
4622                    (mod:SI (reg:SI 0) (match_dup 2)))
4623               (use (match_dup 3))
4624               (clobber (reg:CC 17))])]
4625   "
4626 {
4627   /* Avoid use of cltd in favour of a mov+shift.  */
4628   if (!TARGET_USE_CLTD && !optimize_size)
4629     {
4630       if (true_regnum (operands[1]))
4631         emit_move_insn (operands[0], operands[1]);
4632       else
4633         emit_move_insn (operands[3], operands[1]);
4634       operands[4] = operands[3];
4635     }
4636   else
4637     {
4638       if (true_regnum (operands[1]))
4639         abort();
4640       operands[4] = operands[1];
4641     }
4642 }")
4643 ;; %%% Split me.
4644 (define_insn "divmodhi4"
4645   [(set (match_operand:HI 0 "register_operand" "=a")
4646         (div:HI (match_operand:HI 1 "register_operand" "0")
4647                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4648    (set (match_operand:HI 3 "register_operand" "=&d")
4649         (mod:HI (match_dup 1) (match_dup 2)))
4650    (clobber (reg:CC 17))]
4651   "TARGET_HIMODE_MATH"
4652   "cwtd\;idiv{w}\\t%2"
4653   [(set_attr "type" "multi")
4654    (set_attr "length_immediate" "0")
4655    (set_attr "mode" "SI")])
4656
4657 (define_insn "udivmodsi4"
4658   [(set (match_operand:SI 0 "register_operand" "=a")
4659         (udiv:SI (match_operand:SI 1 "register_operand" "0")
4660                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
4661    (set (match_operand:SI 3 "register_operand" "=&d")
4662         (umod:SI (match_dup 1) (match_dup 2)))
4663    (clobber (reg:CC 17))]
4664   ""
4665   "xor{l}\\t%3, %3\;div{l}\\t%2"
4666   [(set_attr "type" "multi")
4667    (set_attr "length_immediate" "0")
4668    (set_attr "mode" "SI")])
4669
4670 (define_insn "*udivmodsi4_noext"
4671   [(set (match_operand:SI 0 "register_operand" "=a")
4672         (udiv:SI (match_operand:SI 1 "register_operand" "0")
4673                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
4674    (set (match_operand:SI 3 "register_operand" "=d")
4675         (umod:SI (match_dup 1) (match_dup 2)))
4676    (use (match_dup 3))
4677    (clobber (reg:CC 17))]
4678   ""
4679   "div{l}\\t%2"
4680   [(set_attr "type" "idiv")
4681    (set_attr "ppro_uops" "few")
4682    (set_attr "mode" "SI")])
4683
4684 (define_split
4685   [(set (match_operand:SI 0 "register_operand" "")
4686         (udiv:SI (match_operand:SI 1 "register_operand" "")
4687                  (match_operand:SI 2 "nonimmediate_operand" "")))
4688    (set (match_operand:SI 3 "register_operand" "")
4689         (umod:SI (match_dup 1) (match_dup 2)))
4690    (clobber (reg:CC 17))]
4691   "reload_completed"
4692   [(set (match_dup 3) (const_int 0))
4693    (parallel [(set (match_dup 0)
4694                    (udiv:SI (match_dup 1) (match_dup 2)))
4695               (set (match_dup 3)
4696                    (umod:SI (match_dup 1) (match_dup 2)))
4697               (use (match_dup 3))
4698               (clobber (reg:CC 17))])]
4699   "")
4700
4701 (define_expand "udivmodhi4"
4702   [(set (match_dup 4) (const_int 0))
4703    (parallel [(set (match_operand:HI 0 "register_operand" "")
4704                    (udiv:HI (match_operand:HI 1 "register_operand" "")
4705                             (match_operand:HI 2 "nonimmediate_operand" "")))
4706               (set (match_operand:HI 3 "register_operand" "")
4707                    (umod:HI (match_dup 1) (match_dup 2)))
4708               (use (match_dup 4))
4709               (clobber (reg:CC 17))])]
4710   "TARGET_HIMODE_MATH"
4711   "operands[4] = gen_reg_rtx (HImode);")
4712
4713 (define_insn "*udivmodhi_noext"
4714   [(set (match_operand:HI 0 "register_operand" "=a")
4715         (udiv:HI (match_operand:HI 1 "register_operand" "0")
4716                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
4717    (set (match_operand:HI 3 "register_operand" "=d")
4718         (umod:HI (match_dup 1) (match_dup 2)))
4719    (use (match_operand:HI 4 "register_operand" "3"))
4720    (clobber (reg:CC 17))]
4721   ""
4722   "div{w}\\t%2"
4723   [(set_attr "type" "idiv")
4724    (set_attr "mode" "HI")
4725    (set_attr "ppro_uops" "few")])
4726
4727 ;; We can not use div/idiv for double division, because it causes
4728 ;; "division by zero" on the overflow and that's not what we expect
4729 ;; from truncate.  Because true (non truncating) double division is
4730 ;; never generated, we can't create this insn anyway.
4731 ;
4732 ;(define_insn ""
4733 ;  [(set (match_operand:SI 0 "register_operand" "=a")
4734 ;       (truncate:SI
4735 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
4736 ;                  (zero_extend:DI
4737 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
4738 ;   (set (match_operand:SI 3 "register_operand" "=d")
4739 ;       (truncate:SI
4740 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
4741 ;   (clobber (reg:CC 17))]
4742 ;  ""
4743 ;  "div{l}\\t{%2, %0|%0, %2}"
4744 ;  [(set_attr "type" "idiv")
4745 ;   (set_attr "ppro_uops" "few")])
4746 \f
4747 ;;- Logical AND instructions
4748
4749 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
4750 ;; Note that this excludes ah.
4751
4752 (define_insn "*testsi_ccz_1"
4753   [(set (reg:CCZ 17)
4754         (compare:CCZ
4755           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
4756                   (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
4757           (const_int 0)))]
4758   ""
4759   "test{l}\\t{%1, %0|%0, %1}"
4760   [(set_attr "type" "test")
4761    (set_attr "modrm" "0,1,1")
4762    (set_attr "mode" "SI")
4763    (set_attr "pent_pair" "uv,np,uv")])
4764
4765 (define_insn "testsi_ccno_1"
4766   [(set (reg:CCNO 17)
4767         (compare:CCNO
4768           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
4769                   (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
4770           (const_int 0)))]
4771   ""
4772   "test{l}\\t{%1, %0|%0, %1}"
4773   [(set_attr "type" "test")
4774    (set_attr "modrm" "0,1,1")
4775    (set_attr "mode" "SI")
4776    (set_attr "pent_pair" "uv,np,uv")])
4777
4778 (define_insn "*testhi_1"
4779   [(set (reg 17)
4780         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
4781                          (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
4782                  (const_int 0)))]
4783   "ix86_match_ccmode (insn, CCNOmode)"
4784   "test{w}\\t{%1, %0|%0, %1}"
4785   [(set_attr "type" "test")
4786    (set_attr "modrm" "0,1,1")
4787    (set_attr "mode" "HI")
4788    (set_attr "pent_pair" "uv,np,uv")])
4789
4790 (define_insn "testqi_ccz_1"
4791   [(set (reg:CCZ 17)
4792         (compare:CCZ
4793           (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
4794                   (match_operand:QI 1 "nonmemory_operand" "n,n,qn"))
4795           (const_int 0)))]
4796   ""
4797   "test{b}\\t{%1, %0|%0, %1}"
4798   [(set_attr "type" "test")
4799    (set_attr "modrm" "0,1,1")
4800    (set_attr "mode" "QI")
4801    (set_attr "pent_pair" "uv,np,uv")])
4802
4803 (define_insn "testqi_ccno_1"
4804   [(set (reg:CCNO 17)
4805         (compare:CCNO (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
4806                               (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
4807                       (const_int 0)))]
4808   ""
4809   "@
4810    test{b}\\t{%1, %0|%0, %1} 
4811    test{b}\\t{%1, %0|%0, %1} 
4812    test{b}\\t{%1, %0|%0, %1} 
4813    test{l}\\t{%1, %0|%0, %1}"
4814   [(set_attr "type" "test")
4815    (set_attr "modrm" "0,1,1,1")
4816    (set_attr "mode" "QI,QI,QI,SI")
4817    (set_attr "pent_pair" "uv,np,uv,np")])
4818
4819 (define_insn "*testqi_ext_ccz_0"
4820   [(set (reg:CCZ 17)
4821         (compare:CCZ
4822           (and:SI
4823             (zero_extract:SI
4824               (match_operand 0 "ext_register_operand" "q")
4825               (const_int 8)
4826               (const_int 8))
4827             (match_operand 1 "const_int_operand" "n"))
4828           (const_int 0)))]
4829   "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff"
4830   "test{b}\\t{%1, %h0|%h0, %1}"
4831   [(set_attr "type" "test")
4832    (set_attr "mode" "QI")
4833    (set_attr "length_immediate" "1")
4834    (set_attr "pent_pair" "np")])
4835
4836 (define_insn "testqi_ext_ccno_0"
4837   [(set (reg:CCNO 17)
4838         (compare:CCNO
4839           (and:SI
4840             (zero_extract:SI
4841               (match_operand 0 "ext_register_operand" "q")
4842               (const_int 8)
4843               (const_int 8))
4844             (match_operand 1 "const_int_operand" "n"))
4845           (const_int 0)))]
4846   "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff"
4847   "test{b}\\t{%1, %h0|%h0, %1}"
4848   [(set_attr "type" "test")
4849    (set_attr "mode" "QI")
4850    (set_attr "length_immediate" "1")
4851    (set_attr "pent_pair" "np")])
4852
4853 (define_insn "*testqi_ext_1"
4854   [(set (reg 17)
4855         (compare
4856           (and:SI
4857             (zero_extract:SI
4858               (match_operand 0 "ext_register_operand" "q")
4859               (const_int 8)
4860               (const_int 8))
4861             (zero_extend:SI
4862               (match_operand:QI 1 "nonimmediate_operand" "qm")))
4863           (const_int 0)))]
4864   "ix86_match_ccmode (insn, CCNOmode)"
4865   "test{b}\\t{%1, %h0|%h0, %1}"
4866   [(set_attr "type" "test")
4867    (set_attr "mode" "QI")])
4868
4869 (define_insn "*testqi_ext_2"
4870   [(set (reg 17)
4871         (compare
4872           (and:SI
4873             (zero_extract:SI
4874               (match_operand 0 "ext_register_operand" "q")
4875               (const_int 8)
4876               (const_int 8))
4877             (zero_extract:SI
4878               (match_operand 1 "ext_register_operand" "q")
4879               (const_int 8)
4880               (const_int 8)))
4881           (const_int 0)))]
4882   "ix86_match_ccmode (insn, CCNOmode)"
4883   "test{b}\\t{%h1, %h0|%h0, %h1}"
4884   [(set_attr "type" "test")
4885    (set_attr "mode" "QI")])
4886
4887 ;; Combine likes to form bit extractions for some tests.  Humor it.
4888 (define_insn "*testqi_ext_3"
4889   [(set (reg 17)
4890         (compare (zero_extract:SI
4891                    (match_operand 0 "nonimmediate_operand" "rm")
4892                    (match_operand:SI 1 "const_int_operand" "")
4893                    (match_operand:SI 2 "const_int_operand" ""))
4894                  (const_int 0)))]
4895   "ix86_match_ccmode (insn, CCNOmode)
4896    && (GET_MODE (operands[0]) == SImode
4897        || GET_MODE (operands[0]) == HImode
4898        || GET_MODE (operands[0]) == QImode)"
4899   "#")
4900
4901 (define_split
4902   [(set (reg 17)
4903         (compare (zero_extract:SI
4904                    (match_operand 0 "nonimmediate_operand" "rm")
4905                    (match_operand:SI 1 "const_int_operand" "")
4906                    (match_operand:SI 2 "const_int_operand" ""))
4907                  (const_int 0)))]
4908   "ix86_match_ccmode (insn, CCNOmode)"
4909   [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
4910   "
4911 {
4912   HOST_WIDE_INT len = INTVAL (operands[1]);
4913   HOST_WIDE_INT pos = INTVAL (operands[2]);
4914   HOST_WIDE_INT mask;
4915   enum machine_mode mode;
4916
4917   mode = GET_MODE (operands[0]);
4918   if (GET_CODE (operands[0]) == MEM)
4919     {
4920       /* ??? Combine likes to put non-volatile mem extractions in QImode
4921          no matter the size of the test.  So find a mode that works.  */
4922       if (! MEM_VOLATILE_P (operands[0]))
4923         {
4924           mode = smallest_mode_for_size (pos + len, MODE_INT);
4925           operands[0] = change_address (operands[0], mode, NULL_RTX);
4926         }
4927     }
4928   else if (mode == HImode && pos + len <= 8)
4929     {
4930       /* Small HImode tests can be converted to QImode.  */
4931       mode = QImode;
4932       operands[0] = gen_lowpart (QImode, operands[0]);
4933     }
4934
4935   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
4936   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
4937
4938   operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
4939 }")
4940
4941 ;; %%% This used to optimize known byte-wide and operations to memory,
4942 ;; and sometimes to QImode registers.  If this is considered useful,
4943 ;; it should be done with splitters.
4944
4945 (define_expand "andsi3"
4946   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4947         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
4948                 (match_operand:SI 2 "general_operand" "")))
4949    (clobber (reg:CC 17))]
4950   ""
4951   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
4952
4953 (define_insn "*andsi_1"
4954   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
4955         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
4956                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
4957    (clobber (reg:CC 17))]
4958   "ix86_binary_operator_ok (AND, SImode, operands)"
4959   "*
4960 {
4961   switch (get_attr_type (insn))
4962     {
4963     case TYPE_IMOVX:
4964       {
4965         enum machine_mode mode;
4966
4967         if (GET_CODE (operands[2]) != CONST_INT)
4968           abort ();
4969         if (INTVAL (operands[2]) == 0xff)
4970           mode = QImode;
4971         else if (INTVAL (operands[2]) == 0xffff)
4972           mode = HImode;
4973         else
4974           abort ();
4975         
4976         operands[1] = gen_lowpart (mode, operands[1]);
4977         if (mode == QImode)
4978           return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
4979         else
4980           return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
4981       }
4982
4983     default:
4984       if (! rtx_equal_p (operands[0], operands[1]))
4985         abort ();
4986       return \"and{l}\\t{%2, %0|%0, %2}\";
4987     }
4988 }"
4989   [(set_attr "type" "alu,alu,imovx")
4990    (set_attr "length_immediate" "*,*,0")
4991    (set_attr "mode" "SI")])
4992
4993 (define_split
4994   [(set (match_operand:SI 0 "register_operand" "")
4995         (and:SI (match_dup 0)
4996                 (const_int -65536)))
4997    (clobber (reg:CC 17))]
4998   "optimize_size"
4999   [(set (strict_low_part (match_dup 1)) (const_int 0))]
5000   "operands[1] = gen_lowpart (HImode, operands[0]);")
5001
5002 (define_split
5003   [(set (match_operand:SI 0 "q_regs_operand" "")
5004         (and:SI (match_dup 0)
5005                 (const_int -256)))
5006    (clobber (reg:CC 17))]
5007   "(optimize_size || !TARGET_PARTIAL_REG_STALL)
5008    && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
5009   [(set (strict_low_part (match_dup 1)) (const_int 0))]
5010   "operands[1] = gen_lowpart (QImode, operands[0]);")
5011
5012 (define_split
5013   [(set (match_operand 0 "register_operand" "")
5014         (and (match_dup 0)
5015              (const_int -65281)))
5016    (clobber (reg:CC 17))]
5017   "(optimize_size || !TARGET_PARTIAL_REG_STALL)
5018    && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
5019   [(parallel [(set (zero_extract:SI (match_dup 0)
5020                                     (const_int 8)
5021                                     (const_int 8))
5022                    (xor:SI 
5023                      (zero_extract:SI (match_dup 0)
5024                                       (const_int 8)
5025                                       (const_int 8))
5026                      (zero_extract:SI (match_dup 0)
5027                                       (const_int 8)
5028                                       (const_int 8))))
5029               (clobber (reg:CC 17))])]
5030   "operands[0] = gen_lowpart (SImode, operands[0]);")
5031
5032 (define_insn "*andsi_2"
5033   [(set (reg 17)
5034         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5035                          (match_operand:SI 2 "general_operand" "rim,ri"))
5036                  (const_int 0)))
5037    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5038         (and:SI (match_dup 1) (match_dup 2)))]
5039   "ix86_match_ccmode (insn, CCNOmode)
5040    && ix86_binary_operator_ok (AND, SImode, operands)"
5041   "and{l}\\t{%2, %0|%0, %2}"
5042   [(set_attr "type" "alu")
5043    (set_attr "mode" "SI")])
5044
5045 (define_expand "andhi3"
5046   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5047         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
5048                 (match_operand:HI 2 "general_operand" "")))
5049    (clobber (reg:CC 17))]
5050   "TARGET_HIMODE_MATH"
5051   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
5052
5053 (define_insn "*andhi_1"
5054   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5055         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
5056                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
5057    (clobber (reg:CC 17))]
5058   "ix86_binary_operator_ok (AND, HImode, operands)"
5059   "*
5060 {
5061   switch (get_attr_type (insn))
5062     {
5063     case TYPE_IMOVX:
5064       if (GET_CODE (operands[2]) != CONST_INT)
5065         abort ();
5066       if (INTVAL (operands[2]) == 0xff)
5067         return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
5068       abort ();
5069
5070     default:
5071       if (! rtx_equal_p (operands[0], operands[1]))
5072         abort ();
5073
5074       return \"and{w}\\t{%2, %0|%0, %2}\";
5075     }
5076 }"
5077   [(set_attr "type" "alu,alu,imovx")
5078    (set_attr "length_immediate" "*,*,0")
5079    (set_attr "mode" "HI,HI,SI")])
5080
5081 (define_insn "*andhi_2"
5082   [(set (reg 17)
5083         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5084                          (match_operand:HI 2 "general_operand" "rim,ri"))
5085                  (const_int 0)))
5086    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5087         (and:HI (match_dup 1) (match_dup 2)))]
5088   "ix86_match_ccmode (insn, CCNOmode)
5089    && ix86_binary_operator_ok (AND, HImode, operands)"
5090   "and{w}\\t{%2, %0|%0, %2}"
5091   [(set_attr "type" "alu")
5092    (set_attr "mode" "HI")])
5093
5094 (define_expand "andqi3"
5095   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5096         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
5097                 (match_operand:QI 2 "general_operand" "")))
5098    (clobber (reg:CC 17))]
5099   "TARGET_QIMODE_MATH"
5100   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
5101
5102 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5103 (define_insn "*andqi_1"
5104   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5105         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5106                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
5107    (clobber (reg:CC 17))]
5108   "ix86_binary_operator_ok (AND, QImode, operands)"
5109   "@
5110    and{b}\\t{%2, %0|%0, %2}
5111    and{b}\\t{%2, %0|%0, %2}
5112    and{l}\\t{%k2, %k0|%k0, %k2}"
5113   [(set_attr "type" "alu")
5114    (set_attr "mode" "QI,QI,SI")])
5115
5116 (define_insn "*andqi_2"
5117   [(set (reg 17)
5118         (compare (and:QI
5119                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5120                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
5121                  (const_int 0)))
5122    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
5123         (and:QI (match_dup 1) (match_dup 2)))]
5124   "ix86_match_ccmode (insn, CCNOmode)
5125    && ix86_binary_operator_ok (AND, QImode, operands)"
5126   "@
5127    and{b}\\t{%2, %0|%0, %2}
5128    and{b}\\t{%2, %0|%0, %2}
5129    and{l}\\t{%2, %k0|%k0, %2}"
5130   [(set_attr "type" "alu")
5131    (set_attr "mode" "QI,QI,SI")])
5132
5133 ;; ??? A bug in recog prevents it from recognizing a const_int as an
5134 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
5135 ;; for a QImode operand, which of course failed.
5136
5137 (define_insn "andqi_ext_0"
5138   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5139                          (const_int 8)
5140                          (const_int 8))
5141         (and:SI 
5142           (zero_extract:SI
5143             (match_operand 1 "ext_register_operand" "0")
5144             (const_int 8)
5145             (const_int 8))
5146           (match_operand 2 "const_int_operand" "n")))
5147    (clobber (reg:CC 17))]
5148   "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
5149   "and{b}\\t{%2, %h0|%h0, %2}"
5150   [(set_attr "type" "alu")
5151    (set_attr "length_immediate" "1")
5152    (set_attr "mode" "QI")])
5153
5154 ;; Generated by peephole translating test to and.  This shows up
5155 ;; often in fp comparisons.
5156
5157 (define_insn "*andqi_ext_0_cc"
5158   [(set (reg 17)
5159         (compare
5160           (and:SI
5161             (zero_extract:SI
5162               (match_operand 1 "ext_register_operand" "q")
5163                 (const_int 8)
5164               (const_int 8))
5165             (match_operand 2 "const_int_operand" "n"))
5166           (const_int 0)))
5167    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5168                          (const_int 8)
5169                          (const_int 8))
5170         (and:SI 
5171           (zero_extract:SI
5172             (match_dup 1)
5173             (const_int 8)
5174             (const_int 8))
5175           (match_dup 2)))]
5176   "ix86_match_ccmode (insn, CCNOmode)
5177    && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
5178   "and{b}\\t{%2, %h0|%h0, %2}"
5179   [(set_attr "type" "alu")
5180    (set_attr "length_immediate" "1")
5181    (set_attr "mode" "QI")])
5182
5183 (define_insn "*andqi_ext_1"
5184   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5185                          (const_int 8)
5186                          (const_int 8))
5187         (and:SI 
5188           (zero_extract:SI
5189             (match_operand 1 "ext_register_operand" "0")
5190             (const_int 8)
5191             (const_int 8))
5192           (zero_extend:SI
5193             (match_operand:QI 2 "general_operand" "qm"))))
5194    (clobber (reg:CC 17))]
5195   ""
5196   "and{b}\\t{%2, %h0|%h0, %2}"
5197   [(set_attr "type" "alu")
5198    (set_attr "length_immediate" "0")
5199    (set_attr "mode" "QI")])
5200
5201 (define_insn "*andqi_ext_2"
5202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5203                          (const_int 8)
5204                          (const_int 8))
5205         (and:SI
5206           (zero_extract:SI
5207             (match_operand 1 "ext_register_operand" "%0")
5208             (const_int 8)
5209             (const_int 8))
5210           (zero_extract:SI
5211             (match_operand 2 "ext_register_operand" "q")
5212             (const_int 8)
5213             (const_int 8))))
5214    (clobber (reg:CC 17))]
5215   ""
5216   "and{b}\\t{%h2, %h0|%h0, %h2}"
5217   [(set_attr "type" "alu")
5218    (set_attr "length_immediate" "0")
5219    (set_attr "mode" "QI")])
5220 \f
5221 ;; Logical inclusive OR instructions
5222
5223 ;; %%% This used to optimize known byte-wide and operations to memory.
5224 ;; If this is considered useful, it should be done with splitters.
5225
5226 (define_expand "iorsi3"
5227   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5228         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
5229                 (match_operand:SI 2 "general_operand" "")))
5230    (clobber (reg:CC 17))]
5231   ""
5232   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
5233
5234 (define_insn "*iorsi_1"
5235   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5236         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5237                 (match_operand:SI 2 "general_operand" "ri,rmi")))
5238    (clobber (reg:CC 17))]
5239   "ix86_binary_operator_ok (IOR, SImode, operands)"
5240   "or{l}\\t{%2, %0|%0, %2}"
5241   [(set_attr "type" "alu")
5242    (set_attr "mode" "SI")])
5243
5244 (define_insn "*iorsi_2"
5245   [(set (reg 17)
5246         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5247                          (match_operand:SI 2 "general_operand" "rim,ri"))
5248                  (const_int 0)))
5249    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5250         (ior:SI (match_dup 1) (match_dup 2)))]
5251   "ix86_match_ccmode (insn, CCNOmode)
5252    && ix86_binary_operator_ok (IOR, SImode, operands)"
5253   "or{l}\\t{%2, %0|%0, %2}"
5254   [(set_attr "type" "alu")
5255    (set_attr "mode" "SI")])
5256
5257 (define_expand "iorhi3"
5258   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5259         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
5260                 (match_operand:HI 2 "general_operand" "")))
5261    (clobber (reg:CC 17))]
5262   "TARGET_HIMODE_MATH"
5263   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
5264
5265 (define_insn "*iorhi_1"
5266   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
5267         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5268                 (match_operand:HI 2 "general_operand" "rmi,ri")))
5269    (clobber (reg:CC 17))]
5270   "ix86_binary_operator_ok (IOR, HImode, operands)"
5271   "or{w}\\t{%2, %0|%0, %2}"
5272   [(set_attr "type" "alu")
5273    (set_attr "mode" "HI")])
5274
5275 (define_insn "*iorhi_2"
5276   [(set (reg 17)
5277         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5278                          (match_operand:HI 2 "general_operand" "rim,ri"))
5279                  (const_int 0)))
5280    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5281         (ior:HI (match_dup 1) (match_dup 2)))]
5282   "ix86_match_ccmode (insn, CCNOmode)
5283    && ix86_binary_operator_ok (IOR, HImode, operands)"
5284   "or{w}\\t{%2, %0|%0, %2}"
5285   [(set_attr "type" "alu")
5286    (set_attr "mode" "HI")])
5287
5288 (define_expand "iorqi3"
5289   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5290         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
5291                 (match_operand:QI 2 "general_operand" "")))
5292    (clobber (reg:CC 17))]
5293   "TARGET_QIMODE_MATH"
5294   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
5295
5296 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5297 (define_insn "*iorqi_1"
5298   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
5299         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5300                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
5301    (clobber (reg:CC 17))]
5302   "ix86_binary_operator_ok (IOR, QImode, operands)"
5303   "@
5304    or{b}\\t{%2, %0|%0, %2}
5305    or{b}\\t{%2, %0|%0, %2}
5306    or{l}\\t{%k2, %k0|%k0, %k2}"
5307   [(set_attr "type" "alu")
5308    (set_attr "mode" "QI")])
5309
5310 (define_insn "*iorqi_2"
5311   [(set (reg 17)
5312         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5313                          (match_operand:QI 2 "general_operand" "qim,qi"))
5314                  (const_int 0)))
5315    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5316         (ior:QI (match_dup 1) (match_dup 2)))]
5317   "ix86_match_ccmode (insn, CCNOmode)
5318    && ix86_binary_operator_ok (IOR, QImode, operands)"
5319   "or{b}\\t{%2, %0|%0, %2}"
5320   [(set_attr "type" "alu")
5321    (set_attr "mode" "QI")])
5322 \f
5323 ;; Logical XOR instructions
5324
5325 ;; %%% This used to optimize known byte-wide and operations to memory.
5326 ;; If this is considered useful, it should be done with splitters.
5327
5328 (define_expand "xorsi3"
5329   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5330         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
5331                 (match_operand:SI 2 "general_operand" "")))
5332    (clobber (reg:CC 17))]
5333   ""
5334   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
5335
5336 (define_insn "*xorsi_1"
5337   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5338         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5339                 (match_operand:SI 2 "general_operand" "ri,rm")))
5340    (clobber (reg:CC 17))]
5341   "ix86_binary_operator_ok (XOR, SImode, operands)"
5342   "xor{l}\\t{%2, %0|%0, %2}"
5343   [(set_attr "type" "alu")
5344    (set_attr "mode" "SI")])
5345
5346 (define_insn "*xorsi_2"
5347   [(set (reg 17)
5348         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5349                          (match_operand:SI 2 "general_operand" "rim,ri"))
5350                  (const_int 0)))
5351    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5352         (xor:SI (match_dup 1) (match_dup 2)))]
5353   "ix86_match_ccmode (insn, CCNOmode)
5354    && ix86_binary_operator_ok (XOR, SImode, operands)"
5355   "xor{l}\\t{%2, %0|%0, %2}"
5356   [(set_attr "type" "alu")
5357    (set_attr "mode" "SI")])
5358
5359 (define_expand "xorhi3"
5360   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5361         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
5362                 (match_operand:HI 2 "general_operand" "")))
5363    (clobber (reg:CC 17))]
5364   "TARGET_HIMODE_MATH"
5365   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
5366
5367 (define_insn "*xorhi_1"
5368   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
5369         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5370                 (match_operand:HI 2 "general_operand" "rmi,ri")))
5371    (clobber (reg:CC 17))]
5372   "ix86_binary_operator_ok (XOR, HImode, operands)"
5373   "xor{w}\\t{%2, %0|%0, %2}"
5374   [(set_attr "type" "alu")
5375    (set_attr "mode" "HI")])
5376
5377 (define_insn "*xorhi_2"
5378   [(set (reg 17)
5379         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5380                          (match_operand:HI 2 "general_operand" "rim,ri"))
5381                  (const_int 0)))
5382    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5383         (xor:HI (match_dup 1) (match_dup 2)))]
5384   "ix86_match_ccmode (insn, CCNOmode)
5385    && ix86_binary_operator_ok (XOR, HImode, operands)"
5386   "xor{w}\\t{%2, %0|%0, %2}"
5387   [(set_attr "type" "alu")
5388    (set_attr "mode" "HI")])
5389
5390 (define_expand "xorqi3"
5391   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5392         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
5393                 (match_operand:QI 2 "general_operand" "")))
5394    (clobber (reg:CC 17))]
5395   "TARGET_QIMODE_MATH"
5396   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
5397
5398 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5399 (define_insn "*xorqi_1"
5400   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
5401         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5402                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
5403    (clobber (reg:CC 17))]
5404   "ix86_binary_operator_ok (XOR, QImode, operands)"
5405   "@
5406    xor{b}\\t{%2, %0|%0, %2}
5407    xor{b}\\t{%2, %0|%0, %2}
5408    xor{l}\\t{%k2, %k0|%k0, %k2}"
5409   [(set_attr "type" "alu")
5410    (set_attr "mode" "QI,QI,SI")])
5411
5412 (define_insn "xorqi_ext_1"
5413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5414                          (const_int 8)
5415                          (const_int 8))
5416         (xor:SI 
5417           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
5418                            (const_int 8)
5419                            (const_int 8))
5420           (zero_extract:SI (match_operand 2 "ext_register_operand" "q")
5421                            (const_int 8)
5422                            (const_int 8))))
5423    (clobber (reg:CC 17))]
5424   ""
5425   "xor{b}\\t{%h2, %h0|%h0, %h2}"
5426   [(set_attr "type" "alu")
5427    (set_attr "length_immediate" "0")
5428    (set_attr "mode" "QI")])
5429
5430 (define_insn "*xorqi_cc_1"
5431   [(set (reg 17)
5432         (compare
5433           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5434                   (match_operand:QI 2 "general_operand" "qim,qi"))
5435           (const_int 0)))
5436    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5437         (xor:QI (match_dup 1) (match_dup 2)))]
5438   "ix86_match_ccmode (insn, CCNOmode)
5439    && ix86_binary_operator_ok (XOR, QImode, operands)"
5440   "xor{b}\\t{%2, %0|%0, %2}"
5441   [(set_attr "type" "alu")
5442    (set_attr "mode" "QI")])
5443
5444 (define_insn "xorqi_cc_ext_1"
5445   [(set (reg:CCNO 17)
5446         (compare:CCNO
5447           (xor:SI
5448             (zero_extract:SI
5449               (match_operand 1 "ext_register_operand" "0")
5450               (const_int 8)
5451               (const_int 8))
5452             (match_operand:QI 2 "general_operand" "qmn"))
5453           (const_int 0)))
5454    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5455                          (const_int 8)
5456                          (const_int 8))
5457         (xor:SI 
5458           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
5459           (match_dup 2)))]
5460   ""
5461   "xor{b}\\t{%2, %h0|%h0, %2}"
5462   [(set_attr "type" "alu")
5463    (set_attr "mode" "QI")])
5464 \f
5465 ;; Negation instructions
5466
5467 ;; %%% define_expand from the very first?
5468
5469 (define_expand "negdi2"
5470   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
5471                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
5472               (clobber (reg:CC 17))])]
5473   ""
5474   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
5475
5476 (define_insn "*negdi2_1"
5477   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
5478         (neg:DI (match_operand:DI 1 "general_operand" "0")))
5479    (clobber (reg:CC 17))]
5480   "ix86_unary_operator_ok (NEG, DImode, operands)"
5481   "#")
5482
5483 (define_split
5484   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5485         (neg:DI (match_operand:DI 1 "general_operand" "")))
5486    (clobber (reg:CC 17))]
5487   "reload_completed"
5488   [(parallel
5489     [(set (reg:CCZ 17)
5490           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
5491      (set (match_dup 0) (neg:SI (match_dup 2)))])
5492    (parallel
5493     [(set (match_dup 1)
5494           (plus:SI (match_dup 3)
5495             (plus:SI (const_int 0)
5496               (ltu:SI (reg:CC 17) (const_int 0)))))
5497      (clobber (reg:CC 17))])
5498    (parallel
5499     [(set (match_dup 1)
5500           (neg:SI (match_dup 1)))
5501      (clobber (reg:CC 17))])]
5502   "split_di (operands+1, 1, operands+2, operands+3);
5503    split_di (operands+0, 1, operands+0, operands+1);")
5504
5505 (define_expand "negsi2"
5506   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5507                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
5508               (clobber (reg:CC 17))])]
5509   ""
5510   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
5511
5512 (define_insn "*negsi2_1"
5513   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5514         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
5515    (clobber (reg:CC 17))]
5516   "ix86_unary_operator_ok (NEG, SImode, operands)"
5517   "neg{l}\\t%0"
5518   [(set_attr "type" "negnot")
5519    (set_attr "mode" "SI")])
5520
5521 ;; The problem with neg is that it does not perform (compare x 0),
5522 ;; it really performs (compare 0 x), which leaves us with the zero
5523 ;; flag being the only useful item.
5524
5525 (define_insn "*negsi2_cmpz"
5526   [(set (reg:CCZ 17)
5527         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
5528                      (const_int 0)))
5529    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5530         (neg:SI (match_dup 1)))]
5531   "ix86_unary_operator_ok (NEG, SImode, operands)"
5532   "neg{l}\\t%0"
5533   [(set_attr "type" "negnot")
5534    (set_attr "mode" "SI")])
5535
5536 (define_expand "neghi2"
5537   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5538                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
5539               (clobber (reg:CC 17))])]
5540   "TARGET_HIMODE_MATH"
5541   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
5542
5543 (define_insn "*neghi2_1"
5544   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5545         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
5546    (clobber (reg:CC 17))]
5547   "ix86_unary_operator_ok (NEG, HImode, operands)"
5548   "neg{w}\\t%0"
5549   [(set_attr "type" "negnot")
5550    (set_attr "mode" "HI")])
5551
5552 (define_insn "*neghi2_cmpz"
5553   [(set (reg:CCZ 17)
5554         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
5555                      (const_int 0)))
5556    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5557         (neg:HI (match_dup 1)))]
5558   "ix86_unary_operator_ok (NEG, HImode, operands)"
5559   "neg{w}\\t%0"
5560   [(set_attr "type" "negnot")
5561    (set_attr "mode" "HI")])
5562
5563 (define_expand "negqi2"
5564   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5565                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
5566               (clobber (reg:CC 17))])]
5567   "TARGET_QIMODE_MATH"
5568   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
5569
5570 (define_insn "*negqi2_1"
5571   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5572         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
5573    (clobber (reg:CC 17))]
5574   "ix86_unary_operator_ok (NEG, QImode, operands)"
5575   "neg{b}\\t%0"
5576   [(set_attr "type" "negnot")
5577    (set_attr "mode" "QI")])
5578
5579 (define_insn "*negqi2_cmpz"
5580   [(set (reg:CCZ 17)
5581         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
5582                      (const_int 0)))
5583    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5584         (neg:QI (match_dup 1)))]
5585   "ix86_unary_operator_ok (NEG, QImode, operands)"
5586   "neg{b}\\t%0"
5587   [(set_attr "type" "negnot")
5588    (set_attr "mode" "QI")])
5589
5590 ;; Changing of sign for FP values is doable using integer unit too.
5591
5592 (define_expand "negsf2"
5593   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
5594                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
5595               (clobber (reg:CC 17))])]
5596   "TARGET_80387"
5597   "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
5598
5599 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5600 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5601 ;; to itself.
5602 (define_insn "*negsf2_if"
5603   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
5604         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
5605    (clobber (reg:CC 17))]
5606   "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
5607   "#")
5608
5609 (define_split
5610   [(set (match_operand:SF 0 "register_operand" "")
5611         (neg:SF (match_operand:SF 1 "register_operand" "")))
5612    (clobber (reg:CC 17))]
5613   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5614   [(set (match_dup 0)
5615         (neg:SF (match_dup 1)))]
5616   "")
5617
5618 (define_split
5619   [(set (match_operand:SF 0 "register_operand" "")
5620         (neg:SF (match_operand:SF 1 "register_operand" "")))
5621    (clobber (reg:CC 17))]
5622   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5623   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
5624               (clobber (reg:CC 17))])]
5625   "operands[1] = GEN_INT (0x80000000);
5626    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
5627
5628 (define_split
5629   [(set (match_operand 0 "memory_operand" "")
5630         (neg (match_operand 1 "memory_operand" "")))
5631    (clobber (reg:CC 17))]
5632   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5633   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5634               (clobber (reg:CC 17))])]
5635   "
5636 {
5637   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
5638
5639   /* XFmode's size is 12, but only 10 bytes are used.  */
5640   if (size == 12)
5641     size = 10;
5642   operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
5643   operands[0] = adj_offsettable_operand (operands[0], size - 1);
5644   operands[1] = GEN_INT (0x80);
5645 }")
5646
5647 (define_expand "negdf2"
5648   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
5649                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
5650               (clobber (reg:CC 17))])]
5651   "TARGET_80387"
5652   "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
5653
5654 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5655 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5656 ;; to itself.
5657 (define_insn "*negdf2_if"
5658   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
5659         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
5660    (clobber (reg:CC 17))]
5661   "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
5662   "#")
5663
5664 (define_split
5665   [(set (match_operand:DF 0 "register_operand" "")
5666         (neg:DF (match_operand:DF 1 "register_operand" "")))
5667    (clobber (reg:CC 17))]
5668   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5669   [(set (match_dup 0)
5670         (neg:DF (match_dup 1)))]
5671   "")
5672
5673 (define_split
5674   [(set (match_operand:DF 0 "register_operand" "")
5675         (neg:DF (match_operand:DF 1 "register_operand" "")))
5676    (clobber (reg:CC 17))]
5677   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5678   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
5679               (clobber (reg:CC 17))])]
5680   "operands[4] = GEN_INT (0x80000000);
5681    split_di (operands+0, 1, operands+2, operands+3);")
5682
5683 (define_expand "negxf2"
5684   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
5685                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
5686               (clobber (reg:CC 17))])]
5687   "TARGET_80387"
5688   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
5689
5690 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5691 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5692 ;; to itself.
5693 (define_insn "*negxf2_if"
5694   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
5695         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
5696    (clobber (reg:CC 17))]
5697   "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
5698   "#")
5699
5700 (define_split
5701   [(set (match_operand:XF 0 "register_operand" "")
5702         (neg:XF (match_operand:XF 1 "register_operand" "")))
5703    (clobber (reg:CC 17))]
5704   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5705   [(set (match_dup 0)
5706         (neg:XF (match_dup 1)))]
5707   "")
5708
5709 (define_split
5710   [(set (match_operand:XF 0 "register_operand" "")
5711         (neg:XF (match_operand:XF 1 "register_operand" "")))
5712    (clobber (reg:CC 17))]
5713   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5714   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
5715               (clobber (reg:CC 17))])]
5716   "operands[1] = GEN_INT (0x8000);
5717    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
5718
5719 ;; Conditionize these after reload. If they matches before reload, we 
5720 ;; lose the clobber and ability to use integer instructions.
5721
5722 (define_insn "*negsf2_1"
5723   [(set (match_operand:SF 0 "register_operand" "=f")
5724         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
5725   "TARGET_80387 && reload_completed"
5726   "fchs"
5727   [(set_attr "type" "fsgn")
5728    (set_attr "mode" "SF")
5729    (set_attr "ppro_uops" "few")])
5730
5731 (define_insn "*negdf2_1"
5732   [(set (match_operand:DF 0 "register_operand" "=f")
5733         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
5734   "TARGET_80387 && reload_completed"
5735   "fchs"
5736   [(set_attr "type" "fsgn")
5737    (set_attr "mode" "DF")
5738    (set_attr "ppro_uops" "few")])
5739
5740 (define_insn "*negextendsfdf2"
5741   [(set (match_operand:DF 0 "register_operand" "=f")
5742         (neg:DF (float_extend:DF
5743                   (match_operand:SF 1 "register_operand" "0"))))]
5744   "TARGET_80387"
5745   "fchs"
5746   [(set_attr "type" "fsgn")
5747    (set_attr "mode" "DF")
5748    (set_attr "ppro_uops" "few")])
5749
5750 (define_insn "*negxf2_1"
5751   [(set (match_operand:XF 0 "register_operand" "=f")
5752         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
5753   "TARGET_80387 && reload_completed"
5754   "fchs"
5755   [(set_attr "type" "fsgn")
5756    (set_attr "mode" "XF")
5757    (set_attr "ppro_uops" "few")])
5758
5759 (define_insn "*negextenddfxf2"
5760   [(set (match_operand:XF 0 "register_operand" "=f")
5761         (neg:XF (float_extend:XF
5762                   (match_operand:DF 1 "register_operand" "0"))))]
5763   "TARGET_80387"
5764   "fchs"
5765   [(set_attr "type" "fsgn")
5766    (set_attr "mode" "XF")
5767    (set_attr "ppro_uops" "few")])
5768
5769 (define_insn "*negextendsfxf2"
5770   [(set (match_operand:XF 0 "register_operand" "=f")
5771         (neg:XF (float_extend:XF
5772                   (match_operand:SF 1 "register_operand" "0"))))]
5773   "TARGET_80387"
5774   "fchs"
5775   [(set_attr "type" "fsgn")
5776    (set_attr "mode" "XF")
5777    (set_attr "ppro_uops" "few")])
5778 \f
5779 ;; Absolute value instructions
5780
5781 (define_expand "abssf2"
5782   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
5783                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
5784               (clobber (reg:CC 17))])]
5785   "TARGET_80387"
5786   "ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
5787
5788 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5789 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5790 ;; to itself.
5791 (define_insn "*abssf2_if"
5792   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
5793         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
5794    (clobber (reg:CC 17))]
5795   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
5796   "#")
5797
5798 (define_split
5799   [(set (match_operand:SF 0 "register_operand" "")
5800         (abs:SF (match_operand:SF 1 "register_operand" "")))
5801    (clobber (reg:CC 17))]
5802   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
5803   [(set (match_dup 0)
5804         (abs:SF (match_dup 1)))]
5805   "")
5806
5807 (define_split
5808   [(set (match_operand:SF 0 "register_operand" "")
5809         (abs:SF (match_operand:SF 1 "register_operand" "")))
5810    (clobber (reg:CC 17))]
5811   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5812   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
5813               (clobber (reg:CC 17))])]
5814   "operands[1] = GEN_INT (~0x80000000);
5815    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
5816
5817 (define_split
5818   [(set (match_operand 0 "memory_operand" "")
5819         (abs (match_operand 1 "memory_operand" "")))
5820    (clobber (reg:CC 17))]
5821   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5822   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5823               (clobber (reg:CC 17))])]
5824   "
5825 {
5826   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
5827
5828   /* XFmode's size is 12, but only 10 bytes are used.  */
5829   if (size == 12)
5830     size = 10;
5831   operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
5832   operands[0] = adj_offsettable_operand (operands[0], size - 1);
5833   operands[1] = GEN_INT (~0x80);
5834 }")
5835
5836 (define_expand "absdf2"
5837   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
5838                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
5839               (clobber (reg:CC 17))])]
5840   "TARGET_80387"
5841   "ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
5842
5843 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5844 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5845 ;; to itself.
5846 (define_insn "*absdf2_if"
5847   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
5848         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
5849    (clobber (reg:CC 17))]
5850   "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
5851   "#")
5852
5853 (define_split
5854   [(set (match_operand:DF 0 "register_operand" "")
5855         (abs:DF (match_operand:DF 1 "register_operand" "")))
5856    (clobber (reg:CC 17))]
5857   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5858   [(set (match_dup 0)
5859         (abs:DF (match_dup 1)))]
5860   "")
5861
5862 (define_split
5863   [(set (match_operand:DF 0 "register_operand" "")
5864         (abs:DF (match_operand:DF 1 "register_operand" "")))
5865    (clobber (reg:CC 17))]
5866   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5867   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
5868               (clobber (reg:CC 17))])]
5869   "operands[4] = GEN_INT (~0x80000000);
5870    split_di (operands+0, 1, operands+2, operands+3);")
5871
5872 (define_expand "absxf2"
5873   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
5874                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
5875               (clobber (reg:CC 17))])]
5876   "TARGET_80387"
5877   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
5878
5879 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5880 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5881 ;; to itself.
5882 (define_insn "*absxf2_if"
5883   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
5884         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
5885    (clobber (reg:CC 17))]
5886   "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
5887   "#")
5888
5889 (define_split
5890   [(set (match_operand:XF 0 "register_operand" "")
5891         (abs:XF (match_operand:XF 1 "register_operand" "")))
5892    (clobber (reg:CC 17))]
5893   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5894   [(set (match_dup 0)
5895         (abs:XF (match_dup 1)))]
5896   "")
5897
5898 (define_split
5899   [(set (match_operand:XF 0 "register_operand" "")
5900         (abs:XF (match_operand:XF 1 "register_operand" "")))
5901    (clobber (reg:CC 17))]
5902   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5903   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
5904               (clobber (reg:CC 17))])]
5905   "operands[1] = GEN_INT (~0x8000);
5906    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
5907
5908 (define_insn "*abssf2_1"
5909   [(set (match_operand:SF 0 "register_operand" "=f")
5910         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
5911   "TARGET_80387 && reload_completed"
5912   "fabs"
5913   [(set_attr "type" "fsgn")
5914    (set_attr "mode" "SF")])
5915
5916 (define_insn "*absdf2_1"
5917   [(set (match_operand:DF 0 "register_operand" "=f")
5918         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
5919   "TARGET_80387 && reload_completed"
5920   "fabs"
5921   [(set_attr "type" "fsgn")
5922    (set_attr "mode" "DF")])
5923
5924 (define_insn "*absextendsfdf2"
5925   [(set (match_operand:DF 0 "register_operand" "=f")
5926         (abs:DF (float_extend:DF
5927                   (match_operand:SF 1 "register_operand" "0"))))]
5928   "TARGET_80387"
5929   "fabs"
5930   [(set_attr "type" "fsgn")
5931    (set_attr "mode" "DF")])
5932
5933 (define_insn "*absxf2_1"
5934   [(set (match_operand:XF 0 "register_operand" "=f")
5935         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
5936   "TARGET_80387 && reload_completed"
5937   "fabs"
5938   [(set_attr "type" "fsgn")
5939    (set_attr "mode" "DF")])
5940
5941 (define_insn "*absextenddfxf2"
5942   [(set (match_operand:XF 0 "register_operand" "=f")
5943         (abs:XF (float_extend:XF
5944           (match_operand:DF 1 "register_operand" "0"))))]
5945   "TARGET_80387"
5946   "fabs"
5947   [(set_attr "type" "fsgn")
5948    (set_attr "mode" "XF")])
5949
5950 (define_insn "*absextendsfxf2"
5951   [(set (match_operand:XF 0 "register_operand" "=f")
5952         (abs:XF (float_extend:XF
5953           (match_operand:SF 1 "register_operand" "0"))))]
5954   "TARGET_80387"
5955   "fabs"
5956   [(set_attr "type" "fsgn")
5957    (set_attr "mode" "XF")])
5958 \f
5959 ;; One complement instructions
5960
5961 (define_expand "one_cmplsi2"
5962   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5963         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
5964   ""
5965   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
5966
5967 (define_insn "*one_cmplsi2_1"
5968   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5969         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
5970   "ix86_unary_operator_ok (NOT, SImode, operands)"
5971   "not{l}\\t%0"
5972   [(set_attr "type" "negnot")
5973    (set_attr "mode" "SI")])
5974
5975 (define_insn "*one_cmplsi2_2"
5976   [(set (reg 17)
5977         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
5978                  (const_int 0)))
5979    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5980         (not:SI (match_dup 1)))]
5981   "ix86_match_ccmode (insn, CCNOmode)
5982    && ix86_unary_operator_ok (NOT, SImode, operands)"
5983   "#"
5984   [(set_attr "type" "alu1")
5985    (set_attr "mode" "SI")])
5986
5987 (define_split
5988   [(set (reg 17)
5989         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
5990                  (const_int 0)))
5991    (set (match_operand:SI 0 "nonimmediate_operand" "")
5992         (not:SI (match_dup 1)))]
5993   "ix86_match_ccmode (insn, CCNOmode)"
5994   [(parallel [(set (reg:CCNO 17)
5995                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
5996                                  (const_int 0)))
5997               (set (match_dup 0)
5998                    (xor:SI (match_dup 1) (const_int -1)))])]
5999   "")
6000
6001 (define_expand "one_cmplhi2"
6002   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6003         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
6004   "TARGET_HIMODE_MATH"
6005   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
6006
6007 (define_insn "*one_cmplhi2_1"
6008   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6009         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
6010   "ix86_unary_operator_ok (NOT, HImode, operands)"
6011   "not{w}\\t%0"
6012   [(set_attr "type" "negnot")
6013    (set_attr "mode" "HI")])
6014
6015 (define_insn "*one_cmplhi2_2"
6016   [(set (reg 17)
6017         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
6018                  (const_int 0)))
6019    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6020         (not:HI (match_dup 1)))]
6021   "ix86_match_ccmode (insn, CCNOmode)
6022    && ix86_unary_operator_ok (NEG, HImode, operands)"
6023   "#"
6024   [(set_attr "type" "alu1")
6025    (set_attr "mode" "HI")])
6026
6027 (define_split
6028   [(set (reg 17)
6029         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
6030                  (const_int 0)))
6031    (set (match_operand:HI 0 "nonimmediate_operand" "")
6032         (not:HI (match_dup 1)))]
6033   "ix86_match_ccmode (insn, CCNOmode)"
6034   [(parallel [(set (reg:CCNO 17)
6035                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
6036                                  (const_int 0)))
6037               (set (match_dup 0)
6038                    (xor:HI (match_dup 1) (const_int -1)))])]
6039   "")
6040
6041 ;; %%% Potential partial reg stall on alternative 1.  What to do?
6042 (define_expand "one_cmplqi2"
6043   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6044         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
6045   "TARGET_QIMODE_MATH"
6046   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
6047
6048 (define_insn "*one_cmplqi2_1"
6049   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
6050         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
6051   "ix86_unary_operator_ok (NOT, QImode, operands)"
6052   "@
6053    not{b}\\t%0
6054    not{l}\\t%k0"
6055   [(set_attr "type" "negnot")
6056    (set_attr "mode" "QI,SI")])
6057
6058 (define_insn "*one_cmplqi2_2"
6059   [(set (reg 17)
6060         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
6061                  (const_int 0)))
6062    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6063         (not:QI (match_dup 1)))]
6064   "ix86_match_ccmode (insn, CCNOmode)
6065    && ix86_unary_operator_ok (NOT, QImode, operands)"
6066   "#"
6067   [(set_attr "type" "alu1")
6068    (set_attr "mode" "QI")])
6069
6070 (define_split
6071   [(set (reg 17)
6072         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
6073                  (const_int 0)))
6074    (set (match_operand:QI 0 "nonimmediate_operand" "")
6075         (not:QI (match_dup 1)))]
6076   "ix86_match_ccmode (insn, CCNOmode)"
6077   [(parallel [(set (reg:CCNO 17)
6078                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
6079                                  (const_int 0)))
6080               (set (match_dup 0)
6081                    (xor:QI (match_dup 1) (const_int -1)))])]
6082   "")
6083 \f
6084 ;; Arithmetic shift instructions
6085
6086 ;; DImode shifts are implemented using the i386 "shift double" opcode,
6087 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
6088 ;; is variable, then the count is in %cl and the "imm" operand is dropped
6089 ;; from the assembler input.
6090 ;;
6091 ;; This instruction shifts the target reg/mem as usual, but instead of
6092 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
6093 ;; is a left shift double, bits are taken from the high order bits of
6094 ;; reg, else if the insn is a shift right double, bits are taken from the
6095 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
6096 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
6097 ;;
6098 ;; Since sh[lr]d does not change the `reg' operand, that is done
6099 ;; separately, making all shifts emit pairs of shift double and normal
6100 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
6101 ;; support a 63 bit shift, each shift where the count is in a reg expands
6102 ;; to a pair of shifts, a branch, a shift by 32 and a label.
6103 ;;
6104 ;; If the shift count is a constant, we need never emit more than one
6105 ;; shift pair, instead using moves and sign extension for counts greater
6106 ;; than 31.
6107
6108 (define_expand "ashldi3"
6109   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6110                    (ashift:DI (match_operand:DI 1 "register_operand" "0")
6111                               (match_operand:QI 2 "nonmemory_operand" "Jc")))
6112               (clobber (reg:CC 17))])]
6113   ""
6114   "
6115 {
6116   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6117     {
6118       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
6119       DONE;
6120     }
6121 }")
6122
6123 (define_insn "ashldi3_1"
6124   [(set (match_operand:DI 0 "register_operand" "=r")
6125         (ashift:DI (match_operand:DI 1 "register_operand" "0")
6126                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
6127    (clobber (match_scratch:SI 3 "=&r"))
6128    (clobber (reg:CC 17))]
6129   "TARGET_CMOVE"
6130   "#"
6131   [(set_attr "type" "multi")])
6132
6133 (define_insn "*ashldi3_2"
6134   [(set (match_operand:DI 0 "register_operand" "=r")
6135         (ashift:DI (match_operand:DI 1 "register_operand" "0")
6136                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
6137    (clobber (reg:CC 17))]
6138   ""
6139   "#"
6140   [(set_attr "type" "multi")])
6141
6142 (define_split
6143   [(set (match_operand:DI 0 "register_operand" "")
6144         (ashift:DI (match_operand:DI 1 "register_operand" "")
6145                    (match_operand:QI 2 "nonmemory_operand" "")))
6146    (clobber (match_scratch:SI 3 ""))
6147    (clobber (reg:CC 17))]
6148   "TARGET_CMOVE && reload_completed"
6149   [(const_int 0)]
6150   "ix86_split_ashldi (operands, operands[3]); DONE;")
6151
6152 (define_split
6153   [(set (match_operand:DI 0 "register_operand" "")
6154         (ashift:DI (match_operand:DI 1 "register_operand" "")
6155                    (match_operand:QI 2 "nonmemory_operand" "")))
6156    (clobber (reg:CC 17))]
6157   "reload_completed"
6158   [(const_int 0)]
6159   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
6160
6161 (define_insn "x86_shld_1"
6162   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
6163         (ior:SI (ashift:SI (match_dup 0)
6164                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
6165                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6166                   (minus:QI (const_int 32) (match_dup 2)))))
6167    (clobber (reg:CC 17))]
6168   ""
6169   "@
6170    shld{l}\\t{%2, %1, %0|%0, %1, %2}
6171    shld{l}\\t{%s2%1, %0|%0, %1, %2}"
6172   [(set_attr "type" "ishift")
6173    (set_attr "prefix_0f" "1")
6174    (set_attr "mode" "SI")
6175    (set_attr "pent_pair" "np")
6176    (set_attr "athlon_decode" "vector")
6177    (set_attr "ppro_uops" "few")])
6178
6179 (define_expand "x86_shift_adj_1"
6180   [(set (reg:CCZ 17)
6181         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
6182                              (const_int 32))
6183                      (const_int 0)))
6184    (set (match_operand:SI 0 "register_operand" "")
6185         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
6186                          (match_operand:SI 1 "register_operand" "")
6187                          (match_dup 0)))
6188    (set (match_dup 1)
6189         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
6190                          (match_operand:SI 3 "register_operand" "r")
6191                          (match_dup 1)))]
6192   "TARGET_CMOVE"
6193   "")
6194
6195 (define_expand "x86_shift_adj_2"
6196   [(use (match_operand:SI 0 "register_operand" ""))
6197    (use (match_operand:SI 1 "register_operand" ""))
6198    (use (match_operand:QI 2 "register_operand" ""))]
6199   ""
6200   "
6201 {
6202   rtx label = gen_label_rtx ();
6203   rtx tmp;
6204
6205   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
6206
6207   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
6208   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6209   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
6210                               gen_rtx_LABEL_REF (VOIDmode, label),
6211                               pc_rtx);
6212   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
6213   JUMP_LABEL (tmp) = label;
6214
6215   emit_move_insn (operands[0], operands[1]);
6216   emit_move_insn (operands[1], const0_rtx);
6217
6218   emit_label (label);
6219   LABEL_NUSES (label) = 1;
6220
6221   DONE;
6222 }")
6223
6224 (define_expand "ashlsi3"
6225   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6226         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
6227                    (match_operand:QI 2 "nonmemory_operand" "")))
6228    (clobber (reg:CC 17))]
6229   ""
6230   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
6231
6232 (define_insn "*ashlsi3_1"
6233   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6234         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
6235                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
6236    (clobber (reg:CC 17))]
6237   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
6238   "*
6239 {
6240   switch (get_attr_type (insn))
6241     {
6242     case TYPE_ALU:
6243       if (operands[2] != const1_rtx)
6244         abort ();
6245       if (!rtx_equal_p (operands[0], operands[1]))
6246         abort ();
6247       return \"add{l}\\t{%0, %0|%0, %0}\";
6248
6249     case TYPE_LEA:
6250       if (GET_CODE (operands[2]) != CONST_INT
6251           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
6252         abort ();
6253       operands[1] = gen_rtx_MULT (SImode, operands[1],
6254                                   GEN_INT (1 << INTVAL (operands[2])));
6255       return \"lea{l}\\t{%a1, %0|%0, %a1}\";
6256
6257     default:
6258       if (REG_P (operands[2]))
6259         return \"sal{l}\\t{%b2, %0|%0, %b2}\";
6260       else if (GET_CODE (operands[2]) == CONST_INT
6261                && INTVAL (operands[2]) == 1
6262                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6263         return \"sal{l}\\t%0\";
6264       else
6265         return \"sal{l}\\t{%2, %0|%0, %2}\";
6266     }
6267 }"
6268   [(set (attr "type")
6269      (cond [(eq_attr "alternative" "1")
6270               (const_string "lea")
6271             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6272                           (const_int 0))
6273                       (match_operand 0 "register_operand" ""))
6274                  (match_operand 2 "const1_operand" ""))
6275               (const_string "alu")
6276            ]
6277            (const_string "ishift")))
6278    (set_attr "mode" "SI")])
6279
6280 ;; Convert lea to the lea pattern to avoid flags dependency.
6281 (define_split
6282   [(set (match_operand:SI 0 "register_operand" "")
6283         (ashift:SI (match_operand:SI 1 "register_operand" "")
6284                    (match_operand:QI 2 "immediate_operand" "")))
6285    (clobber (reg:CC 17))]
6286   "reload_completed
6287    && true_regnum (operands[0]) != true_regnum (operands[1])"
6288   [(set (match_dup 0)
6289         (mult:SI (match_dup 1)
6290                  (match_dup 2)))]
6291   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));")
6292
6293 ;; This pattern can't accept a variable shift count, since shifts by
6294 ;; zero don't affect the flags.  We assume that shifts by constant
6295 ;; zero are optimized away.
6296 (define_insn "*ashlsi3_cmpno"
6297   [(set (reg 17)
6298         (compare
6299           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6300                      (match_operand:QI 2 "immediate_operand" "I"))
6301           (const_int 0)))
6302    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6303         (ashift:SI (match_dup 1) (match_dup 2)))]
6304   "ix86_match_ccmode (insn, CCNOmode)
6305    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
6306   "*
6307 {
6308   switch (get_attr_type (insn))
6309     {
6310     case TYPE_ALU:
6311       if (operands[2] != const1_rtx)
6312         abort ();
6313       return \"add{l}\\t{%0, %0|%0, %0}\";
6314
6315     default:
6316       if (REG_P (operands[2]))
6317         return \"sal{l}\\t{%b2, %0|%0, %b2}\";
6318       else if (GET_CODE (operands[2]) == CONST_INT
6319                && INTVAL (operands[2]) == 1
6320                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6321         return \"sal{l}\\t%0\";
6322       else
6323         return \"sal{l}\\t{%2, %0|%0, %2}\";
6324     }
6325 }"
6326   [(set (attr "type")
6327      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6328                           (const_int 0))
6329                       (match_operand 0 "register_operand" ""))
6330                  (match_operand 2 "const1_operand" ""))
6331               (const_string "alu")
6332            ]
6333            (const_string "ishift")))
6334    (set_attr "mode" "SI")])
6335
6336 (define_expand "ashlhi3"
6337   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6338         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
6339                    (match_operand:QI 2 "nonmemory_operand" "")))
6340    (clobber (reg:CC 17))]
6341   "TARGET_HIMODE_MATH"
6342   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
6343
6344 (define_insn "*ashlhi3_1"
6345   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6346         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6347                    (match_operand:QI 2 "nonmemory_operand" "cI")))
6348    (clobber (reg:CC 17))]
6349   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
6350   "*
6351 {
6352   switch (get_attr_type (insn))
6353     {
6354     case TYPE_ALU:
6355       if (operands[2] != const1_rtx)
6356         abort ();
6357       return \"add{w}\\t{%0, %0|%0, %0}\";
6358
6359     default:
6360       if (REG_P (operands[2]))
6361         return \"sal{w}\\t{%b2, %0|%0, %b2}\";
6362       else if (GET_CODE (operands[2]) == CONST_INT
6363                && INTVAL (operands[2]) == 1
6364                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6365         return \"sal{w}\\t%0\";
6366       else
6367         return \"sal{w}\\t{%2, %0|%0, %2}\";
6368     }
6369 }"
6370   [(set (attr "type")
6371      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6372                           (const_int 0))
6373                       (match_operand 0 "register_operand" ""))
6374                  (match_operand 2 "const1_operand" ""))
6375               (const_string "alu")
6376            ]
6377            (const_string "ishift")))
6378    (set_attr "mode" "HI")])
6379
6380 ;; This pattern can't accept a variable shift count, since shifts by
6381 ;; zero don't affect the flags.  We assume that shifts by constant
6382 ;; zero are optimized away.
6383 (define_insn "*ashlhi3_cmpno"
6384   [(set (reg 17)
6385         (compare
6386           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6387                      (match_operand:QI 2 "immediate_operand" "I"))
6388           (const_int 0)))
6389    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6390         (ashift:HI (match_dup 1) (match_dup 2)))]
6391   "ix86_match_ccmode (insn, CCNOmode)
6392    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
6393   "*
6394 {
6395   switch (get_attr_type (insn))
6396     {
6397     case TYPE_ALU:
6398       if (operands[2] != const1_rtx)
6399         abort ();
6400       return \"add{w}\\t{%0, %0|%0, %0}\";
6401
6402     default:
6403       if (REG_P (operands[2]))
6404         return \"sal{w}\\t{%b2, %0|%0, %b2}\";
6405       else if (GET_CODE (operands[2]) == CONST_INT
6406                && INTVAL (operands[2]) == 1
6407                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6408         return \"sal{w}\\t%0\";
6409       else
6410         return \"sal{w}\\t{%2, %0|%0, %2}\";
6411     }
6412 }"
6413   [(set (attr "type")
6414      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6415                           (const_int 0))
6416                       (match_operand 0 "register_operand" ""))
6417                  (match_operand 2 "const1_operand" ""))
6418               (const_string "alu")
6419            ]
6420            (const_string "ishift")))
6421    (set_attr "mode" "HI")])
6422
6423 (define_expand "ashlqi3"
6424   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6425         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
6426                    (match_operand:QI 2 "nonmemory_operand" "")))
6427    (clobber (reg:CC 17))]
6428   "TARGET_QIMODE_MATH"
6429   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
6430
6431 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6432 (define_insn "*ashlqi3_1"
6433   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
6434         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6435                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
6436    (clobber (reg:CC 17))]
6437   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
6438   "*
6439 {
6440   switch (get_attr_type (insn))
6441     {
6442     case TYPE_ALU:
6443       if (operands[2] != const1_rtx)
6444         abort ();
6445       if (NON_QI_REG_P (operands[1]))
6446         return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
6447       else
6448         return \"add{b}\\t{%0, %0|%0, %0}\";
6449
6450     default:
6451       if (REG_P (operands[2]))
6452         {
6453           if (NON_QI_REG_P (operands[1]))
6454             return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
6455           else
6456             return \"sal{b}\\t{%b2, %0|%0, %b2}\";
6457         }
6458       else if (GET_CODE (operands[2]) == CONST_INT
6459                && INTVAL (operands[2]) == 1
6460                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6461         {
6462           if (NON_QI_REG_P (operands[1]))
6463             return \"sal{l}\\t%0\";
6464           else
6465             return \"sal{b}\\t%0\";
6466         }
6467       else
6468         {
6469           if (NON_QI_REG_P (operands[1]))
6470             return \"sal{l}\\t{%2, %k0|%k0, %2}\";
6471           else
6472             return \"sal{b}\\t{%2, %0|%0, %2}\";
6473         }
6474     }
6475 }"
6476   [(set (attr "type")
6477      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6478                           (const_int 0))
6479                       (match_operand 0 "register_operand" ""))
6480                  (match_operand 2 "const1_operand" ""))
6481               (const_string "alu")
6482            ]
6483            (const_string "ishift")))
6484    (set_attr "mode" "QI,SI")])
6485
6486 ;; This pattern can't accept a variable shift count, since shifts by
6487 ;; zero don't affect the flags.  We assume that shifts by constant
6488 ;; zero are optimized away.
6489 (define_insn "*ashlqi3_cmpno"
6490   [(set (reg 17)
6491         (compare
6492           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6493                      (match_operand:QI 2 "immediate_operand" "I"))
6494           (const_int 0)))
6495    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6496         (ashift:QI (match_dup 1) (match_dup 2)))]
6497   "ix86_match_ccmode (insn, CCNOmode)
6498    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
6499   "*
6500 {
6501   switch (get_attr_type (insn))
6502     {
6503     case TYPE_ALU:
6504       if (operands[2] != const1_rtx)
6505         abort ();
6506       return \"add{b}\\t{%0, %0|%0, %0}\";
6507
6508     default:
6509       if (REG_P (operands[2]))
6510         return \"sal{b}\\t{%b2, %0|%0, %b2}\";
6511       else if (GET_CODE (operands[2]) == CONST_INT
6512                && INTVAL (operands[2]) == 1
6513                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6514         return \"sal{b}\\t%0\";
6515       else
6516         return \"sal{b}\\t{%2, %0|%0, %2}\";
6517     }
6518 }"
6519   [(set (attr "type")
6520      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6521                           (const_int 0))
6522                       (match_operand 0 "register_operand" ""))
6523                  (match_operand 2 "const1_operand" ""))
6524               (const_string "alu")
6525            ]
6526            (const_string "ishift")))
6527    (set_attr "mode" "QI")])
6528
6529 ;; See comment above `ashldi3' about how this works.
6530
6531 (define_expand "ashrdi3"
6532   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6533                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6534                                 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6535               (clobber (reg:CC 17))])]
6536   ""
6537   "
6538 {
6539   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6540     {
6541       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
6542       DONE;
6543     }
6544 }")
6545
6546 (define_insn "ashrdi3_1"
6547   [(set (match_operand:DI 0 "register_operand" "=r")
6548         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6549                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
6550    (clobber (match_scratch:SI 3 "=&r"))
6551    (clobber (reg:CC 17))]
6552   "TARGET_CMOVE"
6553   "#"
6554   [(set_attr "type" "multi")])
6555
6556 (define_insn "*ashrdi3_2"
6557   [(set (match_operand:DI 0 "register_operand" "=r")
6558         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6559                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
6560    (clobber (reg:CC 17))]
6561   ""
6562   "#"
6563   [(set_attr "type" "multi")])
6564
6565 (define_split
6566   [(set (match_operand:DI 0 "register_operand" "")
6567         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6568                      (match_operand:QI 2 "nonmemory_operand" "")))
6569    (clobber (match_scratch:SI 3 ""))
6570    (clobber (reg:CC 17))]
6571   "TARGET_CMOVE && reload_completed"
6572   [(const_int 0)]
6573   "ix86_split_ashrdi (operands, operands[3]); DONE;")
6574
6575 (define_split
6576   [(set (match_operand:DI 0 "register_operand" "")
6577         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6578                      (match_operand:QI 2 "nonmemory_operand" "")))
6579    (clobber (reg:CC 17))]
6580   "reload_completed"
6581   [(const_int 0)]
6582   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
6583
6584 (define_insn "x86_shrd_1"
6585   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
6586         (ior:SI (ashiftrt:SI (match_dup 0)
6587                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
6588                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
6589                   (minus:QI (const_int 32) (match_dup 2)))))
6590    (clobber (reg:CC 17))]
6591   ""
6592   "@
6593    shrd{l}\\t{%2, %1, %0|%0, %1, %2}
6594    shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
6595   [(set_attr "type" "ishift")
6596    (set_attr "prefix_0f" "1")
6597    (set_attr "pent_pair" "np")
6598    (set_attr "ppro_uops" "few")
6599    (set_attr "mode" "SI")])
6600
6601 (define_expand "x86_shift_adj_3"
6602   [(use (match_operand:SI 0 "register_operand" ""))
6603    (use (match_operand:SI 1 "register_operand" ""))
6604    (use (match_operand:QI 2 "register_operand" ""))]
6605   ""
6606   "
6607 {
6608   rtx label = gen_label_rtx ();
6609   rtx tmp;
6610
6611   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
6612
6613   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
6614   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6615   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
6616                               gen_rtx_LABEL_REF (VOIDmode, label),
6617                               pc_rtx);
6618   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
6619   JUMP_LABEL (tmp) = label;
6620
6621   emit_move_insn (operands[0], operands[1]);
6622   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
6623
6624   emit_label (label);
6625   LABEL_NUSES (label) = 1;
6626
6627   DONE;
6628 }")
6629
6630 (define_insn "ashrsi3_31"
6631   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
6632         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
6633                      (match_operand:SI 2 "const_int_operand" "i,i")))
6634    (clobber (reg:CC 17))]
6635   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
6636    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6637   "@
6638    {cltd|cdq}
6639    sar{l}\\t{%2, %0|%0, %2}"
6640   [(set_attr "type" "imovx,ishift")
6641    (set_attr "prefix_0f" "0,*")
6642    (set_attr "length_immediate" "0,*")
6643    (set_attr "modrm" "0,1")
6644    (set_attr "mode" "SI")])
6645
6646 (define_expand "ashrsi3"
6647   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6648         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
6649                      (match_operand:QI 2 "nonmemory_operand" "")))
6650    (clobber (reg:CC 17))]
6651   ""
6652   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
6653
6654 (define_insn "*ashrsi3_1_one_bit"
6655   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6656         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6657                      (match_operand:QI 2 "const_int_1_operand" "")))
6658    (clobber (reg:CC 17))]
6659   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
6660    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
6661   "sar{l}\\t%0"
6662   [(set_attr "type" "ishift")
6663    (set (attr "length") 
6664      (if_then_else (match_operand:SI 0 "register_operand" "") 
6665         (const_string "2")
6666         (const_string "*")))])
6667
6668 (define_insn "*ashrsi3_1"
6669   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6670         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6671                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6672    (clobber (reg:CC 17))]
6673   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6674   "@
6675    sar{l}\\t{%2, %0|%0, %2}
6676    sar{l}\\t{%b2, %0|%0, %b2}"
6677   [(set_attr "type" "ishift")
6678    (set_attr "mode" "SI")])
6679
6680 ;; This pattern can't accept a variable shift count, since shifts by
6681 ;; zero don't affect the flags.  We assume that shifts by constant
6682 ;; zero are optimized away.
6683 (define_insn "*ashrsi3_one_bit_cmpno"
6684   [(set (reg 17)
6685         (compare
6686           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6687                        (match_operand:QI 2 "const_int_1_operand" ""))
6688           (const_int 0)))
6689    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6690         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
6691   "ix86_match_ccmode (insn, CCNOmode)
6692    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
6693    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6694   "sar{l}\\t%0"
6695   [(set_attr "type" "ishift")
6696    (set (attr "length") 
6697      (if_then_else (match_operand:SI 0 "register_operand" "") 
6698         (const_string "2")
6699         (const_string "*")))])
6700
6701 ;; This pattern can't accept a variable shift count, since shifts by
6702 ;; zero don't affect the flags.  We assume that shifts by constant
6703 ;; zero are optimized away.
6704 (define_insn "*ashrsi3_cmpno"
6705   [(set (reg 17)
6706         (compare
6707           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6708                        (match_operand:QI 2 "immediate_operand" "I"))
6709           (const_int 0)))
6710    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6711         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
6712   "ix86_match_ccmode (insn, CCNOmode)
6713    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6714   "@
6715    sar{l}\\t{%2, %0|%0, %2}"
6716   [(set_attr "type" "ishift")
6717    (set_attr "mode" "SI")])
6718
6719 (define_expand "ashrhi3"
6720   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6721         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
6722                      (match_operand:QI 2 "nonmemory_operand" "")))
6723    (clobber (reg:CC 17))]
6724   "TARGET_HIMODE_MATH"
6725   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
6726
6727 (define_insn "*ashrhi3_1_one_bit"
6728   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6729         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6730                      (match_operand:QI 2 "const_int_1_operand" "")))
6731    (clobber (reg:CC 17))]
6732   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
6733    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
6734   "sar{w}\\t%0"
6735   [(set_attr "type" "ishift")
6736    (set (attr "length") 
6737      (if_then_else (match_operand:SI 0 "register_operand" "") 
6738         (const_string "2")
6739         (const_string "*")))])
6740
6741 (define_insn "*ashrhi3_1"
6742   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6743         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6744                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6745    (clobber (reg:CC 17))]
6746   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6747   "@
6748    sar{w}\\t{%2, %0|%0, %2}
6749    sar{w}\\t{%b2, %0|%0, %b2}"
6750   [(set_attr "type" "ishift")
6751    (set_attr "mode" "HI")])
6752
6753 ;; This pattern can't accept a variable shift count, since shifts by
6754 ;; zero don't affect the flags.  We assume that shifts by constant
6755 ;; zero are optimized away.
6756 (define_insn "*ashrhi3_one_bit_cmpno"
6757   [(set (reg 17)
6758         (compare
6759           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6760                        (match_operand:QI 2 "const_int_1_operand" ""))
6761           (const_int 0)))
6762    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6763         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
6764   "ix86_match_ccmode (insn, CCNOmode)
6765    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
6766    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6767   "sar{w}\\t%0"
6768   [(set_attr "type" "ishift")
6769    (set (attr "length") 
6770      (if_then_else (match_operand:SI 0 "register_operand" "") 
6771         (const_string "2")
6772         (const_string "*")))])
6773
6774 ;; This pattern can't accept a variable shift count, since shifts by
6775 ;; zero don't affect the flags.  We assume that shifts by constant
6776 ;; zero are optimized away.
6777 (define_insn "*ashrhi3_cmpno"
6778   [(set (reg 17)
6779         (compare
6780           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6781                        (match_operand:QI 2 "immediate_operand" "I"))
6782           (const_int 0)))
6783    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6784         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
6785   "ix86_match_ccmode (insn, CCNOmode)
6786    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6787   "@
6788    sar{w}\\t{%2, %0|%0, %2}"
6789   [(set_attr "type" "ishift")
6790    (set_attr "mode" "HI")])
6791
6792 (define_expand "ashrqi3"
6793   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6794         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
6795                      (match_operand:QI 2 "nonmemory_operand" "")))
6796    (clobber (reg:CC 17))]
6797   "TARGET_QIMODE_MATH"
6798   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
6799
6800 (define_insn "*ashrqi3_1_one_bit"
6801   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6802         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6803                      (match_operand:QI 2 "const_int_1_operand" "")))
6804    (clobber (reg:CC 17))]
6805   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
6806    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
6807   "sar{b}\\t%0"
6808   [(set_attr "type" "ishift")
6809    (set (attr "length") 
6810      (if_then_else (match_operand:SI 0 "register_operand" "") 
6811         (const_string "2")
6812         (const_string "*")))])
6813
6814 (define_insn "*ashrqi3_1"
6815   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6816         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6818    (clobber (reg:CC 17))]
6819   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6820   "@
6821    sar{b}\\t{%2, %0|%0, %2}
6822    sar{b}\\t{%b2, %0|%0, %b2}"
6823   [(set_attr "type" "ishift")
6824    (set_attr "mode" "QI")])
6825
6826 ;; This pattern can't accept a variable shift count, since shifts by
6827 ;; zero don't affect the flags.  We assume that shifts by constant
6828 ;; zero are optimized away.
6829 (define_insn "*ashrqi3_cmpno_one_bit"
6830   [(set (reg 17)
6831         (compare
6832           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6833                        (match_operand:QI 2 "const_int_1_operand" "I"))
6834           (const_int 0)))
6835    (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
6836         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
6837   "ix86_match_ccmode (insn, CCNOmode)
6838    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
6839    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6840   "sar{b}\\t%0"
6841   [(set_attr "type" "ishift")
6842    (set (attr "length") 
6843      (if_then_else (match_operand:SI 0 "register_operand" "") 
6844         (const_string "2")
6845         (const_string "*")))])
6846
6847 ;; This pattern can't accept a variable shift count, since shifts by
6848 ;; zero don't affect the flags.  We assume that shifts by constant
6849 ;; zero are optimized away.
6850 (define_insn "*ashrqi3_cmpno"
6851   [(set (reg 17)
6852         (compare
6853           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6854                        (match_operand:QI 2 "immediate_operand" "I"))
6855           (const_int 0)))
6856    (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
6857         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
6858   "ix86_match_ccmode (insn, CCNOmode)
6859    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6860   "@
6861    sar{b}\\t{%2, %0|%0, %2}"
6862   [(set_attr "type" "ishift")
6863    (set_attr "mode" "QI")])
6864 \f
6865 ;; Logical shift instructions
6866
6867 ;; See comment above `ashldi3' about how this works.
6868
6869 (define_expand "lshrdi3"
6870   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6871                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6872                                 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6873               (clobber (reg:CC 17))])]
6874   ""
6875   "
6876 {
6877   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6878     {
6879       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
6880       DONE;
6881     }
6882 }")
6883
6884 (define_insn "lshrdi3_1"
6885   [(set (match_operand:DI 0 "register_operand" "=r")
6886         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6887                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
6888    (clobber (match_scratch:SI 3 "=&r"))
6889    (clobber (reg:CC 17))]
6890   "TARGET_CMOVE"
6891   "#"
6892   [(set_attr "type" "multi")])
6893
6894 (define_insn "*lshrdi3_2"
6895   [(set (match_operand:DI 0 "register_operand" "=r")
6896         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6897                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
6898    (clobber (reg:CC 17))]
6899   ""
6900   "#"
6901   [(set_attr "type" "multi")])
6902
6903 (define_split 
6904   [(set (match_operand:DI 0 "register_operand" "")
6905         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6906                      (match_operand:QI 2 "nonmemory_operand" "")))
6907    (clobber (match_scratch:SI 3 ""))
6908    (clobber (reg:CC 17))]
6909   "TARGET_CMOVE && reload_completed"
6910   [(const_int 0)]
6911   "ix86_split_lshrdi (operands, operands[3]); DONE;")
6912
6913 (define_split 
6914   [(set (match_operand:DI 0 "register_operand" "")
6915         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6916                      (match_operand:QI 2 "nonmemory_operand" "")))
6917    (clobber (reg:CC 17))]
6918   "reload_completed"
6919   [(const_int 0)]
6920   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
6921
6922 (define_expand "lshrsi3"
6923   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6924         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
6925                      (match_operand:QI 2 "nonmemory_operand" "")))
6926    (clobber (reg:CC 17))]
6927   ""
6928   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
6929
6930 (define_insn "*lshrsi3_1_one_bit"
6931   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6932         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6933                      (match_operand:QI 2 "const_int_1_operand" "")))
6934    (clobber (reg:CC 17))]
6935   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
6936    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
6937   "shr{l}\\t%0"
6938   [(set_attr "type" "ishift")
6939    (set (attr "length") 
6940      (if_then_else (match_operand:SI 0 "register_operand" "") 
6941         (const_string "2")
6942         (const_string "*")))])
6943
6944 (define_insn "*lshrsi3_1"
6945   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6946         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6947                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6948    (clobber (reg:CC 17))]
6949   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6950   "@
6951    shr{l}\\t{%2, %0|%0, %2}
6952    shr{l}\\t{%b2, %0|%0, %b2}"
6953   [(set_attr "type" "ishift")
6954    (set_attr "mode" "SI")])
6955
6956 ;; This pattern can't accept a variable shift count, since shifts by
6957 ;; zero don't affect the flags.  We assume that shifts by constant
6958 ;; zero are optimized away.
6959 (define_insn "*lshrsi3_cmpno_one_bit"
6960   [(set (reg 17)
6961         (compare
6962           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6963                        (match_operand:QI 2 "const_int_1_operand" ""))
6964           (const_int 0)))
6965    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6966         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
6967   "ix86_match_ccmode (insn, CCNOmode)
6968    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
6969    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6970   "shr{l}\\t%0"
6971   [(set_attr "type" "ishift")
6972    (set (attr "length") 
6973      (if_then_else (match_operand:SI 0 "register_operand" "") 
6974         (const_string "2")
6975         (const_string "*")))])
6976
6977 ;; This pattern can't accept a variable shift count, since shifts by
6978 ;; zero don't affect the flags.  We assume that shifts by constant
6979 ;; zero are optimized away.
6980 (define_insn "*lshrsi3_cmpno"
6981   [(set (reg 17)
6982         (compare
6983           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6984                        (match_operand:QI 2 "immediate_operand" "I"))
6985           (const_int 0)))
6986    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6987         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
6988   "ix86_match_ccmode (insn, CCNOmode)
6989    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6990   "@
6991    shr{l}\\t{%2, %0|%0, %2}"
6992   [(set_attr "type" "ishift")
6993    (set_attr "mode" "SI")])
6994
6995 (define_expand "lshrhi3"
6996   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6997         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
6998                      (match_operand:QI 2 "nonmemory_operand" "")))
6999    (clobber (reg:CC 17))]
7000   "TARGET_HIMODE_MATH"
7001   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
7002
7003 (define_insn "*lshrhi3_1_one_bit"
7004   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7005         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7006                      (match_operand:QI 2 "const_int_1_operand" "")))
7007    (clobber (reg:CC 17))]
7008   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
7009    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7010   "shr{w}\\t%0"
7011   [(set_attr "type" "ishift")
7012    (set (attr "length") 
7013      (if_then_else (match_operand:SI 0 "register_operand" "") 
7014         (const_string "2")
7015         (const_string "*")))])
7016
7017 (define_insn "*lshrhi3_1"
7018   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
7019         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7020                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
7021    (clobber (reg:CC 17))]
7022   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
7023   "@
7024    shr{w}\\t{%2, %0|%0, %2}
7025    shr{w}\\t{%b2, %0|%0, %b2}"
7026   [(set_attr "type" "ishift")
7027    (set_attr "mode" "HI")])
7028
7029 ;; This pattern can't accept a variable shift count, since shifts by
7030 ;; zero don't affect the flags.  We assume that shifts by constant
7031 ;; zero are optimized away.
7032 (define_insn "*lshrhi3_cmpno_one_bit"
7033   [(set (reg 17)
7034         (compare
7035           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7036                        (match_operand:QI 2 "const_int_1_operand" ""))
7037           (const_int 0)))
7038    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7039         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
7040   "ix86_match_ccmode (insn, CCNOmode)
7041    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
7042    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
7043   "shr{w}\\t%0"
7044   [(set_attr "type" "ishift")
7045    (set (attr "length") 
7046      (if_then_else (match_operand:SI 0 "register_operand" "") 
7047         (const_string "2")
7048         (const_string "*")))])
7049
7050 ;; This pattern can't accept a variable shift count, since shifts by
7051 ;; zero don't affect the flags.  We assume that shifts by constant
7052 ;; zero are optimized away.
7053 (define_insn "*lshrhi3_cmpno"
7054   [(set (reg 17)
7055         (compare
7056           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7057                        (match_operand:QI 2 "immediate_operand" "I"))
7058           (const_int 0)))
7059    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7060         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
7061   "ix86_match_ccmode (insn, CCNOmode)
7062    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
7063   "@
7064    shr{w}\\t{%2, %0|%0, %2}"
7065   [(set_attr "type" "ishift")
7066    (set_attr "mode" "HI")])
7067
7068 (define_expand "lshrqi3"
7069   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7070         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
7071                      (match_operand:QI 2 "nonmemory_operand" "")))
7072    (clobber (reg:CC 17))]
7073   "TARGET_QIMODE_MATH"
7074   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
7075
7076 (define_insn "*lshrqi3_1_one_bit"
7077   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7078         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7079                      (match_operand:QI 2 "const_int_1_operand" "")))
7080    (clobber (reg:CC 17))]
7081   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
7082    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7083   "shr{b}\\t%0"
7084   [(set_attr "type" "ishift")
7085    (set (attr "length") 
7086      (if_then_else (match_operand:SI 0 "register_operand" "") 
7087         (const_string "2")
7088         (const_string "*")))])
7089
7090 (define_insn "*lshrqi3_1"
7091   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
7092         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7093                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
7094    (clobber (reg:CC 17))]
7095   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
7096   "@
7097    shr{b}\\t{%2, %0|%0, %2}
7098    shr{b}\\t{%b2, %0|%0, %b2}"
7099   [(set_attr "type" "ishift")
7100    (set_attr "mode" "QI")])
7101
7102 ;; This pattern can't accept a variable shift count, since shifts by
7103 ;; zero don't affect the flags.  We assume that shifts by constant
7104 ;; zero are optimized away.
7105 (define_insn "*lshrqi2_cmpno_one_bit"
7106   [(set (reg 17)
7107         (compare
7108           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7109                        (match_operand:QI 2 "const_int_1_operand" ""))
7110           (const_int 0)))
7111    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7112         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
7113   "ix86_match_ccmode (insn, CCNOmode)
7114    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
7115    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
7116   "shr{b}\\t%0"
7117   [(set_attr "type" "ishift")
7118    (set (attr "length") 
7119      (if_then_else (match_operand:SI 0 "register_operand" "") 
7120         (const_string "2")
7121         (const_string "*")))])
7122
7123 ;; This pattern can't accept a variable shift count, since shifts by
7124 ;; zero don't affect the flags.  We assume that shifts by constant
7125 ;; zero are optimized away.
7126 (define_insn "*lshrqi2_cmpno"
7127   [(set (reg 17)
7128         (compare
7129           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7130                        (match_operand:QI 2 "immediate_operand" "I"))
7131           (const_int 0)))
7132    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7133         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
7134   "ix86_match_ccmode (insn, CCNOmode)
7135    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
7136   "shr{b}\\t{%2, %0|%0, %2}"
7137   [(set_attr "type" "ishift")
7138    (set_attr "mode" "QI")])
7139 \f
7140 ;; Rotate instructions
7141
7142 (define_expand "rotlsi3"
7143   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7144         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
7145                    (match_operand:QI 2 "nonmemory_operand" "")))
7146    (clobber (reg:CC 17))]
7147   ""
7148   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
7149
7150 (define_insn "*rotlsi3_1_one_bit"
7151   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7152         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
7153                    (match_operand:QI 2 "const_int_1_operand" "")))
7154    (clobber (reg:CC 17))]
7155   "ix86_binary_operator_ok (ROTATE, SImode, operands)
7156    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7157   "rol{l}\\t%0"
7158   [(set_attr "type" "ishift")
7159    (set (attr "length") 
7160      (if_then_else (match_operand:SI 0 "register_operand" "") 
7161         (const_string "2")
7162         (const_string "*")))])
7163
7164 (define_insn "*rotlsi3_1"
7165   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7166         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7167                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
7168    (clobber (reg:CC 17))]
7169   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
7170   "@
7171    rol{l}\\t{%2, %0|%0, %2}
7172    rol{l}\\t{%b2, %0|%0, %b2}"
7173   [(set_attr "type" "ishift")
7174    (set_attr "mode" "SI")])
7175
7176 (define_expand "rotlhi3"
7177   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7178         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
7179                    (match_operand:QI 2 "nonmemory_operand" "")))
7180    (clobber (reg:CC 17))]
7181   "TARGET_HIMODE_MATH"
7182   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
7183
7184 (define_insn "*rotlhi3_1_one_bit"
7185   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7186         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7187                    (match_operand:QI 2 "const_int_1_operand" "")))
7188    (clobber (reg:CC 17))]
7189   "ix86_binary_operator_ok (ROTATE, HImode, operands)
7190    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7191   "rol{w}\\t%0"
7192   [(set_attr "type" "ishift")
7193    (set (attr "length") 
7194      (if_then_else (match_operand:SI 0 "register_operand" "") 
7195         (const_string "2")
7196         (const_string "*")))])
7197
7198 (define_insn "*rotlhi3_1"
7199   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
7200         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7201                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
7202    (clobber (reg:CC 17))]
7203   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
7204   "@
7205    rol{w}\\t{%2, %0|%0, %2}
7206    rol{w}\\t{%b2, %0|%0, %b2}"
7207   [(set_attr "type" "ishift")
7208    (set_attr "mode" "HI")])
7209
7210 (define_expand "rotlqi3"
7211   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7212         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
7213                    (match_operand:QI 2 "nonmemory_operand" "")))
7214    (clobber (reg:CC 17))]
7215   "TARGET_QIMODE_MATH"
7216   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
7217
7218 (define_insn "*rotlqi3_1_one_bit"
7219   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7220         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7221                    (match_operand:QI 2 "const_int_1_operand" "")))
7222    (clobber (reg:CC 17))]
7223   "ix86_binary_operator_ok (ROTATE, QImode, operands)
7224    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7225   "rol{b}\\t%0"
7226   [(set_attr "type" "ishift")
7227    (set (attr "length") 
7228      (if_then_else (match_operand:SI 0 "register_operand" "") 
7229         (const_string "2")
7230         (const_string "*")))])
7231
7232 (define_insn "*rotlqi3_1"
7233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
7234         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7235                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
7236    (clobber (reg:CC 17))]
7237   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
7238   "@
7239    rol{b}\\t{%2, %0|%0, %2}
7240    rol{b}\\t{%b2, %0|%0, %b2}"
7241   [(set_attr "type" "ishift")
7242    (set_attr "mode" "QI")])
7243
7244 (define_expand "rotrsi3"
7245   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7246         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
7247                      (match_operand:QI 2 "nonmemory_operand" "")))
7248    (clobber (reg:CC 17))]
7249   ""
7250   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
7251
7252 (define_insn "*rotrsi3_1_one_bit"
7253   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7254         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
7255                      (match_operand:QI 2 "const_int_1_operand" "")))
7256    (clobber (reg:CC 17))]
7257   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
7258    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7259   "ror{l}\\t%0"
7260   [(set_attr "type" "ishift")
7261    (set (attr "length") 
7262      (if_then_else (match_operand:SI 0 "register_operand" "") 
7263         (const_string "2")
7264         (const_string "*")))])
7265
7266 (define_insn "*rotrsi3_1"
7267   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7268         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7269                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
7270    (clobber (reg:CC 17))]
7271   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
7272   "@
7273    ror{l}\\t{%2, %0|%0, %2}
7274    ror{l}\\t{%b2, %0|%0, %b2}"
7275   [(set_attr "type" "ishift")
7276    (set_attr "mode" "SI")])
7277
7278 (define_expand "rotrhi3"
7279   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7280         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
7281                      (match_operand:QI 2 "nonmemory_operand" "")))
7282    (clobber (reg:CC 17))]
7283   "TARGET_HIMODE_MATH"
7284   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
7285
7286 (define_insn "*rotrhi3_one_bit"
7287   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7288         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7289                      (match_operand:QI 2 "const_int_1_operand" "")))
7290    (clobber (reg:CC 17))]
7291   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
7292    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7293   "ror{w}\\t%0"
7294   [(set_attr "type" "ishift")
7295    (set (attr "length") 
7296      (if_then_else (match_operand:SI 0 "register_operand" "") 
7297         (const_string "2")
7298         (const_string "*")))])
7299
7300 (define_insn "*rotrhi3"
7301   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
7302         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7303                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
7304    (clobber (reg:CC 17))]
7305   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
7306   "@
7307    ror{w}\\t{%2, %0|%0, %2}
7308    ror{w}\\t{%b2, %0|%0, %b2}"
7309   [(set_attr "type" "ishift")
7310    (set_attr "mode" "HI")])
7311
7312 (define_expand "rotrqi3"
7313   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7314         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
7315                      (match_operand:QI 2 "nonmemory_operand" "")))
7316    (clobber (reg:CC 17))]
7317   "TARGET_QIMODE_MATH"
7318   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
7319
7320 (define_insn "*rotrqi3_1_one_bit"
7321   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7322         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7323                      (match_operand:QI 2 "const_int_1_operand" "")))
7324    (clobber (reg:CC 17))]
7325   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
7326    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7327   "ror{b}\\t%0"
7328   [(set_attr "type" "ishift")
7329    (set (attr "length") 
7330      (if_then_else (match_operand:SI 0 "register_operand" "") 
7331         (const_string "2")
7332         (const_string "*")))])
7333
7334 (define_insn "*rotrqi3_1"
7335   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
7336         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7337                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
7338    (clobber (reg:CC 17))]
7339   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
7340   "@
7341    ror{b}\\t{%2, %0|%0, %2}
7342    ror{b}\\t{%b2, %0|%0, %b2}"
7343   [(set_attr "type" "ishift")
7344    (set_attr "mode" "QI")])
7345 \f
7346 ;; Bit set / bit test instructions
7347
7348 (define_expand "extv"
7349   [(set (match_operand:SI 0 "register_operand" "")
7350         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
7351                          (match_operand:SI 2 "immediate_operand" "")
7352                          (match_operand:SI 3 "immediate_operand" "")))]
7353   ""
7354   "
7355 {
7356   /* Handle extractions from %ah et al.  */
7357   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
7358     FAIL;
7359
7360   /* From mips.md: extract_bit_field doesn't verify that our source
7361      matches the predicate, so check it again here.  */
7362   if (! register_operand (operands[1], VOIDmode))
7363     FAIL;
7364 }")
7365
7366 (define_expand "extzv"
7367   [(set (match_operand:SI 0 "register_operand" "")
7368         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
7369                          (match_operand:SI 2 "immediate_operand" "")
7370                          (match_operand:SI 3 "immediate_operand" "")))]
7371   ""
7372   "
7373 {
7374   /* Handle extractions from %ah et al.  */
7375   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
7376     FAIL;
7377
7378   /* From mips.md: extract_bit_field doesn't verify that our source
7379      matches the predicate, so check it again here.  */
7380   if (! register_operand (operands[1], VOIDmode))
7381     FAIL;
7382 }")
7383
7384 (define_expand "insv"
7385   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
7386                          (match_operand:SI 1 "immediate_operand" "")
7387                          (match_operand:SI 2 "immediate_operand" ""))
7388         (match_operand:SI 3 "register_operand" ""))]
7389   ""
7390   "
7391 {
7392   /* Handle extractions from %ah et al.  */
7393   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
7394     FAIL;
7395
7396   /* From mips.md: insert_bit_field doesn't verify that our source
7397      matches the predicate, so check it again here.  */
7398   if (! register_operand (operands[0], VOIDmode))
7399     FAIL;
7400 }")
7401
7402 ;; %%% bts, btr, btc, bt.
7403 \f
7404 ;; Store-flag instructions.
7405
7406 ;; For all sCOND expanders, also expand the compare or test insn that
7407 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
7408
7409 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
7410 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
7411 ;; way, which can later delete the movzx if only QImode is needed.
7412
7413 (define_expand "seq"
7414   [(set (match_operand:SI 0 "register_operand" "")
7415         (eq:SI (reg:CC 17) (const_int 0)))]
7416   ""
7417   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
7418
7419 (define_expand "sne"
7420   [(set (match_operand:SI 0 "register_operand" "")
7421         (ne:SI (reg:CC 17) (const_int 0)))]
7422   ""
7423   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
7424
7425 (define_expand "sgt"
7426   [(set (match_operand:SI 0 "register_operand" "")
7427         (gt:SI (reg:CC 17) (const_int 0)))]
7428   ""
7429   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
7430
7431 (define_expand "sgtu"
7432   [(set (match_operand:SI 0 "register_operand" "")
7433         (gtu:SI (reg:CC 17) (const_int 0)))]
7434   ""
7435   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
7436
7437 (define_expand "slt"
7438   [(set (match_operand:SI 0 "register_operand" "")
7439         (lt:SI (reg:CC 17) (const_int 0)))]
7440   ""
7441   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
7442
7443 (define_expand "sltu"
7444   [(set (match_operand:SI 0 "register_operand" "")
7445         (ltu:SI (reg:CC 17) (const_int 0)))]
7446   ""
7447   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
7448
7449 (define_expand "sge"
7450   [(set (match_operand:SI 0 "register_operand" "")
7451         (ge:SI (reg:CC 17) (const_int 0)))]
7452   ""
7453   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
7454
7455 (define_expand "sgeu"
7456   [(set (match_operand:SI 0 "register_operand" "")
7457         (geu:SI (reg:CC 17) (const_int 0)))]
7458   ""
7459   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
7460
7461 (define_expand "sle"
7462   [(set (match_operand:SI 0 "register_operand" "")
7463         (le:SI (reg:CC 17) (const_int 0)))]
7464   ""
7465   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
7466
7467 (define_expand "sleu"
7468   [(set (match_operand:SI 0 "register_operand" "")
7469         (leu:SI (reg:CC 17) (const_int 0)))]
7470   ""
7471   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
7472
7473 (define_expand "sunordered"
7474   [(set (match_operand:SI 0 "register_operand" "")
7475         (unordered:SI (reg:CC 17) (const_int 0)))]
7476   "TARGET_80387"
7477   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
7478
7479 (define_expand "sordered"
7480   [(set (match_operand:SI 0 "register_operand" "")
7481         (ordered:SI (reg:CC 17) (const_int 0)))]
7482   "TARGET_80387"
7483   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
7484
7485 (define_expand "suneq"
7486   [(set (match_operand:SI 0 "register_operand" "")
7487         (uneq:SI (reg:CC 17) (const_int 0)))]
7488   "TARGET_80387"
7489   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
7490
7491 (define_expand "sunge"
7492   [(set (match_operand:SI 0 "register_operand" "")
7493         (unge:SI (reg:CC 17) (const_int 0)))]
7494   "TARGET_80387"
7495   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
7496
7497 (define_expand "sungt"
7498   [(set (match_operand:SI 0 "register_operand" "")
7499         (ungt:SI (reg:CC 17) (const_int 0)))]
7500   "TARGET_80387"
7501   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
7502
7503 (define_expand "sunle"
7504   [(set (match_operand:SI 0 "register_operand" "")
7505         (unle:SI (reg:CC 17) (const_int 0)))]
7506   "TARGET_80387"
7507   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
7508
7509 (define_expand "sunlt"
7510   [(set (match_operand:SI 0 "register_operand" "")
7511         (unlt:SI (reg:CC 17) (const_int 0)))]
7512   "TARGET_80387"
7513   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
7514
7515 (define_expand "sltgt"
7516   [(set (match_operand:SI 0 "register_operand" "")
7517         (ltgt:SI (reg:CC 17) (const_int 0)))]
7518   "TARGET_80387"
7519   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
7520
7521 (define_insn "*setcc_1"
7522   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7523         (match_operator:QI 1 "no_comparison_operator"
7524           [(reg 17) (const_int 0)]))]
7525   ""
7526   "set%C1\\t%0"
7527   [(set_attr "type" "setcc")
7528    (set_attr "mode" "QI")])
7529
7530 (define_insn "*setcc_2"
7531   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
7532         (match_operator:QI 1 "no_comparison_operator"
7533           [(reg 17) (const_int 0)]))]
7534   ""
7535   "set%C1\\t%0"
7536   [(set_attr "type" "setcc")
7537    (set_attr "mode" "QI")])
7538
7539 (define_insn "*setcc_3"
7540   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7541         (match_operator:QI 1 "uno_comparison_operator"
7542           [(reg:CC 17) (const_int 0)]))]
7543   ""
7544   "set%C1\\t%0"
7545   [(set_attr "type" "setcc")
7546    (set_attr "mode" "QI")])
7547
7548 (define_insn "*setcc_4"
7549   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
7550         (match_operator:QI 1 "uno_comparison_operator"
7551           [(reg:CC 17) (const_int 0)]))]
7552   ""
7553   "set%C1\\t%0"
7554   [(set_attr "type" "setcc")
7555    (set_attr "mode" "QI")])
7556 \f
7557 ;; Basic conditional jump instructions.
7558 ;; We ignore the overflow flag for signed branch instructions.
7559
7560 ;; For all bCOND expanders, also expand the compare or test insn that
7561 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
7562
7563 (define_expand "beq"
7564   [(set (pc)
7565         (if_then_else (match_dup 1)
7566                       (label_ref (match_operand 0 "" ""))
7567                       (pc)))]
7568   ""
7569   "ix86_expand_branch (EQ, operands[0]); DONE;")
7570
7571 (define_expand "bne"
7572   [(set (pc)
7573         (if_then_else (match_dup 1)
7574                       (label_ref (match_operand 0 "" ""))
7575                       (pc)))]
7576   ""
7577   "ix86_expand_branch (NE, operands[0]); DONE;")
7578
7579 (define_expand "bgt"
7580   [(set (pc)
7581         (if_then_else (match_dup 1)
7582                       (label_ref (match_operand 0 "" ""))
7583                       (pc)))]
7584   ""
7585   "ix86_expand_branch (GT, operands[0]); DONE;")
7586
7587 (define_expand "bgtu"
7588   [(set (pc)
7589         (if_then_else (match_dup 1)
7590                       (label_ref (match_operand 0 "" ""))
7591                       (pc)))]
7592   ""
7593   "ix86_expand_branch (GTU, operands[0]); DONE;")
7594
7595 (define_expand "blt"
7596   [(set (pc)
7597         (if_then_else (match_dup 1)
7598                       (label_ref (match_operand 0 "" ""))
7599                       (pc)))]
7600   ""
7601   "ix86_expand_branch (LT, operands[0]); DONE;")
7602
7603 (define_expand "bltu"
7604   [(set (pc)
7605         (if_then_else (match_dup 1)
7606                       (label_ref (match_operand 0 "" ""))
7607                       (pc)))]
7608   ""
7609   "ix86_expand_branch (LTU, operands[0]); DONE;")
7610
7611 (define_expand "bge"
7612   [(set (pc)
7613         (if_then_else (match_dup 1)
7614                       (label_ref (match_operand 0 "" ""))
7615                       (pc)))]
7616   ""
7617   "ix86_expand_branch (GE, operands[0]); DONE;")
7618
7619 (define_expand "bgeu"
7620   [(set (pc)
7621         (if_then_else (match_dup 1)
7622                       (label_ref (match_operand 0 "" ""))
7623                       (pc)))]
7624   ""
7625   "ix86_expand_branch (GEU, operands[0]); DONE;")
7626
7627 (define_expand "ble"
7628   [(set (pc)
7629         (if_then_else (match_dup 1)
7630                       (label_ref (match_operand 0 "" ""))
7631                       (pc)))]
7632   ""
7633   "ix86_expand_branch (LE, operands[0]); DONE;")
7634
7635 (define_expand "bleu"
7636   [(set (pc)
7637         (if_then_else (match_dup 1)
7638                       (label_ref (match_operand 0 "" ""))
7639                       (pc)))]
7640   ""
7641   "ix86_expand_branch (LEU, operands[0]); DONE;")
7642
7643 (define_expand "bunordered"
7644   [(set (pc)
7645         (if_then_else (match_dup 1)
7646                       (label_ref (match_operand 0 "" ""))
7647                       (pc)))]
7648   "TARGET_80387"
7649   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
7650
7651 (define_expand "bordered"
7652   [(set (pc)
7653         (if_then_else (match_dup 1)
7654                       (label_ref (match_operand 0 "" ""))
7655                       (pc)))]
7656   "TARGET_80387"
7657   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
7658
7659 (define_expand "buneq"
7660   [(set (pc)
7661         (if_then_else (match_dup 1)
7662                       (label_ref (match_operand 0 "" ""))
7663                       (pc)))]
7664   "TARGET_80387"
7665   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
7666
7667 (define_expand "bunge"
7668   [(set (pc)
7669         (if_then_else (match_dup 1)
7670                       (label_ref (match_operand 0 "" ""))
7671                       (pc)))]
7672   "TARGET_80387"
7673   "ix86_expand_branch (UNGE, operands[0]); DONE;")
7674
7675 (define_expand "bungt"
7676   [(set (pc)
7677         (if_then_else (match_dup 1)
7678                       (label_ref (match_operand 0 "" ""))
7679                       (pc)))]
7680   "TARGET_80387"
7681   "ix86_expand_branch (UNGT, operands[0]); DONE;")
7682
7683 (define_expand "bunle"
7684   [(set (pc)
7685         (if_then_else (match_dup 1)
7686                       (label_ref (match_operand 0 "" ""))
7687                       (pc)))]
7688   "TARGET_80387"
7689   "ix86_expand_branch (UNLE, operands[0]); DONE;")
7690
7691 (define_expand "bunlt"
7692   [(set (pc)
7693         (if_then_else (match_dup 1)
7694                       (label_ref (match_operand 0 "" ""))
7695                       (pc)))]
7696   "TARGET_80387"
7697   "ix86_expand_branch (UNLT, operands[0]); DONE;")
7698
7699 (define_expand "bltgt"
7700   [(set (pc)
7701         (if_then_else (match_dup 1)
7702                       (label_ref (match_operand 0 "" ""))
7703                       (pc)))]
7704   "TARGET_80387"
7705   "ix86_expand_branch (LTGT, operands[0]); DONE;")
7706
7707 (define_insn "*jcc_1"
7708   [(set (pc)
7709         (if_then_else (match_operator 1 "no_comparison_operator"
7710                                       [(reg 17) (const_int 0)])
7711                       (label_ref (match_operand 0 "" ""))
7712                       (pc)))]
7713   ""
7714   "j%C1\\t%l0"
7715   [(set_attr "type" "ibr")
7716    (set (attr "prefix_0f")
7717            (if_then_else (and (ge (minus (match_dup 0) (pc))
7718                                   (const_int -128))
7719                               (lt (minus (match_dup 0) (pc))
7720                                   (const_int 124)))
7721              (const_int 0)
7722              (const_int 1)))])
7723
7724 (define_insn "*jcc_2"
7725   [(set (pc)
7726         (if_then_else (match_operator 1 "no_comparison_operator"
7727                                       [(reg 17) (const_int 0)])
7728                       (pc)
7729                       (label_ref (match_operand 0 "" ""))))]
7730   ""
7731   "j%c1\\t%l0"
7732   [(set_attr "type" "ibr")
7733    (set (attr "prefix_0f")
7734            (if_then_else (and (ge (minus (match_dup 0) (pc))
7735                                   (const_int -128))
7736                               (lt (minus (match_dup 0) (pc))
7737                                   (const_int 124)))
7738              (const_int 0)
7739              (const_int 1)))])
7740
7741 (define_insn "*jcc_3"
7742   [(set (pc)
7743         (if_then_else (match_operator 1 "uno_comparison_operator"
7744                                       [(reg:CC 17) (const_int 0)])
7745                       (label_ref (match_operand 0 "" ""))
7746                       (pc)))]
7747   ""
7748   "j%C1\\t%l0"
7749   [(set_attr "type" "ibr")
7750    (set (attr "prefix_0f")
7751            (if_then_else (and (ge (minus (match_dup 0) (pc))
7752                                   (const_int -128))
7753                               (lt (minus (match_dup 0) (pc))
7754                                   (const_int 124)))
7755              (const_int 0)
7756              (const_int 1)))])
7757
7758 (define_insn "*jcc_4"
7759   [(set (pc)
7760         (if_then_else (match_operator 1 "uno_comparison_operator"
7761                                       [(reg:CC 17) (const_int 0)])
7762                       (pc)
7763                       (label_ref (match_operand 0 "" ""))))]
7764   ""
7765   "j%c1\\t%l0"
7766   [(set_attr "type" "ibr")
7767    (set (attr "prefix_0f")
7768            (if_then_else (and (ge (minus (match_dup 0) (pc))
7769                                   (const_int -128))
7770                               (lt (minus (match_dup 0) (pc))
7771                                   (const_int 124)))
7772              (const_int 0)
7773              (const_int 1)))])
7774
7775 ;; Define combination compare-and-branch fp compare instructions to use
7776 ;; during early optimization.  Splitting the operation apart early makes
7777 ;; for bad code when we want to reverse the operation.
7778
7779 (define_insn "*fp_jcc_1"
7780   [(set (pc)
7781         (if_then_else (match_operator 0 "comparison_operator"
7782                         [(match_operand 1 "register_operand" "f")
7783                          (match_operand 2 "register_operand" "f")])
7784           (label_ref (match_operand 3 "" ""))
7785           (pc)))
7786    (clobber (reg:CCFP 18))
7787    (clobber (reg:CCFP 17))]
7788   "TARGET_CMOVE && TARGET_80387
7789    && FLOAT_MODE_P (GET_MODE (operands[1]))
7790    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7791   "#")
7792
7793 (define_insn "*fp_jcc_2"
7794   [(set (pc)
7795         (if_then_else (match_operator 0 "comparison_operator"
7796                         [(match_operand 1 "register_operand" "f")
7797                          (match_operand 2 "register_operand" "f")])
7798           (pc)
7799           (label_ref (match_operand 3 "" ""))))
7800    (clobber (reg:CCFP 18))
7801    (clobber (reg:CCFP 17))]
7802   "TARGET_CMOVE && TARGET_80387
7803    && FLOAT_MODE_P (GET_MODE (operands[1]))
7804    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7805   "#")
7806
7807 (define_insn "*fp_jcc_3"
7808   [(set (pc)
7809         (if_then_else (match_operator:CCFP 0 "comparison_operator"
7810                         [(match_operand 1 "register_operand" "f")
7811                          (match_operand 2 "nonimmediate_operand" "fm")])
7812           (label_ref (match_operand 3 "" ""))
7813           (pc)))
7814    (clobber (reg:CCFP 18))
7815    (clobber (reg:CCFP 17))
7816    (clobber (match_scratch:HI 4 "=a"))]
7817   "TARGET_80387
7818    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
7819    && GET_MODE (operands[1]) == GET_MODE (operands[2])
7820    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
7821   "#")
7822
7823 (define_insn "*fp_jcc_4"
7824   [(set (pc)
7825         (if_then_else (match_operator:CCFP 0 "comparison_operator"
7826                         [(match_operand 1 "register_operand" "f")
7827                          (match_operand 2 "nonimmediate_operand" "fm")])
7828           (pc)
7829           (label_ref (match_operand 3 "" ""))))
7830    (clobber (reg:CCFP 18))
7831    (clobber (reg:CCFP 17))
7832    (clobber (match_scratch:HI 4 "=a"))]
7833   "TARGET_80387
7834    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
7835    && GET_MODE (operands[1]) == GET_MODE (operands[2])
7836    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
7837   "#")
7838
7839 (define_insn "*fp_jcc_5"
7840   [(set (pc)
7841         (if_then_else (match_operator 0 "comparison_operator"
7842                         [(match_operand 1 "register_operand" "f")
7843                          (match_operand 2 "register_operand" "f")])
7844           (label_ref (match_operand 3 "" ""))
7845           (pc)))
7846    (clobber (reg:CCFP 18))
7847    (clobber (reg:CCFP 17))
7848    (clobber (match_scratch:HI 4 "=a"))]
7849   "TARGET_80387
7850    && FLOAT_MODE_P (GET_MODE (operands[1]))
7851    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7852   "#")
7853
7854 (define_insn "*fp_jcc_6"
7855   [(set (pc)
7856         (if_then_else (match_operator 0 "comparison_operator"
7857                         [(match_operand 1 "register_operand" "f")
7858                          (match_operand 2 "register_operand" "f")])
7859           (pc)
7860           (label_ref (match_operand 3 "" ""))))
7861    (clobber (reg:CCFP 18))
7862    (clobber (reg:CCFP 17))
7863    (clobber (match_scratch:HI 4 "=a"))]
7864   "TARGET_80387
7865    && FLOAT_MODE_P (GET_MODE (operands[1]))
7866    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7867   "#")
7868
7869 (define_split
7870   [(set (pc)
7871         (if_then_else (match_operator 0 "comparison_operator"
7872                         [(match_operand 1 "register_operand" "")
7873                          (match_operand 2 "nonimmediate_operand" "")])
7874           (match_operand 3 "" "")
7875           (match_operand 4 "" "")))
7876    (clobber (reg:CCFP 18))
7877    (clobber (reg:CCFP 17))]
7878   "reload_completed"
7879   [(set (pc)
7880         (if_then_else (match_dup 5)
7881           (match_dup 3)
7882           (match_dup 4)))]
7883   "
7884 {
7885   operands[5] = ix86_expand_fp_compare (GET_CODE (operands[0]), operands[1],
7886                                         operands[2], NULL_RTX);
7887 }")
7888
7889 (define_split
7890   [(set (pc)
7891         (if_then_else (match_operator 0 "comparison_operator"
7892                         [(match_operand 1 "register_operand" "")
7893                          (match_operand 2 "nonimmediate_operand" "")])
7894           (match_operand 3 "" "")
7895           (match_operand 4 "" "")))
7896    (clobber (reg:CCFP 18))
7897    (clobber (reg:CCFP 17))
7898    (clobber (match_scratch:HI 5 "=a"))]
7899   "reload_completed"
7900   [(set (pc)
7901         (if_then_else (match_dup 6)
7902           (match_dup 3)
7903           (match_dup 4)))]
7904   "
7905 {
7906   operands[6] = ix86_expand_fp_compare (GET_CODE (operands[0]), operands[1],
7907                                         operands[2], operands[5]);
7908 }")
7909 \f
7910 ;; Unconditional and other jump instructions
7911
7912 (define_insn "jump"
7913   [(set (pc)
7914         (label_ref (match_operand 0 "" "")))]
7915   ""
7916   "jmp\\t%l0"
7917   [(set_attr "type" "ibr")])
7918
7919 (define_insn "indirect_jump"
7920   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
7921   ""
7922   "jmp\\t%*%0"
7923   [(set_attr "type" "ibr")
7924    (set_attr "length_immediate" "0")])
7925
7926 (define_insn "tablejump"
7927   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
7928    (use (label_ref (match_operand 1 "" "")))]
7929   "! flag_pic"
7930   "jmp\\t%*%0"
7931   [(set_attr "type" "ibr")
7932    (set_attr "length_immediate" "0")])
7933
7934 ;; Implement switch statements when generating PIC code.  Switches are
7935 ;; implemented by `tablejump' when not using -fpic.
7936 ;;
7937 ;; Emit code here to do the range checking and make the index zero based.
7938 ;;
7939 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
7940 ;; two rules below:
7941 ;; 
7942 ;;      .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
7943 ;; 
7944 ;; 1. An expression involving an external reference may only use the
7945 ;;    addition operator, and only with an assembly-time constant.
7946 ;;    The example above satisfies this because ".-.L2" is a constant.
7947 ;; 
7948 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
7949 ;;    given the value of "GOT - .", where GOT is the actual address of
7950 ;;    the Global Offset Table.  Therefore, the .long above actually
7951 ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
7952 ;;    expression "GOT - .L2" by itself would generate an error from as(1).
7953 ;; 
7954 ;; The pattern below emits code that looks like this:
7955 ;; 
7956 ;;      movl %ebx,reg
7957 ;;      subl TABLE@GOTOFF(%ebx,index,4),reg
7958 ;;      jmp reg
7959 ;; 
7960 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
7961 ;; the addr_diff_vec is known to be part of this module.
7962 ;; 
7963 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
7964 ;; evaluates to just ".L2".
7965
7966 (define_expand "casesi"
7967   [(set (match_dup 5)
7968         (match_operand:SI 0 "general_operand" ""))
7969    (parallel [(set (match_dup 6)
7970                    (minus:SI (match_dup 5)
7971                              (match_operand:SI 1 "general_operand" "")))
7972               (clobber (reg:CC 17))])
7973    (set (reg:CC 17)
7974         (compare:CC (match_dup 6)
7975                     (match_operand:SI 2 "general_operand" "")))
7976    (set (pc)
7977         (if_then_else (gtu (reg:CC 17)
7978                            (const_int 0))
7979                       (label_ref (match_operand 4 "" ""))
7980                       (pc)))
7981    (parallel
7982      [(set (match_dup 7)
7983            (minus:SI (match_dup 8)
7984              (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
7985                               (match_dup 8))
7986                      (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
7987       (clobber (reg:CC 17))])
7988    (parallel [(set (pc) (match_dup 7))
7989               (use (label_ref (match_dup 3)))])]
7990   "flag_pic"
7991   "
7992 {
7993   operands[5] = gen_reg_rtx (SImode);
7994   operands[6] = gen_reg_rtx (SImode);
7995   operands[7] = gen_reg_rtx (SImode);
7996   operands[8] = pic_offset_table_rtx;
7997   current_function_uses_pic_offset_table = 1;
7998 }")
7999
8000 (define_insn "*tablejump_pic"
8001   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
8002    (use (label_ref (match_operand 1 "" "")))]
8003   ""
8004   "jmp\\t%*%0"
8005   [(set_attr "type" "ibr")
8006    (set_attr "length_immediate" "0")])
8007 \f
8008 ;; Loop instruction
8009 ;;
8010 ;; This is all complicated by the fact that since this is a jump insn
8011 ;; we must handle our own reloads.
8012
8013 (define_expand "decrement_and_branch_on_count"
8014   [(parallel [(set (pc) (if_then_else
8015                           (ne (match_operand:SI 0 "register_operand" "")
8016                               (const_int 1))
8017                           (label_ref (match_operand 1 "" ""))
8018                           (pc)))
8019               (set (match_dup 0)
8020                    (plus:SI (match_dup 0)
8021                             (const_int -1)))
8022               (clobber (match_scratch:SI 2 ""))
8023               (clobber (reg:CC 17))])]
8024   "TARGET_USE_LOOP"
8025   "")
8026
8027 (define_insn "*dbra_ne"
8028   [(set (pc)
8029         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
8030                           (const_int 1))
8031                       (label_ref (match_operand 0 "" ""))
8032                       (pc)))
8033    (set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
8034         (plus:SI (match_dup 1)
8035                  (const_int -1)))
8036    (clobber (match_scratch:SI 3 "=X,X,r"))
8037    (clobber (reg:CC 17))]
8038   "TARGET_USE_LOOP"
8039   "*
8040 {
8041   if (which_alternative != 0)
8042     return \"#\";
8043   if (get_attr_length (insn) == 2)
8044     return \"loop\\t%l0\";
8045   else
8046     return \"dec{l}\\t%1\;jne\\t%l0\";
8047 }"
8048   [(set_attr "ppro_uops" "many")
8049    (set (attr "type")
8050         (if_then_else (and (eq_attr "alternative" "0")
8051                            (and (ge (minus (match_dup 0) (pc))
8052                                     (const_int -128))
8053                                 (lt (minus (match_dup 0) (pc))
8054                                     (const_int 124))))
8055                       (const_string "ibr")
8056                       (const_string "multi")))])
8057
8058 (define_insn "*dbra_ge"
8059   [(set (pc)
8060         (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
8061                           (const_int 0))
8062                       (label_ref (match_operand 0 "" ""))
8063                       (pc)))
8064    (set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
8065         (plus:SI (match_dup 1)
8066                  (const_int -1)))
8067    (clobber (match_scratch:SI 3 "=X,X,r"))
8068    (clobber (reg:CC 17))]
8069   "TARGET_USE_LOOP && find_reg_note (insn, REG_NONNEG, 0)"
8070   "*
8071 {
8072   if (which_alternative != 0)
8073     return \"#\";
8074   if (get_attr_length (insn) == 2)
8075     return \"loop\\t%l0\";
8076   else
8077     return \"dec{l}\\t%1\;jne\\t%l0\";
8078 }"
8079   [(set (attr "type")
8080         (if_then_else (and (eq_attr "alternative" "0")
8081                            (and (ge (minus (match_dup 0) (pc))
8082                                     (const_int -128))
8083                                 (lt (minus (match_dup 0) (pc))
8084                                     (const_int 124))))
8085                       (const_string "ibr")
8086                       (const_string "multi")))
8087    (set_attr "ppro_uops" "many")])
8088
8089 (define_split
8090   [(set (pc)
8091         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
8092                           (const_int 1))
8093                       (match_operand 0 "" "")
8094                       (pc)))
8095    (set (match_operand:SI 2 "register_operand" "")
8096         (plus:SI (match_dup 1)
8097                  (const_int -1)))
8098    (clobber (match_scratch:SI 3 ""))
8099    (clobber (reg:CC 17))]
8100   "TARGET_USE_LOOP && reload_completed
8101    && ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
8102   [(set (match_dup 2) (match_dup 1))
8103    (parallel [(set (reg:CCZ 17)
8104                    (compare:CCZ (plus:SI (match_dup 2) (const_int -1))
8105                                  (const_int 0)))
8106               (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
8107    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
8108                            (match_dup 0)
8109                            (pc)))]
8110   "")
8111   
8112 (define_split
8113   [(set (pc)
8114         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
8115                           (const_int 1))
8116                       (match_operand 0 "" "")
8117                       (pc)))
8118    (set (match_operand:SI 2 "memory_operand" "")
8119         (plus:SI (match_dup 1)
8120                  (const_int -1)))
8121    (clobber (match_scratch:SI 3 ""))
8122    (clobber (reg:CC 17))]
8123   "TARGET_USE_LOOP && reload_completed"
8124   [(set (match_dup 3) (match_dup 1))
8125    (parallel [(set (reg:CCZ 17)
8126                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
8127                                 (const_int 0)))
8128               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
8129    (set (match_dup 2) (match_dup 3))
8130    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
8131                            (match_dup 0)
8132                            (pc)))]
8133   "")
8134
8135 (define_split
8136   [(set (pc)
8137         (if_then_else (ge (match_operand:SI 1 "register_operand" "")
8138                           (const_int 0))
8139                       (match_operand 0 "" "")
8140                       (pc)))
8141    (set (match_operand:SI 2 "register_operand" "")
8142         (plus:SI (match_dup 1)
8143                  (const_int -1)))
8144    (clobber (match_scratch:SI 3 ""))
8145    (clobber (reg:CC 17))]
8146   "TARGET_USE_LOOP && reload_completed
8147    && ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
8148   [(set (match_dup 2) (match_dup 1))
8149    (parallel [(set (reg:CCNO 17)
8150                    (compare:CCNO (plus:SI (match_dup 2) (const_int -1))
8151                                  (const_int 0)))
8152               (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
8153    (set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
8154                            (match_dup 0)
8155                            (pc)))]
8156   "")
8157   
8158 (define_split
8159   [(set (pc)
8160         (if_then_else (ge (match_operand:SI 1 "register_operand" "")
8161                           (const_int 0))
8162                       (match_operand 0 "" "")
8163                       (pc)))
8164    (set (match_operand:SI 2 "memory_operand" "")
8165         (plus:SI (match_dup 1)
8166                  (const_int -1)))
8167    (clobber (match_scratch:SI 3 ""))
8168    (clobber (reg:CC 17))]
8169   "TARGET_USE_LOOP && reload_completed"
8170   [(set (match_dup 3) (match_dup 1))
8171    (parallel [(set (reg:CCNO 17)
8172                    (compare:CCNO (plus:SI (match_dup 3) (const_int -1))
8173                                  (const_int 0)))
8174               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
8175    (set (match_dup 2) (match_dup 3))
8176    (set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
8177                            (match_dup 0)
8178                            (pc)))]
8179   "")
8180 \f
8181 ;; Call instructions.
8182
8183 ;; The predicates normally associated with named expanders are not properly
8184 ;; checked for calls.  This is a bug in the generic code, but it isn't that
8185 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
8186
8187 ;; Call subroutine returning no value.
8188
8189 (define_expand "call_pop"
8190   [(parallel [(call (match_operand:QI 0 "" "")
8191                     (match_operand:SI 1 "" ""))
8192               (set (reg:SI 7)
8193                    (plus:SI (reg:SI 7)
8194                             (match_operand:SI 3 "" "")))])]
8195   ""
8196   "
8197 {
8198   if (operands[3] == const0_rtx)
8199     {
8200       emit_insn (gen_call (operands[0], operands[1]));
8201       DONE;
8202     }
8203   /* Static functions and indirect calls don't need
8204      current_function_uses_pic_offset_table.  */
8205   if (flag_pic
8206       && constant_call_address_operand (operands[0], SImode)
8207       && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF
8208           || !SYMBOL_REF_FLAG (XEXP (operands[0], 0))))
8209     current_function_uses_pic_offset_table = 1;
8210   if (! call_insn_operand (operands[0], QImode))
8211     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8212 }")
8213
8214 (define_insn "*call_pop_0"
8215   [(call (match_operand:QI 0 "constant_call_address_operand" "")
8216          (match_operand:SI 1 "" ""))
8217    (set (reg:SI 7) (plus:SI (reg:SI 7)
8218                             (match_operand:SI 3 "immediate_operand" "")))]
8219   ""
8220   "*
8221 {
8222   if (SIBLING_CALL_P (insn))
8223     return \"jmp\\t%P0\";
8224   else
8225     return \"call\\t%P0\";
8226 }"
8227   [(set_attr "type" "call")])
8228   
8229 (define_insn "*call_pop_1"
8230   [(call (match_operand:QI 0 "call_insn_operand" "m")
8231          (match_operand:SI 1 "" ""))
8232    (set (reg:SI 7) (plus:SI (reg:SI 7)
8233                             (match_operand:SI 3 "immediate_operand" "i")))]
8234   ""
8235   "*
8236 {
8237   if (constant_call_address_operand (operands[0], QImode))
8238     {
8239       if (SIBLING_CALL_P (insn))
8240         return \"jmp\\t%P0\";
8241       else
8242         return \"call\\t%P0\";
8243     }
8244   operands[0] = XEXP (operands[0], 0);
8245   if (SIBLING_CALL_P (insn))
8246     return \"jmp\\t%*%0\";
8247   else
8248     return \"call\\t%*%0\";
8249 }"
8250   [(set_attr "type" "call")])
8251
8252 (define_expand "call"
8253   [(call (match_operand:QI 0 "" "")
8254          (match_operand:SI 1 "" ""))]
8255   ;; Operand 1 not used on the i386.
8256   ""
8257   "
8258 {
8259   /* Static functions and indirect calls don't need
8260      current_function_uses_pic_offset_table.  */
8261   if (flag_pic
8262       && constant_call_address_operand (operands[0], SImode)
8263       && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF
8264           || !SYMBOL_REF_FLAG (XEXP (operands[0], 0))))
8265     current_function_uses_pic_offset_table = 1;
8266   if (! call_insn_operand (operands[0], QImode))
8267     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8268 }")
8269
8270 (define_insn "*call_0"
8271   [(call (match_operand:QI 0 "constant_call_address_operand" "")
8272          (match_operand:SI 1 "" ""))]
8273   ""
8274   "*
8275 {
8276   if (SIBLING_CALL_P (insn))
8277     return \"jmp\\t%P0\";
8278   else
8279     return \"call\\t%P0\";
8280 }"
8281   [(set_attr "type" "call")])
8282
8283 (define_insn "*call_1"
8284   [(call (match_operand:QI 0 "call_insn_operand" "m")
8285          (match_operand:SI 1 "" ""))]
8286   ""
8287   "*
8288 {
8289   if (constant_call_address_operand (operands[0], QImode))
8290     {
8291       if (SIBLING_CALL_P (insn))
8292         return \"jmp\\t%P0\";
8293       else
8294         return \"call\\t%P0\";
8295     }
8296   operands[0] = XEXP (operands[0], 0);
8297   if (SIBLING_CALL_P (insn))
8298     return \"jmp\\t%*%0\";
8299   else
8300     return \"call\\t%*%0\";
8301 }"
8302   [(set_attr "type" "call")])
8303
8304 ;; Call subroutine, returning value in operand 0
8305 ;; (which must be a hard register).
8306
8307 (define_expand "call_value_pop"
8308   [(parallel [(set (match_operand 0 "" "")
8309                    (call (match_operand:QI 1 "" "")
8310                          (match_operand:SI 2 "" "")))
8311               (set (reg:SI 7)
8312                    (plus:SI (reg:SI 7)
8313                             (match_operand:SI 4 "" "")))])]
8314   ""
8315   "
8316 {
8317   if (operands[4] == const0_rtx)
8318     {
8319       emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
8320       DONE;
8321     }
8322   /* Static functions and indirect calls don't need
8323      current_function_uses_pic_offset_table.  */
8324   if (flag_pic
8325       && constant_call_address_operand (operands[1], SImode)
8326       && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF
8327           || !SYMBOL_REF_FLAG (XEXP (operands[1], 0))))
8328     current_function_uses_pic_offset_table = 1;
8329   if (! call_insn_operand (operands[1], QImode))
8330     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
8331 }")
8332
8333 (define_expand "call_value"
8334   [(set (match_operand 0 "" "")
8335         (call (match_operand:QI 1 "" "")
8336               (match_operand:SI 2 "" "")))]
8337   ;; Operand 2 not used on the i386.
8338   ""
8339   "
8340 {
8341   /* Static functions and indirect calls don't need
8342      current_function_uses_pic_offset_table.  */
8343   if (flag_pic
8344       && constant_call_address_operand (operands[1], SImode)
8345       && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF
8346           || !SYMBOL_REF_FLAG (XEXP (operands[1], 0))))
8347     current_function_uses_pic_offset_table = 1;
8348   if (! call_insn_operand (operands[1], QImode))
8349     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
8350 }")
8351
8352 ;; Call subroutine returning any type.
8353
8354 (define_expand "untyped_call"
8355   [(parallel [(call (match_operand 0 "" "")
8356                     (const_int 0))
8357               (match_operand 1 "" "")
8358               (match_operand 2 "" "")])]
8359   ""
8360   "
8361 {
8362   int i;
8363
8364   /* In order to give reg-stack an easier job in validating two
8365      coprocessor registers as containing a possible return value,
8366      simply pretend the untyped call returns a complex long double
8367      value.  */
8368
8369   emit_call_insn (TARGET_80387
8370                   ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
8371                                     operands[0], const0_rtx)
8372                   : gen_call (operands[0], const0_rtx));
8373
8374   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8375     {
8376       rtx set = XVECEXP (operands[2], 0, i);
8377       emit_move_insn (SET_DEST (set), SET_SRC (set));
8378     }
8379
8380   /* The optimizer does not know that the call sets the function value
8381      registers we stored in the result block.  We avoid problems by
8382      claiming that all hard registers are used and clobbered at this
8383      point.  */
8384   emit_insn (gen_blockage ());
8385
8386   DONE;
8387 }")
8388 \f
8389 ;; Prologue and epilogue instructions
8390
8391 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8392 ;; all of memory.  This blocks insns from being moved across this point.
8393
8394 (define_insn "blockage"
8395   [(unspec_volatile [(const_int 0)] 0)]
8396   ""
8397   ""
8398   [(set_attr "length" "0")])
8399
8400 ;; Insn emitted into the body of a function to return from a function.
8401 ;; This is only done if the function's epilogue is known to be simple.
8402 ;; See comments for simple_386_epilogue in i386.c.
8403
8404 (define_expand "return"
8405   [(return)]
8406   "ix86_can_use_return_insn_p ()"
8407   "
8408 {
8409   if (current_function_pops_args)
8410     {
8411       rtx popc = GEN_INT (current_function_pops_args);
8412       emit_jump_insn (gen_return_pop_internal (popc));
8413       DONE;
8414     }
8415 }")
8416
8417 (define_insn "return_internal"
8418   [(return)]
8419   "reload_completed"
8420   "ret"
8421   [(set_attr "length" "1")
8422    (set_attr "length_immediate" "0")
8423    (set_attr "modrm" "0")])
8424
8425 (define_insn "return_pop_internal"
8426   [(return)
8427    (use (match_operand:SI 0 "const_int_operand" ""))]
8428   "reload_completed"
8429   "ret\\t%0"
8430   [(set_attr "length" "3")
8431    (set_attr "length_immediate" "2")
8432    (set_attr "modrm" "0")])
8433
8434 (define_insn "nop"
8435   [(const_int 0)]
8436   ""
8437   "nop"
8438   [(set_attr "length" "1")
8439    (set_attr "length_immediate" "0")
8440    (set_attr "modrm" "0")
8441    (set_attr "ppro_uops" "one")])
8442
8443 (define_expand "prologue"
8444   [(const_int 1)]
8445   ""
8446   "ix86_expand_prologue (); DONE;")
8447
8448 (define_insn "prologue_set_got"
8449   [(set (match_operand:SI 0 "register_operand" "=r")
8450         (unspec_volatile:SI
8451          [(plus:SI (match_dup 0)
8452                    (plus:SI (match_operand:SI 1 "symbolic_operand" "")
8453                             (minus:SI (pc) (match_operand 2 "" ""))))] 1))
8454    (clobber (reg:CC 17))]
8455   ""
8456   "*
8457 {
8458   if (GET_CODE (operands[2]) == LABEL_REF)
8459      operands[2] = XEXP (operands[2], 0);
8460   if (TARGET_DEEP_BRANCH_PREDICTION) 
8461     return \"add{l}\\t{%1, %0|%0, %1}\";
8462   else  
8463     return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
8464 }"
8465   [(set_attr "type" "alu")
8466    ; Since this insn may have two constant operands, we must set the
8467    ; length manually.
8468    (set_attr "length_immediate" "4")
8469    (set_attr "mode" "SI")])
8470
8471 (define_insn "prologue_get_pc"
8472   [(set (match_operand:SI 0 "register_operand" "=r")
8473     (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
8474   ""
8475   "*
8476 {
8477   if (GET_CODE (operands[1]) == LABEL_REF)
8478     operands[1] = XEXP (operands[1], 0);
8479   output_asm_insn (\"call\\t%X1\", operands);
8480   if (! TARGET_DEEP_BRANCH_PREDICTION)
8481     {
8482       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
8483                                  CODE_LABEL_NUMBER (operands[1]));
8484     }
8485   RET;
8486 }"
8487   [(set_attr "type" "multi")])
8488
8489 (define_expand "epilogue"
8490   [(const_int 1)]
8491   ""
8492   "ix86_expand_epilogue (1); DONE;")
8493
8494 (define_expand "sibcall_epilogue"
8495   [(const_int 1)]
8496   ""
8497   "ix86_expand_epilogue (0); DONE;")
8498
8499 (define_insn "leave"
8500   [(set (reg:SI 7) (reg:SI 6))
8501    (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
8502   ""
8503   "leave"
8504   [(set_attr "length_immediate" "0")
8505    (set_attr "length" "1")
8506    (set_attr "modrm" "0")
8507    (set_attr "modrm" "0")
8508    (set_attr "athlon_decode" "vector")
8509    (set_attr "ppro_uops" "few")])
8510 \f
8511 (define_expand "ffssi2"
8512   [(set (match_operand:SI 0 "nonimmediate_operand" "") 
8513         (ffs:SI (match_operand:SI 1 "general_operand" "")))]
8514   ""
8515   "
8516 {
8517   rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
8518   rtx in = operands[1];
8519
8520   if (TARGET_CMOVE)
8521     {
8522       emit_move_insn (tmp, constm1_rtx);
8523       emit_insn (gen_ffssi_1 (out, in));
8524       emit_insn (gen_rtx_SET (VOIDmode, out,
8525                   gen_rtx_IF_THEN_ELSE (SImode, 
8526                     gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
8527                                 const0_rtx),
8528                     tmp,
8529                     out)));
8530       emit_insn (gen_addsi3 (out, out, const1_rtx));
8531       emit_move_insn (operands[0], out);
8532     }
8533
8534   /* Pentium bsf instruction is extremly slow.  The following code is
8535      recommended by the Intel Optimizing Manual as a reasonable replacement:
8536            TEST    EAX,EAX
8537            JZ      SHORT BS2
8538            XOR     ECX,ECX
8539            MOV     DWORD PTR [TEMP+4],ECX
8540            SUB     ECX,EAX
8541            AND     EAX,ECX
8542            MOV     DWORD PTR [TEMP],EAX
8543            FILD    QWORD PTR [TEMP]
8544            FSTP    QWORD PTR [TEMP]
8545            WAIT    ; WAIT only needed for compatibility with
8546                    ; earlier processors
8547            MOV     ECX, DWORD PTR [TEMP+4]
8548            SHR     ECX,20
8549            SUB     ECX,3FFH
8550            TEST    EAX,EAX       ; clear zero flag
8551        BS2:
8552      Following piece of code expand ffs to similar beast.
8553        */
8554
8555   else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
8556     {
8557       rtx label = gen_label_rtx ();
8558       rtx lo, hi;
8559       rtx mem = assign_386_stack_local (DImode, 0);
8560       rtx fptmp = gen_reg_rtx (DFmode);
8561       split_di (&mem, 1, &lo, &hi);
8562
8563       emit_move_insn (out, const0_rtx);
8564
8565       emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
8566
8567       emit_move_insn (hi, out);
8568       emit_insn (gen_subsi3 (out, out, in));
8569       emit_insn (gen_andsi3 (out, out, in));
8570       emit_move_insn (lo, out);
8571       emit_insn (gen_floatdidf2 (fptmp,mem));
8572       emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
8573       emit_move_insn (out, hi);
8574       emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
8575       emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
8576
8577       emit_label (label);
8578       LABEL_NUSES (label) = 1;
8579
8580       emit_move_insn (operands[0], out);
8581     }
8582   else
8583     {
8584       emit_move_insn (tmp, const0_rtx);
8585       emit_insn (gen_ffssi_1 (out, in));
8586       emit_insn (gen_rtx_SET (VOIDmode, 
8587                   gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
8588                   gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
8589                               const0_rtx)));
8590       emit_insn (gen_negsi2 (tmp, tmp));
8591       emit_insn (gen_iorsi3 (out, out, tmp));
8592       emit_insn (gen_addsi3 (out, out, const1_rtx));
8593       emit_move_insn (operands[0], out);
8594     }
8595   DONE;  
8596 }")
8597
8598 (define_insn "ffssi_1"
8599   [(set (reg:CCZ 17)
8600         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
8601                      (const_int 0)))
8602    (set (match_operand:SI 0 "register_operand" "=r")
8603         (unspec:SI [(match_dup 1)] 5))]
8604   ""
8605   "bsf{l}\\t{%1, %0|%0, %1}"
8606   [(set_attr "prefix_0f" "1")
8607    (set_attr "ppro_uops" "few")])
8608
8609 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
8610 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
8611 \f
8612 ;; These patterns match the binary 387 instructions for addM3, subM3,
8613 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
8614 ;; SFmode.  The first is the normal insn, the second the same insn but
8615 ;; with one operand a conversion, and the third the same insn but with
8616 ;; the other operand a conversion.  The conversion may be SFmode or
8617 ;; SImode if the target mode DFmode, but only SImode if the target mode
8618 ;; is SFmode.
8619
8620 ;; Gcc is slightly more smart about handling normal two address instructions
8621 ;; so use special patterns for add and mull.
8622 (define_insn "*fop_sf_comm"
8623   [(set (match_operand:SF 0 "register_operand" "=f")
8624         (match_operator:SF 3 "binary_fp_operator"
8625                         [(match_operand:SF 1 "register_operand" "%0")
8626                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
8627   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
8628   "* return output_387_binary_op (insn, operands);"
8629   [(set (attr "type") 
8630         (if_then_else (match_operand:SF 3 "mult_operator" "") 
8631            (const_string "fmul")
8632            (const_string "fop")))
8633    (set_attr "mode" "SF")])
8634
8635 (define_insn "*fop_df_comm"
8636   [(set (match_operand:DF 0 "register_operand" "=f")
8637         (match_operator:DF 3 "binary_fp_operator"
8638                         [(match_operand:DF 1 "register_operand" "%0")
8639                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
8640   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
8641   "* return output_387_binary_op (insn, operands);"
8642   [(set (attr "type") 
8643         (if_then_else (match_operand:DF 3 "mult_operator" "") 
8644            (const_string "fmul")
8645            (const_string "fop")))
8646    (set_attr "mode" "DF")])
8647
8648 (define_insn "*fop_xf_comm"
8649   [(set (match_operand:XF 0 "register_operand" "=f")
8650         (match_operator:XF 3 "binary_fp_operator"
8651                         [(match_operand:XF 1 "register_operand" "%0")
8652                          (match_operand:XF 2 "register_operand" "f")]))]
8653   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
8654   "* return output_387_binary_op (insn, operands);"
8655   [(set (attr "type") 
8656         (if_then_else (match_operand:XF 3 "mult_operator" "") 
8657            (const_string "fmul")
8658            (const_string "fop")))
8659    (set_attr "mode" "XF")])
8660
8661 (define_insn "*fop_sf_1"
8662   [(set (match_operand:SF 0 "register_operand" "=f,f")
8663         (match_operator:SF 3 "binary_fp_operator"
8664                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
8665                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
8666   "TARGET_80387
8667    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
8668    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8669   "* return output_387_binary_op (insn, operands);"
8670   [(set (attr "type") 
8671         (cond [(match_operand:SF 3 "mult_operator" "") 
8672                  (const_string "fmul")
8673                (match_operand:SF 3 "div_operator" "") 
8674                  (const_string "fdiv")
8675               ]
8676               (const_string "fop")))
8677    (set_attr "mode" "SF")])
8678
8679 (define_insn "*fop_sf_2"
8680   [(set (match_operand:SF 0 "register_operand" "=f,f")
8681         (match_operator:SF 3 "binary_fp_operator"
8682           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
8683            (match_operand:SF 2 "register_operand" "0,0")]))]
8684   "TARGET_80387 && TARGET_USE_FIOP"
8685   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8686   [(set (attr "type") 
8687         (cond [(match_operand:SF 3 "mult_operator" "") 
8688                  (const_string "fmul")
8689                (match_operand:SF 3 "div_operator" "") 
8690                  (const_string "fdiv")
8691               ]
8692               (const_string "fop")))
8693    (set_attr "fp_int_src" "true")
8694    (set_attr "ppro_uops" "many")
8695    (set_attr "mode" "SI")])
8696
8697 (define_insn "*fop_sf_3"
8698   [(set (match_operand:SF 0 "register_operand" "=f,f")
8699         (match_operator:SF 3 "binary_fp_operator"
8700           [(match_operand:SF 1 "register_operand" "0,0")
8701            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8702   "TARGET_80387 && TARGET_USE_FIOP"
8703   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8704   [(set (attr "type") 
8705         (cond [(match_operand:SF 3 "mult_operator" "") 
8706                  (const_string "fmul")
8707                (match_operand:SF 3 "div_operator" "") 
8708                  (const_string "fdiv")
8709               ]
8710               (const_string "fop")))
8711    (set_attr "fp_int_src" "true")
8712    (set_attr "ppro_uops" "many")
8713    (set_attr "mode" "SI")])
8714
8715 (define_insn "*fop_df_1"
8716   [(set (match_operand:DF 0 "register_operand" "=f,f")
8717         (match_operator:DF 3 "binary_fp_operator"
8718                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
8719                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
8720   "TARGET_80387
8721    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
8722    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8723   "* return output_387_binary_op (insn, operands);"
8724   [(set (attr "type") 
8725         (cond [(match_operand:DF 3 "mult_operator" "") 
8726                  (const_string "fmul")
8727                (match_operand:DF 3 "div_operator" "") 
8728                  (const_string "fdiv")
8729               ]
8730               (const_string "fop")))
8731    (set_attr "mode" "DF")])
8732
8733 (define_insn "*fop_df_2"
8734   [(set (match_operand:DF 0 "register_operand" "=f,f")
8735         (match_operator:DF 3 "binary_fp_operator"
8736            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
8737             (match_operand:DF 2 "register_operand" "0,0")]))]
8738   "TARGET_80387 && TARGET_USE_FIOP"
8739   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8740   [(set (attr "type") 
8741         (cond [(match_operand:DF 3 "mult_operator" "") 
8742                  (const_string "fmul")
8743                (match_operand:DF 3 "div_operator" "") 
8744                  (const_string "fdiv")
8745               ]
8746               (const_string "fop")))
8747    (set_attr "fp_int_src" "true")
8748    (set_attr "ppro_uops" "many")
8749    (set_attr "mode" "SI")])
8750
8751 (define_insn "*fop_df_3"
8752   [(set (match_operand:DF 0 "register_operand" "=f,f")
8753         (match_operator:DF 3 "binary_fp_operator"
8754            [(match_operand:DF 1 "register_operand" "0,0")
8755             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8756   "TARGET_80387 && TARGET_USE_FIOP"
8757   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8758   [(set (attr "type") 
8759         (cond [(match_operand:DF 3 "mult_operator" "") 
8760                  (const_string "fmul")
8761                (match_operand:DF 3 "div_operator" "") 
8762                  (const_string "fdiv")
8763               ]
8764               (const_string "fop")))
8765    (set_attr "fp_int_src" "true")
8766    (set_attr "ppro_uops" "many")
8767    (set_attr "mode" "SI")])
8768
8769 (define_insn "*fop_df_4"
8770   [(set (match_operand:DF 0 "register_operand" "=f,f")
8771         (match_operator:DF 3 "binary_fp_operator"
8772            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
8773             (match_operand:DF 2 "register_operand" "0,f")]))]
8774   "TARGET_80387
8775    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8776   "* return output_387_binary_op (insn, operands);"
8777   [(set (attr "type") 
8778         (cond [(match_operand:DF 3 "mult_operator" "") 
8779                  (const_string "fmul")
8780                (match_operand:DF 3 "div_operator" "") 
8781                  (const_string "fdiv")
8782               ]
8783               (const_string "fop")))
8784    (set_attr "mode" "SF")])
8785
8786 (define_insn "*fop_df_5"
8787   [(set (match_operand:DF 0 "register_operand" "=f,f")
8788         (match_operator:DF 3 "binary_fp_operator"
8789           [(match_operand:DF 1 "register_operand" "0,f")
8790            (float_extend:DF
8791             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8792   "TARGET_80387"
8793   "* return output_387_binary_op (insn, operands);"
8794   [(set (attr "type") 
8795         (cond [(match_operand:DF 3 "mult_operator" "") 
8796                  (const_string "fmul")
8797                (match_operand:DF 3 "div_operator" "") 
8798                  (const_string "fdiv")
8799               ]
8800               (const_string "fop")))
8801    (set_attr "mode" "SF")])
8802
8803 (define_insn "*fop_xf_1"
8804   [(set (match_operand:XF 0 "register_operand" "=f,f")
8805         (match_operator:XF 3 "binary_fp_operator"
8806                         [(match_operand:XF 1 "register_operand" "0,f")
8807                          (match_operand:XF 2 "register_operand" "f,0")]))]
8808   "TARGET_80387
8809    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
8810   "* return output_387_binary_op (insn, operands);"
8811   [(set (attr "type") 
8812         (cond [(match_operand:XF 3 "mult_operator" "") 
8813                  (const_string "fmul")
8814                (match_operand:XF 3 "div_operator" "") 
8815                  (const_string "fdiv")
8816               ]
8817               (const_string "fop")))
8818    (set_attr "mode" "XF")])
8819
8820 (define_insn "*fop_xf_2"
8821   [(set (match_operand:XF 0 "register_operand" "=f,f")
8822         (match_operator:XF 3 "binary_fp_operator"
8823            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
8824             (match_operand:XF 2 "register_operand" "0,0")]))]
8825   "TARGET_80387 && TARGET_USE_FIOP"
8826   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8827   [(set (attr "type") 
8828         (cond [(match_operand:XF 3 "mult_operator" "") 
8829                  (const_string "fmul")
8830                (match_operand:XF 3 "div_operator" "") 
8831                  (const_string "fdiv")
8832               ]
8833               (const_string "fop")))
8834    (set_attr "fp_int_src" "true")
8835    (set_attr "mode" "SI")
8836    (set_attr "ppro_uops" "many")])
8837
8838 (define_insn "*fop_xf_3"
8839   [(set (match_operand:XF 0 "register_operand" "=f,f")
8840         (match_operator:XF 3 "binary_fp_operator"
8841           [(match_operand:XF 1 "register_operand" "0,0")
8842            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8843   "TARGET_80387 && TARGET_USE_FIOP"
8844   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8845   [(set (attr "type") 
8846         (cond [(match_operand:XF 3 "mult_operator" "") 
8847                  (const_string "fmul")
8848                (match_operand:XF 3 "div_operator" "") 
8849                  (const_string "fdiv")
8850               ]
8851               (const_string "fop")))
8852    (set_attr "fp_int_src" "true")
8853    (set_attr "mode" "SI")
8854    (set_attr "ppro_uops" "many")])
8855
8856 (define_insn "*fop_xf_4"
8857   [(set (match_operand:XF 0 "register_operand" "=f,f")
8858         (match_operator:XF 3 "binary_fp_operator"
8859            [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
8860             (match_operand:XF 2 "register_operand" "0,f")]))]
8861   "TARGET_80387"
8862   "* return output_387_binary_op (insn, operands);"
8863   [(set (attr "type") 
8864         (cond [(match_operand:XF 3 "mult_operator" "") 
8865                  (const_string "fmul")
8866                (match_operand:XF 3 "div_operator" "") 
8867                  (const_string "fdiv")
8868               ]
8869               (const_string "fop")))
8870    (set_attr "mode" "SF")])
8871
8872 (define_insn "*fop_xf_5"
8873   [(set (match_operand:XF 0 "register_operand" "=f,f")
8874         (match_operator:XF 3 "binary_fp_operator"
8875           [(match_operand:XF 1 "register_operand" "0,f")
8876            (float_extend:XF
8877             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8878   "TARGET_80387"
8879   "* return output_387_binary_op (insn, operands);"
8880   [(set (attr "type") 
8881         (cond [(match_operand:XF 3 "mult_operator" "") 
8882                  (const_string "fmul")
8883                (match_operand:XF 3 "div_operator" "") 
8884                  (const_string "fdiv")
8885               ]
8886               (const_string "fop")))
8887    (set_attr "mode" "SF")])
8888
8889 (define_insn "*fop_xf_6"
8890   [(set (match_operand:XF 0 "register_operand" "=f,f")
8891         (match_operator:XF 3 "binary_fp_operator"
8892            [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
8893             (match_operand:XF 2 "register_operand" "0,f")]))]
8894   "TARGET_80387"
8895   "* return output_387_binary_op (insn, operands);"
8896   [(set (attr "type") 
8897         (cond [(match_operand:XF 3 "mult_operator" "") 
8898                  (const_string "fmul")
8899                (match_operand:XF 3 "div_operator" "") 
8900                  (const_string "fdiv")
8901               ]
8902               (const_string "fop")))
8903    (set_attr "mode" "DF")])
8904
8905 (define_insn "*fop_xf_7"
8906   [(set (match_operand:XF 0 "register_operand" "=f,f")
8907         (match_operator:XF 3 "binary_fp_operator"
8908           [(match_operand:XF 1 "register_operand" "0,f")
8909            (float_extend:XF
8910             (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
8911   "TARGET_80387"
8912   "* return output_387_binary_op (insn, operands);"
8913   [(set (attr "type") 
8914         (cond [(match_operand:XF 3 "mult_operator" "") 
8915                  (const_string "fmul")
8916                (match_operand:XF 3 "div_operator" "") 
8917                  (const_string "fdiv")
8918               ]
8919               (const_string "fop")))
8920    (set_attr "mode" "DF")])
8921
8922 (define_split
8923   [(set (match_operand 0 "register_operand" "")
8924         (match_operator 3 "binary_fp_operator"
8925            [(float (match_operand:SI 1 "register_operand" ""))
8926             (match_operand 2 "register_operand" "")]))]
8927   "TARGET_80387 && reload_completed
8928    && FLOAT_MODE_P (GET_MODE (operands[0]))"
8929   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
8930    (set (match_dup 0)
8931         (match_op_dup 3 [(match_dup 4) (match_dup 2)]))
8932    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
8933               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
8934   "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
8935                                 gen_rtx_MEM (SImode, stack_pointer_rtx));")
8936
8937 (define_split
8938   [(set (match_operand 0 "register_operand" "")
8939         (match_operator 3 "binary_fp_operator"
8940            [(match_operand 1 "register_operand" "")
8941             (float (match_operand:SI 2 "register_operand" ""))]))]
8942   "TARGET_80387 && reload_completed
8943    && FLOAT_MODE_P (GET_MODE (operands[0]))"
8944   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
8945    (set (match_dup 0)
8946         (match_op_dup 3 [(match_dup 1) (match_dup 4)]))
8947    (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
8948               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
8949   "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
8950                                 gen_rtx_MEM (SImode, stack_pointer_rtx));")
8951 \f
8952 ;; FPU special functions.
8953
8954 (define_insn "sqrtsf2"
8955   [(set (match_operand:SF 0 "register_operand" "=f")
8956         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
8957   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8958   "fsqrt"
8959   [(set_attr "type" "fpspc")
8960    (set_attr "mode" "SF")
8961    (set_attr "athlon_decode" "direct")])
8962
8963 (define_insn "sqrtdf2"
8964   [(set (match_operand:DF 0 "register_operand" "=f")
8965         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
8966   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
8967    && (TARGET_IEEE_FP || flag_fast_math) "
8968   "fsqrt"
8969   [(set_attr "type" "fpspc")
8970    (set_attr "mode" "DF")
8971    (set_attr "athlon_decode" "direct")])
8972
8973 (define_insn "*sqrtextendsfdf2"
8974   [(set (match_operand:DF 0 "register_operand" "=f")
8975         (sqrt:DF (float_extend:DF
8976                   (match_operand:SF 1 "register_operand" "0"))))]
8977   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8978   "fsqrt"
8979   [(set_attr "type" "fpspc")
8980    (set_attr "mode" "DF")
8981    (set_attr "athlon_decode" "direct")])
8982
8983 (define_insn "sqrtxf2"
8984   [(set (match_operand:XF 0 "register_operand" "=f")
8985         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
8986   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
8987    && (TARGET_IEEE_FP || flag_fast_math) "
8988   "fsqrt"
8989   [(set_attr "type" "fpspc")
8990    (set_attr "mode" "XF")
8991    (set_attr "athlon_decode" "direct")])
8992
8993 (define_insn "*sqrtextenddfxf2"
8994   [(set (match_operand:XF 0 "register_operand" "=f")
8995         (sqrt:XF (float_extend:XF
8996                   (match_operand:DF 1 "register_operand" "0"))))]
8997   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8998   "fsqrt"
8999   [(set_attr "type" "fpspc")
9000    (set_attr "mode" "XF")
9001    (set_attr "athlon_decode" "direct")])
9002
9003 (define_insn "*sqrtextendsfxf2"
9004   [(set (match_operand:XF 0 "register_operand" "=f")
9005         (sqrt:XF (float_extend:XF
9006                   (match_operand:SF 1 "register_operand" "0"))))]
9007   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
9008   "fsqrt"
9009   [(set_attr "type" "fpspc")
9010    (set_attr "mode" "XF")
9011    (set_attr "athlon_decode" "direct")])
9012
9013 (define_insn "sindf2"
9014   [(set (match_operand:DF 0 "register_operand" "=f")
9015         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
9016   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9017   "fsin"
9018   [(set_attr "type" "fpspc")
9019    (set_attr "mode" "DF")])
9020
9021 (define_insn "sinsf2"
9022   [(set (match_operand:SF 0 "register_operand" "=f")
9023         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
9024   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9025   "fsin"
9026   [(set_attr "type" "fpspc")
9027    (set_attr "mode" "SF")])
9028
9029 (define_insn "*sinextendsfdf2"
9030   [(set (match_operand:DF 0 "register_operand" "=f")
9031         (unspec:DF [(float_extend:DF
9032                      (match_operand:SF 1 "register_operand" "0"))] 1))]
9033   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9034   "fsin"
9035   [(set_attr "type" "fpspc")
9036    (set_attr "mode" "DF")])
9037
9038 (define_insn "sinxf2"
9039   [(set (match_operand:XF 0 "register_operand" "=f")
9040         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
9041   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9042   "fsin"
9043   [(set_attr "type" "fpspc")
9044    (set_attr "mode" "XF")])
9045
9046 (define_insn "cosdf2"
9047   [(set (match_operand:DF 0 "register_operand" "=f")
9048         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
9049   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9050   "fcos"
9051   [(set_attr "type" "fpspc")
9052    (set_attr "mode" "DF")])
9053
9054 (define_insn "cossf2"
9055   [(set (match_operand:SF 0 "register_operand" "=f")
9056         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
9057   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9058   "fcos"
9059   [(set_attr "type" "fpspc")
9060    (set_attr "mode" "SF")])
9061
9062 (define_insn "*cosextendsfdf2"
9063   [(set (match_operand:DF 0 "register_operand" "=f")
9064         (unspec:DF [(float_extend:DF
9065                      (match_operand:SF 1 "register_operand" "0"))] 2))]
9066   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9067   "fcos"
9068   [(set_attr "type" "fpspc")
9069    (set_attr "mode" "DF")])
9070
9071 (define_insn "cosxf2"
9072   [(set (match_operand:XF 0 "register_operand" "=f")
9073         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
9074   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9075   "fcos"
9076   [(set_attr "type" "fpspc")
9077    (set_attr "mode" "XF")])
9078 \f
9079 ;; Block operation instructions
9080
9081 (define_insn "cld"
9082  [(set (reg:SI 19) (const_int 0))]
9083  ""
9084  "cld"
9085   [(set_attr "type" "cld")])
9086
9087 (define_expand "movstrsi"
9088   [(use (match_operand:BLK 0 "memory_operand" ""))
9089    (use (match_operand:BLK 1 "memory_operand" ""))
9090    (use (match_operand:SI 2 "nonmemory_operand" ""))
9091    (use (match_operand:SI 3 "const_int_operand" ""))]
9092   ""
9093   "
9094 {
9095   rtx srcreg, destreg, countreg;
9096   int align = 0;
9097   int count = -1;
9098
9099   if (GET_CODE (operands[3]) == CONST_INT)
9100     align = INTVAL (operands[3]);
9101
9102   /* This simple hack avoids all inlining code and simplifies code bellow.  */
9103   if (!TARGET_ALIGN_STRINGOPS)
9104     align = 32;
9105
9106   if (GET_CODE (operands[2]) == CONST_INT)
9107     count = INTVAL (operands[2]);
9108
9109   destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9110   srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
9111
9112   emit_insn (gen_cld());
9113
9114   /* When optimizing for size emit simple rep ; movsb instruction for
9115      counts not divisible by 4.  */
9116
9117   if ((!optimize || optimize_size) 
9118       && (count < 0 || (count & 0x03)))
9119     {
9120       countreg = copy_to_mode_reg (SImode, operands[2]);
9121       emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
9122                                 destreg, srcreg, countreg));
9123     }
9124
9125   /* For constant aligned (or small unaligned) copies use rep movsl
9126      followed by code copying the rest.  For PentiumPro ensure 8 byte
9127      alignment to allow rep movsl acceleration.  */
9128
9129   else if (count >= 0 
9130            && (align >= 8
9131                || (!TARGET_PENTIUMPRO && align >= 4)
9132                || optimize_size || count < 64))
9133     {
9134       if (count & ~0x03)
9135         {
9136           countreg = copy_to_mode_reg (SImode,
9137                                        GEN_INT ((count >> 2)
9138                                                 & 0x3fffffff));
9139           emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
9140                                     destreg, srcreg, countreg));
9141         }
9142       if (count & 0x02)
9143         emit_insn (gen_strmovhi (destreg, srcreg));
9144       if (count & 0x01)
9145         emit_insn (gen_strmovqi (destreg, srcreg));
9146     }
9147   /* The generic code based on the glibc implementation:
9148      - align destination to 4 bytes (8 byte alignment is used for PentiumPro
9149        allowing accelerated copying there)
9150      - copy the data using rep movsl
9151      - copy the rest.  */
9152   else
9153     {
9154       rtx countreg2;
9155       rtx label = NULL;
9156
9157       /* In case we don't know anything about the alignment, default to
9158          library version, since it is usually equally fast and result in
9159          shorter code.  */
9160       if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
9161         FAIL;
9162
9163       if (TARGET_SINGLE_STRINGOP)
9164         emit_insn (gen_cld());
9165
9166       countreg2 = gen_reg_rtx (SImode);
9167       countreg = copy_to_mode_reg (SImode, operands[2]);
9168
9169       /* We don't use loops to align destination and to copy parts smaller
9170          than 4 bytes, because gcc is able to optimize such code better (in
9171          the case the destination or the count really is aligned, gcc is often
9172          able to predict the branches) and also it is friendlier to the
9173          hardware branch prediction.  
9174
9175          Using loops is benefical for generic case, because we can
9176          handle small counts using the loops.  Many CPUs (such as Athlon)
9177          have large REP prefix setup costs.
9178
9179          This is quite costy.  Maybe we can revisit this decision later or
9180          add some customizability to this code.  */
9181
9182       if (count < 0
9183           && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
9184         {
9185           label = gen_label_rtx ();
9186           emit_cmp_and_jump_insns (countreg, GEN_INT (3),
9187                                    LEU, 0, SImode, 1, 0, label);
9188         }
9189       if (align <= 1)
9190         {
9191           rtx label = gen_label_rtx ();
9192           rtx tmpcount = gen_reg_rtx (SImode);
9193           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
9194           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9195                                    SImode, 1, 0, label);
9196           emit_insn (gen_strmovqi (destreg, srcreg));
9197           emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
9198           emit_label (label);
9199           LABEL_NUSES (label) = 1;
9200         }
9201       if (align <= 2)
9202         {
9203           rtx label = gen_label_rtx ();
9204           rtx tmpcount = gen_reg_rtx (SImode);
9205           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
9206           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9207                                    SImode, 1, 0, label);
9208           emit_insn (gen_strmovhi (destreg, srcreg));
9209           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
9210           emit_label (label);
9211           LABEL_NUSES (label) = 1;
9212         }
9213       if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
9214         {
9215           rtx label = gen_label_rtx ();
9216           rtx tmpcount = gen_reg_rtx (SImode);
9217           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
9218           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9219                                    SImode, 1, 0, label);
9220           emit_insn (gen_strmovsi (destreg, srcreg));
9221           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
9222           emit_label (label);
9223           LABEL_NUSES (label) = 1;
9224         }
9225
9226       if (!TARGET_SINGLE_STRINGOP)
9227         emit_insn (gen_cld());
9228       emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
9229       emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
9230                                 destreg, srcreg, countreg2));
9231
9232       if (label)
9233         {
9234           emit_label (label);
9235           LABEL_NUSES (label) = 1;
9236         }
9237       if (align > 2 && count > 0 && (count & 2))
9238         emit_insn (gen_strmovhi (destreg, srcreg));
9239       if (align <= 2 || count < 0)
9240         {
9241           rtx label = gen_label_rtx ();
9242           rtx tmpcount = gen_reg_rtx (SImode);
9243           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
9244           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9245                                    SImode, 1, 0, label);
9246           emit_insn (gen_strmovhi (destreg, srcreg));
9247           emit_label (label);
9248           LABEL_NUSES (label) = 1;
9249         }
9250       if (align > 1 && count > 0 && (count & 1))
9251         emit_insn (gen_strmovsi (destreg, srcreg));
9252       if (align <= 1 || count < 0)
9253         {
9254           rtx label = gen_label_rtx ();
9255           rtx tmpcount = gen_reg_rtx (SImode);
9256           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
9257           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9258                                    SImode, 1, 0, label);
9259           emit_insn (gen_strmovqi (destreg, srcreg));
9260           emit_label (label);
9261           LABEL_NUSES (label) = 1;
9262         }
9263     }
9264   DONE;
9265 }")
9266
9267 ;; Most CPUs don't like single string operations
9268 ;; Handle this case here to simplify previous expander.
9269
9270 (define_expand "strmovsi"
9271   [(set (match_dup 2)
9272         (mem:SI (match_operand:SI 1 "register_operand" "")))
9273    (set (mem:SI (match_operand:SI 0 "register_operand" ""))
9274         (match_dup 2))
9275    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
9276               (clobber (reg:CC 17))])
9277    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
9278               (clobber (reg:CC 17))])]
9279   ""
9280   "
9281 {
9282   if (TARGET_SINGLE_STRINGOP || optimize_size)
9283     {
9284       emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
9285                                 operands[1]));
9286       DONE;
9287     }
9288   else 
9289     operands[2] = gen_reg_rtx (SImode);
9290 }")
9291
9292 (define_expand "strmovhi"
9293   [(set (match_dup 2)
9294         (mem:HI (match_operand:SI 1 "register_operand" "")))
9295    (set (mem:HI (match_operand:SI 0 "register_operand" ""))
9296         (match_dup 2))
9297    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
9298               (clobber (reg:CC 17))])
9299    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
9300               (clobber (reg:CC 17))])]
9301   ""
9302   "
9303 {
9304   if (TARGET_SINGLE_STRINGOP || optimize_size)
9305     {
9306       emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
9307                                 operands[1]));
9308       DONE;
9309     }
9310   else 
9311     operands[2] = gen_reg_rtx (HImode);
9312 }")
9313
9314 (define_expand "strmovqi"
9315   [(set (match_dup 2)
9316         (mem:QI (match_operand:SI 1 "register_operand" "")))
9317    (set (mem:QI (match_operand:SI 0 "register_operand" ""))
9318         (match_dup 2))
9319    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
9320               (clobber (reg:CC 17))])
9321    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
9322               (clobber (reg:CC 17))])]
9323   ""
9324   "
9325 {
9326   if (TARGET_SINGLE_STRINGOP || optimize_size)
9327     {
9328       emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
9329                                 operands[1]));
9330       DONE;
9331     }
9332   else 
9333     operands[2] = gen_reg_rtx (QImode);
9334 }")
9335
9336 (define_insn "strmovsi_1"
9337   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
9338         (mem:SI (match_operand:SI 3 "register_operand" "1")))
9339    (set (match_operand:SI 0 "register_operand" "=D")
9340         (plus:SI (match_dup 0)
9341                  (const_int 4)))
9342    (set (match_operand:SI 1 "register_operand" "=S")
9343         (plus:SI (match_dup 1)
9344                  (const_int 4)))
9345    (use (reg:SI 19))]
9346   "TARGET_SINGLE_STRINGOP || optimize_size"
9347   "movsl"
9348   [(set_attr "type" "str")
9349    (set_attr "mode" "SI")
9350    (set_attr "memory" "both")])
9351
9352 (define_insn "strmovhi_1"
9353   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
9354         (mem:HI (match_operand:SI 3 "register_operand" "1")))
9355    (set (match_operand:SI 0 "register_operand" "=D")
9356         (plus:SI (match_dup 0)
9357                  (const_int 2)))
9358    (set (match_operand:SI 1 "register_operand" "=S")
9359         (plus:SI (match_dup 1)
9360                  (const_int 2)))
9361    (use (reg:SI 19))]
9362   "TARGET_SINGLE_STRINGOP || optimize_size"
9363   "movsw"
9364   [(set_attr "type" "str")
9365    (set_attr "memory" "both")
9366    (set_attr "mode" "HI")])
9367
9368 (define_insn "strmovqi_1"
9369   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
9370         (mem:QI (match_operand:SI 3 "register_operand" "1")))
9371    (set (match_operand:SI 0 "register_operand" "=D")
9372         (plus:SI (match_dup 0)
9373                  (const_int 1)))
9374    (set (match_operand:SI 1 "register_operand" "=S")
9375         (plus:SI (match_dup 1)
9376                  (const_int 1)))
9377    (use (reg:SI 19))]
9378   "TARGET_SINGLE_STRINGOP || optimize_size"
9379   "movsb"
9380   [(set_attr "type" "str")
9381    (set_attr "memory" "both")
9382    (set_attr "mode" "QI")])
9383
9384 ;; It might seem that operands 3 & 4 could use predicate register_operand.
9385 ;; But strength reduction might offset the MEM expression.  So we let
9386 ;; reload put the address into %edi & %esi.
9387
9388 (define_insn "rep_movsi"
9389   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
9390    (use (match_operand:SI 5 "register_operand" "2"))
9391    (set (match_operand:SI 0 "register_operand" "=D") 
9392         (plus:SI (match_operand:SI 3 "address_operand" "0")
9393                  (ashift:SI (match_dup 5) (const_int 2))))
9394    (set (match_operand:SI 1 "register_operand" "=S") 
9395         (plus:SI (match_operand:SI 4 "address_operand" "1")
9396                  (ashift:SI (match_dup 5) (const_int 2))))
9397    (set (mem:BLK (match_dup 3))
9398         (mem:BLK (match_dup 4)))
9399    (use (reg:SI 19))]
9400   ""
9401   "rep\;movsl|rep movsd"
9402   [(set_attr "type" "str")
9403    (set_attr "prefix_rep" "1")
9404    (set_attr "memory" "both")
9405    (set_attr "mode" "SI")])
9406
9407 (define_insn "rep_movqi"
9408   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
9409    (use (match_operand:SI 5 "register_operand" "2"))
9410    (set (match_operand:SI 0 "register_operand" "=D") 
9411         (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 5)))
9412    (set (match_operand:SI 1 "register_operand" "=S") 
9413         (plus:SI (match_operand:SI 4 "address_operand" "1") (match_dup 5)))
9414    (set (mem:BLK (match_dup 3))
9415         (mem:BLK (match_dup 4)))
9416    (use (reg:SI 19))]
9417   ""
9418   "rep\;movsb|rep movsb"
9419   [(set_attr "type" "str")
9420    (set_attr "prefix_rep" "1")
9421    (set_attr "memory" "both")
9422    (set_attr "mode" "SI")])
9423
9424 (define_expand "clrstrsi"
9425    [(use (match_operand:BLK 0 "memory_operand" ""))
9426     (use (match_operand:SI 1 "nonmemory_operand" ""))
9427     (use (match_operand:SI 2 "const_int_operand" ""))]
9428   ""
9429   "
9430 {
9431   /* See comments in movstr expanders.  The code is mostly identical.  */
9432
9433   rtx destreg, zeroreg, countreg;
9434   int align = 0;
9435   int count = -1;
9436
9437   if (GET_CODE (operands[2]) == CONST_INT)
9438     align = INTVAL (operands[2]);
9439
9440   /* This simple hack avoids all inlining code and simplifies code bellow.  */
9441   if (!TARGET_ALIGN_STRINGOPS)
9442     align = 32;
9443
9444   if (GET_CODE (operands[1]) == CONST_INT)
9445     count = INTVAL (operands[1]);
9446
9447   destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9448
9449   emit_insn (gen_cld());
9450
9451   /* When optimizing for size emit simple rep ; movsb instruction for
9452      counts not divisible by 4.  */
9453
9454   if ((!optimize || optimize_size) 
9455       && (count < 0 || (count & 0x03)))
9456     {
9457       countreg = copy_to_mode_reg (SImode, operands[1]);
9458       zeroreg = copy_to_mode_reg (QImode, const0_rtx);
9459       emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
9460                                  destreg, countreg));
9461     }
9462   else if (count >= 0 
9463            && (align >= 8
9464                || (!TARGET_PENTIUMPRO && align >= 4)
9465                || optimize_size || count < 64))
9466     {
9467       zeroreg = copy_to_mode_reg (SImode, const0_rtx);
9468       if (INTVAL (operands[1]) & ~0x03)
9469         {
9470           countreg = copy_to_mode_reg (SImode,
9471                                        GEN_INT ((INTVAL (operands[1]) >> 2)
9472                                                 & 0x3fffffff));
9473           emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
9474                                      destreg, countreg));
9475         }
9476       if (INTVAL (operands[1]) & 0x02)
9477         emit_insn (gen_strsethi (destreg,
9478                                  gen_rtx_SUBREG (HImode, zeroreg, 0)));
9479       if (INTVAL (operands[1]) & 0x01)
9480         emit_insn (gen_strsetqi (destreg,
9481                                  gen_rtx_SUBREG (QImode, zeroreg, 0)));
9482     }
9483   else
9484     {
9485       rtx countreg2;
9486       rtx label = NULL;
9487
9488       /* In case we don't know anything about the alignment, default to
9489          library version, since it is usually equally fast and result in
9490          shorter code.  */
9491       if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
9492         FAIL;
9493
9494       if (TARGET_SINGLE_STRINGOP)
9495         emit_insn (gen_cld());
9496
9497       countreg2 = gen_reg_rtx (SImode);
9498       countreg = copy_to_mode_reg (SImode, operands[1]);
9499       zeroreg = copy_to_mode_reg (SImode, const0_rtx);
9500
9501       if (count < 0
9502           && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
9503         {
9504           label = gen_label_rtx ();
9505           emit_cmp_and_jump_insns (countreg, GEN_INT (3),
9506                                    LEU, 0, SImode, 1, 0, label);
9507         }
9508       if (align <= 1)
9509         {
9510           rtx label = gen_label_rtx ();
9511           rtx tmpcount = gen_reg_rtx (SImode);
9512           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
9513           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9514                                    SImode, 1, 0, label);
9515           emit_insn (gen_strsetqi (destreg,
9516                                    gen_rtx_SUBREG (QImode, zeroreg, 0)));
9517           emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
9518           emit_label (label);
9519           LABEL_NUSES (label) = 1;
9520         }
9521       if (align <= 2)
9522         {
9523           rtx label = gen_label_rtx ();
9524           rtx tmpcount = gen_reg_rtx (SImode);
9525           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
9526           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9527                                    SImode, 1, 0, label);
9528           emit_insn (gen_strsethi (destreg,
9529                                    gen_rtx_SUBREG (HImode, zeroreg, 0)));
9530           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
9531           emit_label (label);
9532           LABEL_NUSES (label) = 1;
9533         }
9534       if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
9535         {
9536           rtx label = gen_label_rtx ();
9537           rtx tmpcount = gen_reg_rtx (SImode);
9538           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
9539           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9540                                    SImode, 1, 0, label);
9541           emit_insn (gen_strsetsi (destreg, zeroreg));
9542           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
9543           emit_label (label);
9544           LABEL_NUSES (label) = 1;
9545         }
9546
9547       if (!TARGET_SINGLE_STRINGOP)
9548         emit_insn (gen_cld());
9549       emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
9550       emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
9551                                  destreg, countreg2));
9552
9553       if (label)
9554         {
9555           emit_label (label);
9556           LABEL_NUSES (label) = 1;
9557         }
9558       if (align > 2 && count > 0 && (count & 2))
9559         emit_insn (gen_strsethi (destreg,
9560                                  gen_rtx_SUBREG (HImode, zeroreg, 0)));
9561       if (align <= 2 || count < 0)
9562         {
9563           rtx label = gen_label_rtx ();
9564           rtx tmpcount = gen_reg_rtx (SImode);
9565           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
9566           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9567                                    SImode, 1, 0, label);
9568           emit_insn (gen_strsethi (destreg,
9569                                    gen_rtx_SUBREG (HImode, zeroreg, 0)));
9570           emit_label (label);
9571           LABEL_NUSES (label) = 1;
9572         }
9573       if (align > 1 && count > 0 && (count & 1))
9574         emit_insn (gen_strsetqi (destreg,
9575                                  gen_rtx_SUBREG (QImode, zeroreg, 0)));
9576       if (align <= 1 || count < 0)
9577         {
9578           rtx label = gen_label_rtx ();
9579           rtx tmpcount = gen_reg_rtx (SImode);
9580           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
9581           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9582                                    SImode, 1, 0, label);
9583           emit_insn (gen_strsetqi (destreg,
9584                                    gen_rtx_SUBREG (QImode, zeroreg, 0)));
9585           emit_label (label);
9586           LABEL_NUSES (label) = 1;
9587         }
9588     }
9589   DONE;
9590 }")
9591
9592 ;; Most CPUs don't like single string operations
9593 ;; Handle this case here to simplify previous expander.
9594
9595 (define_expand "strsetsi"
9596   [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
9597         (match_operand:SI 1 "register_operand" ""))
9598    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
9599               (clobber (reg:CC 17))])]
9600   ""
9601   "
9602 {
9603   if (TARGET_SINGLE_STRINGOP || optimize_size)
9604     {
9605       emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
9606       DONE;
9607     }
9608 }")
9609
9610 (define_expand "strsethi"
9611   [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
9612         (match_operand:HI 1 "register_operand" ""))
9613    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
9614               (clobber (reg:CC 17))])]
9615   ""
9616   "
9617 {
9618   if (TARGET_SINGLE_STRINGOP || optimize_size)
9619     {
9620       emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
9621       DONE;
9622     }
9623 }")
9624
9625 (define_expand "strsetqi"
9626   [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
9627         (match_operand:QI 1 "register_operand" ""))
9628    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
9629               (clobber (reg:CC 17))])]
9630   ""
9631   "
9632 {
9633   if (TARGET_SINGLE_STRINGOP || optimize_size)
9634     {
9635       emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
9636       DONE;
9637     }
9638 }")
9639
9640 (define_insn "strsetsi_1"
9641   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
9642         (match_operand:SI 2 "register_operand" "a"))
9643    (set (match_operand:SI 0 "register_operand" "=D")
9644         (plus:SI (match_dup 0)
9645                  (const_int 4)))
9646    (use (reg:SI 19))]
9647   "TARGET_SINGLE_STRINGOP || optimize_size"
9648   "stosl"
9649   [(set_attr "type" "str")
9650    (set_attr "memory" "store")
9651    (set_attr "mode" "SI")])
9652
9653 (define_insn "strsethi_1"
9654   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
9655         (match_operand:HI 2 "register_operand" "a"))
9656    (set (match_operand:SI 0 "register_operand" "=D")
9657         (plus:SI (match_dup 0)
9658                  (const_int 2)))
9659    (use (reg:SI 19))]
9660   "TARGET_SINGLE_STRINGOP || optimize_size"
9661   "stosw"
9662   [(set_attr "type" "str")
9663    (set_attr "memory" "store")
9664    (set_attr "mode" "HI")])
9665
9666 (define_insn "strsetqi_1"
9667   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
9668         (match_operand:QI 2 "register_operand" "a"))
9669    (set (match_operand:SI 0 "register_operand" "=D")
9670         (plus:SI (match_dup 0)
9671                  (const_int 1)))
9672    (use (reg:SI 19))]
9673   "TARGET_SINGLE_STRINGOP || optimize_size"
9674   "stosb"
9675   [(set_attr "type" "str")
9676    (set_attr "memory" "store")
9677    (set_attr "mode" "QI")])
9678
9679 ;; It might seem that operand 0 could use predicate register_operand.
9680 ;; But strength reduction might offset the MEM expression.  So we let
9681 ;; reload put the address into %edi.
9682
9683 (define_insn "rep_stossi"
9684   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
9685    (use (match_operand:SI 2 "register_operand" "a"))
9686    (use (match_operand:SI 4 "register_operand" "1"))
9687    (set (match_operand:SI 0 "register_operand" "=D") 
9688         (plus:SI (match_operand:SI 3 "address_operand" "0")
9689                  (ashift:SI (match_dup 3) (const_int 2))))
9690    (set (mem:BLK (match_dup 3))
9691         (const_int 0))
9692    (use (reg:SI 19))]
9693   ""
9694   "rep\;stosl|rep stosd"
9695   [(set_attr "type" "str")
9696    (set_attr "prefix_rep" "1")
9697    (set_attr "memory" "store")
9698    (set_attr "mode" "SI")])
9699
9700 (define_insn "rep_stosqi"
9701   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
9702    (use (match_operand:QI 2 "register_operand" "a"))
9703    (use (match_operand:SI 4 "register_operand" "1"))
9704    (set (match_operand:SI 0 "register_operand" "=D") 
9705         (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 3)))
9706    (set (mem:BLK (match_dup 3))
9707         (const_int 0))
9708    (use (reg:SI 19))]
9709   ""
9710   "rep\;stosb|rep stosb"
9711   [(set_attr "type" "str")
9712    (set_attr "prefix_rep" "1")
9713    (set_attr "memory" "store")
9714    (set_attr "mode" "QI")])
9715
9716 (define_expand "cmpstrsi"
9717   [(set (match_operand:SI 0 "register_operand" "")
9718         (compare:SI (match_operand:BLK 1 "general_operand" "")
9719                     (match_operand:BLK 2 "general_operand" "")))
9720    (use (match_operand:SI 3 "general_operand" ""))
9721    (use (match_operand:SI 4 "immediate_operand" ""))]
9722   ""
9723   "
9724 {
9725   rtx addr1, addr2, out, outlow, count, countreg, align;
9726
9727   out = operands[0];
9728   if (GET_CODE (out) != REG)
9729     out = gen_reg_rtx (SImode);
9730
9731   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
9732   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
9733   
9734   count = operands[3];
9735   countreg = copy_to_mode_reg (SImode, count);
9736
9737   /* %%% Iff we are testing strict equality, we can use known alignment
9738      to good advantage.  This may be possible with combine, particularly
9739      once cc0 is dead.  */
9740   align = operands[4];
9741
9742   emit_insn (gen_cld ());
9743   if (GET_CODE (count) == CONST_INT)
9744     {
9745       if (INTVAL (count) == 0)
9746         {
9747           emit_move_insn (operands[0], const0_rtx);
9748           DONE;
9749         }
9750       emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align));
9751     }
9752   else
9753     {
9754       emit_insn (gen_cmpsi_1 (countreg, countreg));
9755       emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align));
9756     }
9757
9758   outlow = gen_lowpart (QImode, out);
9759   emit_insn (gen_cmpintqi (outlow));
9760   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
9761
9762   if (operands[0] != out)
9763     emit_move_insn (operands[0], out);
9764
9765   DONE;
9766 }")
9767
9768 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
9769
9770 (define_expand "cmpintqi"
9771   [(set (match_dup 1)
9772         (gtu:QI (reg:CC 17) (const_int 0)))
9773    (set (match_dup 2)
9774         (ltu:QI (reg:CC 17) (const_int 0)))
9775    (parallel [(set (match_operand:QI 0 "register_operand" "")
9776                    (minus:QI (match_dup 1)
9777                              (match_dup 2)))
9778               (clobber (reg:CC 17))])]
9779   ""
9780   "operands[1] = gen_reg_rtx (QImode);
9781    operands[2] = gen_reg_rtx (QImode);")
9782
9783 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
9784 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
9785 ;;
9786 ;; It might seem that operands 0 & 1 could use predicate register_operand.
9787 ;; But strength reduction might offset the MEM expression.  So we let
9788 ;; reload put the address into %edi & %esi.
9789
9790 (define_insn "cmpstrsi_nz_1"
9791   [(set (reg:CC 17)
9792         (compare:CC (mem:BLK (match_operand:SI 0 "address_operand" "S"))
9793                     (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
9794    (use (match_operand:SI 2 "register_operand" "c"))
9795    (use (match_operand:SI 3 "immediate_operand" "i"))
9796    (use (reg:SI 19))
9797    (clobber (match_dup 0))
9798    (clobber (match_dup 1))
9799    (clobber (match_dup 2))]
9800   ""
9801   "repz{\;| }cmpsb"
9802   [(set_attr "type" "str")
9803    (set_attr "mode" "QI")
9804    (set_attr "prefix_rep" "1")])
9805
9806 ;; The same, but the count is not known to not be zero.
9807
9808 (define_insn "cmpstrsi_1"
9809   [(set (reg:CC 17)
9810         (if_then_else:CC (ne (match_operand:SI 2 "register_operand" "c")
9811                              (const_int 0))
9812           (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
9813                       (mem:BLK (match_operand:SI 1 "address_operand" "D")))
9814           (const_int 0)))
9815    (use (match_operand:SI 3 "immediate_operand" "i"))
9816    (use (reg:CC 17))
9817    (use (reg:SI 19))
9818    (clobber (match_dup 0))
9819    (clobber (match_dup 1))
9820    (clobber (match_dup 2))]
9821   ""
9822   "repz{\;| }cmpsb"
9823   [(set_attr "type" "str")
9824    (set_attr "mode" "QI")
9825    (set_attr "prefix_rep" "1")])
9826
9827 (define_expand "strlensi"
9828   [(set (match_operand:SI 0 "register_operand" "")
9829         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
9830                     (match_operand:QI 2 "immediate_operand" "")
9831                     (match_operand:SI 3 "immediate_operand" "")] 0))]
9832   ""
9833   "
9834 {
9835   rtx out, addr, scratch1, scratch2, scratch3;
9836   rtx eoschar = operands[2];
9837   rtx align = operands[3];
9838
9839   /* The generic case of strlen expander is long.  Avoid it's
9840      expanding unless TARGET_INLINE_ALL_STRINGOPS.  */
9841
9842   if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
9843       && !TARGET_INLINE_ALL_STRINGOPS
9844       && !optimize_size
9845       && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
9846     FAIL;
9847
9848   out = operands[0];
9849   addr = force_reg (Pmode, XEXP (operands[1], 0));
9850   scratch1 = gen_reg_rtx (SImode);
9851
9852   if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
9853       && !optimize_size)
9854     {
9855       /* Well it seems that some optimizer does not combine a call like
9856              foo(strlen(bar), strlen(bar));
9857          when the move and the subtraction is done here.  It does calculate
9858          the length just once when these instructions are done inside of
9859          output_strlen_unroll().  But I think since &bar[strlen(bar)] is
9860          often used and I use one fewer register for the lifetime of
9861          output_strlen_unroll() this is better.  */
9862
9863       if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)
9864         emit_move_insn (scratch1, addr);
9865
9866       emit_move_insn (out, addr);
9867
9868       ix86_expand_strlensi_unroll_1 (out, align, scratch1);
9869
9870       /* strlensi_unroll_1 returns the address of the zero at the end of
9871          the string, like memchr(), so compute the length by subtracting
9872          the start address.  */
9873       emit_insn (gen_subsi3 (out, out, addr));
9874     }
9875   else
9876     {
9877       scratch2 = gen_reg_rtx (SImode);
9878       scratch3 = gen_reg_rtx (SImode);
9879
9880       emit_move_insn (scratch3, addr);
9881
9882       emit_insn (gen_cld ());
9883       emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
9884                                  align, constm1_rtx));
9885       emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
9886       emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
9887     }
9888   DONE;
9889 }")
9890
9891 ;; It might seem that operands 0 & 1 could use predicate register_operand.
9892 ;; But strength reduction might offset the MEM expression.  So we let
9893 ;; reload put the address into %edi.
9894
9895 (define_insn "strlensi_1"
9896   [(set (match_operand:SI 0 "register_operand" "=&c")
9897         (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
9898                     (match_operand:QI 2 "general_operand" "a")
9899                     (match_operand:SI 3 "immediate_operand" "i")
9900                     (match_operand:SI 4 "immediate_operand" "0")] 0))
9901    (use (reg:SI 19))
9902    (clobber (match_dup 1))
9903    (clobber (reg:CC 17))]
9904   ""
9905   "repnz{\;| }scasb"
9906   [(set_attr "type" "str")
9907    (set_attr "mode" "QI")
9908    (set_attr "prefix_rep" "1")])
9909 \f
9910 ;; Conditional move instructions.
9911
9912 (define_expand "movsicc"
9913   [(set (match_operand:SI 0 "register_operand" "")
9914         (if_then_else:SI (match_operand 1 "comparison_operator" "")
9915                          (match_operand:SI 2 "general_operand" "")
9916                          (match_operand:SI 3 "general_operand" "")))]
9917   ""
9918   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
9919
9920 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
9921 ;; the register first winds up with `sbbl $0,reg', which is also weird.
9922 ;; So just document what we're doing explicitly.
9923
9924 (define_insn "x86_movsicc_0_m1"
9925   [(set (match_operand:SI 0 "register_operand" "=r")
9926         (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
9927           (const_int -1)
9928           (const_int 0)))
9929    (clobber (reg:CC 17))]
9930   ""
9931   "sbb{l}\\t%0, %0"
9932   ; Since we don't have the proper number of operands for an alu insn,
9933   ; fill in all the blanks.
9934   [(set_attr "type" "alu")
9935    (set_attr "memory" "none")
9936    (set_attr "imm_disp" "false")
9937    (set_attr "mode" "SI")
9938    (set_attr "length_immediate" "0")])
9939
9940 (define_insn "*movsicc_noc"
9941   [(set (match_operand:SI 0 "register_operand" "=r,r")
9942         (if_then_else:SI (match_operator 1 "no_comparison_operator" 
9943                                 [(reg 17) (const_int 0)])
9944                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
9945                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
9946   "TARGET_CMOVE
9947    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9948   "@
9949    cmov%C1\\t{%2, %0|%0, %2}
9950    cmov%c1\\t{%3, %0|%0, %3}"
9951   [(set_attr "type" "icmov")
9952    (set_attr "mode" "SI")])
9953
9954 (define_insn "*movsicc_c"
9955   [(set (match_operand:SI 0 "register_operand" "=r,r")
9956         (if_then_else:SI (match_operator 1 "uno_comparison_operator" 
9957                                 [(reg:CC 17) (const_int 0)])
9958                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
9959                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
9960   "TARGET_CMOVE
9961    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9962   "@
9963    cmov%C1\\t{%2, %0|%0, %2}
9964    cmov%c1\\t{%3, %0|%0, %3}"
9965   [(set_attr "type" "icmov")
9966    (set_attr "mode" "SI")])
9967
9968 (define_expand "movhicc"
9969   [(set (match_operand:HI 0 "register_operand" "")
9970         (if_then_else:HI (match_operand 1 "comparison_operator" "")
9971                          (match_operand:HI 2 "nonimmediate_operand" "")
9972                          (match_operand:HI 3 "nonimmediate_operand" "")))]
9973   "TARGET_CMOVE && TARGET_HIMODE_MATH"
9974   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
9975
9976 (define_insn "*movhicc_noc"
9977   [(set (match_operand:HI 0 "register_operand" "=r,r")
9978         (if_then_else:HI (match_operator 1 "no_comparison_operator" 
9979                                 [(reg 17) (const_int 0)])
9980                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
9981                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
9982   "TARGET_CMOVE
9983    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9984   "@
9985    cmov%C1\\t{%2, %0|%0, %2}
9986    cmov%c1\\t{%3, %0|%0, %3}"
9987   [(set_attr "type" "icmov")
9988    (set_attr "mode" "HI")])
9989
9990 (define_insn "*movhicc_c"
9991   [(set (match_operand:HI 0 "register_operand" "=r,r")
9992         (if_then_else:HI (match_operator 1 "uno_comparison_operator" 
9993                                 [(reg:CC 17) (const_int 0)])
9994                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
9995                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
9996   "TARGET_CMOVE
9997    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9998   "@
9999    cmov%C1\\t{%2, %0|%0, %2}
10000    cmov%c1\\t{%3, %0|%0, %3}"
10001   [(set_attr "type" "icmov")
10002    (set_attr "mode" "HI")])
10003
10004 (define_expand "movsfcc"
10005   [(set (match_operand:SF 0 "register_operand" "")
10006         (if_then_else:SF (match_operand 1 "comparison_operator" "")
10007                          (match_operand:SF 2 "register_operand" "")
10008                          (match_operand:SF 3 "register_operand" "")))]
10009   "TARGET_CMOVE"
10010   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
10011
10012 (define_insn "*movsfcc_1"
10013   [(set (match_operand:SF 0 "register_operand" "=f,f")
10014         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
10015                                 [(reg 17) (const_int 0)])
10016                       (match_operand:SF 2 "register_operand" "f,0")
10017                       (match_operand:SF 3 "register_operand" "0,f")))]
10018   "TARGET_CMOVE"
10019   "@
10020    fcmov%F1\\t{%2, %0|%0, %2}
10021    fcmov%f1\\t{%3, %0|%0, %3}"
10022   [(set_attr "type" "fcmov")
10023    (set_attr "mode" "SF")])
10024
10025 (define_expand "movdfcc"
10026   [(set (match_operand:DF 0 "register_operand" "")
10027         (if_then_else:DF (match_operand 1 "comparison_operator" "")
10028                          (match_operand:DF 2 "register_operand" "")
10029                          (match_operand:DF 3 "register_operand" "")))]
10030   "TARGET_CMOVE"
10031   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
10032
10033 (define_insn "*movdfcc_1"
10034   [(set (match_operand:DF 0 "register_operand" "=f,f")
10035         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
10036                                 [(reg 17) (const_int 0)])
10037                       (match_operand:DF 2 "register_operand" "f,0")
10038                       (match_operand:DF 3 "register_operand" "0,f")))]
10039   "TARGET_CMOVE"
10040   "@
10041    fcmov%F1\\t{%2, %0|%0, %2}
10042    fcmov%f1\\t{%3, %0|%0, %3}"
10043   [(set_attr "type" "fcmov")
10044    (set_attr "mode" "DF")])
10045
10046 (define_expand "movxfcc"
10047   [(set (match_operand:XF 0 "register_operand" "")
10048         (if_then_else:XF (match_operand 1 "comparison_operator" "")
10049                          (match_operand:XF 2 "register_operand" "")
10050                          (match_operand:XF 3 "register_operand" "")))]
10051   "TARGET_CMOVE"
10052   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
10053
10054 (define_insn "*movxfcc_1"
10055   [(set (match_operand:XF 0 "register_operand" "=f,f")
10056         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
10057                                 [(reg 17) (const_int 0)])
10058                       (match_operand:XF 2 "register_operand" "f,0")
10059                       (match_operand:XF 3 "register_operand" "0,f")))]
10060   "TARGET_CMOVE"
10061   "@
10062    fcmov%F1\\t{%2, %0|%0, %2}
10063    fcmov%f1\\t{%3, %0|%0, %3}"
10064   [(set_attr "type" "fcmov")
10065    (set_attr "mode" "XF")])
10066 \f
10067 ;; Misc patterns (?)
10068
10069 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
10070 ;; Otherwise there will be nothing to keep
10071 ;; 
10072 ;; [(set (reg ebp) (reg esp))]
10073 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
10074 ;;  (clobber (eflags)]
10075 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
10076 ;;
10077 ;; in proper program order.
10078
10079 (define_insn "pro_epilogue_adjust_stack"
10080   [(set (match_operand:SI 0 "register_operand" "=r,r")
10081         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
10082                  (match_operand:SI 2 "immediate_operand" "i,i")))
10083    (set (match_operand:SI 3 "register_operand" "+r,r")
10084         (match_dup 3))
10085    (clobber (reg:CC 17))]
10086   ""
10087   "*
10088 {
10089   switch (get_attr_type (insn))
10090     {
10091     case TYPE_IMOV:
10092       return \"mov{l}\\t{%1, %0|%0, %1}\";
10093
10094     case TYPE_ALU:
10095       if (GET_CODE (operands[2]) == CONST_INT
10096           && (INTVAL (operands[2]) == 128
10097               || (INTVAL (operands[2]) < 0
10098                   && INTVAL (operands[2]) != -128)))
10099         {
10100           operands[2] = GEN_INT (-INTVAL (operands[2]));
10101           return \"sub{l}\\t{%2, %0|%0, %2}\";
10102         }
10103       return \"add{l}\\t{%2, %0|%0, %2}\";
10104
10105     case TYPE_LEA:
10106       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
10107       return \"lea{l}\\t{%a2, %0|%0, %a2}\";
10108
10109     default:
10110       abort ();
10111     }
10112 }"
10113   [(set (attr "type")
10114         (cond [(eq_attr "alternative" "0")
10115                  (const_string "alu")
10116                (match_operand:SI 2 "const0_operand" "")
10117                  (const_string "imov")
10118               ]
10119               (const_string "lea")))
10120    (set_attr "mode" "SI")])
10121
10122 (define_insn "allocate_stack_worker"
10123   [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
10124    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
10125    (clobber (match_dup 0))
10126    (clobber (reg:CC 17))]
10127   "TARGET_STACK_PROBE"
10128   "call\\t__alloca"
10129   [(set_attr "type" "multi")
10130    (set_attr "length" "5")])
10131
10132 (define_expand "allocate_stack"
10133   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
10134                    (minus:SI (reg:SI 7)
10135                              (match_operand:SI 1 "general_operand" "")))
10136               (clobber (reg:CC 17))])
10137    (parallel [(set (reg:SI 7)
10138                    (minus:SI (reg:SI 7) (match_dup 1)))
10139               (clobber (reg:CC 17))])]
10140   "TARGET_STACK_PROBE"
10141   "
10142 {
10143 #ifdef CHECK_STACK_LIMIT
10144   if (GET_CODE (operands[1]) == CONST_INT
10145       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
10146     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
10147                            operands[1]));
10148   else 
10149 #endif
10150     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
10151                                                             operands[1])));
10152
10153   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10154   DONE;
10155 }")
10156
10157 (define_expand "exception_receiver"
10158   [(const_int 0)]
10159   "flag_pic"
10160   "
10161 {
10162   load_pic_register ();
10163   DONE;
10164 }")
10165
10166 (define_expand "builtin_setjmp_receiver"
10167   [(label_ref (match_operand 0 "" ""))]
10168   "flag_pic"
10169   "
10170 {
10171   load_pic_register ();
10172   DONE;
10173 }")
10174 \f
10175 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
10176
10177 (define_split
10178   [(set (match_operand 0 "register_operand" "")
10179         (match_operator 3 "promotable_binary_operator"
10180            [(match_operand 1 "register_operand" "")
10181             (match_operand 2 "aligned_operand" "")]))
10182    (clobber (reg:CC 17))]
10183   "! TARGET_PARTIAL_REG_STALL && reload_completed
10184    && ((GET_MODE (operands[0]) == HImode 
10185         && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
10186             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
10187        || (GET_MODE (operands[0]) == QImode 
10188            && (TARGET_PROMOTE_QImode || optimize_size)))"
10189   [(parallel [(set (match_dup 0)
10190                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10191               (clobber (reg:CC 17))])]
10192   "operands[0] = gen_lowpart (SImode, operands[0]);
10193    operands[1] = gen_lowpart (SImode, operands[1]);
10194    if (GET_CODE (operands[3]) != ASHIFT)
10195      operands[2] = gen_lowpart (SImode, operands[2]);
10196    GET_MODE (operands[3]) = SImode;")
10197
10198 (define_split
10199   [(set (reg 17)
10200         (compare (and (match_operand 1 "aligned_operand" "")
10201                       (match_operand 2 "const_int_operand" ""))
10202                  (const_int 0)))
10203    (set (match_operand 0 "register_operand" "")
10204         (and (match_dup 1) (match_dup 2)))]
10205   "! TARGET_PARTIAL_REG_STALL && reload_completed
10206    && ix86_match_ccmode (insn, CCNOmode)
10207    && (GET_MODE (operands[0]) == HImode
10208        || (GET_MODE (operands[0]) == QImode 
10209            && (TARGET_PROMOTE_QImode || optimize_size)))"
10210   [(parallel [(set (reg:CCNO 17)
10211                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
10212                                  (const_int 0)))
10213               (set (match_dup 0)
10214                    (and:SI (match_dup 1) (match_dup 2)))])]
10215   "operands[2]
10216      = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
10217    operands[0] = gen_lowpart (SImode, operands[0]);
10218    operands[1] = gen_lowpart (SImode, operands[1]);")
10219
10220 (define_split
10221   [(set (reg 17)
10222         (compare (and (match_operand 0 "aligned_operand" "")
10223                       (match_operand 1 "const_int_operand" ""))
10224                  (const_int 0)))]
10225   "! TARGET_PARTIAL_REG_STALL && reload_completed
10226    && ix86_match_ccmode (insn, CCNOmode)
10227    && (GET_MODE (operands[0]) == HImode
10228        || (GET_MODE (operands[0]) == QImode 
10229            && (TARGET_PROMOTE_QImode || optimize_size)))"
10230   [(set (reg:CCNO 17)
10231         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
10232                       (const_int 0)))]
10233   "operands[1]
10234      = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
10235    operands[0] = gen_lowpart (SImode, operands[0]);")
10236
10237 (define_split
10238   [(set (match_operand 0 "register_operand" "")
10239         (neg (match_operand 1 "register_operand" "")))
10240    (clobber (reg:CC 17))]
10241   "! TARGET_PARTIAL_REG_STALL && reload_completed
10242    && (GET_MODE (operands[0]) == HImode
10243        || (GET_MODE (operands[0]) == QImode 
10244            && (TARGET_PROMOTE_QImode || optimize_size)))"
10245   [(parallel [(set (match_dup 0)
10246                    (neg:SI (match_dup 1)))
10247               (clobber (reg:CC 17))])]
10248   "operands[0] = gen_lowpart (SImode, operands[0]);
10249    operands[1] = gen_lowpart (SImode, operands[1]);")
10250
10251 (define_split
10252   [(set (match_operand 0 "register_operand" "")
10253         (not (match_operand 1 "register_operand" "")))]
10254   "! TARGET_PARTIAL_REG_STALL && reload_completed
10255    && (GET_MODE (operands[0]) == HImode
10256        || (GET_MODE (operands[0]) == QImode 
10257            && (TARGET_PROMOTE_QImode || optimize_size)))"
10258   [(set (match_dup 0)
10259         (not:SI (match_dup 1)))]
10260   "operands[0] = gen_lowpart (SImode, operands[0]);
10261    operands[1] = gen_lowpart (SImode, operands[1]);")
10262
10263 (define_split 
10264   [(set (match_operand 0 "register_operand" "")
10265         (if_then_else (match_operator 1 "comparison_operator" 
10266                                 [(reg 17) (const_int 0)])
10267                       (match_operand 2 "register_operand" "")
10268                       (match_operand 3 "register_operand" "")))]
10269   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
10270    && (GET_MODE (operands[0]) == HImode
10271        || (GET_MODE (operands[0]) == QImode 
10272            && (TARGET_PROMOTE_QImode || optimize_size)))"
10273   [(set (match_dup 0)
10274         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
10275   "operands[0] = gen_lowpart (SImode, operands[0]);
10276    operands[2] = gen_lowpart (SImode, operands[2]);
10277    operands[3] = gen_lowpart (SImode, operands[3]);")
10278                         
10279 \f
10280 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
10281 ;; transform a complex memory operation into two memory to register operations.
10282
10283 ;; Don't push memory operands
10284 (define_peephole2
10285   [(set (match_operand:SI 0 "push_operand" "")
10286         (match_operand:SI 1 "memory_operand" ""))
10287    (match_scratch:SI 2 "r")]
10288   "! optimize_size && ! TARGET_PUSH_MEMORY"
10289   [(set (match_dup 2) (match_dup 1))
10290    (set (match_dup 0) (match_dup 2))]
10291   "")
10292
10293 ;; We need to handle SFmode only, because DFmode and XFmode is split to
10294 ;; SImode pushes.
10295 (define_peephole2
10296   [(set (match_operand:SF 0 "push_operand" "")
10297         (match_operand:SF 1 "memory_operand" ""))
10298    (match_scratch:SF 2 "r")]
10299   "! optimize_size && ! TARGET_PUSH_MEMORY"
10300   [(set (match_dup 2) (match_dup 1))
10301    (set (match_dup 0) (match_dup 2))]
10302   "")
10303
10304 (define_peephole2
10305   [(set (match_operand:HI 0 "push_operand" "")
10306         (match_operand:HI 1 "memory_operand" ""))
10307    (match_scratch:HI 2 "r")]
10308   "! optimize_size && ! TARGET_PUSH_MEMORY"
10309   [(set (match_dup 2) (match_dup 1))
10310    (set (match_dup 0) (match_dup 2))]
10311   "")
10312
10313 (define_peephole2
10314   [(set (match_operand:QI 0 "push_operand" "")
10315         (match_operand:QI 1 "memory_operand" ""))
10316    (match_scratch:QI 2 "q")]
10317   "! optimize_size && ! TARGET_PUSH_MEMORY"
10318   [(set (match_dup 2) (match_dup 1))
10319    (set (match_dup 0) (match_dup 2))]
10320   "")
10321
10322 ;; Don't move an immediate directly to memory when the instruction
10323 ;; gets too big.
10324 (define_peephole2
10325   [(match_scratch:SI 1 "r")
10326    (set (match_operand:SI 0 "memory_operand" "")
10327         (const_int 0))]
10328   "! optimize_size
10329    && ! TARGET_USE_MOV0
10330    && TARGET_SPLIT_LONG_MOVES
10331    && get_attr_length (insn) >= ix86_cost->large_insn
10332    && peep2_regno_dead_p (0, FLAGS_REG)"
10333   [(parallel [(set (match_dup 1) (const_int 0))
10334               (clobber (reg:CC 17))])
10335    (set (match_dup 0) (match_dup 1))]
10336   "")
10337
10338 (define_peephole2
10339   [(match_scratch:HI 1 "r")
10340    (set (match_operand:HI 0 "memory_operand" "")
10341         (const_int 0))]
10342   "! optimize_size
10343    && ! TARGET_USE_MOV0
10344    && TARGET_SPLIT_LONG_MOVES
10345    && get_attr_length (insn) >= ix86_cost->large_insn
10346    && peep2_regno_dead_p (0, FLAGS_REG)"
10347   [(parallel [(set (match_dup 2) (const_int 0))
10348               (clobber (reg:CC 17))])
10349    (set (match_dup 0) (match_dup 1))]
10350   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
10351
10352 (define_peephole2
10353   [(match_scratch:QI 1 "q")
10354    (set (match_operand:QI 0 "memory_operand" "")
10355         (const_int 0))]
10356   "! optimize_size
10357    && ! TARGET_USE_MOV0
10358    && TARGET_SPLIT_LONG_MOVES
10359    && get_attr_length (insn) >= ix86_cost->large_insn
10360    && peep2_regno_dead_p (0, FLAGS_REG)"
10361   [(parallel [(set (match_dup 2) (const_int 0))
10362               (clobber (reg:CC 17))])
10363    (set (match_dup 0) (match_dup 1))]
10364   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
10365
10366 (define_peephole2
10367   [(match_scratch:SI 2 "r")
10368    (set (match_operand:SI 0 "memory_operand" "")
10369         (match_operand:SI 1 "immediate_operand" ""))]
10370   "! optimize_size
10371    && get_attr_length (insn) >= ix86_cost->large_insn
10372    && TARGET_SPLIT_LONG_MOVES"
10373   [(set (match_dup 2) (match_dup 1))
10374    (set (match_dup 0) (match_dup 2))]
10375   "")
10376
10377 (define_peephole2
10378   [(match_scratch:HI 2 "r")
10379    (set (match_operand:HI 0 "memory_operand" "")
10380         (match_operand:HI 1 "immediate_operand" ""))]
10381   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
10382   && TARGET_SPLIT_LONG_MOVES"
10383   [(set (match_dup 2) (match_dup 1))
10384    (set (match_dup 0) (match_dup 2))]
10385   "")
10386
10387 (define_peephole2
10388   [(match_scratch:QI 2 "q")
10389    (set (match_operand:QI 0 "memory_operand" "")
10390         (match_operand:QI 1 "immediate_operand" ""))]
10391   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
10392   && TARGET_SPLIT_LONG_MOVES"
10393   [(set (match_dup 2) (match_dup 1))
10394    (set (match_dup 0) (match_dup 2))]
10395   "")
10396
10397 ;; Don't compare memory with zero, load and use a test instead.
10398 (define_peephole2
10399   [(set (reg 17)
10400         (compare (match_operand:SI 0 "memory_operand" "")
10401                  (const_int 0)))
10402    (match_scratch:SI 3 "r")]
10403   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
10404   [(set (match_dup 3) (match_dup 0))
10405    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
10406   "")
10407
10408 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
10409 ;; Don't split NOTs with a displacement operand, because resulting XOR
10410 ;; will not be pariable anyway.
10411 ;;
10412 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
10413 ;; represented using a modRM byte.  The XOR replacement is long decoded,
10414 ;; so this split helps here as well.
10415 ;;
10416 ;; Note: Can't do this as a regular split because we can't get proper
10417 ;; lifetime information then.
10418
10419 (define_peephole2
10420   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10421         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10422   "!optimize_size
10423    && peep2_regno_dead_p (0, FLAGS_REG)
10424    && ((TARGET_PENTIUM 
10425         && (GET_CODE (operands[0]) != MEM
10426             || !memory_displacement_operand (operands[0], SImode)))
10427        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
10428   [(parallel [(set (match_dup 0)
10429                    (xor:SI (match_dup 1) (const_int -1)))
10430               (clobber (reg:CC 17))])]
10431   "")
10432
10433 (define_peephole2
10434   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10435         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10436   "!optimize_size
10437    && peep2_regno_dead_p (0, FLAGS_REG)
10438    && ((TARGET_PENTIUM 
10439         && (GET_CODE (operands[0]) != MEM
10440             || !memory_displacement_operand (operands[0], HImode)))
10441        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
10442   [(parallel [(set (match_dup 0)
10443                    (xor:HI (match_dup 1) (const_int -1)))
10444               (clobber (reg:CC 17))])]
10445   "")
10446
10447 (define_peephole2
10448   [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
10449         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
10450   "!optimize_size
10451    && peep2_regno_dead_p (0, FLAGS_REG)
10452    && ((TARGET_PENTIUM 
10453         && (GET_CODE (operands[0]) != MEM
10454             || !memory_displacement_operand (operands[0], QImode)))
10455        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
10456   [(parallel [(set (match_dup 0)
10457                    (xor:QI (match_dup 1) (const_int -1)))
10458               (clobber (reg:CC 17))])]
10459   "")
10460
10461 ;; Non pairable "test imm, reg" instructions can be translated to
10462 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
10463 ;; byte opcode instead of two, have a short form for byte operands),
10464 ;; so do it for other CPUs as well.  Given that the value was dead,
10465 ;; this should not create any new dependancies.  Pass on the sub-word
10466 ;; versions if we're concerned about partial register stalls.
10467
10468 (define_peephole2
10469   [(set (reg 17)
10470         (compare (and:SI (match_operand:SI 0 "register_operand" "")
10471                          (match_operand:SI 1 "immediate_operand" ""))
10472                  (const_int 0)))]
10473   "ix86_match_ccmode (insn, CCNOmode)
10474    && (true_regnum (operands[0]) != 0
10475        || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
10476    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
10477   [(parallel
10478      [(set (reg:CCNO 17)
10479            (compare:CCNO (and:SI (match_dup 0)
10480                                  (match_dup 1))
10481                          (const_int 0)))
10482       (set (match_dup 0)
10483            (and:SI (match_dup 0) (match_dup 1)))])]
10484   "")
10485
10486 ;; We don't need to handle HImode case, because it will be promoted to SImode
10487 ;; on ! TARGET_PARTIAL_REG_STALL
10488
10489 (define_peephole2
10490   [(set (reg 17)
10491         (compare (and:QI (match_operand:QI 0 "register_operand" "")
10492                          (match_operand:QI 1 "immediate_operand" ""))
10493                  (const_int 0)))]
10494   "! TARGET_PARTIAL_REG_STALL
10495    && ix86_match_ccmode (insn, CCNOmode)
10496    && true_regnum (operands[0]) != 0
10497    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
10498   [(parallel
10499      [(set (reg:CCNO 17)
10500            (compare:CCNO (and:QI (match_dup 0)
10501                                  (match_dup 1))
10502                          (const_int 0)))
10503       (set (match_dup 0)
10504            (and:QI (match_dup 0) (match_dup 1)))])]
10505   "")
10506
10507 (define_peephole2
10508   [(set (reg 17)
10509         (compare
10510           (and:SI
10511             (zero_extract:SI
10512               (match_operand 0 "ext_register_operand" "q")
10513               (const_int 8)
10514               (const_int 8))
10515             (match_operand 1 "const_int_operand" "n"))
10516           (const_int 0)))]
10517   "! TARGET_PARTIAL_REG_STALL
10518    && ix86_match_ccmode (insn, CCNOmode)
10519    && true_regnum (operands[0]) != 0
10520    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
10521   [(parallel [(set (reg:CCNO 17)
10522                    (compare:CCNO
10523                        (and:SI
10524                          (zero_extract:SI
10525                          (match_dup 0)
10526                          (const_int 8)
10527                          (const_int 8))
10528                         (match_dup 1))
10529                    (const_int 0)))
10530               (set (zero_extract:SI (match_dup 0)
10531                                     (const_int 8)
10532                                     (const_int 8))
10533                    (and:SI 
10534                      (zero_extract:SI
10535                        (match_dup 0)
10536                        (const_int 8)
10537                        (const_int 8))
10538                      (match_dup 1)))])]
10539   "")
10540
10541 ;; Don't do logical operations with memory inputs.
10542 (define_peephole2
10543   [(match_scratch:SI 2 "r")
10544    (parallel [(set (match_operand:SI 0 "register_operand" "")
10545                    (match_operator:SI 3 "arith_or_logical_operator"
10546                      [(match_dup 0)
10547                       (match_operand:SI 1 "memory_operand" "")]))
10548               (clobber (reg:CC 17))])]
10549   "! optimize_size && ! TARGET_READ_MODIFY"
10550   [(set (match_dup 2) (match_dup 1))
10551    (parallel [(set (match_dup 0)
10552                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
10553               (clobber (reg:CC 17))])]
10554   "")
10555
10556 (define_peephole2
10557   [(match_scratch:SI 2 "r")
10558    (parallel [(set (match_operand:SI 0 "register_operand" "")
10559                    (match_operator:SI 3 "arith_or_logical_operator"
10560                      [(match_operand:SI 1 "memory_operand" "")
10561                       (match_dup 0)]))
10562               (clobber (reg:CC 17))])]
10563   "! optimize_size && ! TARGET_READ_MODIFY"
10564   [(set (match_dup 2) (match_dup 1))
10565    (parallel [(set (match_dup 0)
10566                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
10567               (clobber (reg:CC 17))])]
10568   "")
10569
10570 ; Don't do logical operations with memory outputs
10571 ;
10572 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
10573 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
10574 ; the same decoder scheduling characteristics as the original.
10575
10576 (define_peephole2
10577   [(match_scratch:SI 2 "r")
10578    (parallel [(set (match_operand:SI 0 "memory_operand" "")
10579                    (match_operator:SI 3 "arith_or_logical_operator"
10580                      [(match_dup 0)
10581                       (match_operand:SI 1 "nonmemory_operand" "")]))
10582               (clobber (reg:CC 17))])]
10583   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
10584   [(set (match_dup 2) (match_dup 0))
10585    (parallel [(set (match_dup 2)
10586                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
10587               (clobber (reg:CC 17))])
10588    (set (match_dup 0) (match_dup 2))]
10589   "")
10590
10591 (define_peephole2
10592   [(match_scratch:SI 2 "r")
10593    (parallel [(set (match_operand:SI 0 "memory_operand" "")
10594                    (match_operator:SI 3 "arith_or_logical_operator"
10595                      [(match_operand:SI 1 "nonmemory_operand" "")
10596                       (match_dup 0)]))
10597               (clobber (reg:CC 17))])]
10598   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
10599   [(set (match_dup 2) (match_dup 0))
10600    (parallel [(set (match_dup 2)
10601                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10602               (clobber (reg:CC 17))])
10603    (set (match_dup 0) (match_dup 2))]
10604   "")
10605
10606 ;; Attempt to always use XOR for zeroing registers.
10607 (define_peephole2
10608   [(set (match_operand 0 "register_operand" "")
10609         (const_int 0))]
10610   "(GET_MODE (operands[0]) == QImode
10611     || GET_MODE (operands[0]) == HImode
10612     || GET_MODE (operands[0]) == SImode)
10613    && (! TARGET_USE_MOV0 || optimize_size)
10614    && peep2_regno_dead_p (0, FLAGS_REG)"
10615   [(parallel [(set (match_dup 0) (const_int 0))
10616               (clobber (reg:CC 17))])]
10617   "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
10618
10619 (define_peephole2
10620   [(set (strict_low_part (match_operand 0 "register_operand" ""))
10621         (const_int 0))]
10622   "(GET_MODE (operands[0]) == QImode
10623     || GET_MODE (operands[0]) == HImode)
10624    && (! TARGET_USE_MOV0 || optimize_size)
10625    && peep2_regno_dead_p (0, FLAGS_REG)"
10626   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
10627               (clobber (reg:CC 17))])])
10628
10629 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
10630 (define_peephole2
10631   [(set (match_operand 0 "register_operand" "")
10632         (const_int -1))]
10633   "(GET_MODE (operands[0]) == HImode
10634     || GET_MODE (operands[0]) == SImode)
10635    && (optimize_size || TARGET_PENTIUM)
10636    && peep2_regno_dead_p (0, FLAGS_REG)"
10637   [(parallel [(set (match_dup 0) (const_int -1))
10638               (clobber (reg:CC 17))])]
10639   "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
10640
10641 ;; Attempt to convert simple leas to adds. These can be created by
10642 ;; move expanders.
10643 (define_peephole2
10644   [(set (match_operand:SI 0 "register_operand" "")
10645         (plus:SI (match_dup 0)
10646                  (match_operand:SI 1 "nonmemory_operand" "")))]
10647   "peep2_regno_dead_p (0, FLAGS_REG)"
10648   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
10649               (clobber (reg:CC 17))])]
10650   "")
10651
10652 (define_peephole2
10653   [(set (match_operand:SI 0 "register_operand" "")
10654         (mult:SI (match_dup 0)
10655                  (match_operand:SI 1 "immediate_operand" "")))]
10656   "exact_log2 (INTVAL (operands[1])) >= 0
10657    && peep2_regno_dead_p (0, FLAGS_REG)"
10658   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
10659               (clobber (reg:CC 17))])]
10660   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
10661
10662 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
10663 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
10664 ;; many CPUs it is also faster, since special hardware to avoid esp
10665 ;; dependancies is present.
10666
10667 ;; While some of these converisons may be done using splitters, we use peepholes
10668 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
10669
10670 ;; Convert prologue esp substractions to push.
10671 ;; We need register to push.  In order to keep verify_flow_info happy we have
10672 ;; two choices
10673 ;; - use scratch and clobber it in order to avoid dependencies
10674 ;; - use already live register
10675 ;; We can't use the second way right now, since there is no reliable way how to
10676 ;; verify that given register is live.  First choice will also most likely in
10677 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
10678 ;; call clobbered registers are dead.  We may want to use base pointer as an
10679 ;; alternative when no register is available later.
10680
10681 (define_peephole2
10682   [(match_scratch:SI 0 "r")
10683    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
10684               (set (reg:SI 6) (reg:SI 6))
10685               (clobber (reg:CC 17))])]
10686   "optimize_size || !TARGET_SUB_ESP_4"
10687   [(clobber (match_dup 0))
10688    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
10689               (set (reg:SI 6) (reg:SI 6))])])
10690
10691 (define_peephole2
10692   [(match_scratch:SI 0 "r")
10693    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
10694               (set (reg:SI 6) (reg:SI 6))
10695               (clobber (reg:CC 17))])]
10696   "optimize_size || !TARGET_SUB_ESP_8"
10697   [(clobber (match_dup 0))
10698    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
10699    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
10700               (set (reg:SI 6) (reg:SI 6))])])
10701
10702 ;; Convert esp substractions to push.
10703 (define_peephole2
10704   [(match_scratch:SI 0 "r")
10705    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
10706               (clobber (reg:CC 17))])]
10707   "optimize_size || !TARGET_SUB_ESP_4"
10708   [(clobber (match_dup 0))
10709    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
10710
10711 (define_peephole2
10712   [(match_scratch:SI 0 "r")
10713    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
10714               (clobber (reg:CC 17))])]
10715   "optimize_size || !TARGET_SUB_ESP_8"
10716   [(clobber (match_dup 0))
10717    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
10718    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
10719
10720 ;; Convert epilogue deallocator to pop.
10721 (define_peephole2
10722   [(match_scratch:SI 0 "r")
10723    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10724               (set (reg:SI 6) (reg:SI 6))
10725               (clobber (reg:CC 17))])]
10726   "optimize_size || !TARGET_ADD_ESP_4"
10727   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10728               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10729               (set (reg:SI 6) (reg:SI 6))])]
10730   "")
10731
10732 ;; Two pops case is tricky, since pop causes dependency on destination register.
10733 ;; We use two registers if available.
10734 (define_peephole2
10735   [(match_scratch:SI 0 "r")
10736    (match_scratch:SI 1 "r")
10737    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10738               (set (reg:SI 6) (reg:SI 6))
10739               (clobber (reg:CC 17))])]
10740   "optimize_size || !TARGET_ADD_ESP_8"
10741   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10742               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10743               (set (reg:SI 6) (reg:SI 6))])
10744    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
10745               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10746   "")
10747
10748 (define_peephole2
10749   [(match_scratch:SI 0 "r")
10750    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10751               (set (reg:SI 6) (reg:SI 6))
10752               (clobber (reg:CC 17))])]
10753   "optimize_size"
10754   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10755               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10756               (set (reg:SI 6) (reg:SI 6))])
10757    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10758               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10759   "")
10760
10761 ;; Convert esp additions to pop.
10762 (define_peephole2
10763   [(match_scratch:SI 0 "r")
10764    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10765               (clobber (reg:CC 17))])]
10766   ""
10767   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10768               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10769   "")
10770
10771 ;; Two pops case is tricky, since pop causes dependency on destination register.
10772 ;; We use two registers if available.
10773 (define_peephole2
10774   [(match_scratch:SI 0 "r")
10775    (match_scratch:SI 1 "r")
10776    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10777               (clobber (reg:CC 17))])]
10778   ""
10779   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10780               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
10781    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
10782               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10783   "")
10784
10785 (define_peephole2
10786   [(match_scratch:SI 0 "r")
10787    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10788               (clobber (reg:CC 17))])]
10789   "optimize_size"
10790   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10791               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
10792    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10793               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10794   "")
10795 \f
10796 ;; Call-value patterns last so that the wildcard operand does not
10797 ;; disrupt insn-recog's switch tables.
10798
10799 (define_insn "*call_value_pop_0"
10800   [(set (match_operand 0 "" "")
10801         (call (match_operand:QI 1 "constant_call_address_operand" "")
10802               (match_operand:SI 2 "" "")))
10803    (set (reg:SI 7) (plus:SI (reg:SI 7)
10804                             (match_operand:SI 4 "immediate_operand" "")))]
10805   ""
10806   "*
10807 {
10808   if (SIBLING_CALL_P (insn))
10809     return \"jmp\\t%P1\";
10810   else
10811     return \"call\\t%P1\";
10812 }"
10813   [(set_attr "type" "callv")])
10814
10815 (define_insn "*call_value_pop_1"
10816   [(set (match_operand 0 "" "")
10817         (call (match_operand:QI 1 "call_insn_operand" "m")
10818               (match_operand:SI 2 "" "")))
10819    (set (reg:SI 7) (plus:SI (reg:SI 7)
10820                             (match_operand:SI 4 "immediate_operand" "i")))]
10821   ""
10822   "*
10823 {
10824   if (constant_call_address_operand (operands[1], QImode))
10825     {
10826       if (SIBLING_CALL_P (insn))
10827         return \"jmp\\t%P1\";
10828       else
10829         return \"call\\t%P1\";
10830     }
10831   operands[1] = XEXP (operands[1], 0);
10832   if (SIBLING_CALL_P (insn))
10833     return \"jmp\\t%*%1\";
10834   else
10835     return \"call\\t%*%1\";
10836 }"
10837   [(set_attr "type" "callv")])
10838
10839 (define_insn "*call_value_0"
10840   [(set (match_operand 0 "" "")
10841         (call (match_operand:QI 1 "constant_call_address_operand" "")
10842               (match_operand:SI 2 "" "")))]
10843   ""
10844   "*
10845 {
10846   if (SIBLING_CALL_P (insn))
10847     return \"jmp\\t%P1\";
10848   else
10849     return \"call\\t%P1\";
10850 }"
10851   [(set_attr "type" "callv")])
10852
10853 (define_insn "*call_value_1"
10854   [(set (match_operand 0 "" "")
10855         (call (match_operand:QI 1 "call_insn_operand" "m")
10856               (match_operand:SI 2 "" "")))]
10857   ""
10858   "*
10859 {
10860   if (constant_call_address_operand (operands[1], QImode))
10861     {
10862       if (SIBLING_CALL_P (insn))
10863         return \"jmp\\t%P1\";
10864       else
10865         return \"call\\t%P1\";
10866     }
10867   operands[1] = XEXP (operands[1], 0);
10868   if (SIBLING_CALL_P (insn))
10869     return \"jmp\\t%*%1\";
10870   else
10871     return \"call\\t%*%1\";
10872 }"
10873   [(set_attr "type" "callv")])