OSDN Git Service

5696c2645a76daeb54dfee271e2b317f78e3d4fa
[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,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 ;; The (bounding maximum) length of an instruction in bytes.
91 (define_attr "length" ""
92   (symbol_ref "ix86_attr_length_default(insn)"))
93
94 ;; Supporting: number of prefix bytes
95 (define_attr "length_prefix" ""
96   (cond [(and (eq_attr "type" "alu,alu1,negnot,icmp,imovx,incdec,ishift,imul,idiv,imov,pop")
97               (match_operand:HI 0 "general_operand" ""))
98            (const_int 1)
99          (and (eq_attr "type" "push")
100               (match_operand:HI 1 "general_operand" ""))
101            (const_int 1)
102         ]
103         (const_int 0)))
104
105 ;; Supporting: bytes in the opcode+modrm.
106 (define_attr "length_opcode" ""
107   (cond [(eq_attr "type" "imovx,setcc,icmov")
108            (const_int 3)
109          (eq_attr "type" "str,cld")
110            (const_int 1)
111          (and (eq_attr "type" "incdec")
112               (ior (match_operand:SI 1 "register_operand" "")
113                    (match_operand:HI 1 "register_operand" "")))
114            (const_int 1)
115          (and (eq_attr "type" "push")
116               (not (match_operand 1 "memory_operand" "")))
117            (const_int 1)
118          (and (eq_attr "type" "pop")
119               (not (match_operand 0 "memory_operand" "")))
120            (const_int 1)
121          (and (eq_attr "type" "imov")
122               (and (match_operand 0 "register_operand" "")
123                    (match_operand 1 "immediate_operand" "")))
124            (const_int 1)
125          ]
126          (const_int 2)))
127
128 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
129 ;; `store' if there is a simple memory reference therein, or `unknown'
130 ;; if the instruction is complex.
131
132 (define_attr "memory" "none,load,store,both,unknown"
133   (cond [(eq_attr "type" "other,multi,str")
134            (const_string "unknown")
135          (eq_attr "type" "lea,fcmov,fpspc,cld")
136            (const_string "none")
137          (eq_attr "type" "push")
138            (if_then_else (match_operand 1 "memory_operand" "")
139              (const_string "both")
140              (const_string "store"))
141          (eq_attr "type" "pop,setcc")
142            (if_then_else (match_operand 0 "memory_operand" "")
143              (const_string "both")
144              (const_string "load"))
145          (eq_attr "type" "icmp")
146            (if_then_else (ior (match_operand 0 "memory_operand" "")
147                               (match_operand 1 "memory_operand" ""))
148              (const_string "load")
149              (const_string "none"))
150          (eq_attr "type" "ibr")
151            (if_then_else (match_operand 0 "memory_operand" "")
152              (const_string "load")
153              (const_string "none"))
154          (eq_attr "type" "call")
155            (if_then_else (match_operand 0 "constant_call_address_operand" "")
156              (const_string "none")
157              (const_string "load"))
158          (eq_attr "type" "callv")
159            (if_then_else (match_operand 1 "constant_call_address_operand" "")
160              (const_string "none")
161              (const_string "load"))
162          (and (eq_attr "type" "alu1,negnot")
163               (match_operand 1 "memory_operand" ""))
164            (const_string "both")
165          (and (match_operand 0 "memory_operand" "")
166               (match_operand 1 "memory_operand" ""))
167            (const_string "both")
168          (match_operand 0 "memory_operand" "")
169            (const_string "store")
170          (match_operand 1 "memory_operand" "")
171            (const_string "load")
172          (and (eq_attr "type" "!icmp,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp")
173               (match_operand 2 "memory_operand" ""))
174            (const_string "load")
175          (and (eq_attr "type" "icmov")
176               (match_operand 3 "memory_operand" ""))
177            (const_string "load")
178         ]
179         (const_string "none")))
180
181 ;; Indicates if an instruction has both an immediate and a displacement.
182
183 (define_attr "imm_disp" "false,true,unknown"
184   (cond [(eq_attr "type" "other,multi")
185            (const_string "unknown")
186          (and (eq_attr "type" "icmp,imov")
187               (and (match_operand 0 "memory_displacement_operand" "")
188                    (match_operand 1 "immediate_operand" "")))
189            (const_string "true")
190          (and (eq_attr "type" "alu,ishift,imul,idiv")
191               (and (match_operand 0 "memory_displacement_operand" "")
192                    (match_operand 2 "immediate_operand" "")))
193            (const_string "true")
194         ]
195         (const_string "false")))
196
197 ;; Indicates if an FP operation has an integer source.
198
199 (define_attr "fp_int_src" "false,true"
200   (const_string "false"))
201
202 ;; Describe a user's asm statement.
203 (define_asm_attributes
204   [(set_attr "length" "128")
205    (set_attr "type" "multi")])
206 \f
207 ;; Pentium Scheduling
208 ;;
209 ;; The Pentium is an in-order core with two integer pipelines.
210
211 ;; Categorize how an instruction slots.
212
213 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
214 ;; while MMX Pentium can slot it on either U or V.  Model non-MMX Pentium
215 ;; rules, because it results in noticeably better code on non-MMX Pentium
216 ;; and doesn't hurt much on MMX.  (Prefixed instructions are not very
217 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
218
219 (define_attr "pent_pair" "uv,pu,pv,np"
220   (cond [(eq_attr "imm_disp" "true")
221            (const_string "np")
222          (eq_attr "type" "alu1,alu,imov,icmp,lea,incdec")
223            (if_then_else (eq_attr "length_prefix" "1")
224              (const_string "pu")
225              (const_string "uv"))
226          (eq_attr "type" "ibr")
227            (const_string "pv")
228          (and (eq_attr "type" "ishift")
229               (match_operand 2 "const_int_operand" ""))
230            (const_string "pu")
231          (and (eq_attr "type" "pop,push")
232               (eq_attr "memory" "!both"))
233            (if_then_else (eq_attr "length_prefix" "1")
234              (const_string "pu")
235              (const_string "uv"))
236          (and (eq_attr "type" "call")
237               (match_operand 0 "constant_call_address_operand" ""))
238            (const_string "pv")
239          (and (eq_attr "type" "callv")
240               (match_operand 1 "constant_call_address_operand" ""))
241            (const_string "pv")
242         ]
243         (const_string "np")))
244
245 ;; Rough readiness numbers.  Fine tuning happens in i386.c.
246 ;;
247 ;; u    describes pipe U
248 ;; v    describes pipe V
249 ;; uv   describes either pipe U or V for those that can issue to either
250 ;; np   describes not paring
251 ;; fpu  describes fpu
252 ;; fpm  describes fp insns of different types are not pipelined.
253 ;;
254 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
255
256 (define_function_unit "pent_np" 1 0
257   (and (eq_attr "cpu" "pentium")
258        (eq_attr "type" "imul"))
259   11 11)
260
261 (define_function_unit "pent_mul" 1 1
262   (and (eq_attr "cpu" "pentium")
263        (eq_attr "type" "imul"))
264   11 11)
265
266 ;; Rep movs takes minimally 12 cycles.
267 (define_function_unit "pent_np" 1 0
268   (and (eq_attr "cpu" "pentium")
269        (eq_attr "type" "str"))
270   12 12)
271
272 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
273 (define_function_unit "pent_np" 1 0
274   (and (eq_attr "cpu" "pentium")
275        (eq_attr "type" "idiv"))
276   46 46)
277
278 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
279 ; 3 cycles for XFmode.  Stores takes 2 cycles for SF/DF and 3 for XF.
280 ; fldz and fld1 takes 2 cycles.  Only reg-reg moves are pairable.
281 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
282 ; like normal fp operation and fist takes 6 cycles.
283
284 (define_function_unit "fpu" 1 0
285   (and (eq_attr "cpu" "pentium")
286        (and (eq_attr "type" "fmov")
287             (ior (and (eq_attr "memory" "store")
288                       (match_operand:XF 0 "memory_operand" ""))
289                  (and (eq_attr "memory" "load")
290                       (match_operand:XF 1 "memory_operand" "")))))
291   3 3)
292
293 (define_function_unit "pent_np" 1 0
294   (and (eq_attr "cpu" "pentium")
295        (and (eq_attr "type" "fmov")
296             (ior (and (eq_attr "memory" "store")
297                       (match_operand:XF 0 "memory_operand" ""))
298                  (and (eq_attr "memory" "load")
299                       (match_operand:XF 1 "memory_operand" "")))))
300   3 3)
301
302 (define_function_unit "fpu" 1 0
303   (and (eq_attr "cpu" "pentium")
304        (and (eq_attr "type" "fmov")
305             (ior (match_operand 1 "immediate_operand" "")
306                  (eq_attr "memory" "store"))))
307   2 2)
308
309 (define_function_unit "pent_np" 1 0
310   (and (eq_attr "cpu" "pentium")
311        (and (eq_attr "type" "fmov")
312             (ior (match_operand 1 "immediate_operand" "")
313                  (eq_attr "memory" "store"))))
314   2 2)
315
316 (define_function_unit "pent_np" 1 0
317   (and (eq_attr "cpu" "pentium")
318        (eq_attr "type" "cld"))
319   2 2)
320
321 (define_function_unit "fpu" 1 0
322   (and (eq_attr "cpu" "pentium")
323        (and (eq_attr "type" "fmov")
324             (eq_attr "memory" "none,load")))
325   1 1)
326
327 ; Read/Modify/Write instructions usually take 3 cycles.
328 (define_function_unit "pent_u" 1 0
329   (and (eq_attr "cpu" "pentium")
330        (and (eq_attr "type" "alu,alu1,ishift")
331             (and (eq_attr "pent_pair" "pu")
332                  (eq_attr "memory" "both"))))
333   3 3)
334
335 (define_function_unit "pent_uv" 2 0
336   (and (eq_attr "cpu" "pentium")
337        (and (eq_attr "type" "alu,alu1,ishift")
338             (and (eq_attr "pent_pair" "!np")
339                  (eq_attr "memory" "both"))))
340   3 3)
341
342 (define_function_unit "pent_np" 1 0
343   (and (eq_attr "cpu" "pentium")
344        (and (eq_attr "type" "alu,alu1,negnot,ishift")
345             (and (eq_attr "pent_pair" "np")
346                  (eq_attr "memory" "both"))))
347   3 3)
348
349 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
350 (define_function_unit "pent_u" 1 0
351   (and (eq_attr "cpu" "pentium")
352        (and (eq_attr "type" "alu,ishift")
353             (and (eq_attr "pent_pair" "pu")
354                  (eq_attr "memory" "load,store"))))
355   2 2)
356
357 (define_function_unit "pent_uv" 2 0
358   (and (eq_attr "cpu" "pentium")
359        (and (eq_attr "type" "alu,ishift")
360             (and (eq_attr "pent_pair" "!np")
361                  (eq_attr "memory" "load,store"))))
362   2 2)
363
364 (define_function_unit "pent_np" 1 0
365   (and (eq_attr "cpu" "pentium")
366        (and (eq_attr "type" "alu,ishift")
367             (and (eq_attr "pent_pair" "np")
368                  (eq_attr "memory" "load,store"))))
369   2 2)
370
371 ; Insns w/o memory operands and move instructions usually take one cycle.
372 (define_function_unit "pent_u" 1 0
373   (and (eq_attr "cpu" "pentium")
374        (eq_attr "pent_pair" "pu"))
375   1 1)
376
377 (define_function_unit "pent_v" 1 0
378   (and (eq_attr "cpu" "pentium")
379        (eq_attr "pent_pair" "pv"))
380   1 1)
381
382 (define_function_unit "pent_uv" 2 0
383   (and (eq_attr "cpu" "pentium")
384        (eq_attr "pent_pair" "!np"))
385   1 1)
386
387 (define_function_unit "pent_np" 1 0
388   (and (eq_attr "cpu" "pentium")
389        (eq_attr "pent_pair" "np"))
390   1 1)
391
392 ; Pairable insns only conflict with other non-pairable insns.
393 (define_function_unit "pent_np" 1 0
394   (and (eq_attr "cpu" "pentium")
395        (and (eq_attr "type" "alu,alu1,ishift")
396             (and (eq_attr "pent_pair" "!np")
397                  (eq_attr "memory" "both"))))
398   3 3
399   [(eq_attr "pent_pair" "np")])
400
401 (define_function_unit "pent_np" 1 0
402   (and (eq_attr "cpu" "pentium")
403        (and (eq_attr "type" "alu,alu1,ishift")
404             (and (eq_attr "pent_pair" "!np")
405                  (eq_attr "memory" "load,store"))))
406   2 2
407   [(eq_attr "pent_pair" "np")])
408
409 (define_function_unit "pent_np" 1 0
410   (and (eq_attr "cpu" "pentium")
411        (eq_attr "pent_pair" "!np"))
412   1 1
413   [(eq_attr "pent_pair" "np")])
414
415 ; Floating point instructions usually blocks cycle longer when combined with
416 ; integer instructions, because of the inpaired fxch instruction.
417 (define_function_unit "pent_np" 1 0
418   (and (eq_attr "cpu" "pentium")
419        (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
420   2 2
421   [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
422
423 (define_function_unit "fpu" 1 0
424   (and (eq_attr "cpu" "pentium")
425        (eq_attr "type" "fcmp,fxch,fsgn"))
426   1 1)
427
428 ; Addition takes 3 cycles; assume other random cruft does as well.
429 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
430 (define_function_unit "fpu" 1 0
431   (and (eq_attr "cpu" "pentium")
432        (eq_attr "type" "fop,fop1"))
433   3 1)
434
435 ; Multiplication takes 3 cycles and is only half pipelined.
436 (define_function_unit "fpu" 1 0
437   (and (eq_attr "cpu" "pentium")
438        (eq_attr "type" "fmul"))
439   3 1)
440
441 (define_function_unit "pent_mul" 1 1
442   (and (eq_attr "cpu" "pentium")
443        (eq_attr "type" "fmul"))
444   2 2)
445
446 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles. 
447 ; They can overlap with integer insns.  Only the last two cycles can overlap
448 ; with other fp insns.  Only fsin/fcos can overlap with multiplies.
449 ; Only last two cycles of fsin/fcos can overlap with other instructions.
450 (define_function_unit "fpu" 1 0
451   (and (eq_attr "cpu" "pentium")
452        (eq_attr "type" "fdiv"))
453   39 37)
454
455 (define_function_unit "pent_mul" 1 1
456   (and (eq_attr "cpu" "pentium")
457        (eq_attr "type" "fdiv"))
458   39 39)
459
460 (define_function_unit "fpu" 1 0
461   (and (eq_attr "cpu" "pentium")
462        (eq_attr "type" "fpspc"))
463   70 68)
464
465 (define_function_unit "pent_mul" 1 1
466   (and (eq_attr "cpu" "pentium")
467        (eq_attr "type" "fpspc"))
468   70 70)
469 \f
470 ;; Pentium Pro/PII Scheduling
471 ;;
472 ;; The PPro has an out-of-order core, but the instruction decoders are
473 ;; naturally in-order and asymmetric.  We get best performance by scheduling
474 ;; for the decoders, for in doing so we give the oo execution unit the 
475 ;; most choices.
476
477 ;; Categorize how many uops an ia32 instruction evaluates to:
478 ;;   one --  an instruction with 1 uop can be decoded by any of the
479 ;;           three decoders.
480 ;;   few --  an instruction with 1 to 4 uops can be decoded only by 
481 ;;           decoder 0.
482 ;;   many -- a complex instruction may take an unspecified number of
483 ;;           cycles to decode in decoder 0.
484
485 (define_attr "ppro_uops" "one,few,many"
486   (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
487            (const_string "many")
488          (eq_attr "type" "icmov,fcmov,str,cld")
489            (const_string "few")
490          (eq_attr "type" "imov")
491            (if_then_else (eq_attr "memory" "store,both")
492              (const_string "few")
493              (const_string "one"))
494          (eq_attr "memory" "!none")
495            (const_string "few")
496         ]
497         (const_string "one")))
498
499 ;; Rough readiness numbers.  Fine tuning happens in i386.c.
500 ;;
501 ;; p0   describes port 0.
502 ;; p01  describes ports 0 and 1 as a pair; alu insns can issue to either.
503 ;; p2   describes port 2 for loads.
504 ;; p34  describes ports 3 and 4 for stores.
505 ;; fpu  describes the fpu accessed via port 0. 
506 ;;      ??? It is less than clear if there are separate fadd and fmul units
507 ;;      that could operate in parallel.
508 ;;
509 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
510
511 (define_function_unit "ppro_p0" 1 0
512   (and (eq_attr "cpu" "pentiumpro")
513        (eq_attr "type" "ishift,lea,ibr,cld"))
514   1 1)
515
516 (define_function_unit "ppro_p0" 1 0
517   (and (eq_attr "cpu" "pentiumpro")
518        (eq_attr "type" "imul"))
519   4 1)
520
521 ;; ??? Does the divider lock out the pipe while it works,
522 ;; or is there a disconnected unit?
523 (define_function_unit "ppro_p0" 1 0
524   (and (eq_attr "cpu" "pentiumpro")
525        (eq_attr "type" "idiv"))
526   17 17)
527
528 (define_function_unit "ppro_p0" 1 0
529   (and (eq_attr "cpu" "pentiumpro")
530        (eq_attr "type" "fop,fop1,fsgn"))
531   3 1)
532
533 (define_function_unit "ppro_p0" 1 0
534   (and (eq_attr "cpu" "pentiumpro")
535        (eq_attr "type" "fcmov"))
536   2 1)
537
538 (define_function_unit "ppro_p0" 1 0
539   (and (eq_attr "cpu" "pentiumpro")
540        (eq_attr "type" "fcmp"))
541   1 1)
542
543 (define_function_unit "ppro_p0" 1 0
544   (and (eq_attr "cpu" "pentiumpro")
545        (eq_attr "type" "fmov"))
546   1 1)
547
548 (define_function_unit "ppro_p0" 1 0
549   (and (eq_attr "cpu" "pentiumpro")
550        (eq_attr "type" "fmul"))
551   5 1)
552
553 (define_function_unit "ppro_p0" 1 0
554   (and (eq_attr "cpu" "pentiumpro")
555        (eq_attr "type" "fdiv,fpspc"))
556   56 1)
557
558 (define_function_unit "ppro_p01" 2 0
559   (and (eq_attr "cpu" "pentiumpro")
560        (eq_attr "type" "!imov,fmov"))
561   1 1)
562
563 (define_function_unit "ppro_p01" 2 0
564   (and (and (eq_attr "cpu" "pentiumpro")
565             (eq_attr "type" "imov,fmov"))
566        (eq_attr "memory" "none"))
567   1 1)
568
569 (define_function_unit "ppro_p2" 1 0
570   (and (eq_attr "cpu" "pentiumpro")
571        (ior (eq_attr "type" "pop")
572             (eq_attr "memory" "load,both")))
573   3 1)
574
575 (define_function_unit "ppro_p34" 1 0
576   (and (eq_attr "cpu" "pentiumpro")
577        (ior (eq_attr "type" "push")
578             (eq_attr "memory" "store,both")))
579   1 1)
580
581 (define_function_unit "fpu" 1 0
582   (and (eq_attr "cpu" "pentiumpro")
583        (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
584   1 1)
585
586 (define_function_unit "fpu" 1 0
587   (and (eq_attr "cpu" "pentiumpro")
588        (eq_attr "type" "fmul"))
589   5 2)
590
591 (define_function_unit "fpu" 1 0
592   (and (eq_attr "cpu" "pentiumpro")
593        (eq_attr "type" "fdiv,fpspc"))
594   56 56)
595
596 ;; imul uses the fpu.  ??? does it have the same throughput as fmul?
597 (define_function_unit "fpu" 1 0
598   (and (eq_attr "cpu" "pentiumpro")
599        (eq_attr "type" "imul"))
600   4 1)
601 \f
602 ;; AMD K6/K6-2 Scheduling
603 ;;
604 ;; The K6 has similar architecture to PPro.  Important difference is, that
605 ;; there are only two decoders and they seems to be much slower than execution
606 ;; units.  So we have to pay much more attention to proper decoding for
607 ;; schedulers.  We share most of scheduler code for PPro in i386.c
608 ;;
609 ;; The fp unit is not pipelined and do one operation per two cycles including
610 ;; the FXCH.
611 ;;
612 ;; alu    describes both ALU units (ALU-X and ALU-Y).
613 ;; alux   describes X alu unit
614 ;; fpu    describes FPU unit
615 ;; load   describes load unit.
616 ;; branch describes branch unit.
617 ;; store  decsribes store unit.  This unit is not modelled completely and only
618 ;;        used to model lea operation.  Otherwise it lie outside of the critical
619 ;;        path.
620 ;;
621 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
622
623 ;; The decoder specification is in the PPro section above!
624
625 ;; Shift instructions and certain arithmetic are issued only to X pipe.
626 (define_function_unit "k6_alux" 1 0
627   (and (eq_attr "cpu" "k6")
628        (eq_attr "type" "ishift,alu1,negnot,cld"))
629   1 1)
630
631 ;; The QI mode arithmetic is issued to X pipe only.
632 (define_function_unit "k6_alux" 1 0
633   (and (eq_attr "cpu" "k6")
634        (and (eq_attr "type" "alu,alu1,negnot,icmp,imovx,incdec")
635             (match_operand:QI 0 "general_operand" "")))
636   1 1)
637
638 (define_function_unit "k6_alu" 2 0
639   (and (eq_attr "cpu" "k6")
640        (eq_attr "type" "ishift,alu1,negnot,alu,icmp,imovx,incdec,setcc,lea"))
641   1 1)
642
643 (define_function_unit "k6_alu" 2 0
644   (and (eq_attr "cpu" "k6")
645        (and (eq_attr "type" "imov")
646             (eq_attr "memory" "none")))
647   1 1)
648
649 (define_function_unit "k6_branch" 1 0
650   (and (eq_attr "cpu" "k6")
651        (eq_attr "type" "call,callv,ibr"))
652   1 1)
653
654 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
655 (define_function_unit "k6_load" 1 0
656   (and (eq_attr "cpu" "k6")
657        (ior (eq_attr "type" "pop")
658             (eq_attr "memory" "load,both")))
659   1 1)
660
661 (define_function_unit "k6_load" 1 0
662   (and (eq_attr "cpu" "k6")
663        (and (eq_attr "type" "str")
664             (eq_attr "memory" "load,both")))
665   10 10)
666
667 ;; Lea have two instructions, so latency is probably 2
668 (define_function_unit "k6_store" 1 0
669   (and (eq_attr "cpu" "k6")
670        (eq_attr "type" "lea"))
671   2 1)
672
673 (define_function_unit "k6_store" 1 0
674   (and (eq_attr "cpu" "k6")
675        (eq_attr "type" "str"))
676   10 10)
677
678 (define_function_unit "k6_store" 1 0
679   (and (eq_attr "cpu" "k6")
680        (ior (eq_attr "type" "push")
681             (eq_attr "memory" "store,both")))
682   1 1)
683
684 (define_function_unit "k6_fpu" 1 1
685   (and (eq_attr "cpu" "k6")
686        (eq_attr "type" "fop,fop1,fmov,fcmp"))
687   2 2)
688
689 (define_function_unit "k6_fpu" 1 1
690   (and (eq_attr "cpu" "k6")
691        (eq_attr "type" "fmul"))
692   2 2)
693
694 ;; ??? Guess
695 (define_function_unit "k6_fpu" 1 1
696   (and (eq_attr "cpu" "k6")
697        (eq_attr "type" "fdiv,fpspc"))
698   56 56)
699
700 (define_function_unit "k6_alu" 2 0
701   (and (eq_attr "cpu" "k6")
702        (eq_attr "type" "imul"))
703   2 2)
704
705 (define_function_unit "k6_alux" 1 0
706   (and (eq_attr "cpu" "k6")
707        (eq_attr "type" "imul"))
708   2 2)
709
710 ;; ??? Guess
711 (define_function_unit "k6_alu" 2 0
712   (and (eq_attr "cpu" "k6")
713        (eq_attr "type" "idiv"))
714   17 17)
715
716 (define_function_unit "k6_alux" 1 0
717   (and (eq_attr "cpu" "k6")
718        (eq_attr "type" "idiv"))
719   17 17)
720 \f
721 ;; AMD Athlon Scheduling
722 ;;
723 ;; The Athlon does contain three pipelined FP units, three integer units and
724 ;; three address generation units. 
725 ;;
726 ;; The predecode logic is determining boundaries of instructions in the 64
727 ;; byte cache line. So the cache line straddling problem of K6 might be issue
728 ;; here as well, but it is not noted in the documentation.
729 ;;
730 ;; Three DirectPath instructions decoders and only one VectorPath decoder
731 ;; is available. They can decode three DirectPath instructions or one VectorPath
732 ;; instruction per cycle.
733 ;; Decoded macro instructions are then passed to 72 entry instruction control
734 ;; unit, that passes
735 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
736 ;;
737 ;; The load/store queue unit is not attached to the schedulers but
738 ;; communicates with all the execution units seperately instead.
739
740 (define_attr "athlon_decode" "direct,vector"
741   (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
742            (const_string "vector")
743          (and (eq_attr "type" "push")
744               (match_operand 1 "memory_operand" ""))
745            (const_string "vector")
746          (and (eq_attr "type" "fmov")
747               (ior (match_operand:XF 0 "memory_operand" "")
748                    (match_operand:XF 1 "memory_operand" "")))
749            (const_string "vector")]
750         (const_string "direct")))
751
752 (define_function_unit "athlon_vectordec" 1 0
753   (and (eq_attr "cpu" "athlon")
754        (eq_attr "athlon_decode" "vector"))
755   1 1)
756
757 (define_function_unit "athlon_directdec" 3 0
758   (and (eq_attr "cpu" "athlon")
759        (eq_attr "athlon_decode" "direct"))
760   1 1)
761
762 (define_function_unit "athlon_vectordec" 1 0
763   (and (eq_attr "cpu" "athlon")
764        (eq_attr "athlon_decode" "direct"))
765   1 1 [(eq_attr "athlon_decode" "vector")])
766
767 (define_function_unit "athlon_ieu" 3 0
768   (and (eq_attr "cpu" "athlon")
769        (eq_attr "type" "alu1,negnot,alu,icmp,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
770   1 1)
771
772 (define_function_unit "athlon_ieu" 3 0
773   (and (eq_attr "cpu" "athlon")
774        (eq_attr "type" "str"))
775   15 15)
776
777 (define_function_unit "athlon_ieu" 3 0
778   (and (eq_attr "cpu" "athlon")
779        (eq_attr "type" "imul"))
780   5 0)
781
782 (define_function_unit "athlon_ieu" 3 0
783   (and (eq_attr "cpu" "athlon")
784        (eq_attr "type" "idiv"))
785   42 0)
786
787 (define_function_unit "athlon_muldiv" 1 0
788   (and (eq_attr "cpu" "athlon")
789        (eq_attr "type" "imul"))
790   5 0)
791
792 (define_function_unit "athlon_muldiv" 1 0
793   (and (eq_attr "cpu" "athlon")
794        (eq_attr "type" "idiv"))
795   42 42)
796
797 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
798   (cond [(eq_attr "type" "fop,fop1,fcmp")
799            (const_string "add")
800          (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
801            (const_string "mul")
802          (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
803            (const_string "store")
804          (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
805            (const_string "any")
806          (and (eq_attr "type" "fmov")
807               (ior (match_operand:SI 1 "register_operand" "")
808                    (match_operand 1 "immediate_operand" "")))
809            (const_string "store")
810          (eq_attr "type" "fmov")
811            (const_string "muladd")]
812         (const_string "none")))
813
814 ;; We use latencies 1 for definitions.  This is OK to model colisions
815 ;; in execution units.  The real latencies are modeled in the "fp" pipeline.
816
817 ;; fsin, fcos: 96-192
818 ;; fsincos: 107-211
819 ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
820 (define_function_unit "athlon_fp" 3 0
821   (and (eq_attr "cpu" "athlon")
822        (eq_attr "type" "fpspc"))
823   100 1)
824
825 ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
826 (define_function_unit "athlon_fp" 3 0
827   (and (eq_attr "cpu" "athlon")
828        (eq_attr "type" "fdiv"))
829   24 1)
830
831 (define_function_unit "athlon_fp" 3 0
832   (and (eq_attr "cpu" "athlon")
833        (eq_attr "type" "fop,fop1,fmul"))
834   4 1)
835
836 ;; XFmode loads are slow.
837 ;; XFmode store is slow too (8 cycles), but we don't need to model it, because
838 ;; there are no dependent instructions.
839
840 (define_function_unit "athlon_fp" 3 0
841   (and (eq_attr "cpu" "athlon")
842        (and (eq_attr "type" "fmov")
843             (match_operand:XF 1 "memory_operand" "")))
844   10 1)
845
846 (define_function_unit "athlon_fp" 3 0
847   (and (eq_attr "cpu" "athlon")
848        (eq_attr "type" "fmov,fsgn"))
849   2 1)
850
851 ;; fcmp and ftst instructions
852 (define_function_unit "athlon_fp" 3 0
853   (and (eq_attr "cpu" "athlon")
854        (and (eq_attr "type" "fcmp")
855             (eq_attr "athlon_decode" "direct")))
856   3 1)
857
858 ;; fcmpi instructions.
859 (define_function_unit "athlon_fp" 3 0
860   (and (eq_attr "cpu" "athlon")
861        (and (eq_attr "type" "fcmp")
862             (eq_attr "athlon_decode" "vector")))
863   3 1)
864
865 (define_function_unit "athlon_fp" 3 0
866   (and (eq_attr "cpu" "athlon")
867        (eq_attr "type" "fcmov"))
868   7 1)
869
870 (define_function_unit "athlon_fp_mul" 1 0
871   (and (eq_attr "cpu" "athlon")
872        (eq_attr "athlon_fpunits" "mul"))
873   1 1)
874
875 (define_function_unit "athlon_fp_add" 1 0
876   (and (eq_attr "cpu" "athlon")
877        (eq_attr "athlon_fpunits" "add"))
878   1 1)
879
880 (define_function_unit "athlon_fp_muladd" 2 0
881   (and (eq_attr "cpu" "athlon")
882        (eq_attr "athlon_fpunits" "muladd,mul,add"))
883   1 1)
884
885 (define_function_unit "athlon_fp_store" 1 0
886   (and (eq_attr "cpu" "athlon")
887        (eq_attr "athlon_fpunits" "store"))
888   1 1)
889
890 ;; We don't need to model the Adress Generation Unit, since we don't model
891 ;; the re-order buffer yet and thus we never schedule more than three operations
892 ;; at time.  Later we may want to experiment with MD_SCHED macros modeling the
893 ;; decoders independently on the functional units.
894
895 ;(define_function_unit "athlon_agu" 3 0
896 ;  (and (eq_attr "cpu" "athlon")
897 ;       (and (eq_attr "memory" "!none")
898 ;            (eq_attr "athlon_fpunits" "none")))
899 ;  1 1)
900
901 ;; Model load unit to avoid too long sequences of loads.  We don't need to
902 ;; model store queue, since it is hardly going to be bottleneck.
903
904 (define_function_unit "athlon_load" 2 0
905   (and (eq_attr "cpu" "athlon")
906        (eq_attr "memory" "load,both"))
907   1 1)
908
909 \f
910 ;; Compare instructions.
911
912 ;; All compare insns have expanders that save the operands away without
913 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
914 ;; after the cmp) will actually emit the cmpM.
915
916 (define_expand "cmpdi"
917   [(set (reg:CC 17)
918         (compare:CC (match_operand:DI 0 "general_operand" "")
919                     (match_operand:DI 1 "general_operand" "")))]
920   ""
921   "
922 {
923   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
924       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
925     operands[0] = force_reg (DImode, operands[0]);
926   ix86_compare_op0 = operands[0];
927   ix86_compare_op1 = operands[1];
928   DONE;
929 }")
930
931 (define_expand "cmpsi"
932   [(set (reg:CC 17)
933         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
934                     (match_operand:SI 1 "general_operand" "")))]
935   ""
936   "
937 {
938   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
939       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
940     operands[0] = force_reg (SImode, operands[0]);
941   ix86_compare_op0 = operands[0];
942   ix86_compare_op1 = operands[1];
943   DONE;
944 }")
945
946 (define_expand "cmphi"
947   [(set (reg:CC 17)
948         (compare:CC (match_operand:HI 0 "general_operand" "")
949                     (match_operand:HI 1 "general_operand" "")))]
950   ""
951   "
952 {
953   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
954       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
955     operands[0] = force_reg (HImode, operands[0]);
956   ix86_compare_op0 = operands[0];
957   ix86_compare_op1 = operands[1];
958   DONE;
959 }")
960
961 (define_expand "cmpqi"
962   [(set (reg:CC 17)
963         (compare:CC (match_operand:QI 0 "general_operand" "")
964                     (match_operand:QI 1 "general_operand" "")))]
965   "TARGET_QIMODE_MATH"
966   "
967 {
968   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
969       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
970     operands[0] = force_reg (QImode, operands[0]);
971   ix86_compare_op0 = operands[0];
972   ix86_compare_op1 = operands[1];
973   DONE;
974 }")
975
976 (define_insn "cmpsi_ccz_1"
977   [(set (reg:CCZ 17)
978         (compare:CCZ (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
979                      (match_operand:SI 1 "const0_operand" "n,n")))]
980   ""
981   "@
982    test{l}\\t{%0, %0|%0, %0}
983    cmp{l}\\t{%1, %0|%0, %1}"
984   [(set_attr "type" "icmp")])
985
986 (define_insn "cmpsi_ccno_1"
987   [(set (reg:CCNO 17)
988         (compare:CCNO (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
989                       (match_operand:SI 1 "const0_operand" "n,n")))]
990   ""
991   "@
992    test{l}\\t{%0, %0|%0, %0}
993    cmp{l}\\t{%1, %0|%0, %1}"
994   [(set_attr "type" "icmp")])
995
996 (define_insn "cmpsi_1"
997   [(set (reg:CC 17)
998         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
999                     (match_operand:SI 1 "general_operand" "ri,mr")))]
1000   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1001   "cmp{l}\\t{%1, %0|%0, %1}"
1002   [(set_attr "type" "icmp")])
1003
1004 (define_insn "*cmphi_0"
1005   [(set (reg 17)
1006         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1007                  (match_operand:HI 1 "const0_operand" "n,n")))]
1008   "ix86_match_ccmode (insn, CCNOmode)"
1009   "@
1010    test{w}\\t{%0, %0|%0, %0}
1011    cmp{w}\\t{%1, %0|%0, %1}"
1012   [(set_attr "type" "icmp")])
1013
1014 (define_insn "*cmphi_1"
1015   [(set (reg:CC 17)
1016         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1017                     (match_operand:HI 1 "general_operand" "ri,mr")))]
1018   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1019   "cmp{w}\\t{%1, %0|%0, %1}"
1020   [(set_attr "type" "icmp")])
1021
1022 (define_insn "cmpqi_ccz_1"
1023   [(set (reg:CCZ 17)
1024         (compare:CCZ (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1025                      (match_operand:QI 1 "const0_operand" "n,n")))]
1026   ""
1027   "@
1028    test{b}\\t{%0, %0|%0, %0}
1029    cmp{b}\\t{$0, %0|%0, 0}"
1030   [(set_attr "type" "icmp")])
1031
1032 (define_insn "*cmpqi_ccno_1"
1033   [(set (reg:CCNO 17)
1034         (compare:CCNO (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1035                       (match_operand:QI 1 "const0_operand" "n,n")))]
1036   ""
1037   "@
1038    test{b}\\t{%0, %0|%0, %0}
1039    cmp{b}\\t{$0, %0|%0, 0}"
1040   [(set_attr "type" "icmp")])
1041
1042 (define_insn "*cmpqi_1"
1043   [(set (reg:CC 17)
1044         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1045                     (match_operand:QI 1 "general_operand" "qi,mq")))]
1046   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1047   "cmp{b}\\t{%1, %0|%0, %1}"
1048   [(set_attr "type" "icmp")])
1049
1050 (define_insn "*cmpqi_ext_1"
1051   [(set (reg:CC 17)
1052         (compare:CC
1053           (match_operand:QI 0 "general_operand" "qm")
1054           (subreg:QI
1055             (zero_extract:SI
1056               (match_operand 1 "ext_register_operand" "q")
1057               (const_int 8)
1058               (const_int 8)) 0)))]
1059   ""
1060   "cmp{b}\\t{%h1, %0|%0, %h1}"
1061   [(set_attr "type" "icmp")])
1062
1063 (define_insn "*cmpqi_ext_2"
1064   [(set (reg 17)
1065         (compare
1066           (subreg:QI
1067             (zero_extract:SI
1068               (match_operand 0 "ext_register_operand" "q")
1069               (const_int 8)
1070               (const_int 8)) 0)
1071           (match_operand:QI 1 "const0_operand" "n")))]
1072   "ix86_match_ccmode (insn, CCNOmode)"
1073   "test{b}\\t%h0, %h0"
1074   [(set_attr "type" "icmp")])
1075
1076 (define_insn "cmpqi_ext_3"
1077   [(set (reg:CC 17)
1078         (compare:CC
1079           (subreg:QI
1080             (zero_extract:SI
1081               (match_operand 0 "ext_register_operand" "q")
1082               (const_int 8)
1083               (const_int 8)) 0)
1084           (match_operand:QI 1 "general_operand" "qmn")))]
1085   ""
1086   "cmp{b}\\t{%1, %h0|%h0, %1}"
1087   [(set_attr "type" "icmp")])
1088
1089 (define_insn "*cmpqi_ext_4"
1090   [(set (reg:CC 17)
1091         (compare:CC
1092           (subreg:QI
1093             (zero_extract:SI
1094               (match_operand 0 "ext_register_operand" "q")
1095               (const_int 8)
1096               (const_int 8)) 0)
1097           (subreg:QI
1098             (zero_extract:SI
1099               (match_operand 1 "ext_register_operand" "q")
1100               (const_int 8)
1101               (const_int 8)) 0)))]
1102   ""
1103   "cmp{b}\\t{%h1, %h0|%h0, %h1}"
1104   [(set_attr "type" "icmp")])
1105
1106 ;; These implement float point compares.
1107 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1108 ;; which would allow mix and match FP modes on the compares.  Which is what
1109 ;; the old patterns did, but with many more of them.
1110
1111 (define_expand "cmpxf"
1112   [(set (reg:CC 17)
1113         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1114                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1115   "TARGET_80387"
1116   "
1117 {
1118   ix86_compare_op0 = operands[0];
1119   ix86_compare_op1 = operands[1];
1120   DONE;
1121 }")
1122
1123 (define_expand "cmpdf"
1124   [(set (reg:CC 17)
1125         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1126                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1127   "TARGET_80387"
1128   "
1129 {
1130   ix86_compare_op0 = operands[0];
1131   ix86_compare_op1 = operands[1];
1132   DONE;
1133 }")
1134
1135 (define_expand "cmpsf"
1136   [(set (reg:CC 17)
1137         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1138                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1139   "TARGET_80387"
1140   "
1141 {
1142   ix86_compare_op0 = operands[0];
1143   ix86_compare_op1 = operands[1];
1144   DONE;
1145 }")
1146
1147 ;; FP compares, step 1:
1148 ;; Set the FP condition codes.
1149 ;;
1150 ;; CCFPmode     compare with exceptions
1151 ;; CCFPUmode    compare with no exceptions
1152
1153 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1154 ;; and that fp moves clobber the condition codes, and that there is
1155 ;; currently no way to describe this fact to reg-stack.  So there are
1156 ;; no splitters yet for this.
1157
1158 ;; %%% YIKES!  This scheme does not retain a strong connection between 
1159 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1160 ;; work!  Only allow tos/mem with tos in op 0.
1161 ;;
1162 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
1163 ;; things aren't as bad as they sound...
1164
1165 (define_insn "*cmpfp_0"
1166   [(set (match_operand:HI 0 "register_operand" "=a")
1167         (unspec:HI
1168           [(compare:CCFP (match_operand 1 "register_operand" "f")
1169                          (match_operand 2 "const0_operand" "X"))] 9))]
1170   "TARGET_80387
1171    && FLOAT_MODE_P (GET_MODE (operands[1]))
1172    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1173   "*
1174 {
1175   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1176     return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\";
1177   else
1178     return \"ftst\;fnstsw\\t%0\";
1179 }"
1180   [(set_attr "type" "multi")])
1181
1182 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1183 ;; used to manage the reg stack popping would not be preserved.
1184
1185 (define_insn "*cmpfp_2_sf"
1186   [(set (reg:CCFP 18)
1187         (compare:CCFP
1188           (match_operand:SF 0 "register_operand" "f")
1189           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1190   "TARGET_80387"
1191   "* return output_fp_compare (insn, operands, 0, 0);"
1192   [(set_attr "type" "fcmp")])
1193
1194 (define_insn "*cmpfp_2_sf_1"
1195   [(set (match_operand:HI 0 "register_operand" "=a")
1196         (unspec:HI
1197           [(compare:CCFP
1198              (match_operand:SF 1 "register_operand" "f")
1199              (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1200   "TARGET_80387"
1201   "* return output_fp_compare (insn, operands, 2, 0);"
1202   [(set_attr "type" "fcmp")])
1203
1204 (define_insn "*cmpfp_2_df"
1205   [(set (reg:CCFP 18)
1206         (compare:CCFP
1207           (match_operand:DF 0 "register_operand" "f")
1208           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1209   "TARGET_80387"
1210   "* return output_fp_compare (insn, operands, 0, 0);"
1211   [(set_attr "type" "fcmp")])
1212
1213 (define_insn "*cmpfp_2_df_1"
1214   [(set (match_operand:HI 0 "register_operand" "=a")
1215         (unspec:HI
1216           [(compare:CCFP
1217              (match_operand:DF 1 "register_operand" "f")
1218              (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1219   "TARGET_80387"
1220   "* return output_fp_compare (insn, operands, 2, 0);"
1221   [(set_attr "type" "multi")])
1222
1223 (define_insn "*cmpfp_2_xf"
1224   [(set (reg:CCFP 18)
1225         (compare:CCFP
1226           (match_operand:XF 0 "register_operand" "f")
1227           (match_operand:XF 1 "register_operand" "f")))]
1228   "TARGET_80387"
1229   "* return output_fp_compare (insn, operands, 0, 0);"
1230   [(set_attr "type" "fcmp")])
1231
1232 (define_insn "*cmpfp_2_xf_1"
1233   [(set (match_operand:HI 0 "register_operand" "=a")
1234         (unspec:HI
1235           [(compare:CCFP
1236              (match_operand:XF 1 "register_operand" "f")
1237              (match_operand:XF 2 "register_operand" "f"))] 9))]
1238   "TARGET_80387"
1239   "* return output_fp_compare (insn, operands, 2, 0);"
1240   [(set_attr "type" "multi")])
1241
1242 (define_insn "*cmpfp_2u"
1243   [(set (reg:CCFPU 18)
1244         (compare:CCFPU
1245           (match_operand 0 "register_operand" "f")
1246           (match_operand 1 "register_operand" "f")))]
1247   "TARGET_80387
1248    && FLOAT_MODE_P (GET_MODE (operands[0]))
1249    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1250   "* return output_fp_compare (insn, operands, 0, 1);"
1251   [(set_attr "type" "fcmp")])
1252
1253 (define_insn "*cmpfp_2u_1"
1254   [(set (match_operand:HI 0 "register_operand" "=a")
1255         (unspec:HI
1256           [(compare:CCFPU
1257              (match_operand 1 "register_operand" "f")
1258              (match_operand 2 "register_operand" "f"))] 9))]
1259   "TARGET_80387
1260    && FLOAT_MODE_P (GET_MODE (operands[1]))
1261    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1262   "* return output_fp_compare (insn, operands, 2, 1);"
1263   [(set_attr "type" "multi")])
1264
1265 ;; Patterns to match the SImode-in-memory ficom instructions.
1266 ;;
1267 ;; %%% Play games with accepting gp registers, as otherwise we have to
1268 ;; force them to memory during rtl generation, which is no good.  We
1269 ;; can get rid of this once we teach reload to do memory input reloads 
1270 ;; via pushes.
1271
1272 (define_insn "*ficom_1"
1273   [(set (reg:CCFP 18)
1274         (compare:CCFP
1275           (match_operand 0 "register_operand" "f,f")
1276           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1277   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1278    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1279   "#")
1280
1281 ;; Split the not-really-implemented gp register case into a
1282 ;; push-op-pop sequence.
1283 ;;
1284 ;; %%% This is most efficient, but am I gonna get in trouble
1285 ;; for separating cc0_setter and cc0_user?
1286
1287 (define_split
1288   [(set (reg:CCFP 18)
1289         (compare:CCFP
1290           (match_operand:SF 0 "register_operand" "")
1291           (float (match_operand:SI 1 "register_operand" ""))))]
1292   "0 && TARGET_80387 && reload_completed"
1293   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1294    (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1295    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1296               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1297   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1298    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1299
1300 ;; FP compares, step 2
1301 ;; Move the fpsw to ax.
1302
1303 (define_insn "x86_fnstsw_1"
1304   [(set (match_operand:HI 0 "register_operand" "=a")
1305         (unspec:HI [(reg 18)] 9))]
1306   "TARGET_80387"
1307   "fnstsw\\t%0"
1308   [(set_attr "length" "2")
1309    (set_attr "ppro_uops" "few")])
1310
1311 ;; FP compares, step 3
1312 ;; Get ax into flags, general case.
1313
1314 (define_insn "x86_sahf_1"
1315   [(set (reg:CC 17)
1316         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1317   ""
1318   "sahf"
1319   [(set_attr "length" "1")
1320    (set_attr "athlon_decode" "vector")
1321    (set_attr "ppro_uops" "one")])
1322
1323 ;; Pentium Pro can do steps 1 through 3 in one go.
1324
1325 (define_insn "*cmpfp_i"
1326   [(set (reg:CCFP 17)
1327         (compare:CCFP (match_operand 0 "register_operand" "f")
1328                       (match_operand 1 "register_operand" "f")))]
1329   "TARGET_80387 && TARGET_CMOVE
1330    && FLOAT_MODE_P (GET_MODE (operands[0]))
1331    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1332   "* return output_fp_compare (insn, operands, 1, 0);"
1333   [(set_attr "type" "fcmp")
1334    (set_attr "athlon_decode" "vector")])
1335
1336 (define_insn "*cmpfp_iu"
1337   [(set (reg:CCFPU 17)
1338         (compare:CCFPU (match_operand 0 "register_operand" "f")
1339                        (match_operand 1 "register_operand" "f")))]
1340   "TARGET_80387 && TARGET_CMOVE
1341    && FLOAT_MODE_P (GET_MODE (operands[0]))
1342    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1343   "* return output_fp_compare (insn, operands, 1, 1);"
1344   [(set_attr "type" "fcmp")
1345    (set_attr "athlon_decode" "vector")])
1346 \f
1347 ;; Move instructions.
1348
1349 ;; General case of fullword move.
1350
1351 (define_expand "movsi"
1352   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1353         (match_operand:SI 1 "general_operand" ""))]
1354   ""
1355   "ix86_expand_move (SImode, operands); DONE;")
1356
1357 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1358 ;; general_operand.
1359 ;;
1360 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1361 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1362 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1363 ;; targets without our curiosities, and it is just as easy to represent
1364 ;; this differently.
1365
1366 (define_insn "pushsi2"
1367   [(set (match_operand:SI 0 "push_operand" "=<")
1368         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1369   ""
1370   "push{l}\\t%1"
1371   [(set_attr "type" "push")])
1372
1373 (define_insn "*pushsi2_prologue"
1374   [(set (match_operand:SI 0 "push_operand" "=<")
1375         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1376    (set (reg:SI 6) (reg:SI 6))]
1377   ""
1378   "push{l}\\t%1"
1379   [(set_attr "type" "push")])
1380
1381 (define_insn "*popsi1_epilogue"
1382   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1383         (mem:SI (reg:SI 7)))
1384    (set (reg:SI 7)
1385         (plus:SI (reg:SI 7) (const_int 4)))
1386    (set (reg:SI 6) (reg:SI 6))]
1387   ""
1388   "pop{l}\\t%0"
1389   [(set_attr "type" "pop")])
1390
1391 (define_insn "popsi1"
1392   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1393         (mem:SI (reg:SI 7)))
1394    (set (reg:SI 7)
1395         (plus:SI (reg:SI 7) (const_int 4)))]
1396   ""
1397   "pop{l}\\t%0"
1398   [(set_attr "type" "pop")])
1399
1400 (define_insn "*movsi_xor"
1401   [(set (match_operand:SI 0 "register_operand" "=r")
1402         (match_operand:SI 1 "const0_operand" "i"))
1403    (clobber (reg:CC 17))]
1404   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1405   "xor{l}\\t{%0, %0|%0, %0}"
1406   [(set_attr "type" "alu1")
1407    (set_attr "length" "2")])
1408
1409 (define_insn "*movsi_or"
1410   [(set (match_operand:SI 0 "register_operand" "=r")
1411         (match_operand:SI 1 "immediate_operand" "i"))
1412    (clobber (reg:CC 17))]
1413   "reload_completed && GET_CODE (operands[1]) == CONST_INT
1414    && INTVAL (operands[1]) == -1
1415    && (TARGET_PENTIUM || optimize_size)"
1416   "*
1417 {
1418   operands[1] = constm1_rtx;
1419   return \"or{l}\\t{%1, %0|%1, %0}\";
1420 }"
1421   [(set_attr "type" "alu1")
1422    (set_attr "length" "3")])
1423
1424 (define_insn "*movsi_1"
1425   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
1426         (match_operand:SI 1 "general_operand" "rinm,rin"))]
1427   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1428   "*
1429 {
1430   switch (get_attr_type (insn))
1431     {
1432     case TYPE_LEA:
1433       return \"lea{l}\\t{%1, %0|%0, %1}\";
1434     default:
1435       if (flag_pic && SYMBOLIC_CONST (operands[1]))
1436         abort();
1437       return \"mov{l}\\t{%1, %0|%0, %1}\";
1438     }
1439 }"
1440   [(set (attr "type")
1441      (cond [(and (ne (symbol_ref "flag_pic") (const_int 0))
1442                  (match_operand:SI 1 "symbolic_operand" ""))
1443               (const_string "lea")
1444            ]
1445            (const_string "imov")))])
1446
1447 (define_insn "*swapsi"
1448   [(set (match_operand:SI 0 "register_operand" "+r")
1449         (match_operand:SI 1 "register_operand" "+r"))
1450    (set (match_dup 1)
1451         (match_dup 0))]
1452   ""
1453   "xchg{l}\\t%1, %0"
1454   [(set_attr "type" "imov")
1455    (set_attr "pent_pair" "np")
1456    (set_attr "athlon_decode" "vector")
1457    (set_attr "ppro_uops" "few")])
1458
1459 (define_expand "movhi"
1460   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1461         (match_operand:HI 1 "general_operand" ""))]
1462   ""
1463   "ix86_expand_move (HImode, operands); DONE;")
1464
1465 (define_insn "pushhi2"
1466   [(set (match_operand:HI 0 "push_operand" "=<,<")
1467         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1468   ""
1469   "@
1470    push{w}\\t{|WORD PTR }%1
1471    push{w}\\t%1"
1472   [(set_attr "type" "push")])
1473
1474 (define_insn "pophi1"
1475   [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m")
1476         (mem:HI (reg:SI 7)))
1477    (set (reg:SI 7)
1478         (plus:SI (reg:SI 7) (const_int 2)))]
1479   ""
1480   "pop{w}\\t%0"
1481   [(set_attr "type" "pop")])
1482
1483 (define_insn "*movhi_1"
1484   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1485         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1486   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1487   "*
1488 {
1489   switch (get_attr_type (insn))
1490     {
1491     case TYPE_IMOVX:
1492       /* movzwl is faster than movw on p2 due to partial word stalls,
1493          though not as fast as an aligned movl.  */
1494       return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
1495     default:
1496       if (get_attr_length_prefix (insn) == 0)
1497         return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1498       else
1499         return \"mov{w}\\t{%1, %0|%0, %1}\";
1500     }
1501 }"
1502   [(set (attr "type")
1503      (cond [(and (eq_attr "alternative" "0")
1504                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1505                           (const_int 0))
1506                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1507                           (const_int 0))))
1508               (const_string "imov")
1509             (and (eq_attr "alternative" "1,2")
1510                  (match_operand:HI 1 "aligned_operand" ""))
1511               (const_string "imov")
1512             (and (ne (symbol_ref "TARGET_MOVX")
1513                      (const_int 0))
1514                  (eq_attr "alternative" "0,2"))
1515               (const_string "imovx")
1516            ]
1517            (const_string "imov")))
1518     (set (attr "length_prefix")
1519       (cond [(eq_attr "type" "imovx")
1520                (const_string "0")
1521              (and (eq_attr "alternative" "1,2")
1522                   (match_operand:HI 1 "aligned_operand" ""))
1523                (const_string "0")
1524              (and (eq_attr "alternative" "0")
1525                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526                            (const_int 0))
1527                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1528                            (const_int 0))))
1529                (const_string "0")
1530             ]
1531             (const_string "1")))
1532     ; There's no place to override just the immediate length
1533     (set (attr "length")
1534       (cond [(and (eq_attr "type" "imov")
1535                   (and (eq_attr "length_prefix" "0")
1536                        (match_operand:HI 1 "immediate_operand" "")))
1537                (const_string "5")
1538             ]
1539             (const_string "*")))])
1540
1541 (define_insn "*swaphi_1"
1542   [(set (match_operand:HI 0 "register_operand" "+r")
1543         (match_operand:HI 1 "register_operand" "+r"))
1544    (set (match_dup 1)
1545         (match_dup 0))]
1546   "TARGET_PARTIAL_REG_STALL"
1547   "xchg{w}\\t%1, %0"
1548   [(set_attr "type" "imov")
1549    (set_attr "pent_pair" "np")
1550    (set_attr "ppro_uops" "few")])
1551
1552 (define_insn "*swaphi_2"
1553   [(set (match_operand:HI 0 "register_operand" "+r")
1554         (match_operand:HI 1 "register_operand" "+r"))
1555    (set (match_dup 1)
1556         (match_dup 0))]
1557   "! TARGET_PARTIAL_REG_STALL"
1558   "xchg{l}\\t%k1, %k0"
1559   [(set_attr "type" "imov")
1560    (set_attr "length_prefix" "0")
1561    (set_attr "pent_pair" "np")
1562    (set_attr "ppro_uops" "few")])
1563
1564 (define_expand "movstricthi"
1565   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1566         (match_operand:HI 1 "general_operand" ""))]
1567   "! TARGET_PARTIAL_REG_STALL"
1568   "
1569 {
1570   /* Don't generate memory->memory moves, go through a register */
1571   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1572     operands[1] = force_reg (HImode, operands[1]);
1573 }")
1574
1575 (define_insn "*movstricthi_1"
1576   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1577         (match_operand:HI 1 "general_operand" "rn,m"))]
1578   "! TARGET_PARTIAL_REG_STALL
1579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1580   "mov{w}\\t{%1, %0|%0, %1}"
1581   [(set_attr "type" "imov")])
1582
1583 (define_expand "movqi"
1584   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1585         (match_operand:QI 1 "general_operand" ""))]
1586   ""
1587   "ix86_expand_move (QImode, operands); DONE;")
1588
1589 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1590 ;; "push a byte".  But actually we use pushw, which has the effect
1591 ;; of rounding the amount pushed up to a halfword.
1592
1593 (define_insn "pushqi2"
1594   [(set (match_operand:QI 0 "push_operand" "=<,<")
1595         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1596   ""
1597   "@
1598    push{w}\\t{|word ptr }%1
1599    push{w}\\t%w1"
1600   [(set_attr "type" "push")
1601    (set_attr "length_prefix" "1")
1602     ; There's no place to override just the immediate length
1603     (set (attr "length")
1604       (if_then_else (eq_attr "length_prefix" "0")
1605         (const_string "4")
1606         (const_string "*")))])
1607
1608 (define_insn "popqi1"
1609   [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m")
1610         (mem:QI (reg:SI 7)))
1611    (set (reg:SI 7)
1612         (plus:SI (reg:SI 7) (const_int 2)))]
1613   ""
1614   "pop{w}\\t%0"
1615   [(set_attr "type" "pop")
1616    (set_attr "length_prefix" "1")])
1617
1618 ;; Situation is quite tricky about when to choose full sized (SImode) move
1619 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1620 ;; partial register dependency machines (such as AMD Athlon), where QImode
1621 ;; moves issue extra dependency and for partial register stalls machines
1622 ;; that don't use QImode patterns (and QImode move cause stall on the next
1623 ;; instruction).
1624 ;;
1625 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1626 ;; register stall machines with, where we use QImode instructions, since
1627 ;; partial register stall can be caused there.  Then we use movzx.
1628 (define_insn "*movqi_1"
1629   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1630         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1631   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1632   "*
1633 {
1634   switch (get_attr_type (insn))
1635     {
1636     case TYPE_IMOVX:
1637       if (!QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1638         abort ();
1639       return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
1640     default:
1641       if (which_alternative == 4 || which_alternative == 3
1642           || (which_alternative == 1 && get_attr_length (insn) == 5)
1643           || (which_alternative == 0
1644               && ((TARGET_PARTIAL_REG_STALL && !TARGET_QIMODE_MATH)
1645                   || TARGET_PARTIAL_REG_DEPENDENCY)))
1646         return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1647       else
1648         return \"mov{b}\\t{%1, %0|%0, %1}\";
1649     }
1650 }"
1651   [(set (attr "type")
1652      (cond [(and (eq_attr "alternative" "3")
1653                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1654                           (const_int 0))
1655                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1656                           (const_int 0))))
1657               (const_string "imov")
1658             (eq_attr "alternative" "3,5")
1659               (const_string "imovx")
1660             (and (ne (symbol_ref "TARGET_MOVX")
1661                      (const_int 0))
1662                  (eq_attr "alternative" "2"))
1663               (const_string "imovx")
1664            ]
1665            (const_string "imov")))
1666     ; There's no place to override just the immediate length
1667     (set (attr "length")
1668       (cond [(and (eq_attr "type" "imov")
1669                   (and (match_operand:HI 1 "immediate_operand" "")
1670                        (eq_attr "alternative" "4")))
1671                (const_string "5")
1672              ;; Avoid extra dependency on partial register.
1673              (and (eq_attr "type" "imov")
1674                   (and (eq_attr "alternative" "1")
1675                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1676                            (const_int 0))))
1677                (const_string "5")
1678              ;; Avoid partial register stalls when not using QImode arithmetic
1679              (and (eq_attr "type" "imov")
1680                   (and (eq_attr "alternative" "1")
1681                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1682                                 (const_int 0))
1683                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1684                                 (const_int 0)))))
1685                (const_string "5")
1686             ]
1687             (const_string "*")))])
1688
1689 (define_expand "reload_outqi"
1690   [(parallel [(match_operand:QI 0 "" "=m")
1691               (match_operand:QI 1 "register_operand" "r")
1692               (match_operand:QI 2 "register_operand" "=&q")])]
1693   ""
1694   "
1695 {
1696   rtx op0, op1, op2;
1697   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1698
1699   if (reg_overlap_mentioned_p (op2, op0))
1700     abort ();
1701   if (! q_regs_operand (op1, QImode))
1702     {
1703       emit_insn (gen_movqi (op2, op1));
1704       op1 = op2;
1705     }
1706   emit_insn (gen_movqi (op0, op1));
1707   DONE;
1708 }")
1709
1710 (define_insn "*swapqi"
1711   [(set (match_operand:QI 0 "register_operand" "+r")
1712         (match_operand:QI 1 "register_operand" "+r"))
1713    (set (match_dup 1)
1714         (match_dup 0))]
1715   ""
1716   "xchg{b}\\t%1, %0"
1717   [(set_attr "type" "imov")
1718    (set_attr "pent_pair" "np")
1719    (set_attr "ppro_uops" "few")])
1720
1721 (define_expand "movstrictqi"
1722   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1723         (match_operand:QI 1 "general_operand" ""))]
1724   "! TARGET_PARTIAL_REG_STALL"
1725   "
1726 {
1727   /* Don't generate memory->memory moves, go through a register */
1728   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1729     operands[1] = force_reg (QImode, operands[1]);
1730 }")
1731
1732 (define_insn "*movstrictqi_1"
1733   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1734         (match_operand:QI 1 "general_operand" "*qn,m"))]
1735   "! TARGET_PARTIAL_REG_STALL
1736    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1737   "mov{b}\\t{%1, %0|%0, %1}"
1738   [(set_attr "type" "imov")])
1739
1740 (define_insn "*movsi_extv_1"
1741   [(set (match_operand:SI 0 "register_operand" "=r")
1742         (sign_extract:SI (match_operand:SI 1 "register_operand" "q")
1743                          (const_int 8)
1744                          (const_int 8)))]
1745   ""
1746   "movs{bl|x}\\t{%h1, %0|%0, %h1}"
1747   [(set_attr "type" "imovx")])
1748
1749 (define_insn "*movhi_extv_1"
1750   [(set (match_operand:HI 0 "register_operand" "=r")
1751         (sign_extract:HI (match_operand:SI 1 "register_operand" "q")
1752                          (const_int 8)
1753                          (const_int 8)))]
1754   ""
1755   "movs{bl|x}\\t{%h1, %k0|%k0, %h1}"
1756   [(set_attr "type" "imovx")])
1757
1758 (define_insn "*movqi_extv_1"
1759   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1760         (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q")
1761                          (const_int 8)
1762                          (const_int 8)))]
1763   ""
1764   "*
1765 {
1766   switch (get_attr_type (insn))
1767     {
1768     case TYPE_IMOVX:
1769       return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1770     default:
1771       return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1772     }
1773 }"
1774   [(set (attr "type")
1775      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1776                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1777                              (ne (symbol_ref "TARGET_MOVX")
1778                                  (const_int 0))))
1779         (const_string "imovx")
1780         (const_string "imov")))])
1781
1782 (define_insn "*movsi_extzv_1"
1783   [(set (match_operand:SI 0 "register_operand" "=r")
1784         (zero_extract:SI (match_operand 1 "ext_register_operand" "q")
1785                          (const_int 8)
1786                          (const_int 8)))]
1787   ""
1788   "movz{bl|x}\\t{%h1, %0|%0, %h1}"
1789   [(set_attr "type" "imovx")])
1790
1791 (define_insn "*movqi_extzv_1"
1792   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1793         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "q,q")
1794                                     (const_int 8)
1795                                     (const_int 8)) 0))]
1796   ""
1797   "*
1798 {
1799   switch (get_attr_type (insn))
1800     {
1801     case TYPE_IMOVX:
1802       return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1803     default:
1804       return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1805     }
1806 }"
1807   [(set (attr "type")
1808      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1809                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1810                              (ne (symbol_ref "TARGET_MOVX")
1811                                  (const_int 0))))
1812         (const_string "imovx")
1813         (const_string "imov")))])
1814
1815 (define_insn "*movsi_insv_1"
1816   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
1817                          (const_int 8)
1818                          (const_int 8))
1819         (match_operand:SI 1 "nonimmediate_operand" "qm"))]
1820   ""
1821   "mov{b}\\t{%b1, %h0|%h0, %b1}"
1822   [(set_attr "type" "imov")])
1823
1824 (define_insn "*movqi_insv_2"
1825   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
1826                          (const_int 8)
1827                          (const_int 8))
1828         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "q")
1829                              (const_int 8))
1830                 (const_int 255)))]
1831   ""
1832   "mov{b}\\t{%h1, %h0|%h0, %h1}"
1833   [(set_attr "type" "imov")])
1834
1835 (define_expand "movdi"
1836   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1837         (match_operand:DI 1 "general_operand" ""))]
1838   ""
1839   "ix86_expand_move (DImode, operands); DONE;")
1840
1841 (define_insn "*pushdi"
1842   [(set (match_operand:DI 0 "push_operand" "=<")
1843         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1844   ""
1845   "#")
1846
1847 (define_insn "*movdi_2"
1848   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
1849         (match_operand:DI 1 "general_operand" "riFo,riF"))]
1850   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1851   "#")
1852
1853 (define_split
1854   [(set (match_operand:DI 0 "push_operand" "")
1855         (match_operand:DI 1 "general_operand" ""))]
1856   "reload_completed"
1857   [(const_int 0)]
1858   "if (!ix86_split_long_move (operands)) abort (); DONE;")
1859
1860 ;; %%% This multiword shite has got to go.
1861 (define_split
1862   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1863         (match_operand:DI 1 "general_operand" ""))]
1864   "reload_completed"
1865   [(set (match_dup 2) (match_dup 5))
1866    (set (match_dup 3) (match_dup 6))]
1867   "if (ix86_split_long_move (operands)) DONE;")
1868   
1869 (define_expand "movsf"
1870   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1871         (match_operand:SF 1 "general_operand" ""))]
1872   ""
1873   "ix86_expand_move (SFmode, operands); DONE;")
1874
1875 (define_insn "*pushsf"
1876   [(set (match_operand:SF 0 "push_operand" "=<,<")
1877         (match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
1878   ""
1879   "*
1880 {
1881   switch (which_alternative)
1882     {
1883     case 0:
1884       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
1885       operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
1886       operands[2] = stack_pointer_rtx;
1887       operands[3] = GEN_INT (4);
1888       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1889         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
1890       else
1891         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
1892
1893     case 1:
1894       return \"push{l}\\t%1\";
1895
1896     default:
1897       abort ();
1898     }
1899 }"
1900   [(set_attr "type" "multi,push")])
1901
1902 (define_split
1903   [(set (match_operand:SF 0 "push_operand" "")
1904         (match_operand:SF 1 "memory_operand" ""))]
1905   "reload_completed
1906    && GET_CODE (operands[1]) == MEM
1907    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1908    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
1909   [(set (match_dup 0)
1910         (match_dup 1))]
1911   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
1912
1913
1914 ;; %%% Kill this when call knows how to work this out.
1915 (define_split
1916   [(set (match_operand:SF 0 "push_operand" "")
1917         (match_operand:SF 1 "register_operand" ""))]
1918   "FP_REGNO_P (REGNO (operands[1]))"
1919   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1920    (set (mem:SF (reg:SI 7)) (match_dup 1))])
1921
1922 (define_insn "*movsf_1"
1923   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
1924         (match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
1925   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1926    && (reload_in_progress || reload_completed
1927        || GET_CODE (operands[1]) != CONST_DOUBLE
1928        || memory_operand (operands[0], SFmode))" 
1929   "*
1930 {
1931   switch (which_alternative)
1932     {
1933     case 0:
1934       if (REG_P (operands[1])
1935           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1936         return \"fstp\\t%y0\";
1937       else if (STACK_TOP_P (operands[0]))
1938         return \"fld%z1\\t%y1\";
1939       else
1940         return \"fst\\t%y0\";
1941
1942     case 1:
1943       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1944         return \"fstp%z0\\t%y0\";
1945       else
1946         return \"fst%z0\\t%y0\";
1947
1948     case 2:
1949       switch (standard_80387_constant_p (operands[1]))
1950         {
1951         case 1:
1952           return \"fldz\";
1953         case 2:
1954           return \"fld1\";
1955         }
1956       abort();
1957
1958     case 3:
1959     case 4:
1960       return \"mov{l}\\t{%1, %0|%0, %1}\";
1961
1962     default:
1963       abort();
1964     }
1965 }"
1966   [(set_attr "type" "fmov,fmov,fmov,imov,imov")])
1967
1968 (define_split
1969   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1970         (match_operand:SF 1 "memory_operand" ""))]
1971   "reload_completed
1972    && GET_CODE (operands[1]) == MEM
1973    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1974    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
1975    && (!(FP_REG_P (operands[0]) || 
1976          (GET_CODE (operands[0]) == SUBREG
1977           && FP_REG_P (SUBREG_REG (operands[0]))))
1978        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
1979   [(set (match_dup 0)
1980         (match_dup 1))]
1981   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
1982
1983 (define_insn "swapsf"
1984   [(set (match_operand:SF 0 "register_operand" "+f")
1985         (match_operand:SF 1 "register_operand" "+f"))
1986    (set (match_dup 1)
1987         (match_dup 0))]
1988   ""
1989   "*
1990 {
1991   if (STACK_TOP_P (operands[0]))
1992     return \"fxch\\t%1\";
1993   else
1994     return \"fxch\\t%0\";
1995 }"
1996   [(set_attr "type" "fxch")])
1997
1998 (define_expand "movdf"
1999   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2000         (match_operand:DF 1 "general_operand" ""))]
2001   ""
2002   "ix86_expand_move (DFmode, operands); DONE;")
2003
2004 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2005 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2006 ;; On the average, pushdf using integers can be still shorter.  Allow this
2007 ;; pattern for optimize_size too.
2008
2009 (define_insn "*pushdf_nointeger"
2010   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2011         (match_operand:DF 1 "general_no_elim_operand" "f,Fo#f,*r#f"))]
2012   "!TARGET_INTEGER_DFMODE_MOVES"
2013   "*
2014 {
2015   switch (which_alternative)
2016     {
2017     case 0:
2018       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2019       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2020       operands[2] = stack_pointer_rtx;
2021       operands[3] = GEN_INT (8);
2022       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2023         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2024       else
2025         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2026
2027     case 1:
2028     case 2:
2029       return \"#\";
2030
2031     default:
2032       abort ();
2033     }
2034 }"
2035   [(set_attr "type" "multi")])
2036
2037 (define_insn "*pushdf_integer"
2038   [(set (match_operand:DF 0 "push_operand" "=<,<")
2039         (match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2040   "TARGET_INTEGER_DFMODE_MOVES"
2041   "*
2042 {
2043   switch (which_alternative)
2044     {
2045     case 0:
2046       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2047       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2048       operands[2] = stack_pointer_rtx;
2049       operands[3] = GEN_INT (8);
2050       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2051         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2052       else
2053         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2054
2055     case 1:
2056       return \"#\";
2057
2058     default:
2059       abort ();
2060     }
2061 }"
2062   [(set_attr "type" "multi")])
2063
2064 ;; %%% Kill this when call knows how to work this out.
2065 (define_split
2066   [(set (match_operand:DF 0 "push_operand" "")
2067         (match_operand:DF 1 "register_operand" ""))]
2068   "reload_completed && FP_REGNO_P (REGNO (operands[1]))"
2069   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2070    (set (mem:DF (reg:SI 7)) (match_dup 1))]
2071   "")
2072
2073 (define_split
2074   [(set (match_operand:DF 0 "push_operand" "")
2075         (match_operand:DF 1 "general_operand" ""))]
2076   "reload_completed"
2077   [(const_int 0)]
2078   "if (!ix86_split_long_move (operands)) abort (); DONE;")
2079
2080 ;; Moving is usually shorter when only FP registers are used. This separate
2081 ;; movdf pattern avoids the use of integer registers for FP operations
2082 ;; when optimizing for size.
2083
2084 (define_insn "*movdf_nointeger"
2085   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2086         (match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2087   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2088    && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2089    && (reload_in_progress || reload_completed
2090        || GET_CODE (operands[1]) != CONST_DOUBLE
2091        || memory_operand (operands[0], DFmode))" 
2092   "*
2093 {
2094   switch (which_alternative)
2095     {
2096     case 0:
2097       if (REG_P (operands[1])
2098           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2099         return \"fstp\\t%y0\";
2100       else if (STACK_TOP_P (operands[0]))
2101         return \"fld%z1\\t%y1\";
2102       else
2103         return \"fst\\t%y0\";
2104
2105     case 1:
2106       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2107         return \"fstp%z0\\t%y0\";
2108       else
2109         return \"fst%z0\\t%y0\";
2110
2111     case 2:
2112       switch (standard_80387_constant_p (operands[1]))
2113         {
2114         case 1:
2115           return \"fldz\";
2116         case 2:
2117           return \"fld1\";
2118         }
2119       abort();
2120
2121     case 3:
2122     case 4:
2123       return \"#\";
2124
2125     default:
2126       abort();
2127     }
2128 }"
2129   [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
2130
2131 (define_insn "*movdf_integer"
2132   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2133         (match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2134   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2135    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2136    && (reload_in_progress || reload_completed
2137        || GET_CODE (operands[1]) != CONST_DOUBLE
2138        || memory_operand (operands[0], DFmode))" 
2139   "*
2140 {
2141   switch (which_alternative)
2142     {
2143     case 0:
2144       if (REG_P (operands[1])
2145           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2146         return \"fstp\\t%y0\";
2147       else if (STACK_TOP_P (operands[0]))
2148         return \"fld%z1\\t%y1\";
2149       else
2150         return \"fst\\t%y0\";
2151
2152     case 1:
2153       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2154         return \"fstp%z0\\t%y0\";
2155       else
2156         return \"fst%z0\\t%y0\";
2157
2158     case 2:
2159       switch (standard_80387_constant_p (operands[1]))
2160         {
2161         case 1:
2162           return \"fldz\";
2163         case 2:
2164           return \"fld1\";
2165         }
2166       abort();
2167
2168     case 3:
2169     case 4:
2170       return \"#\";
2171
2172     default:
2173       abort();
2174     }
2175 }"
2176   [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
2177
2178 (define_split
2179   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2180         (match_operand:DF 1 "general_operand" ""))]
2181   "reload_completed
2182    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2183    && ! (FP_REG_P (operands[0]) || 
2184          (GET_CODE (operands[0]) == SUBREG
2185           && FP_REG_P (SUBREG_REG (operands[0]))))
2186    && ! (FP_REG_P (operands[1]) || 
2187          (GET_CODE (operands[1]) == SUBREG
2188           && FP_REG_P (SUBREG_REG (operands[1]))))"
2189   [(set (match_dup 2) (match_dup 5))
2190    (set (match_dup 3) (match_dup 6))]
2191   "if (ix86_split_long_move (operands)) DONE;")
2192
2193 (define_split
2194   [(set (match_operand:DF 0 "register_operand" "")
2195         (match_operand:DF 1 "memory_operand" ""))]
2196   "reload_completed
2197    && GET_CODE (operands[1]) == MEM
2198    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2199    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2200    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2201   [(set (match_dup 0)
2202         (match_dup 1))]
2203   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2204
2205 (define_insn "swapdf"
2206   [(set (match_operand:DF 0 "register_operand" "+f")
2207         (match_operand:DF 1 "register_operand" "+f"))
2208    (set (match_dup 1)
2209         (match_dup 0))]
2210   ""
2211   "*
2212 {
2213   if (STACK_TOP_P (operands[0]))
2214     return \"fxch\\t%1\";
2215   else
2216     return \"fxch\\t%0\";
2217 }"
2218   [(set_attr "type" "fxch")])
2219
2220 (define_expand "movxf"
2221   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2222         (match_operand:XF 1 "general_operand" ""))]
2223   ""
2224   "ix86_expand_move (XFmode, operands); DONE;")
2225
2226 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2227 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2228 ;; Pushing using integer instructions is longer except for constants
2229 ;; and direct memory references.
2230 ;; (assuming that any given constant is pushed only once, but this ought to be
2231 ;;  handled elsewhere).
2232
2233 (define_insn "*pushxf_nointeger"
2234   [(set (match_operand:XF 0 "push_operand" "=<,<,<")
2235         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2236   "optimize_size"
2237   "*
2238 {
2239   switch (which_alternative)
2240     {
2241     case 0:
2242       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2243       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2244       operands[2] = stack_pointer_rtx;
2245       operands[3] = GEN_INT (12);
2246       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2247         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2248       else
2249         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2250
2251     case 1:
2252     case 2:
2253       return \"#\";
2254
2255     default:
2256       abort ();
2257     }
2258 }"
2259   [(set_attr "type" "multi")])
2260
2261 (define_insn "*pushxf_integer"
2262   [(set (match_operand:XF 0 "push_operand" "=<,<")
2263         (match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2264   "!optimize_size"
2265   "*
2266 {
2267   switch (which_alternative)
2268     {
2269     case 0:
2270       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2271       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2272       operands[2] = stack_pointer_rtx;
2273       operands[3] = GEN_INT (12);
2274       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2275         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2276       else
2277         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2278
2279     case 1:
2280       return \"#\";
2281
2282     default:
2283       abort ();
2284     }
2285 }"
2286   [(set_attr "type" "multi")])
2287
2288 (define_split
2289   [(set (match_operand:XF 0 "push_operand" "")
2290         (match_operand:XF 1 "general_operand" ""))]
2291   "reload_completed
2292    && (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
2293   [(const_int 0)]
2294   "if (!ix86_split_long_move (operands)) abort (); DONE;")
2295
2296 (define_split
2297   [(set (match_operand:XF 0 "push_operand" "")
2298         (match_operand:XF 1 "register_operand" ""))]
2299   "FP_REGNO_P (REGNO (operands[1]))"
2300   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2301    (set (mem:XF (reg:SI 7)) (match_dup 1))])
2302
2303 ;; Do not use integer registers when optimizing for size
2304 (define_insn "*movxf_nointeger"
2305   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2306         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2307   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2308    && optimize_size
2309    && (reload_in_progress || reload_completed
2310        || GET_CODE (operands[1]) != CONST_DOUBLE
2311        || memory_operand (operands[0], XFmode))" 
2312   "*
2313 {
2314   switch (which_alternative)
2315     {
2316     case 0:
2317       if (REG_P (operands[1])
2318           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319         return \"fstp\\t%y0\";
2320       else if (STACK_TOP_P (operands[0]))
2321         return \"fld%z1\\t%y1\";
2322       else
2323         return \"fst\\t%y0\";
2324
2325     case 1:
2326       /* There is no non-popping store to memory for XFmode.  So if
2327          we need one, follow the store with a load.  */
2328       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2329         return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2330       else
2331         return \"fstp%z0\\t%y0\";
2332
2333     case 2:
2334       switch (standard_80387_constant_p (operands[1]))
2335         {
2336         case 1:
2337           return \"fldz\";
2338         case 2:
2339           return \"fld1\";
2340         }
2341       break;
2342
2343     case 3: case 4:
2344       return \"#\";
2345     }
2346   abort();
2347 }"
2348   [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
2349
2350 (define_insn "*movxf_integer"
2351   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2352         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2353   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2354    && !optimize_size
2355    && (reload_in_progress || reload_completed
2356        || GET_CODE (operands[1]) != CONST_DOUBLE
2357        || memory_operand (operands[0], XFmode))" 
2358   "*
2359 {
2360   switch (which_alternative)
2361     {
2362     case 0:
2363       if (REG_P (operands[1])
2364           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2365         return \"fstp\\t%y0\";
2366       else if (STACK_TOP_P (operands[0]))
2367         return \"fld%z1\\t%y1\";
2368       else
2369         return \"fst\\t%y0\";
2370
2371     case 1:
2372       /* There is no non-popping store to memory for XFmode.  So if
2373          we need one, follow the store with a load.  */
2374       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2375         return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2376       else
2377         return \"fstp%z0\\t%y0\";
2378
2379     case 2:
2380       switch (standard_80387_constant_p (operands[1]))
2381         {
2382         case 1:
2383           return \"fldz\";
2384         case 2:
2385           return \"fld1\";
2386         }
2387       break;
2388
2389     case 3: case 4:
2390       return \"#\";
2391     }
2392   abort();
2393 }"
2394   [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
2395
2396 (define_split
2397   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2398         (match_operand:XF 1 "general_operand" ""))]
2399   "reload_completed
2400    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2401    && ! (FP_REG_P (operands[0]) || 
2402          (GET_CODE (operands[0]) == SUBREG
2403           && FP_REG_P (SUBREG_REG (operands[0]))))
2404    && ! (FP_REG_P (operands[1]) || 
2405          (GET_CODE (operands[1]) == SUBREG
2406           && FP_REG_P (SUBREG_REG (operands[1]))))"
2407   [(set (match_dup 2) (match_dup 5))
2408    (set (match_dup 3) (match_dup 6))
2409    (set (match_dup 4) (match_dup 7))]
2410   "if (ix86_split_long_move (operands)) DONE;")
2411
2412 (define_split
2413   [(set (match_operand:XF 0 "register_operand" "")
2414         (match_operand:XF 1 "memory_operand" ""))]
2415   "reload_completed
2416    && GET_CODE (operands[1]) == MEM
2417    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2418    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2419    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2420   [(set (match_dup 0)
2421         (match_dup 1))]
2422   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2423
2424 (define_insn "swapxf"
2425   [(set (match_operand:XF 0 "register_operand" "+f")
2426         (match_operand:XF 1 "register_operand" "+f"))
2427    (set (match_dup 1)
2428         (match_dup 0))]
2429   ""
2430   "*
2431 {
2432   if (STACK_TOP_P (operands[0]))
2433     return \"fxch\\t%1\";
2434   else
2435     return \"fxch\\t%0\";
2436 }"
2437   [(set_attr "type" "fxch")
2438    (set_attr "athlon_decode" "vector")])
2439 \f
2440 ;; Zero extension instructions
2441
2442 (define_expand "zero_extendhisi2"
2443   [(set (match_operand:SI 0 "register_operand" "")
2444      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2445   ""
2446   "
2447 {
2448   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2449     {
2450       operands[1] = force_reg (HImode, operands[1]);
2451       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2452       DONE;
2453     }
2454 }")
2455
2456 (define_insn "zero_extendhisi2_and"
2457   [(set (match_operand:SI 0 "register_operand" "=r")
2458      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2459    (clobber (reg:CC 17))]
2460   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2461   "#"
2462   [(set_attr "type" "alu1")])
2463
2464 (define_split
2465   [(set (match_operand:SI 0 "register_operand" "")
2466         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2467    (clobber (reg:CC 17))]
2468   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2469   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2470               (clobber (reg:CC 17))])]
2471   "")
2472
2473 (define_insn "*zero_extendhisi2_movzwl"
2474   [(set (match_operand:SI 0 "register_operand" "=r")
2475      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2476   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2477   "movz{wl|x}\\t{%1, %0|%0, %1}"
2478   [(set_attr "type" "imovx")])
2479
2480 (define_expand "zero_extendqihi2"
2481   [(parallel
2482     [(set (match_operand:HI 0 "register_operand" "")
2483        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2484      (clobber (reg:CC 17))])]
2485   ""
2486   "")
2487
2488 (define_insn "*zero_extendqihi2_and"
2489   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2490      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2491    (clobber (reg:CC 17))]
2492   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2493   "#"
2494   [(set_attr "type" "alu1")])
2495
2496 (define_insn "*zero_extendqihi2_movzbw_and"
2497   [(set (match_operand:HI 0 "register_operand" "=r,r")
2498      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2499    (clobber (reg:CC 17))]
2500   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2501   "#"
2502   [(set_attr "type" "imovx,alu1")])
2503
2504 (define_insn "*zero_extendqihi2_movzbw"
2505   [(set (match_operand:HI 0 "register_operand" "=r")
2506      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2507   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2508   "movz{bw|x}\\t{%1, %0|%0, %1}"
2509   [(set_attr "type" "imovx")])
2510
2511 ;; For the movzbw case strip only the clobber
2512 (define_split
2513   [(set (match_operand:HI 0 "register_operand" "")
2514         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2515    (clobber (reg:CC 17))]
2516   "reload_completed 
2517    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2518    && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2519   [(set (match_operand:HI 0 "register_operand" "")
2520         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2521
2522 ;; When source and destination does not overlap, clear destination
2523 ;; first and then do the movb
2524 (define_split
2525   [(set (match_operand:HI 0 "register_operand" "")
2526         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2527    (clobber (reg:CC 17))]
2528   "reload_completed
2529    && QI_REG_P (operands[0])
2530    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2531    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2532   [(set (match_dup 0) (const_int 0))
2533    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2534   "operands[2] = gen_lowpart (QImode, operands[0]);")
2535
2536 ;; Rest is handled by single and.
2537 (define_split
2538   [(set (match_operand:HI 0 "register_operand" "")
2539         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2540    (clobber (reg:CC 17))]
2541   "reload_completed
2542    && true_regnum (operands[0]) == true_regnum (operands[1])"
2543   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2544               (clobber (reg:CC 17))])]
2545   "")
2546
2547 (define_expand "zero_extendqisi2"
2548   [(parallel
2549     [(set (match_operand:SI 0 "register_operand" "")
2550        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2551      (clobber (reg:CC 17))])]
2552   ""
2553   "")
2554
2555 (define_insn "*zero_extendqisi2_and"
2556   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2557      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2558    (clobber (reg:CC 17))]
2559   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2560   "#"
2561   [(set_attr "type" "alu1")])
2562
2563 (define_insn "*zero_extendqisi2_movzbw_and"
2564   [(set (match_operand:SI 0 "register_operand" "=r,r")
2565      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2566    (clobber (reg:CC 17))]
2567   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2568   "#"
2569   [(set_attr "type" "imovx,alu1")])
2570
2571 (define_insn "*zero_extendqisi2_movzbw"
2572   [(set (match_operand:SI 0 "register_operand" "=r")
2573      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2574   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2575   "movz{bl|x}\\t{%1, %0|%0, %1}"
2576   [(set_attr "type" "imovx")])
2577
2578 ;; For the movzbl case strip only the clobber
2579 (define_split
2580   [(set (match_operand:SI 0 "register_operand" "")
2581         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2582    (clobber (reg:CC 17))]
2583   "reload_completed 
2584    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2585    && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2586   [(set (match_dup 0)
2587         (zero_extend:SI (match_dup 1)))])
2588
2589 ;; When source and destination does not overlap, clear destination
2590 ;; first and then do the movb
2591 (define_split
2592   [(set (match_operand:SI 0 "register_operand" "")
2593         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2594    (clobber (reg:CC 17))]
2595   "reload_completed
2596    && QI_REG_P (operands[0])
2597    && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
2598    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2599    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2600   [(set (match_dup 0) (const_int 0))
2601    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2602   "operands[2] = gen_lowpart (QImode, operands[0]);")
2603
2604 ;; Rest is handled by single and.
2605 (define_split
2606   [(set (match_operand:SI 0 "register_operand" "")
2607         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
2608    (clobber (reg:CC 17))]
2609   "reload_completed
2610    && true_regnum (operands[0]) == true_regnum (operands[1])"
2611   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
2612               (clobber (reg:CC 17))])]
2613   "")
2614
2615 ;; %%% Kill me once multi-word ops are sane.
2616 (define_insn "zero_extendsidi2"
2617   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
2618         (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))
2619    (clobber (reg:CC 17))]
2620   ""
2621   "#")
2622
2623 (define_split 
2624   [(set (match_operand:DI 0 "register_operand" "")
2625         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2626    (clobber (reg:CC 17))]
2627   "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
2628   [(set (match_dup 4) (const_int 0))]
2629   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2630
2631 (define_split 
2632   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2633         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
2634    (clobber (reg:CC 17))]
2635   "reload_completed"
2636   [(set (match_dup 3) (match_dup 1))
2637    (set (match_dup 4) (const_int 0))]
2638   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2639 \f
2640 ;; Sign extension instructions
2641
2642 (define_insn "extendsidi2"
2643   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
2644         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
2645    (clobber (reg:CC 17))
2646    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
2647   ""
2648   "#")
2649
2650 ;; Extend to memory case when source register does die.
2651 (define_split 
2652   [(set (match_operand:DI 0 "memory_operand" "")
2653         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2654    (clobber (reg:CC 17))
2655    (clobber (match_operand:SI 2 "register_operand" ""))]
2656   "(reload_completed
2657     && dead_or_set_p (insn, operands[1])
2658     && !reg_mentioned_p (operands[1], operands[0]))"
2659   [(set (match_dup 3) (match_dup 1))
2660    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
2661               (clobber (reg:CC 17))])
2662    (set (match_dup 4) (match_dup 1))]
2663   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2664
2665 ;; Extend to memory case when source register does not die.
2666 (define_split 
2667   [(set (match_operand:DI 0 "memory_operand" "")
2668         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2669    (clobber (reg:CC 17))
2670    (clobber (match_operand:SI 2 "register_operand" ""))]
2671   "reload_completed"
2672   [(const_int 0)]
2673   "
2674 {
2675   split_di (&operands[0], 1, &operands[3], &operands[4]);
2676
2677   emit_move_insn (operands[3], operands[1]);
2678
2679   /* Generate a cltd if possible and doing so it profitable.  */
2680   if (true_regnum (operands[1]) == 0
2681       && true_regnum (operands[2]) == 1
2682       && (optimize_size || TARGET_USE_CLTD))
2683     {
2684       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
2685     }
2686   else
2687     {
2688       emit_move_insn (operands[2], operands[1]);
2689       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
2690     }
2691   emit_move_insn (operands[4], operands[2]);
2692   DONE;
2693 }")
2694
2695 ;; Extend to register case.  Optimize case where source and destination
2696 ;; registers match and cases where we can use cltd.
2697 (define_split 
2698   [(set (match_operand:DI 0 "register_operand" "")
2699         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2700    (clobber (reg:CC 17))
2701    (clobber (match_scratch:SI 2 ""))]
2702   "reload_completed"
2703   [(const_int 0)]
2704   "
2705 {
2706   split_di (&operands[0], 1, &operands[3], &operands[4]);
2707
2708   if (true_regnum (operands[3]) != true_regnum (operands[1]))
2709     emit_move_insn (operands[3], operands[1]);
2710
2711   /* Generate a cltd if possible and doing so it profitable.  */
2712   if (true_regnum (operands[3]) == 0
2713       && (optimize_size || TARGET_USE_CLTD))
2714     {
2715       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
2716       DONE;
2717     }
2718
2719   if (true_regnum (operands[4]) != true_regnum (operands[1]))
2720     emit_move_insn (operands[4], operands[1]);
2721
2722   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
2723   DONE;
2724 }")
2725
2726 (define_insn "extendhisi2"
2727   [(set (match_operand:SI 0 "register_operand" "=*a,r")
2728         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
2729   ""
2730   "*
2731 {
2732   switch (get_attr_length (insn))
2733     {
2734     case 1:
2735       return \"{cwtl|cwde}\";
2736     default:
2737       return \"movs{wl|x}\\t{%1,%0|%0, %1}\";
2738     }
2739 }"
2740   [(set_attr "type" "imovx")
2741     (set (attr "length")
2742       ;; movsx is short decodable while cwtl is vector decoded.
2743       (cond [(and (eq_attr "cpu" "!k6")
2744                   (eq_attr "alternative" "0"))
2745                (const_string "1")
2746             ]
2747             (const_string "*")))])
2748
2749 (define_insn "extendqihi2"
2750   [(set (match_operand:HI 0 "register_operand" "=*a,r")
2751         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
2752   ""
2753   "*
2754 {
2755   switch (get_attr_length (insn))
2756     {
2757     case 1:
2758       return \"{cbtw|cbw}\";
2759     default:
2760       return \"movs{bw|x}\\t{%1,%0|%0, %1}\";
2761     }
2762 }"
2763   [(set_attr "type" "imovx")
2764     (set (attr "length")
2765       ;; movsx is short decodable while cwtl is vector decoded.
2766       (cond [(and (eq_attr "cpu" "!k6")
2767                   (eq_attr "alternative" "0"))
2768                (const_string "1")
2769             ]
2770             (const_string "*")))])
2771
2772 (define_insn "extendqisi2"
2773   [(set (match_operand:SI 0 "register_operand" "=r")
2774         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2775   ""
2776   "movs{bl|x}\\t{%1,%0|%0, %1}"
2777    [(set_attr "type" "imovx")])
2778 \f
2779 ;; Conversions between float and double.
2780
2781 ;; These are all no-ops in the model used for the 80387.  So just
2782 ;; emit moves.
2783
2784 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
2785 (define_insn "*dummy_extendsfdf2"
2786   [(set (match_operand:DF 0 "push_operand" "=<")
2787         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f")))]
2788   "0"
2789   "#")
2790
2791 (define_split
2792   [(set (match_operand:DF 0 "push_operand" "")
2793         (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
2794   "FP_REGNO_P (REGNO (operands[1]))"
2795   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2796    (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
2797
2798 (define_insn "*dummy_extendsfxf2"
2799   [(set (match_operand:XF 0 "push_operand" "=<")
2800         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
2801   "0"
2802   "#")
2803
2804 (define_split
2805   [(set (match_operand:XF 0 "push_operand" "")
2806         (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
2807   "FP_REGNO_P (REGNO (operands[1]))"
2808   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2809    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2810
2811 (define_insn "*dummy_extenddfxf2"
2812   [(set (match_operand:XF 0 "push_operand" "=<")
2813         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
2814   "0"
2815   "#")
2816
2817 (define_split
2818   [(set (match_operand:XF 0 "push_operand" "")
2819         (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
2820   "FP_REGNO_P (REGNO (operands[1]))"
2821   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2822    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2823
2824 (define_expand "extendsfdf2"
2825   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2826         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
2827   "TARGET_80387"
2828   "
2829 {
2830   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2831     operands[1] = force_reg (SFmode, operands[1]);
2832 }")
2833
2834 (define_insn "*extendsfdf2_1"
2835   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
2836         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2837   "TARGET_80387
2838    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2839   "*
2840 {
2841   switch (which_alternative)
2842     {
2843     case 0:
2844       if (REG_P (operands[1])
2845           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2846         return \"fstp\\t%y0\";
2847       else if (STACK_TOP_P (operands[0]))
2848         return \"fld%z1\\t%y1\";
2849       else
2850         return \"fst\\t%y0\";
2851
2852     case 1:
2853       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2854         return \"fstp%z0\\t%y0\";
2855
2856       else
2857         return \"fst%z0\\t%y0\";
2858
2859     default:
2860       abort ();
2861     }
2862 }"
2863   [(set_attr "type" "fmov")])
2864
2865 (define_expand "extendsfxf2"
2866   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2867         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
2868   "TARGET_80387"
2869   "
2870 {
2871   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2872     operands[1] = force_reg (SFmode, operands[1]);
2873 }")
2874
2875 (define_insn "*extendsfxf2_1"
2876   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2877         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2878   "TARGET_80387
2879    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2880   "*
2881 {
2882   switch (which_alternative)
2883     {
2884     case 0:
2885       if (REG_P (operands[1])
2886           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2887         return \"fstp\\t%y0\";
2888       else if (STACK_TOP_P (operands[0]))
2889         return \"fld%z1\\t%y1\";
2890       else
2891         return \"fst\\t%y0\";
2892
2893     case 1:
2894       /* There is no non-popping store to memory for XFmode.  So if
2895          we need one, follow the store with a load.  */
2896       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2897         return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
2898       else
2899         return \"fstp%z0\\t%y0\";
2900
2901     default:
2902       abort ();
2903     }
2904 }"
2905   [(set_attr "type" "fmov")])
2906
2907 (define_expand "extenddfxf2"
2908   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2909         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
2910   "TARGET_80387"
2911   "
2912 {
2913   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2914     operands[1] = force_reg (DFmode, operands[1]);
2915 }")
2916
2917 (define_insn "*extenddfxf2_1"
2918   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2919         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
2920   "TARGET_80387
2921    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922   "*
2923 {
2924   switch (which_alternative)
2925     {
2926     case 0:
2927       if (REG_P (operands[1])
2928           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2929         return \"fstp\\t%y0\";
2930       else if (STACK_TOP_P (operands[0]))
2931         return \"fld%z1\\t%y1\";
2932       else
2933         return \"fst\\t%y0\";
2934
2935     case 1:
2936       /* There is no non-popping store to memory for XFmode.  So if
2937          we need one, follow the store with a load.  */
2938       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2939         return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
2940       else
2941         return \"fstp%z0\\t%y0\";
2942
2943     default:
2944       abort ();
2945     }
2946 }"
2947   [(set_attr "type" "fmov")])
2948
2949 ;; %%% This seems bad bad news.
2950 ;; This cannot output into an f-reg because there is no way to be sure
2951 ;; of truncating in that case.  Otherwise this is just like a simple move
2952 ;; insn.  So we pretend we can output to a reg in order to get better
2953 ;; register preferencing, but we really use a stack slot.
2954
2955 (define_expand "truncdfsf2"
2956   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2957                    (float_truncate:SF
2958                     (match_operand:DF 1 "register_operand" "")))
2959               (clobber (match_dup 2))])]
2960   "TARGET_80387"
2961   "operands[2] = assign_386_stack_local (SFmode, 0);")
2962
2963 (define_insn "*truncdfsf2_1"
2964   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
2965         (float_truncate:SF
2966          (match_operand:DF 1 "register_operand" "f,0")))
2967    (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
2968   "TARGET_80387"
2969   "*
2970 {
2971   switch (which_alternative)
2972     {
2973     case 0:
2974       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2975         return \"fstp%z0\\t%y0\";
2976       else
2977         return \"fst%z0\\t%y0\";
2978     case 1:
2979       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
2980     }
2981   abort ();
2982 }"
2983   [(set_attr "type" "fmov,multi")])
2984
2985 (define_insn "*truncdfsf2_2"
2986   [(set (match_operand:SF 0 "memory_operand" "=m")
2987         (float_truncate:SF
2988          (match_operand:DF 1 "register_operand" "f")))]
2989   "TARGET_80387"
2990   "*
2991 {
2992   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2993     return \"fstp%z0\\t%y0\";
2994   else
2995     return \"fst%z0\\t%y0\";
2996 }"
2997   [(set_attr "type" "fmov")])
2998
2999 (define_split
3000   [(set (match_operand:SF 0 "memory_operand" "")
3001         (float_truncate:SF
3002          (match_operand:DF 1 "register_operand" "")))
3003    (clobber (match_operand:SF 2 "memory_operand" ""))]
3004   "TARGET_80387"
3005   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3006   "")
3007
3008 (define_split
3009   [(set (match_operand:SF 0 "register_operand" "")
3010         (float_truncate:SF
3011          (match_operand:DF 1 "register_operand" "")))
3012    (clobber (match_operand:SF 2 "memory_operand" ""))]
3013   "TARGET_80387 && reload_completed"
3014   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3015    (set (match_dup 0) (match_dup 2))]
3016   "")
3017
3018 (define_expand "truncxfsf2"
3019   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3020                    (float_truncate:SF
3021                     (match_operand:XF 1 "register_operand" "")))
3022               (clobber (match_dup 2))])]
3023   "TARGET_80387"
3024   "operands[2] = assign_386_stack_local (SFmode, 0);")
3025
3026 (define_insn "*truncxfsf2_1"
3027   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3028         (float_truncate:SF
3029          (match_operand:XF 1 "register_operand" "f,0")))
3030    (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3031   "TARGET_80387"
3032   "*
3033 {
3034   switch (which_alternative)
3035     {
3036     case 0:
3037       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3038         return \"fstp%z0\\t%y0\";
3039       else
3040         return \"fst%z0\\t%y0\";
3041     case 1:
3042       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3043     }
3044   abort ();
3045 }"
3046   [(set_attr "type" "fmov,multi")])
3047
3048 (define_insn "*truncxfsf2_2"
3049   [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
3050         (float_truncate:SF
3051          (match_operand:XF 1 "register_operand" "f")))]
3052   "TARGET_80387"
3053   "*
3054 {
3055   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3056     return \"fstp%z0\\t%y0\";
3057   else
3058     return \"fst%z0\\t%y0\";
3059 }"
3060   [(set_attr "type" "fmov")])
3061
3062 (define_split
3063   [(set (match_operand:SF 0 "memory_operand" "")
3064         (float_truncate:SF
3065          (match_operand:XF 1 "register_operand" "")))
3066    (clobber (match_operand:SF 2 "memory_operand" ""))]
3067   "TARGET_80387"
3068   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3069   "")
3070
3071 (define_split
3072   [(set (match_operand:SF 0 "register_operand" "")
3073         (float_truncate:SF
3074          (match_operand:XF 1 "register_operand" "")))
3075    (clobber (match_operand:SF 2 "memory_operand" ""))]
3076   "TARGET_80387 && reload_completed"
3077   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3078    (set (match_dup 0) (match_dup 2))]
3079   "")
3080
3081 (define_expand "truncxfdf2"
3082   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3083                    (float_truncate:DF
3084                     (match_operand:XF 1 "register_operand" "")))
3085               (clobber (match_dup 2))])]
3086   "TARGET_80387"
3087   "operands[2] = assign_386_stack_local (DFmode, 0);")
3088
3089 (define_insn "*truncxfdf2_1"
3090   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3091         (float_truncate:DF
3092          (match_operand:XF 1 "register_operand" "f,0")))
3093    (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3094   "TARGET_80387"
3095   "*
3096 {
3097   switch (which_alternative)
3098     {
3099     case 0:
3100       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3101         return \"fstp%z0\\t%y0\";
3102       else
3103         return \"fst%z0\\t%y0\";
3104     case 1:
3105       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3106     }
3107   abort ();
3108 }"
3109   [(set_attr "type" "fmov,multi")])
3110
3111 (define_insn "*truncxfdf2_2"
3112   [(set (match_operand:DF 0 "memory_operand" "=m")
3113         (float_truncate:DF
3114           (match_operand:XF 1 "register_operand" "f")))]
3115   "TARGET_80387"
3116   "*
3117 {
3118   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3119     return \"fstp%z0\\t%y0\";
3120   else
3121     return \"fst%z0\\t%y0\";
3122 }"
3123   [(set_attr "type" "fmov")])
3124
3125 (define_split
3126   [(set (match_operand:DF 0 "memory_operand" "")
3127         (float_truncate:DF
3128          (match_operand:XF 1 "register_operand" "")))
3129    (clobber (match_operand:DF 2 "memory_operand" ""))]
3130   "TARGET_80387"
3131   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3132   "")
3133
3134 (define_split
3135   [(set (match_operand:DF 0 "register_operand" "")
3136         (float_truncate:DF
3137          (match_operand:XF 1 "register_operand" "")))
3138    (clobber (match_operand:DF 2 "memory_operand" ""))]
3139   "TARGET_80387 && reload_completed"
3140   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3141    (set (match_dup 0) (match_dup 2))]
3142   "")
3143
3144 \f
3145 ;; %%% Break up all these bad boys.
3146
3147 ;; Signed conversion to DImode.
3148
3149 (define_expand "fix_truncxfdi2"
3150   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3151                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3152               (clobber (match_dup 2))
3153               (clobber (match_dup 3))
3154               (clobber (match_scratch:SI 4 ""))
3155               (clobber (match_scratch:XF 5 ""))])]
3156   "TARGET_80387"
3157   "operands[2] = assign_386_stack_local (SImode, 0);
3158    operands[3] = assign_386_stack_local (DImode, 1);")
3159
3160 (define_expand "fix_truncdfdi2"
3161   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3162                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3163               (clobber (match_dup 2))
3164               (clobber (match_dup 3))
3165               (clobber (match_scratch:SI 4 ""))
3166               (clobber (match_scratch:DF 5 ""))])]
3167   "TARGET_80387"
3168   "operands[2] = assign_386_stack_local (SImode, 0);
3169    operands[3] = assign_386_stack_local (DImode, 1);")
3170
3171 (define_expand "fix_truncsfdi2"
3172   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3173                    (fix:DI (match_operand:SF 1 "register_operand" "")))
3174               (clobber (match_dup 2))
3175               (clobber (match_dup 3))
3176               (clobber (match_scratch:SI 4 ""))
3177               (clobber (match_scratch:SF 5 ""))])]
3178   "TARGET_80387"
3179   "operands[2] = assign_386_stack_local (SImode, 0);
3180    operands[3] = assign_386_stack_local (DImode, 1);")
3181
3182 (define_insn "*fix_truncdi_1"
3183   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
3184         (fix:DI (match_operand 1 "register_operand" "f,f")))
3185    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3186    (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
3187    (clobber (match_scratch:SI 4 "=&r,&r"))
3188    (clobber (match_scratch 5 "=&f,&f"))]
3189   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3190   "* return output_fix_trunc (insn, operands);"
3191   [(set_attr "type" "multi")])
3192
3193 (define_split 
3194   [(set (match_operand:DI 0 "register_operand" "")
3195         (fix:DI (match_operand 1 "register_operand" "")))
3196    (clobber (match_operand:SI 2 "memory_operand" ""))
3197    (clobber (match_operand:DI 3 "memory_operand" ""))
3198    (clobber (match_scratch:SI 4 ""))
3199    (clobber (match_scratch 5 ""))]
3200   "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
3201   [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
3202               (clobber (match_dup 2))
3203               (clobber (match_dup 3))
3204               (clobber (match_dup 4))
3205               (clobber (match_dup 5))])
3206    (set (match_dup 0) (match_dup 3))]
3207   "")
3208
3209 ;; Signed conversion to SImode.
3210
3211 (define_expand "fix_truncxfsi2"
3212   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3213                    (fix:SI (match_operand:XF 1 "register_operand" "")))
3214               (clobber (match_dup 2))
3215               (clobber (match_dup 3))
3216               (clobber (match_scratch:SI 4 ""))])]
3217   "TARGET_80387"
3218   "operands[2] = assign_386_stack_local (SImode, 0);
3219    operands[3] = assign_386_stack_local (SImode, 1);")
3220
3221 (define_expand "fix_truncdfsi2"
3222   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3223                    (fix:SI (match_operand:DF 1 "register_operand" "")))
3224               (clobber (match_dup 2))
3225               (clobber (match_dup 3))
3226               (clobber (match_scratch:SI 4 ""))])]
3227   "TARGET_80387"
3228   "operands[2] = assign_386_stack_local (SImode, 0);
3229    operands[3] = assign_386_stack_local (SImode, 1);")
3230
3231 (define_expand "fix_truncsfsi2"
3232   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3233                    (fix:SI (match_operand:SF 1 "register_operand" "")))
3234               (clobber (match_dup 2))
3235               (clobber (match_dup 3))
3236               (clobber (match_scratch:SI 4 ""))])]
3237   "TARGET_80387"
3238   "operands[2] = assign_386_stack_local (SImode, 0);
3239    operands[3] = assign_386_stack_local (SImode, 1);")
3240
3241 (define_insn "*fix_truncsi_1"
3242   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
3243         (fix:SI (match_operand 1 "register_operand" "f,f")))
3244    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3245    (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
3246    (clobber (match_scratch:SI 4 "=&r,r"))]
3247   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3248   "* return output_fix_trunc (insn, operands);"
3249   [(set_attr "type" "multi")])
3250
3251 (define_split 
3252   [(set (match_operand:SI 0 "register_operand" "")
3253         (fix:SI (match_operand 1 "register_operand" "")))
3254    (clobber (match_operand:SI 2 "memory_operand" ""))
3255    (clobber (match_operand:SI 3 "memory_operand" ""))
3256    (clobber (match_scratch:SI 4 ""))]
3257   "reload_completed"
3258   [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
3259               (clobber (match_dup 2))
3260               (clobber (match_dup 3))
3261               (clobber (match_dup 4))])
3262    (set (match_dup 0) (match_dup 3))]
3263   "")
3264
3265 ;; Signed conversion to HImode.
3266
3267 (define_expand "fix_truncxfhi2"
3268   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3269                    (fix:HI (match_operand:XF 1 "register_operand" "")))
3270               (clobber (match_dup 2))
3271               (clobber (match_dup 3))
3272               (clobber (match_scratch:SI 4 ""))])]
3273   "TARGET_80387"
3274   "operands[2] = assign_386_stack_local (SImode, 0);
3275    operands[3] = assign_386_stack_local (HImode, 1);")
3276
3277 (define_expand "fix_truncdfhi2"
3278   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3279                    (fix:HI (match_operand:DF 1 "register_operand" "")))
3280               (clobber (match_dup 2))
3281               (clobber (match_dup 3))
3282               (clobber (match_scratch:SI 4 ""))])]
3283   "TARGET_80387"
3284   "operands[2] = assign_386_stack_local (SImode, 0);
3285    operands[3] = assign_386_stack_local (HImode, 1);")
3286
3287 (define_expand "fix_truncsfhi2"
3288   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3289                    (fix:HI (match_operand:SF 1 "register_operand" "")))
3290               (clobber (match_dup 2))
3291               (clobber (match_dup 3))
3292               (clobber (match_scratch:SI 4 ""))])]
3293   "TARGET_80387"
3294   "operands[2] = assign_386_stack_local (SImode, 0);
3295    operands[3] = assign_386_stack_local (HImode, 1);")
3296
3297 (define_insn "*fix_trunchi_1"
3298   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
3299         (fix:HI (match_operand 1 "register_operand" "f,f")))
3300    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3301    (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
3302    (clobber (match_scratch:SI 4 "=&r,r"))]
3303   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3304   "* return output_fix_trunc (insn, operands);"
3305   [(set_attr "type" "multi")])
3306
3307 (define_split 
3308   [(set (match_operand:HI 0 "register_operand" "")
3309         (fix:HI (match_operand 1 "register_operand" "")))
3310    (clobber (match_operand:SI 2 "memory_operand" ""))
3311    (clobber (match_operand:HI 3 "memory_operand" ""))
3312    (clobber (match_scratch:SI 4 ""))]
3313   "reload_completed"
3314   [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
3315               (clobber (match_dup 2))
3316               (clobber (match_dup 3))
3317               (clobber (match_dup 4))])
3318    (set (match_dup 0) (match_dup 3))]
3319   "")
3320
3321 ;; %% Not used yet.
3322 (define_insn "x86_fnstcw_1"
3323   [(set (match_operand:HI 0 "memory_operand" "=m")
3324         (unspec:HI [(reg:HI 18)] 11))]
3325   "TARGET_80387"
3326   "fnstcw\\t%0"
3327   [(set_attr "length_opcode" "2")
3328    (set_attr "ppro_uops" "few")])
3329
3330 (define_insn "x86_fldcw_1"
3331   [(set (reg:HI 18)
3332         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
3333   "TARGET_80387"
3334   "fldcw\\t%0"
3335   [(set_attr "length_opcode" "2")
3336    (set_attr "athlon_decode" "vector")
3337    (set_attr "ppro_uops" "few")])
3338 \f
3339 ;; Conversion between fixed point and floating point.
3340
3341 ;; Even though we only accept memory inputs, the backend _really_
3342 ;; wants to be able to do this between registers.
3343
3344 (define_insn "floathisf2"
3345   [(set (match_operand:SF 0 "register_operand" "=f,f")
3346         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3347   "TARGET_80387"
3348   "@
3349    fild%z1\\t%1
3350    #"
3351   [(set_attr "type" "fmov,multi")
3352    (set_attr "fp_int_src" "true")])
3353
3354 (define_insn "floatsisf2"
3355   [(set (match_operand:SF 0 "register_operand" "=f,f")
3356         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3357   "TARGET_80387"
3358   "@
3359    fild%z1\\t%1
3360    #"
3361   [(set_attr "type" "fmov,multi")
3362    (set_attr "fp_int_src" "true")])
3363
3364 (define_insn "floatdisf2"
3365   [(set (match_operand:SF 0 "register_operand" "=f,f")
3366         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3367   "TARGET_80387"
3368   "@
3369    fild%z1\\t%1
3370    #"
3371   [(set_attr "type" "fmov,multi")
3372    (set_attr "fp_int_src" "true")])
3373
3374 (define_insn "floathidf2"
3375   [(set (match_operand:DF 0 "register_operand" "=f,f")
3376         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3377   "TARGET_80387"
3378   "@
3379    fild%z1\\t%1
3380    #"
3381   [(set_attr "type" "fmov,multi")
3382    (set_attr "fp_int_src" "true")])
3383
3384 (define_insn "floatsidf2"
3385   [(set (match_operand:DF 0 "register_operand" "=f,f")
3386         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3387   "TARGET_80387"
3388   "@
3389    fild%z1\\t%1
3390    #"
3391   [(set_attr "type" "fmov,multi")
3392    (set_attr "fp_int_src" "true")])
3393
3394 (define_insn "floatdidf2"
3395   [(set (match_operand:DF 0 "register_operand" "=f,f")
3396         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3397   "TARGET_80387"
3398   "@
3399    fild%z1\\t%1
3400    #"
3401   [(set_attr "type" "fmov,multi")
3402    (set_attr "fp_int_src" "true")])
3403
3404 (define_insn "floathixf2"
3405   [(set (match_operand:XF 0 "register_operand" "=f,f")
3406         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3407   "TARGET_80387"
3408   "@
3409    fild%z1\\t%1
3410    #"
3411   [(set_attr "type" "fmov,multi")
3412    (set_attr "fp_int_src" "true")])
3413
3414 (define_insn "floatsixf2"
3415   [(set (match_operand:XF 0 "register_operand" "=f,f")
3416         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3417   "TARGET_80387"
3418   "@
3419    fild%z1\\t%1
3420    #"
3421   [(set_attr "type" "fmov,multi")
3422    (set_attr "fp_int_src" "true")])
3423
3424 (define_insn "floatdixf2"
3425   [(set (match_operand:XF 0 "register_operand" "=f,f")
3426         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3427   "TARGET_80387"
3428   "@
3429    fild%z1\\t%1
3430    #"
3431   [(set_attr "type" "fmov,multi")
3432    (set_attr "fp_int_src" "true")])
3433
3434 ;; %%% Kill these when reload knows how to do it.
3435 (define_split
3436   [(set (match_operand 0 "register_operand" "")
3437         (float (match_operand:HI 1 "register_operand" "")))]
3438   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3439   [(set (mem:HI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3440    (set (match_dup 0) (match_dup 2))
3441    (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 2)))]
3442   "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3443                                 gen_rtx_MEM (HImode, stack_pointer_rtx));")
3444
3445 (define_split
3446   [(set (match_operand 0 "register_operand" "")
3447         (float (match_operand:SI 1 "register_operand" "")))]
3448   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3449   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3450    (set (match_dup 0) (match_dup 2))
3451    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
3452               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
3453   "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3454                                 gen_rtx_MEM (SImode, stack_pointer_rtx));")
3455
3456 (define_split
3457   [(set (match_operand 0 "register_operand" "")
3458         (float (match_operand:DI 1 "nonmemory_operand" "")))]
3459   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3460   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
3461    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3462    (set (match_dup 0) (match_dup 3))
3463    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
3464               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
3465    (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
3466               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
3467   "split_di (operands+1, 1, operands+1, operands+2);
3468    operands[3] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3469                                 gen_rtx_MEM (DImode, stack_pointer_rtx));")
3470 \f
3471 ;; Add instructions
3472
3473 ;; %%% define_expand from the very first?
3474 ;; %%% splits for addsidi3
3475 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3476 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
3477 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
3478
3479 (define_insn "adddi3"
3480   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3481         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
3482                  (match_operand:DI 2 "general_operand" "roiF,riF")))
3483    (clobber (reg:CC 17))]
3484   ""
3485   "#")
3486
3487 (define_split
3488   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3489         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
3490                  (match_operand:DI 2 "general_operand" "")))
3491    (clobber (reg:CC 17))]
3492   "reload_completed"
3493   [(parallel [(set (reg:CC 17) (plus:CC (match_dup 1) (match_dup 2)))
3494               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
3495    (parallel [(set (match_dup 3)
3496                    (plus:SI (match_dup 4)
3497                    (plus:SI (match_dup 5)
3498                             (ltu:SI (reg:CC 17) (const_int 0)))))
3499               (clobber (reg:CC 17))])]
3500   "split_di (operands+0, 1, operands+0, operands+3);
3501    split_di (operands+1, 1, operands+1, operands+4);
3502    split_di (operands+2, 1, operands+2, operands+5);")
3503
3504 (define_insn "*addsi3_cc"
3505   [(set (reg:CC 17) (plus:CC (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3506                     (match_operand:SI 2 "general_operand" "ri,rm")))
3507    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3508         (plus:SI (match_dup 1) (match_dup 2)))]
3509   "ix86_binary_operator_ok (PLUS, SImode, operands)"
3510   "add{l}\\t{%2, %0|%0, %2}"
3511   [(set_attr "type" "alu")])
3512
3513 (define_insn "addqi3_cc"
3514   [(set (reg:CC 17) (plus:CC (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3515                     (match_operand:QI 2 "general_operand" "qi,qm")))
3516    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3517         (plus:QI (match_dup 1) (match_dup 2)))]
3518   "ix86_binary_operator_ok (PLUS, QImode, operands)"
3519   "add{b}\\t{%2, %0|%0, %2}"
3520   [(set_attr "type" "alu")])
3521
3522 (define_insn "*addsi3_carry"
3523   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3524           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3525             (plus:SI (match_operand:SI 2 "general_operand" "ri,rm")
3526               (ltu:SI (reg:CC 17) (const_int 0)))))
3527    (clobber (reg:CC 17))]
3528   "ix86_binary_operator_ok (PLUS, SImode, operands)"
3529   "adc{l}\\t{%2, %0|%0, %2}"
3530   [(set_attr "type" "alu")
3531    (set_attr "pent_pair" "pu")
3532    (set_attr "ppro_uops" "few")])
3533
3534 (define_expand "addsi3"
3535   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3536                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3537                             (match_operand:SI 2 "general_operand" "")))
3538               (clobber (reg:CC 17))])]
3539   ""
3540   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
3541
3542 (define_insn "*lea_0"
3543   [(set (match_operand:SI 0 "register_operand" "=r")
3544         (match_operand:SI 1 "address_operand" "p"))]
3545   ""
3546   "lea{l}\\t{%a1, %0|%0, %a1}"
3547   [(set_attr "type" "lea")])
3548
3549 (define_insn "*addsi_1"
3550   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3551         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3552                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
3553    (clobber (reg:CC 17))]
3554   "ix86_binary_operator_ok (PLUS, SImode, operands)"
3555   "*
3556 {
3557   switch (get_attr_type (insn))
3558     {
3559     case TYPE_LEA:
3560       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
3561       return \"lea{l}\\t{%a2, %0|%0, %a2}\";
3562
3563     case TYPE_INCDEC:
3564       if (! rtx_equal_p (operands[0], operands[1]))
3565         abort ();
3566       if (operands[2] == const1_rtx)
3567         return \"inc{l}\\t%0\";
3568       else if (operands[2] == constm1_rtx)
3569         return \"dec{l}\\t%0\";
3570       else
3571         abort();
3572
3573     default:
3574       if (! rtx_equal_p (operands[0], operands[1]))
3575         abort ();
3576
3577       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3578          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3579       if (GET_CODE (operands[2]) == CONST_INT
3580           && (INTVAL (operands[2]) == 128
3581               || (INTVAL (operands[2]) < 0
3582                   && INTVAL (operands[2]) != -128)))
3583         {
3584           operands[2] = GEN_INT (-INTVAL (operands[2]));
3585           return \"sub{l}\\t{%2, %0|%0, %2}\";
3586         }
3587       return \"add{l}\\t{%2, %0|%0, %2}\";
3588     }
3589 }"
3590   [(set (attr "type")
3591      (cond [(eq_attr "alternative" "2")
3592               (const_string "lea")
3593             ; Current assemblers are broken and do not allow @GOTOFF in
3594             ; ought but a memory context.
3595             (match_operand:SI 2 "pic_symbolic_operand" "")
3596               (const_string "lea")
3597             (match_operand:SI 2 "incdec_operand" "")
3598               (const_string "incdec")
3599            ]
3600            (const_string "alu")))])
3601
3602 ;; Convert lea to the lea pattern to avoid flags dependency.
3603 (define_split
3604   [(set (match_operand:SI 0 "register_operand" "")
3605         (plus:SI (match_operand:SI 1 "register_operand" "")
3606                  (match_operand:SI 2 "nonmemory_operand" "")))
3607    (clobber (reg:CC 17))]
3608   "reload_completed
3609    && true_regnum (operands[0]) != true_regnum (operands[1])"
3610   [(set (match_dup 0)
3611         (plus:SI (match_dup 1)
3612                  (match_dup 2)))]
3613   "")
3614
3615 (define_insn "*addsi_2"
3616   [(set (reg 17)
3617         (compare
3618           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3619                    (match_operand:SI 2 "general_operand" "rmni,rni"))
3620           (const_int 0)))                       
3621    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
3622         (plus:SI (match_dup 1) (match_dup 2)))]
3623   "ix86_match_ccmode (insn, CCNOmode)
3624    && ix86_binary_operator_ok (PLUS, SImode, operands)
3625    /* Current assemblers are broken and do not allow @GOTOFF in
3626       ought but a memory context. */
3627    && ! pic_symbolic_operand (operands[2], VOIDmode)"
3628   "*
3629 {
3630   switch (get_attr_type (insn))
3631     {
3632     case TYPE_INCDEC:
3633       if (! rtx_equal_p (operands[0], operands[1]))
3634         abort ();
3635       if (operands[2] == const1_rtx)
3636         return \"inc{l}\\t%0\";
3637       else if (operands[2] == constm1_rtx)
3638         return \"dec{l}\\t%0\";
3639       else
3640         abort();
3641
3642     default:
3643       if (! rtx_equal_p (operands[0], operands[1]))
3644         abort ();
3645       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3646          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3647       if (GET_CODE (operands[2]) == CONST_INT
3648           && (INTVAL (operands[2]) == 128
3649               || (INTVAL (operands[2]) < 0
3650                   && INTVAL (operands[2]) != -128)))
3651         {
3652           operands[2] = GEN_INT (-INTVAL (operands[2]));
3653           return \"sub{l}\\t{%2, %0|%0, %2}\";
3654         }
3655       return \"add{l}\\t{%2, %0|%0, %2}\";
3656     }
3657 }"
3658   [(set (attr "type")
3659      (if_then_else (match_operand:SI 2 "incdec_operand" "")
3660         (const_string "incdec")
3661         (const_string "alu")))])
3662
3663 (define_insn "*addsi_3"
3664   [(set (reg:CC 17)
3665         (compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3666                              (match_operand:SI 2 "general_operand" "rmni,rni"))
3667                     (const_int 0)))                     
3668    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
3669         (plus:SI (match_dup 1) (match_dup 2)))]
3670   "ix86_binary_operator_ok (PLUS, SImode, operands)
3671    /* Current assemblers are broken and do not allow @GOTOFF in
3672       ought but a memory context. */
3673    && ! pic_symbolic_operand (operands[2], VOIDmode)"
3674   "add{l}\\t{%2, %0|%0, %2}"
3675   [(set_attr "type" "alu")])
3676
3677 (define_expand "addhi3"
3678   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3679                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3680                             (match_operand:HI 2 "general_operand" "")))
3681               (clobber (reg:CC 17))])]
3682   "TARGET_HIMODE_MATH"
3683   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
3684
3685 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
3686 ;; type optimizations enabled by define-splits.  This is not important
3687 ;; for PII, and in fact harmful because of partial register stalls.
3688
3689 (define_insn "*addhi_1"
3690   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3691         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3692                  (match_operand:HI 2 "general_operand" "ri,rm")))
3693    (clobber (reg:CC 17))]
3694   "ix86_binary_operator_ok (PLUS, HImode, operands)"
3695   "*
3696 {
3697   switch (get_attr_type (insn))
3698     {
3699     case TYPE_INCDEC:
3700       if (operands[2] == const1_rtx)
3701         return \"inc{w}\\t%0\";
3702       else if (operands[2] == constm1_rtx
3703                || (GET_CODE (operands[2]) == CONST_INT
3704                    && INTVAL (operands[2]) == 65535))
3705         return \"dec{w}\\t%0\";
3706       abort();
3707
3708     default:
3709       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3710          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3711       if (GET_CODE (operands[2]) == CONST_INT
3712           && (INTVAL (operands[2]) == 128
3713               || (INTVAL (operands[2]) < 0
3714                   && INTVAL (operands[2]) != -128)))
3715         {
3716           operands[2] = GEN_INT (-INTVAL (operands[2]));
3717           return \"sub{w}\\t{%2, %0|%0, %2}\";
3718         }
3719       return \"add{w}\\t{%2, %0|%0, %2}\";
3720     }
3721 }"
3722   [(set (attr "type")
3723      (if_then_else (match_operand:HI 2 "incdec_operand" "")
3724         (const_string "incdec")
3725         (const_string "alu")))])
3726
3727 (define_insn "*addhi_2"
3728   [(set (reg 17)
3729         (compare
3730           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3731                    (match_operand:HI 2 "general_operand" "rmni,rni"))
3732           (const_int 0)))                       
3733    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
3734         (plus:HI (match_dup 1) (match_dup 2)))]
3735   "ix86_match_ccmode (insn, CCNOmode)
3736    && ix86_binary_operator_ok (PLUS, HImode, operands)"
3737   "*
3738 {
3739   switch (get_attr_type (insn))
3740     {
3741     case TYPE_INCDEC:
3742       if (operands[2] == const1_rtx)
3743         return \"inc{w}\\t%0\";
3744       else if (operands[2] == constm1_rtx
3745                || (GET_CODE (operands[2]) == CONST_INT
3746                    && INTVAL (operands[2]) == 65535))
3747         return \"dec{w}\\t%0\";
3748       abort();
3749
3750     default:
3751       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3752          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3753       if (GET_CODE (operands[2]) == CONST_INT
3754           && (INTVAL (operands[2]) == 128
3755               || (INTVAL (operands[2]) < 0
3756                   && INTVAL (operands[2]) != -128)))
3757         {
3758           operands[2] = GEN_INT (-INTVAL (operands[2]));
3759           return \"sub{w}\\t{%2, %0|%0, %2}\";
3760         }
3761       return \"add{w}\\t{%2, %0|%0, %2}\";
3762     }
3763 }"
3764   [(set (attr "type")
3765      (if_then_else (match_operand:HI 2 "incdec_operand" "")
3766         (const_string "incdec")
3767         (const_string "alu")))])
3768
3769 (define_insn "*addhi_3"
3770   [(set (reg:CC 17)
3771         (compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3772                              (match_operand:HI 2 "general_operand" "rmni,rni"))
3773                     (const_int 0)))                     
3774    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
3775         (plus:HI (match_dup 1) (match_dup 2)))]
3776   "ix86_binary_operator_ok (PLUS, HImode, operands)"
3777   "add{w}\\t{%2, %0|%0, %2}"
3778   [(set_attr "type" "alu")])
3779
3780 (define_expand "addqi3"
3781   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
3782                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
3783                             (match_operand:QI 2 "general_operand" "")))
3784               (clobber (reg:CC 17))])]
3785   "TARGET_QIMODE_MATH"
3786   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
3787
3788 ;; %%% Potential partial reg stall on alternative 2.  What to do?
3789 (define_insn "*addqi_1"
3790   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
3791         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
3792                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
3793    (clobber (reg:CC 17))]
3794   "ix86_binary_operator_ok (PLUS, QImode, operands)"
3795   "*
3796 {
3797   int widen = (which_alternative == 2);
3798   switch (get_attr_type (insn))
3799     {
3800     case TYPE_INCDEC:
3801       if (operands[2] == const1_rtx)
3802         return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
3803       else if (operands[2] == constm1_rtx
3804                || (GET_CODE (operands[2]) == CONST_INT
3805                    && INTVAL (operands[2]) == 255))
3806         return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
3807       abort();
3808
3809     default:
3810       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3811          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
3812       if (GET_CODE (operands[2]) == CONST_INT
3813           && (INTVAL (operands[2]) == 128
3814               || (INTVAL (operands[2]) < 0
3815                   && INTVAL (operands[2]) != -128)))
3816         {
3817           operands[2] = GEN_INT (-INTVAL (operands[2]));
3818           if (widen)
3819             return \"sub{l}\\t{%2, %k0|%k0, %2}\";
3820           else
3821             return \"sub{b}\\t{%2, %0|%0, %2}\";
3822         }
3823       if (widen)
3824         return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
3825       else
3826         return \"add{b}\\t{%2, %0|%0, %2}\";
3827     }
3828 }"
3829   [(set (attr "type")
3830      (if_then_else (match_operand:QI 2 "incdec_operand" "")
3831         (const_string "incdec")
3832         (const_string "alu")))])
3833
3834 (define_insn "*addqi_2"
3835   [(set (reg 17)
3836         (compare
3837           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3838                    (match_operand:QI 2 "general_operand" "qmni,qni"))
3839           (const_int 0)))
3840    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
3841         (plus:QI (match_dup 1) (match_dup 2)))]
3842   "ix86_match_ccmode (insn, CCNOmode)
3843    && ix86_binary_operator_ok (PLUS, QImode, operands)"
3844   "*
3845 {
3846   switch (get_attr_type (insn))
3847     {
3848     case TYPE_INCDEC:
3849       if (operands[2] == const1_rtx)
3850         return \"inc{b}\\t%0\";
3851       else if (operands[2] == constm1_rtx
3852                || (GET_CODE (operands[2]) == CONST_INT
3853                    && INTVAL (operands[2]) == 255))
3854         return \"dec{b}\\t%0\";
3855       abort();
3856
3857     default:
3858       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
3859       if (GET_CODE (operands[2]) == CONST_INT
3860           && INTVAL (operands[2]) < 0)
3861         {
3862           operands[2] = GEN_INT (-INTVAL (operands[2]));
3863           return \"sub{b}\\t{%2, %0|%0, %2}\";
3864         }
3865       return \"add{b}\\t{%2, %0|%0, %2}\";
3866     }
3867 }"
3868   [(set (attr "type")
3869      (if_then_else (match_operand:QI 2 "incdec_operand" "")
3870         (const_string "incdec")
3871         (const_string "alu")))])
3872
3873 (define_insn "*addqi_3"
3874   [(set (reg:CC 17)
3875         (compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3876                              (match_operand:QI 2 "general_operand" "qmni,qni"))
3877                     (const_int 0)))                     
3878    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
3879         (plus:QI (match_dup 1) (match_dup 2)))]
3880   "ix86_binary_operator_ok (PLUS, QImode, operands)"
3881   "add{b}\\t{%2, %0|%0, %2}"
3882   [(set_attr "type" "alu")])
3883
3884 (define_insn "*addqi_low_1"
3885   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
3886         (plus:QI (match_operand:QI 1 "register_operand" "0")
3887                  (match_operand:QI 2 "general_operand" "qmn")))
3888    (clobber (reg:CC 17))]
3889   ""
3890   "*
3891 {
3892   switch (get_attr_type (insn))
3893     {
3894     case TYPE_INCDEC:
3895       if (operands[2] == const1_rtx)
3896         return \"inc{b}\\t%b0\";
3897       else if (operands[2] == constm1_rtx
3898                || (GET_CODE (operands[2]) == CONST_INT
3899                    && INTVAL (operands[2]) == 255))
3900         return \"dec{b}\\t%b0\";
3901       abort();
3902
3903     default:
3904       return \"add{b}\\t{%2, %b0|%b0, %2}\";
3905     }
3906 }"
3907   [(set (attr "type")
3908      (if_then_else (match_operand:QI 2 "incdec_operand" "")
3909         (const_string "incdec")
3910         (const_string "alu")))])
3911
3912 (define_insn "addqi_ext_1"
3913   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
3914                          (const_int 8)
3915                          (const_int 8))
3916         (plus:SI
3917           (zero_extract:SI
3918             (match_operand 1 "ext_register_operand" "0")
3919             (const_int 8)
3920             (const_int 8))
3921           (match_operand:QI 2 "general_operand" "qmn")))
3922    (clobber (reg:CC 17))]
3923   ""
3924   "*
3925 {
3926   switch (get_attr_type (insn))
3927     {
3928     case TYPE_INCDEC:
3929       if (operands[2] == const1_rtx)
3930         return \"inc{b}\\t%h0\";
3931       else if (operands[2] == constm1_rtx
3932                || (GET_CODE (operands[2]) == CONST_INT
3933                    && INTVAL (operands[2]) == 255))
3934         return \"dec{b}\\t%h0\";
3935       abort();
3936
3937     default:
3938       return \"add{b}\\t{%2, %h0|%h0, %2}\";
3939     }
3940 }"
3941   [(set (attr "type")
3942      (if_then_else (match_operand:QI 2 "incdec_operand" "")
3943         (const_string "incdec")
3944         (const_string "alu")))])
3945
3946 (define_insn "*addqi_ext_2"
3947   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
3948                          (const_int 8)
3949                          (const_int 8))
3950         (plus:SI
3951           (zero_extract:SI
3952             (match_operand 1 "ext_register_operand" "%0")
3953             (const_int 8)
3954             (const_int 8))
3955           (zero_extract:SI
3956             (match_operand 2 "ext_register_operand" "q")
3957             (const_int 8)
3958             (const_int 8))))
3959    (clobber (reg:CC 17))]
3960   ""
3961   "add{b}\\t{%h2, %h0|%h0, %h2}"
3962   [(set_attr "type" "alu")])
3963
3964 ;; The patterns that match these are at the end of this file.
3965
3966 (define_expand "addxf3"
3967   [(set (match_operand:XF 0 "register_operand" "")
3968         (plus:XF (match_operand:XF 1 "register_operand" "")
3969                  (match_operand:XF 2 "register_operand" "")))]
3970   "TARGET_80387"
3971   "")
3972
3973 (define_expand "adddf3"
3974   [(set (match_operand:DF 0 "register_operand" "")
3975         (plus:DF (match_operand:DF 1 "register_operand" "")
3976                  (match_operand:DF 2 "nonimmediate_operand" "")))]
3977   "TARGET_80387"
3978   "")
3979
3980 (define_expand "addsf3"
3981   [(set (match_operand:SF 0 "register_operand" "")
3982         (plus:SF (match_operand:SF 1 "register_operand" "")
3983                  (match_operand:SF 2 "nonimmediate_operand" "")))]
3984   "TARGET_80387"
3985   "")
3986 \f
3987 ;; Subtract instructions
3988
3989 ;; %%% define_expand from the very first?
3990 ;; %%% splits for subsidi3
3991
3992 (define_insn "subdi3"
3993   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3994         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
3995                   (match_operand:DI 2 "general_operand" "roiF,riF")))
3996    (clobber (reg:CC 17))]
3997   ""
3998   "#")
3999
4000 (define_split
4001   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4002         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4003                   (match_operand:DI 2 "general_operand" "")))
4004    (clobber (reg:CC 17))]
4005   "reload_completed"
4006   [(parallel [(set (reg:CC 17) (minus:CC (match_dup 1) (match_dup 2)))
4007               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
4008    (parallel [(set (match_dup 3)
4009                    (minus:SI (match_dup 4)
4010                              (plus:SI (match_dup 5)
4011                              (ltu:SI (reg:CC 17) (const_int 0)))))
4012               (clobber (reg:CC 17))])]
4013   "split_di (operands+0, 1, operands+0, operands+3);
4014    split_di (operands+1, 1, operands+1, operands+4);
4015    split_di (operands+2, 1, operands+2, operands+5);")
4016
4017 (define_insn "*subsi3_cc"
4018   [(set (reg:CC 17) (minus:CC (match_operand:SI 1 "nonimmediate_operand" "0,0")
4019                               (match_operand:SI 2 "general_operand" "ri,rm")))
4020    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4021         (minus:SI (match_dup 1) (match_dup 2)))]
4022   "ix86_binary_operator_ok (MINUS, SImode, operands)"
4023   "sub{l}\\t{%2, %0|%0, %2}"
4024   [(set_attr "type" "alu")])
4025
4026 (define_insn "subsi3_carry"
4027   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4028           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4029             (plus:SI (match_operand:SI 2 "general_operand" "ri,rm")
4030               (ltu:SI (reg:CC 17) (const_int 0)))))
4031    (clobber (reg:CC 17))]
4032   "ix86_binary_operator_ok (MINUS, SImode, operands)"
4033   "sbb{l}\\t{%2, %0|%0, %2}"
4034   [(set_attr "type" "alu")
4035    (set_attr "pent_pair" "pu")
4036    (set_attr "ppro_uops" "few")])
4037
4038 (define_expand "subsi3"
4039   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4040                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4041                              (match_operand:SI 2 "general_operand" "")))
4042               (clobber (reg:CC 17))])]
4043   ""
4044   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
4045
4046 (define_insn "*subsi_1"
4047   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4048         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4049                   (match_operand:SI 2 "general_operand" "ri,rm")))
4050    (clobber (reg:CC 17))]
4051   "ix86_binary_operator_ok (MINUS, SImode, operands)"
4052   "sub{l}\\t{%2, %0|%0, %2}"
4053   [(set_attr "type" "alu")])
4054
4055 (define_insn "*subsi_2"
4056   [(set (reg 17)
4057         (compare
4058           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4059                     (match_operand:SI 2 "general_operand" "ri,rm"))
4060           (const_int 0)))
4061    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4062         (minus:SI (match_dup 1) (match_dup 2)))]
4063   "ix86_match_ccmode (insn, CCmode)
4064    && ix86_binary_operator_ok (MINUS, SImode, operands)"
4065   "sub{l}\\t{%2, %0|%0, %2}"
4066   [(set_attr "type" "alu")])
4067
4068 (define_expand "subhi3"
4069   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4070                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
4071                              (match_operand:HI 2 "general_operand" "")))
4072               (clobber (reg:CC 17))])]
4073   "TARGET_HIMODE_MATH"
4074   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
4075
4076 (define_insn "*subhi_1"
4077   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4078         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
4079                   (match_operand:HI 2 "general_operand" "ri,rm")))
4080    (clobber (reg:CC 17))]
4081   "ix86_binary_operator_ok (MINUS, HImode, operands)"
4082   "sub{w}\\t{%2, %0|%0, %2}"
4083   [(set_attr "type" "alu")])
4084
4085 (define_insn "*subhi_2"
4086   [(set (reg 17)
4087         (compare
4088           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
4089                     (match_operand:HI 2 "general_operand" "ri,rm"))
4090           (const_int 0)))
4091    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4092         (minus:HI (match_dup 1) (match_dup 2)))]
4093   "ix86_match_ccmode (insn, CCmode)
4094    && ix86_binary_operator_ok (MINUS, HImode, operands)"
4095   "sub{w}\\t{%2, %0|%0, %2}"
4096   [(set_attr "type" "alu")])
4097
4098 (define_expand "subqi3"
4099   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
4100                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
4101                              (match_operand:QI 2 "general_operand" "")))
4102               (clobber (reg:CC 17))])]
4103   "TARGET_QIMODE_MATH"
4104   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
4105
4106 (define_insn "*subqi_1"
4107   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4108         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
4109                   (match_operand:QI 2 "general_operand" "qn,qmn")))
4110    (clobber (reg:CC 17))]
4111   "ix86_binary_operator_ok (MINUS, QImode, operands)"
4112   "sub{b}\\t{%2, %0|%0, %2}"
4113   [(set_attr "type" "alu")])
4114
4115 (define_insn "*subqi_2"
4116   [(set (reg 17)
4117         (compare
4118           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
4119                     (match_operand:QI 2 "general_operand" "qi,qm"))
4120           (const_int 0)))
4121    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
4122         (minus:HI (match_dup 1) (match_dup 2)))]
4123   "ix86_match_ccmode (insn, CCmode)
4124    && ix86_binary_operator_ok (MINUS, QImode, operands)"
4125   "sub{b}\\t{%2, %0|%0, %2}"
4126   [(set_attr "type" "alu")])
4127
4128 ;; The patterns that match these are at the end of this file.
4129
4130 (define_expand "subxf3"
4131   [(set (match_operand:XF 0 "register_operand" "")
4132         (minus:XF (match_operand:XF 1 "register_operand" "")
4133                   (match_operand:XF 2 "register_operand" "")))]
4134   "TARGET_80387"
4135   "")
4136
4137 (define_expand "subdf3"
4138   [(set (match_operand:DF 0 "register_operand" "")
4139         (minus:DF (match_operand:DF 1 "register_operand" "")
4140                   (match_operand:DF 2 "nonimmediate_operand" "")))]
4141   "TARGET_80387"
4142   "")
4143
4144 (define_expand "subsf3"
4145   [(set (match_operand:SF 0 "register_operand" "")
4146         (minus:SF (match_operand:SF 1 "register_operand" "")
4147                   (match_operand:SF 2 "nonimmediate_operand" "")))]
4148   "TARGET_80387"
4149   "")
4150 \f
4151 ;; Multiply instructions
4152
4153 (define_expand "mulsi3"
4154   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4155                    (mult:SI (match_operand:SI 1 "register_operand" "")
4156                             (match_operand:SI 2 "general_operand" "")))
4157               (clobber (reg:CC 17))])]
4158   ""
4159   "")
4160
4161 (define_insn "*mulsi3_1"
4162   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4163         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
4164                  (match_operand:SI 2 "general_operand" "K,i,mr")))
4165    (clobber (reg:CC 17))]
4166   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
4167   ; For the {r,0,i} alternative (i.e., register <- register * immediate),
4168   ; there are two ways of writing the exact same machine instruction
4169   ; in assembly language.  One, for example, is:
4170   ;
4171   ;   imul $12, %eax
4172   ;
4173   ; while the other is:
4174   ;
4175   ;   imul $12, %eax, %eax
4176   ;
4177   ; The first is simply short-hand for the latter.  But, some assemblers,
4178   ; like the SCO OSR5 COFF assembler, don't handle the first form.
4179   "@
4180    imul{l}\\t{%2, %1, %0|%0, %1, %2}
4181    imul{l}\\t{%2, %1, %0|%0, %1, %2}
4182    imul{l}\\t{%2, %0|%0, %2}"
4183   [(set_attr "type" "imul")
4184    (set_attr "length" "2,3,2")])
4185
4186 (define_expand "mulhi3"
4187   [(parallel [(set (match_operand:HI 0 "register_operand" "")
4188                    (mult:HI (match_operand:HI 1 "register_operand" "")
4189                             (match_operand:HI 2 "general_operand" "")))
4190               (clobber (reg:CC 17))])]
4191   "TARGET_HIMODE_MATH"
4192   "")
4193
4194 (define_insn "*mulhi3_1"
4195   [(set (match_operand:HI 0 "register_operand" "=r,r")
4196         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0")
4197                  (match_operand:HI 2 "general_operand" "K,g")))
4198    (clobber (reg:CC 17))]
4199   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
4200   ; %%% There was a note about "Assembler has weird restrictions",
4201   ; concerning alternative 1 when op1 == op0.  True?
4202   "@
4203    imul{w}\\t{%2, %1, %0|%0, %1, %2}
4204    imul{w}\\t{%2, %0|%0, %2}"
4205   [(set_attr "type" "imul")])
4206
4207 (define_insn "mulqi3"
4208   [(set (match_operand:QI 0 "register_operand" "=a")
4209         (mult:QI (match_operand:QI 1 "register_operand" "%0")
4210                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
4211    (clobber (reg:CC 17))]
4212   "TARGET_QIMODE_MATH"
4213   "mul{b}\\t%2"
4214   [(set_attr "type" "imul")])
4215
4216 (define_insn "umulqihi3"
4217   [(set (match_operand:HI 0 "register_operand" "=a")
4218         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4219                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
4220    (clobber (reg:CC 17))]
4221   "TARGET_QIMODE_MATH"
4222   "mul{b}\\t%2"
4223   [(set_attr "type" "imul")])
4224
4225 (define_insn "mulqihi3"
4226   [(set (match_operand:HI 0 "register_operand" "=a")
4227         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4228                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
4229    (clobber (reg:CC 17))]
4230   "TARGET_QIMODE_MATH"
4231   "imul{b}\\t%2"
4232   [(set_attr "type" "imul")])
4233
4234 (define_insn "umulsidi3"
4235   [(set (match_operand:DI 0 "register_operand" "=A")
4236         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4237                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
4238    (clobber (reg:CC 17))]
4239   ""
4240   "mul{l}\\t%2"
4241   [(set_attr "type" "imul")
4242    (set_attr "ppro_uops" "few")])
4243
4244 (define_insn "mulsidi3"
4245   [(set (match_operand:DI 0 "register_operand" "=A")
4246         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4247                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
4248    (clobber (reg:CC 17))]
4249   ""
4250   "imul{l}\\t%2"
4251   [(set_attr "type" "imul")])
4252
4253 (define_insn "umulsi3_highpart"
4254   [(set (match_operand:SI 0 "register_operand" "=d")
4255         (truncate:SI
4256           (lshiftrt:DI
4257             (mult:DI (zero_extend:DI
4258                        (match_operand:SI 1 "register_operand" "%a"))
4259                      (zero_extend:DI
4260                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
4261             (const_int 32))))
4262    (clobber (match_scratch:SI 3 "=a"))
4263    (clobber (reg:CC 17))]
4264   ""
4265   "mul{l}\\t%2"
4266   [(set_attr "type" "imul")
4267    (set_attr "ppro_uops" "few")])
4268
4269 (define_insn "smulsi3_highpart"
4270   [(set (match_operand:SI 0 "register_operand" "=d")
4271         (truncate:SI
4272           (lshiftrt:DI
4273             (mult:DI (sign_extend:DI
4274                        (match_operand:SI 1 "register_operand" "%a"))
4275                      (sign_extend:DI
4276                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
4277             (const_int 32))))
4278    (clobber (match_scratch:SI 3 "=a"))
4279    (clobber (reg:CC 17))]
4280   ""
4281   "imul{l}\\t%2"
4282   [(set_attr "type" "imul")
4283    (set_attr "ppro_uops" "few")])
4284
4285 ;; The patterns that match these are at the end of this file.
4286
4287 (define_expand "mulxf3"
4288   [(set (match_operand:XF 0 "register_operand" "")
4289         (mult:XF (match_operand:XF 1 "register_operand" "")
4290                  (match_operand:XF 2 "register_operand" "")))]
4291   "TARGET_80387"
4292   "")
4293
4294 (define_expand "muldf3"
4295   [(set (match_operand:DF 0 "register_operand" "")
4296         (mult:DF (match_operand:DF 1 "register_operand" "")
4297                  (match_operand:DF 2 "nonimmediate_operand" "")))]
4298   "TARGET_80387"
4299   "")
4300
4301 (define_expand "mulsf3"
4302   [(set (match_operand:SF 0 "register_operand" "")
4303         (mult:SF (match_operand:SF 1 "register_operand" "")
4304                  (match_operand:SF 2 "nonimmediate_operand" "")))]
4305   "TARGET_80387"
4306   "")
4307 \f
4308 ;; Divide instructions
4309
4310 (define_insn "divqi3"
4311   [(set (match_operand:QI 0 "register_operand" "=a")
4312         (div:QI (match_operand:HI 1 "register_operand" "0")
4313                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
4314    (clobber (reg:CC 17))]
4315   "TARGET_QIMODE_MATH"
4316   "idiv{b}\\t%2"
4317   [(set_attr "type" "idiv")
4318    (set_attr "ppro_uops" "few")])
4319
4320 (define_insn "udivqi3"
4321   [(set (match_operand:QI 0 "register_operand" "=a")
4322         (udiv:QI (match_operand:HI 1 "register_operand" "0")
4323                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
4324    (clobber (reg:CC 17))]
4325   "TARGET_QIMODE_MATH"
4326   "div{b}\\t%2"
4327   [(set_attr "type" "idiv")
4328    (set_attr "ppro_uops" "few")])
4329
4330 ;; The patterns that match these are at the end of this file.
4331
4332 (define_expand "divxf3"
4333   [(set (match_operand:XF 0 "register_operand" "")
4334         (div:XF (match_operand:XF 1 "register_operand" "")
4335                 (match_operand:XF 2 "register_operand" "")))]
4336   "TARGET_80387"
4337   "")
4338
4339 (define_expand "divdf3"
4340   [(set (match_operand:DF 0 "register_operand" "")
4341         (div:DF (match_operand:DF 1 "register_operand" "")
4342                 (match_operand:DF 2 "nonimmediate_operand" "")))]
4343    "TARGET_80387"
4344    "")
4345  
4346 (define_expand "divsf3"
4347   [(set (match_operand:SF 0 "register_operand" "")
4348         (div:SF (match_operand:SF 1 "register_operand" "")
4349                 (match_operand:SF 2 "nonimmediate_operand" "")))]
4350   "TARGET_80387"
4351   "")
4352 \f
4353 ;; Remainder instructions.
4354 (define_expand "divmodsi4"
4355   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4356                    (div:SI (match_operand:SI 1 "register_operand" "")
4357                            (match_operand:SI 2 "nonimmediate_operand" "")))
4358               (set (match_operand:SI 3 "register_operand" "")
4359                    (mod:SI (match_dup 1) (match_dup 2)))
4360               (clobber (reg:CC 17))])]
4361   ""
4362   "")
4363
4364 ;; Allow to come the parameter in eax or edx to avoid extra moves.
4365 ;; Penalize eax case sligthly because it results in worse scheduling
4366 ;; of code.
4367 (define_insn "*divmodsi4_nocltd"
4368   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
4369         (div:SI (match_operand:SI 2 "register_operand" "1,0")
4370                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
4371    (set (match_operand:SI 1 "register_operand" "=&d,&d")
4372         (mod:SI (match_dup 2) (match_dup 3)))
4373    (clobber (reg:CC 17))]
4374   "!optimize_size && !TARGET_USE_CLTD"
4375   "#"
4376   [(set_attr "type" "multi")])
4377
4378 (define_insn "*divmodsi4_cltd"
4379   [(set (match_operand:SI 0 "register_operand" "=a")
4380         (div:SI (match_operand:SI 2 "register_operand" "a")
4381                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
4382    (set (match_operand:SI 1 "register_operand" "=&d")
4383         (mod:SI (match_dup 2) (match_dup 3)))
4384    (clobber (reg:CC 17))]
4385   "optimize_size || TARGET_USE_CLTD"
4386   "#"
4387   [(set_attr "type" "multi")])
4388
4389 (define_insn "*divmodsi_noext"
4390   [(set (match_operand:SI 0 "register_operand" "=a")
4391         (div:SI (match_operand:SI 1 "register_operand" "0")
4392                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4393    (set (match_operand:SI 3 "register_operand" "=d")
4394         (mod:SI (match_dup 1) (match_dup 2)))
4395    (use (match_operand:SI 4 "register_operand" "3"))
4396    (clobber (reg:CC 17))]
4397   ""
4398   "idiv{l}\\t%2"
4399   [(set_attr "type" "idiv")
4400    (set_attr "ppro_uops" "few")])
4401
4402 (define_split
4403   [(set (match_operand:SI 0 "register_operand" "")
4404         (div:SI (match_operand:SI 1 "register_operand" "")
4405                 (match_operand:SI 2 "nonimmediate_operand" "")))
4406    (set (match_operand:SI 3 "register_operand" "")
4407         (mod:SI (match_dup 1) (match_dup 2)))
4408    (clobber (reg:CC 17))]
4409   "reload_completed"
4410   [(parallel [(set (match_dup 3)
4411                    (ashiftrt:SI (match_dup 4) (const_int 31)))
4412               (clobber (reg:CC 17))])
4413    (parallel [(set (match_dup 0)
4414                    (div:SI (reg:SI 0) (match_dup 2)))
4415               (set (match_dup 3)
4416                    (mod:SI (reg:SI 0) (match_dup 2)))
4417               (use (match_dup 3))
4418               (clobber (reg:CC 17))])]
4419   "
4420 {
4421   /* Avoid use of cltd in favour of a mov+shift.  */
4422   if (!TARGET_USE_CLTD && !optimize_size)
4423     {
4424       if (true_regnum (operands[1]))
4425         emit_move_insn (operands[0], operands[1]);
4426       else
4427         emit_move_insn (operands[3], operands[1]);
4428       operands[4] = operands[3];
4429     }
4430   else
4431     {
4432       if (true_regnum (operands[1]))
4433         abort();
4434       operands[4] = operands[1];
4435     }
4436 }")
4437 ;; %%% Split me.
4438 (define_insn "divmodhi4"
4439   [(set (match_operand:HI 0 "register_operand" "=a")
4440         (div:HI (match_operand:HI 1 "register_operand" "0")
4441                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4442    (set (match_operand:HI 3 "register_operand" "=&d")
4443         (mod:HI (match_dup 1) (match_dup 2)))
4444    (clobber (reg:CC 17))]
4445   "TARGET_HIMODE_MATH"
4446   "cwtd\;idiv{w}\\t%2"
4447   [(set_attr "type" "multi")])
4448
4449 (define_insn "udivmodsi4"
4450   [(set (match_operand:SI 0 "register_operand" "=a")
4451         (udiv:SI (match_operand:SI 1 "register_operand" "0")
4452                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
4453    (set (match_operand:SI 3 "register_operand" "=&d")
4454         (umod:SI (match_dup 1) (match_dup 2)))
4455    (clobber (reg:CC 17))]
4456   ""
4457   "xor{l}\\t%3, %3\;div{l}\\t%2"
4458   [(set_attr "type" "multi")])
4459
4460 (define_insn "*udivmodsi4_noext"
4461   [(set (match_operand:SI 0 "register_operand" "=a")
4462         (udiv:SI (match_operand:SI 1 "register_operand" "0")
4463                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
4464    (set (match_operand:SI 3 "register_operand" "=d")
4465         (umod:SI (match_dup 1) (match_dup 2)))
4466    (use (match_dup 3))
4467    (clobber (reg:CC 17))]
4468   ""
4469   "div{l}\\t%2"
4470   [(set_attr "type" "idiv")
4471    (set_attr "ppro_uops" "few")])
4472
4473 (define_split
4474   [(set (match_operand:SI 0 "register_operand" "")
4475         (udiv:SI (match_operand:SI 1 "register_operand" "")
4476                  (match_operand:SI 2 "nonimmediate_operand" "")))
4477    (set (match_operand:SI 3 "register_operand" "")
4478         (umod:SI (match_dup 1) (match_dup 2)))
4479    (clobber (reg:CC 17))]
4480   "reload_completed"
4481   [(set (match_dup 3) (const_int 0))
4482    (parallel [(set (match_dup 0)
4483                    (udiv:SI (match_dup 1) (match_dup 2)))
4484               (set (match_dup 3)
4485                    (umod:SI (match_dup 1) (match_dup 2)))
4486               (use (match_dup 3))
4487               (clobber (reg:CC 17))])]
4488   "")
4489
4490 (define_expand "udivmodhi4"
4491   [(set (match_dup 4) (const_int 0))
4492    (parallel [(set (match_operand:HI 0 "register_operand" "")
4493                    (udiv:HI (match_operand:HI 1 "register_operand" "")
4494                             (match_operand:HI 2 "nonimmediate_operand" "")))
4495               (set (match_operand:HI 3 "register_operand" "")
4496                    (umod:HI (match_dup 1) (match_dup 2)))
4497               (use (match_dup 4))
4498               (clobber (reg:CC 17))])]
4499   "TARGET_HIMODE_MATH"
4500   "operands[4] = gen_reg_rtx (HImode);")
4501
4502 (define_insn "*udivmodhi_noext"
4503   [(set (match_operand:HI 0 "register_operand" "=a")
4504         (udiv:HI (match_operand:HI 1 "register_operand" "0")
4505                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
4506    (set (match_operand:HI 3 "register_operand" "=d")
4507         (umod:HI (match_dup 1) (match_dup 2)))
4508    (use (match_operand:HI 4 "register_operand" "3"))
4509    (clobber (reg:CC 17))]
4510   ""
4511   "div{w}\\t%2"
4512   [(set_attr "type" "idiv")
4513    (set_attr "ppro_uops" "few")])
4514
4515 ;; We can not use div/idiv for double division, because it causes
4516 ;; "division by zero" on the overflow and that's not what we expect
4517 ;; from truncate.  Because true (non truncating) double division is
4518 ;; never generated, we can't create this insn anyway.
4519 ;
4520 ;(define_insn ""
4521 ;  [(set (match_operand:SI 0 "register_operand" "=a")
4522 ;       (truncate:SI
4523 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
4524 ;                  (zero_extend:DI
4525 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
4526 ;   (set (match_operand:SI 3 "register_operand" "=d")
4527 ;       (truncate:SI
4528 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
4529 ;   (clobber (reg:CC 17))]
4530 ;  ""
4531 ;  "div{l}\\t{%2, %0|%0, %2}"
4532 ;  [(set_attr "type" "idiv")
4533 ;   (set_attr "ppro_uops" "few")])
4534 \f
4535 ;;- Logical AND instructions
4536
4537 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
4538 ;; Note that this excludes ah.
4539
4540 (define_insn "*testsi_ccz_1"
4541   [(set (reg:CCZ 17)
4542         (compare:CCZ
4543           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
4544                   (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
4545           (const_int 0)))]
4546   ""
4547   "test{l}\\t{%1, %0|%0, %1}"
4548   [(set_attr "type" "icmp")
4549    (set_attr "pent_pair" "uv,np,uv")])
4550
4551 (define_insn "testsi_ccno_1"
4552   [(set (reg:CCNO 17)
4553         (compare:CCNO
4554           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
4555                   (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
4556           (const_int 0)))]
4557   ""
4558   "test{l}\\t{%1, %0|%0, %1}"
4559   [(set_attr "type" "icmp")
4560    (set_attr "pent_pair" "uv,np,uv")])
4561
4562 (define_insn "*testhi_1"
4563   [(set (reg 17)
4564         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
4565                          (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
4566                  (const_int 0)))]
4567   "ix86_match_ccmode (insn, CCNOmode)"
4568   "test{w}\\t{%1, %0|%0, %1}"
4569   [(set_attr "type" "icmp")
4570    (set_attr "pent_pair" "uv,np,uv")])
4571
4572 (define_insn "testqi_ccz_1"
4573   [(set (reg:CCZ 17)
4574         (compare:CCZ
4575           (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
4576                   (match_operand:QI 1 "nonmemory_operand" "n,n,qn"))
4577           (const_int 0)))]
4578   ""
4579   "test{b}\\t{%1, %0|%0, %1}"
4580   [(set_attr "type" "icmp")
4581    (set_attr "pent_pair" "uv,np,uv")])
4582
4583 (define_insn "testqi_ccno_1"
4584   [(set (reg:CCNO 17)
4585         (compare:CCNO (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
4586                               (match_operand:QI 1 "nonmemory_operand" "n,n,qn"))
4587                       (const_int 0)))]
4588   ""
4589   "test{b}\\t{%1, %0|%0, %1}"
4590   [(set_attr "type" "icmp")
4591    (set_attr "pent_pair" "uv,np,uv")])
4592
4593 (define_insn "*testqi_ext_ccz_0"
4594   [(set (reg:CCZ 17)
4595         (compare:CCZ
4596           (and:SI
4597             (zero_extract:SI
4598               (match_operand 0 "ext_register_operand" "q")
4599               (const_int 8)
4600               (const_int 8))
4601             (match_operand 1 "const_int_operand" "n"))
4602           (const_int 0)))]
4603   "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff"
4604   "test{b}\\t{%1, %h0|%h0, %1}"
4605   [(set_attr "type" "icmp")
4606    (set_attr "pent_pair" "np")])
4607
4608 (define_insn "testqi_ext_ccno_0"
4609   [(set (reg:CCNO 17)
4610         (compare:CCNO
4611           (and:SI
4612             (zero_extract:SI
4613               (match_operand 0 "ext_register_operand" "q")
4614               (const_int 8)
4615               (const_int 8))
4616             (match_operand 1 "const_int_operand" "n"))
4617           (const_int 0)))]
4618   "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff"
4619   "test{b}\\t{%1, %h0|%h0, %1}"
4620   [(set_attr "type" "icmp")
4621    (set_attr "pent_pair" "np")])
4622
4623 (define_insn "*testqi_ext_1"
4624   [(set (reg 17)
4625         (compare
4626           (and:SI
4627             (zero_extract:SI
4628               (match_operand 0 "ext_register_operand" "q")
4629               (const_int 8)
4630               (const_int 8))
4631             (zero_extend:SI
4632               (match_operand:QI 1 "nonimmediate_operand" "qm")))
4633           (const_int 0)))]
4634   "ix86_match_ccmode (insn, CCNOmode)"
4635   "test{b}\\t{%1, %h0|%h0, %1}"
4636   [(set_attr "type" "icmp")])
4637
4638 (define_insn "*testqi_ext_2"
4639   [(set (reg 17)
4640         (compare
4641           (and:SI
4642             (zero_extract:SI
4643               (match_operand 0 "ext_register_operand" "q")
4644               (const_int 8)
4645               (const_int 8))
4646             (zero_extract:SI
4647               (match_operand 1 "ext_register_operand" "q")
4648               (const_int 8)
4649               (const_int 8)))
4650           (const_int 0)))]
4651   "ix86_match_ccmode (insn, CCNOmode)"
4652   "test{b}\\t{%h1, %h0|%h0, %h1}"
4653   [(set_attr "type" "icmp")])
4654
4655 ;; Combine likes to form bit extractions for some tests.  Humor it.
4656 (define_insn "*testqi_ext_3"
4657   [(set (reg 17)
4658         (compare (zero_extract:SI
4659                    (match_operand 0 "nonimmediate_operand" "rm")
4660                    (match_operand:SI 1 "const_int_operand" "")
4661                    (match_operand:SI 2 "const_int_operand" ""))
4662                  (const_int 0)))]
4663   "ix86_match_ccmode (insn, CCNOmode)
4664    && (GET_MODE (operands[0]) == SImode
4665        || GET_MODE (operands[0]) == HImode
4666        || GET_MODE (operands[0]) == QImode)"
4667   "#")
4668
4669 (define_split
4670   [(set (reg 17)
4671         (compare (zero_extract:SI
4672                    (match_operand 0 "nonimmediate_operand" "rm")
4673                    (match_operand:SI 1 "const_int_operand" "")
4674                    (match_operand:SI 2 "const_int_operand" ""))
4675                  (const_int 0)))]
4676   "ix86_match_ccmode (insn, CCNOmode)"
4677   [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
4678   "
4679 {
4680   HOST_WIDE_INT len = INTVAL (operands[1]);
4681   HOST_WIDE_INT pos = INTVAL (operands[2]);
4682   HOST_WIDE_INT mask;
4683   enum machine_mode mode;
4684
4685   mode = GET_MODE (operands[0]);
4686   if (GET_CODE (operands[0]) == MEM)
4687     {
4688       /* ??? Combine likes to put non-volatile mem extractions in QImode
4689          no matter the size of the test.  So find a mode that works.  */
4690       if (! MEM_VOLATILE_P (operands[0]))
4691         {
4692           mode = smallest_mode_for_size (pos + len, MODE_INT);
4693           operands[0] = change_address (operands[0], mode, NULL_RTX);
4694         }
4695     }
4696   else if (mode == HImode && pos + len <= 8)
4697     {
4698       /* Small HImode tests can be converted to QImode.  */
4699       mode = QImode;
4700       operands[0] = gen_lowpart (QImode, operands[0]);
4701     }
4702
4703   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
4704   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
4705
4706   operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
4707 }")
4708
4709 ;; %%% This used to optimize known byte-wide and operations to memory,
4710 ;; and sometimes to QImode registers.  If this is considered useful,
4711 ;; it should be done with splitters.
4712
4713 (define_expand "andsi3"
4714   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4715         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
4716                 (match_operand:SI 2 "general_operand" "")))
4717    (clobber (reg:CC 17))]
4718   ""
4719   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
4720
4721 (define_insn "*andsi_1"
4722   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
4723         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
4724                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
4725    (clobber (reg:CC 17))]
4726   "ix86_binary_operator_ok (AND, SImode, operands)"
4727   "*
4728 {
4729   switch (get_attr_type (insn))
4730     {
4731     case TYPE_IMOVX:
4732       {
4733         enum machine_mode mode;
4734
4735         if (GET_CODE (operands[2]) != CONST_INT)
4736           abort ();
4737         if (INTVAL (operands[2]) == 0xff)
4738           mode = QImode;
4739         else if (INTVAL (operands[2]) == 0xffff)
4740           mode = HImode;
4741         else
4742           abort ();
4743         
4744         operands[1] = gen_lowpart (mode, operands[1]);
4745         if (mode == QImode)
4746           return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
4747         else
4748           return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
4749       }
4750
4751     default:
4752       if (! rtx_equal_p (operands[0], operands[1]))
4753         abort ();
4754
4755       /* If operands[2] is an immediate, we may be able to use xor.
4756          Walk through the cases to figure out which subword we are
4757          supposed to clear.  */
4758       if (REG_P (operands[0])
4759           && GET_CODE (operands[2]) == CONST_INT
4760           && (optimize_size
4761               || ! TARGET_PARTIAL_REG_STALL))
4762         {
4763           if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffff0000
4764               && optimize_size)
4765             return \"xor{w}\\t{%w0, %w0|%w0, %w0}\";
4766           if (QI_REG_P (operands[0]))
4767             {
4768               if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffff00)
4769                 return \"xor{b}\\t{%b0, %b0|%b0, %b0}\";
4770               if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffff00ff)
4771                 return \"xor{b}\\t{%h0, %h0|%h0, %h0}\";
4772             }
4773         }
4774       return \"and{l}\\t{%2, %0|%0, %2}\";
4775     }
4776 }"
4777   [(set_attr "type" "alu,alu,imovx")])
4778
4779 (define_insn "*andsi_2"
4780   [(set (reg 17)
4781         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4782                          (match_operand:SI 2 "general_operand" "rim,ri"))
4783                  (const_int 0)))
4784    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4785         (and:SI (match_dup 1) (match_dup 2)))]
4786   "ix86_match_ccmode (insn, CCNOmode)
4787    && ix86_binary_operator_ok (AND, SImode, operands)"
4788   "and{l}\\t{%2, %0|%0, %2}"
4789   [(set_attr "type" "alu")])
4790
4791 (define_expand "andhi3"
4792   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4793         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
4794                 (match_operand:HI 2 "general_operand" "")))
4795    (clobber (reg:CC 17))]
4796   "TARGET_HIMODE_MATH"
4797   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
4798
4799 (define_insn "*andhi_1"
4800   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
4801         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
4802                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
4803    (clobber (reg:CC 17))]
4804   "ix86_binary_operator_ok (AND, HImode, operands)"
4805   "*
4806 {
4807   switch (get_attr_type (insn))
4808     {
4809     case TYPE_IMOVX:
4810       if (GET_CODE (operands[2]) != CONST_INT)
4811         abort ();
4812       if (INTVAL (operands[2]) == 0xff)
4813         return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
4814       abort ();
4815
4816     default:
4817       if (! rtx_equal_p (operands[0], operands[1]))
4818         abort ();
4819
4820       /* If operands[2] is an immediate, we may be able to use xor.
4821          Walk through the cases to figure out which subword we are
4822          supposed to clear.  */
4823       /* %%% Do these as splits.  They get length_prefix wrong.  */
4824       if (GET_CODE (operands[2]) == CONST_INT
4825           && QI_REG_P (operands[0])
4826           && (optimize_size 
4827               || ! TARGET_PARTIAL_REG_STALL))
4828         {
4829           if ((INTVAL (operands[2]) & 0xffff) == 0xff00)
4830             return \"xor{b}\\t{%b0, %b0|%b0, %b0}\";
4831           if ((INTVAL (operands[2]) & 0xffff) == 0x00ff)
4832             return \"xor{b}\\t{%h0, %h0|%h0, %h0}\";
4833         }
4834
4835       return \"and{w}\\t{%2, %0|%0, %2}\";
4836     }
4837 }"
4838   [(set_attr "type" "alu,alu,imovx")])
4839
4840 (define_insn "*andhi_2"
4841   [(set (reg 17)
4842         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4843                          (match_operand:HI 2 "general_operand" "rim,ri"))
4844                  (const_int 0)))
4845    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
4846         (and:HI (match_dup 1) (match_dup 2)))]
4847   "ix86_match_ccmode (insn, CCNOmode)
4848    && ix86_binary_operator_ok (AND, HImode, operands)"
4849   "and{w}\\t{%2, %0|%0, %2}"
4850   [(set_attr "type" "alu")])
4851
4852 (define_expand "andqi3"
4853   [(set (match_operand:QI 0 "nonimmediate_operand" "")
4854         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
4855                 (match_operand:QI 2 "general_operand" "")))
4856    (clobber (reg:CC 17))]
4857   "TARGET_QIMODE_MATH"
4858   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
4859
4860 ;; %%% Potential partial reg stall on alternative 2.  What to do?
4861 (define_insn "*andqi_1"
4862   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
4863         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
4864                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
4865    (clobber (reg:CC 17))]
4866   "ix86_binary_operator_ok (AND, QImode, operands)"
4867   "@
4868    and{b}\\t{%2, %0|%0, %2}
4869    and{b}\\t{%2, %0|%0, %2}
4870    and{l}\\t{%k2, %k0|%k0, %k2}"
4871   [(set_attr "type" "alu")])
4872
4873 (define_insn "*andqi_2"
4874   [(set (reg 17)
4875         (compare (and:QI
4876                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
4877                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
4878                  (const_int 0)))
4879    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
4880         (and:QI (match_dup 1) (match_dup 2)))]
4881   "ix86_match_ccmode (insn, CCNOmode)
4882    && ix86_binary_operator_ok (AND, QImode, operands)"
4883   "@
4884    and{b}\\t{%2, %0|%0, %2}
4885    and{b}\\t{%2, %0|%0, %2}
4886    and{l}\\t{%2, %k0|%k0, %2}"
4887   [(set_attr "type" "alu")])
4888
4889 ;; ??? A bug in recog prevents it from recognizing a const_int as an
4890 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
4891 ;; for a QImode operand, which of course failed.
4892
4893 (define_insn "andqi_ext_0"
4894   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4895                          (const_int 8)
4896                          (const_int 8))
4897         (and:SI 
4898           (zero_extract:SI
4899             (match_operand 1 "ext_register_operand" "0")
4900             (const_int 8)
4901             (const_int 8))
4902           (match_operand 2 "const_int_operand" "n")))
4903    (clobber (reg:CC 17))]
4904   "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
4905   "and{b}\\t{%2, %h0|%h0, %2}"
4906   [(set_attr "type" "alu")])
4907
4908 ;; Generated by peephole translating test to and.  This shows up
4909 ;; often in fp comparisons.
4910
4911 (define_insn "*andqi_ext_0_cc"
4912   [(set (reg 17)
4913         (compare
4914           (and:SI
4915             (zero_extract:SI
4916               (match_operand 1 "ext_register_operand" "q")
4917                 (const_int 8)
4918               (const_int 8))
4919             (match_operand 2 "const_int_operand" "n"))
4920           (const_int 0)))
4921    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4922                          (const_int 8)
4923                          (const_int 8))
4924         (and:SI 
4925           (zero_extract:SI
4926             (match_dup 1)
4927             (const_int 8)
4928             (const_int 8))
4929           (match_dup 2)))]
4930   "ix86_match_ccmode (insn, CCNOmode)
4931    && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
4932   "and{b}\\t{%2, %h0|%h0, %2}"
4933   [(set_attr "type" "alu")])
4934
4935 (define_insn "*andqi_ext_1"
4936   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4937                          (const_int 8)
4938                          (const_int 8))
4939         (and:SI 
4940           (zero_extract:SI
4941             (match_operand 1 "ext_register_operand" "0")
4942             (const_int 8)
4943             (const_int 8))
4944           (zero_extend:SI
4945             (match_operand:QI 2 "general_operand" "qm"))))
4946    (clobber (reg:CC 17))]
4947   ""
4948   "and{b}\\t{%2, %h0|%h0, %2}"
4949   [(set_attr "type" "alu")])
4950
4951 (define_insn "*andqi_ext_2"
4952   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4953                          (const_int 8)
4954                          (const_int 8))
4955         (and:SI
4956           (zero_extract:SI
4957             (match_operand 1 "ext_register_operand" "%0")
4958             (const_int 8)
4959             (const_int 8))
4960           (zero_extract:SI
4961             (match_operand 2 "ext_register_operand" "q")
4962             (const_int 8)
4963             (const_int 8))))
4964    (clobber (reg:CC 17))]
4965   ""
4966   "and{b}\\t{%h2, %h0|%h0, %h2}"
4967   [(set_attr "type" "alu")])
4968 \f
4969 ;; Logical inclusive OR instructions
4970
4971 ;; %%% This used to optimize known byte-wide and operations to memory.
4972 ;; If this is considered useful, it should be done with splitters.
4973
4974 (define_expand "iorsi3"
4975   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4976         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
4977                 (match_operand:SI 2 "general_operand" "")))
4978    (clobber (reg:CC 17))]
4979   ""
4980   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
4981
4982 (define_insn "*iorsi_1"
4983   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4984         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4985                 (match_operand:SI 2 "general_operand" "ri,rmi")))
4986    (clobber (reg:CC 17))]
4987   "ix86_binary_operator_ok (IOR, SImode, operands)"
4988   "or{l}\\t{%2, %0|%0, %2}"
4989   [(set_attr "type" "alu")])
4990
4991 (define_insn "*iorsi_2"
4992   [(set (reg 17)
4993         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4994                          (match_operand:SI 2 "general_operand" "rim,ri"))
4995                  (const_int 0)))
4996    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4997         (ior:SI (match_dup 1) (match_dup 2)))]
4998   "ix86_match_ccmode (insn, CCNOmode)
4999    && ix86_binary_operator_ok (IOR, SImode, operands)"
5000   "or{l}\\t{%2, %0|%0, %2}"
5001   [(set_attr "type" "alu")])
5002
5003 (define_expand "iorhi3"
5004   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5005         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
5006                 (match_operand:HI 2 "general_operand" "")))
5007    (clobber (reg:CC 17))]
5008   "TARGET_HIMODE_MATH"
5009   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
5010
5011 (define_insn "*iorhi_1"
5012   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
5013         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5014                 (match_operand:HI 2 "general_operand" "rmi,ri")))
5015    (clobber (reg:CC 17))]
5016   "ix86_binary_operator_ok (IOR, HImode, operands)"
5017   "or{w}\\t{%2, %0|%0, %2}"
5018   [(set_attr "type" "alu")])
5019
5020 (define_insn "*iorhi_2"
5021   [(set (reg 17)
5022         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5023                          (match_operand:HI 2 "general_operand" "rim,ri"))
5024                  (const_int 0)))
5025    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5026         (ior:HI (match_dup 1) (match_dup 2)))]
5027   "ix86_match_ccmode (insn, CCNOmode)
5028    && ix86_binary_operator_ok (IOR, HImode, operands)"
5029   "or{w}\\t{%2, %0|%0, %2}"
5030   [(set_attr "type" "alu")])
5031
5032 (define_expand "iorqi3"
5033   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5034         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
5035                 (match_operand:QI 2 "general_operand" "")))
5036    (clobber (reg:CC 17))]
5037   "TARGET_QIMODE_MATH"
5038   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
5039
5040 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5041 (define_insn "*iorqi_1"
5042   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
5043         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5044                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
5045    (clobber (reg:CC 17))]
5046   "ix86_binary_operator_ok (IOR, QImode, operands)"
5047   "@
5048    or{b}\\t{%2, %0|%0, %2}
5049    or{b}\\t{%2, %0|%0, %2}
5050    or{l}\\t{%k2, %k0|%k0, %k2}"
5051   [(set_attr "type" "alu")])
5052
5053 (define_insn "*iorqi_2"
5054   [(set (reg 17)
5055         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5056                          (match_operand:QI 2 "general_operand" "qim,qi"))
5057                  (const_int 0)))
5058    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5059         (ior:QI (match_dup 1) (match_dup 2)))]
5060   "ix86_match_ccmode (insn, CCNOmode)
5061    && ix86_binary_operator_ok (IOR, QImode, operands)"
5062   "or{b}\\t{%2, %0|%0, %2}"
5063   [(set_attr "type" "alu")])
5064 \f
5065 ;; Logical XOR instructions
5066
5067 ;; %%% This used to optimize known byte-wide and operations to memory.
5068 ;; If this is considered useful, it should be done with splitters.
5069
5070 (define_expand "xorsi3"
5071   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5072         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
5073                 (match_operand:SI 2 "general_operand" "")))
5074    (clobber (reg:CC 17))]
5075   ""
5076   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
5077
5078 (define_insn "*xorsi_1"
5079   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5080         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5081                 (match_operand:SI 2 "general_operand" "ri,rm")))
5082    (clobber (reg:CC 17))]
5083   "ix86_binary_operator_ok (XOR, SImode, operands)"
5084   "xor{l}\\t{%2, %0|%0, %2}"
5085   [(set_attr "type" "alu")])
5086
5087 (define_insn "*xorsi_2"
5088   [(set (reg 17)
5089         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5090                          (match_operand:SI 2 "general_operand" "rim,ri"))
5091                  (const_int 0)))
5092    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5093         (xor:SI (match_dup 1) (match_dup 2)))]
5094   "ix86_match_ccmode (insn, CCNOmode)
5095    && ix86_binary_operator_ok (XOR, SImode, operands)"
5096   "xor{l}\\t{%2, %0|%0, %2}"
5097   [(set_attr "type" "alu")])
5098
5099 (define_expand "xorhi3"
5100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5101         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
5102                 (match_operand:HI 2 "general_operand" "")))
5103    (clobber (reg:CC 17))]
5104   "TARGET_HIMODE_MATH"
5105   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
5106
5107 (define_insn "*xorhi_1"
5108   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
5109         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5110                 (match_operand:HI 2 "general_operand" "rmi,ri")))
5111    (clobber (reg:CC 17))]
5112   "ix86_binary_operator_ok (XOR, HImode, operands)"
5113   "xor{w}\\t{%2, %0|%0, %2}"
5114   [(set_attr "type" "alu")])
5115
5116 (define_insn "*xorhi_2"
5117   [(set (reg 17)
5118         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5119                          (match_operand:HI 2 "general_operand" "rim,ri"))
5120                  (const_int 0)))
5121    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5122         (xor:HI (match_dup 1) (match_dup 2)))]
5123   "ix86_match_ccmode (insn, CCNOmode)
5124    && ix86_binary_operator_ok (XOR, HImode, operands)"
5125   "xor{w}\\t{%2, %0|%0, %2}"
5126   [(set_attr "type" "alu")])
5127
5128 (define_expand "xorqi3"
5129   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5130         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
5131                 (match_operand:QI 2 "general_operand" "")))
5132    (clobber (reg:CC 17))]
5133   "TARGET_QIMODE_MATH"
5134   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
5135
5136 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5137 (define_insn "*xorqi_1"
5138   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
5139         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5140                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
5141    (clobber (reg:CC 17))]
5142   "ix86_binary_operator_ok (XOR, QImode, operands)"
5143   "@
5144    xor{b}\\t{%2, %0|%0, %2}
5145    xor{b}\\t{%2, %0|%0, %2}
5146    xor{l}\\t{%k2, %k0|%k0, %k2}"
5147   [(set_attr "type" "alu")])
5148
5149 (define_insn "*xorqi_cc_1"
5150   [(set (reg 17)
5151         (compare
5152           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5153                   (match_operand:QI 2 "general_operand" "qim,qi"))
5154           (const_int 0)))
5155    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5156         (xor:QI (match_dup 1) (match_dup 2)))]
5157   "ix86_match_ccmode (insn, CCNOmode)
5158    && ix86_binary_operator_ok (XOR, QImode, operands)"
5159   "xor{b}\\t{%2, %0|%0, %2}"
5160   [(set_attr "type" "alu")])
5161
5162 (define_insn "xorqi_cc_ext_1"
5163   [(set (reg:CCNO 17)
5164         (compare:CCNO
5165           (xor:SI
5166             (zero_extract:SI
5167               (match_operand 1 "ext_register_operand" "0")
5168               (const_int 8)
5169               (const_int 8))
5170             (match_operand:QI 2 "general_operand" "qmn"))
5171           (const_int 0)))
5172    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5173                          (const_int 8)
5174                          (const_int 8))
5175         (xor:SI 
5176           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
5177           (match_dup 2)))]
5178   ""
5179   "xor{b}\\t{%2, %h0|%h0, %2}"
5180   [(set_attr "type" "alu")])
5181 \f
5182 ;; Negation instructions
5183
5184 ;; %%% define_expand from the very first?
5185
5186 (define_expand "negdi2"
5187   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
5188                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
5189               (clobber (reg:CC 17))])]
5190   ""
5191   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
5192
5193 (define_insn "*negdi2_1"
5194   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
5195         (neg:DI (match_operand:DI 1 "general_operand" "0")))
5196    (clobber (reg:CC 17))]
5197   "ix86_unary_operator_ok (NEG, DImode, operands)"
5198   "#")
5199
5200 (define_split
5201   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5202         (neg:DI (match_operand:DI 1 "general_operand" "")))
5203    (clobber (reg:CC 17))]
5204   "reload_completed"
5205   [(parallel
5206     [(set (reg:CCZ 17)
5207           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
5208      (set (match_dup 0) (neg:SI (match_dup 2)))])
5209    (parallel
5210     [(set (match_dup 1)
5211           (plus:SI (match_dup 3)
5212             (plus:SI (const_int 0)
5213               (ltu:SI (reg:CC 17) (const_int 0)))))
5214      (clobber (reg:CC 17))])
5215    (parallel
5216     [(set (match_dup 1)
5217           (neg:SI (match_dup 1)))
5218      (clobber (reg:CC 17))])]
5219   "split_di (operands+1, 1, operands+2, operands+3);
5220    split_di (operands+0, 1, operands+0, operands+1);")
5221
5222 (define_expand "negsi2"
5223   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5224                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
5225               (clobber (reg:CC 17))])]
5226   ""
5227   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
5228
5229 (define_insn "*negsi2_1"
5230   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5231         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
5232    (clobber (reg:CC 17))]
5233   "ix86_unary_operator_ok (NEG, SImode, operands)"
5234   "neg{l}\\t%0"
5235   [(set_attr "type" "negnot")])
5236
5237 ;; The problem with neg is that it does not perform (compare x 0),
5238 ;; it really performs (compare 0 x), which leaves us with the zero
5239 ;; flag being the only useful item.
5240
5241 (define_insn "*negsi2_cmpz"
5242   [(set (reg:CCZ 17)
5243         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
5244                      (const_int 0)))
5245    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5246         (neg:SI (match_dup 1)))]
5247   "ix86_unary_operator_ok (NEG, SImode, operands)"
5248   "neg{l}\\t%0"
5249   [(set_attr "type" "negnot")])
5250
5251 (define_expand "neghi2"
5252   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5253                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
5254               (clobber (reg:CC 17))])]
5255   "TARGET_HIMODE_MATH"
5256   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
5257
5258 (define_insn "*neghi2_1"
5259   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5260         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
5261    (clobber (reg:CC 17))]
5262   "ix86_unary_operator_ok (NEG, HImode, operands)"
5263   "neg{w}\\t%0"
5264   [(set_attr "type" "negnot")])
5265
5266 (define_insn "*neghi2_cmpz"
5267   [(set (reg:CCZ 17)
5268         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
5269                      (const_int 0)))
5270    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5271         (neg:HI (match_dup 1)))]
5272   "ix86_unary_operator_ok (NEG, HImode, operands)"
5273   "neg{w}\\t%0"
5274   [(set_attr "type" "negnot")])
5275
5276 (define_expand "negqi2"
5277   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5278                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
5279               (clobber (reg:CC 17))])]
5280   "TARGET_QIMODE_MATH"
5281   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
5282
5283 (define_insn "*negqi2_1"
5284   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5285         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
5286    (clobber (reg:CC 17))]
5287   "ix86_unary_operator_ok (NEG, QImode, operands)"
5288   "neg{b}\\t%0"
5289   [(set_attr "type" "negnot")])
5290
5291 (define_insn "*negqi2_cmpz"
5292   [(set (reg:CCZ 17)
5293         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
5294                      (const_int 0)))
5295    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5296         (neg:QI (match_dup 1)))]
5297   "ix86_unary_operator_ok (NEG, QImode, operands)"
5298   "neg{b}\\t%0"
5299   [(set_attr "type" "negnot")])
5300
5301 ;; Changing of sign for FP values is doable using integer unit too.
5302
5303 (define_expand "negsf2"
5304   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
5305                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
5306               (clobber (reg:CC 17))])]
5307   "TARGET_80387"
5308   "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
5309
5310 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5311 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5312 ;; to itself.
5313 (define_insn "*negsf2_if"
5314   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
5315         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
5316    (clobber (reg:CC 17))]
5317   "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
5318   "#")
5319
5320 (define_split
5321   [(set (match_operand:SF 0 "register_operand" "")
5322         (neg:SF (match_operand:SF 1 "register_operand" "")))
5323    (clobber (reg:CC 17))]
5324   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5325   [(set (match_dup 0)
5326         (neg:SF (match_dup 1)))]
5327   "")
5328
5329 (define_split
5330   [(set (match_operand:SF 0 "register_operand" "")
5331         (neg:SF (match_operand:SF 1 "register_operand" "")))
5332    (clobber (reg:CC 17))]
5333   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5334   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
5335               (clobber (reg:CC 17))])]
5336   "operands[1] = GEN_INT (0x80000000);
5337    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
5338
5339 (define_split
5340   [(set (match_operand 0 "memory_operand" "")
5341         (neg (match_operand 1 "memory_operand" "")))
5342    (clobber (reg:CC 17))]
5343   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5344   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5345               (clobber (reg:CC 17))])]
5346   "
5347 {
5348   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
5349
5350   /* XFmode's size is 12, but only 10 bytes are used.  */
5351   if (size == 12)
5352     size = 10;
5353   operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
5354   operands[0] = adj_offsettable_operand (operands[0], size - 1);
5355   operands[1] = GEN_INT (0x80);
5356 }")
5357
5358 (define_expand "negdf2"
5359   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
5360                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
5361               (clobber (reg:CC 17))])]
5362   "TARGET_80387"
5363   "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
5364
5365 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5366 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5367 ;; to itself.
5368 (define_insn "*negdf2_if"
5369   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
5370         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
5371    (clobber (reg:CC 17))]
5372   "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
5373   "#")
5374
5375 (define_split
5376   [(set (match_operand:DF 0 "register_operand" "")
5377         (neg:DF (match_operand:DF 1 "register_operand" "")))
5378    (clobber (reg:CC 17))]
5379   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5380   [(set (match_dup 0)
5381         (neg:DF (match_dup 1)))]
5382   "")
5383
5384 (define_split
5385   [(set (match_operand:DF 0 "register_operand" "")
5386         (neg:DF (match_operand:DF 1 "register_operand" "")))
5387    (clobber (reg:CC 17))]
5388   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5389   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
5390               (clobber (reg:CC 17))])]
5391   "operands[4] = GEN_INT (0x80000000);
5392    split_di (operands+0, 1, operands+2, operands+3);")
5393
5394 (define_expand "negxf2"
5395   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
5396                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
5397               (clobber (reg:CC 17))])]
5398   "TARGET_80387"
5399   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
5400
5401 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5402 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5403 ;; to itself.
5404 (define_insn "*negxf2_if"
5405   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
5406         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
5407    (clobber (reg:CC 17))]
5408   "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
5409   "#")
5410
5411 (define_split
5412   [(set (match_operand:XF 0 "register_operand" "")
5413         (neg:XF (match_operand:XF 1 "register_operand" "")))
5414    (clobber (reg:CC 17))]
5415   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5416   [(set (match_dup 0)
5417         (neg:XF (match_dup 1)))]
5418   "")
5419
5420 (define_split
5421   [(set (match_operand:XF 0 "register_operand" "")
5422         (neg:XF (match_operand:XF 1 "register_operand" "")))
5423    (clobber (reg:CC 17))]
5424   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5425   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
5426               (clobber (reg:CC 17))])]
5427   "operands[1] = GEN_INT (0x8000);
5428    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
5429
5430 ;; Conditionize these after reload. If they matches before reload, we 
5431 ;; lose the clobber and ability to use integer instructions.
5432
5433 (define_insn "*negsf2_1"
5434   [(set (match_operand:SF 0 "register_operand" "=f")
5435         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
5436   "TARGET_80387 && reload_completed"
5437   "fchs"
5438   [(set_attr "type" "fsgn")
5439    (set_attr "ppro_uops" "few")])
5440
5441 (define_insn "*negdf2_1"
5442   [(set (match_operand:DF 0 "register_operand" "=f")
5443         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
5444   "TARGET_80387 && reload_completed"
5445   "fchs"
5446   [(set_attr "type" "fsgn")
5447    (set_attr "ppro_uops" "few")])
5448
5449 (define_insn "*negextendsfdf2"
5450   [(set (match_operand:DF 0 "register_operand" "=f")
5451         (neg:DF (float_extend:DF
5452                   (match_operand:SF 1 "register_operand" "0"))))]
5453   "TARGET_80387"
5454   "fchs"
5455   [(set_attr "type" "fsgn")
5456    (set_attr "ppro_uops" "few")])
5457
5458 (define_insn "*negxf2_1"
5459   [(set (match_operand:XF 0 "register_operand" "=f")
5460         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
5461   "TARGET_80387 && reload_completed"
5462   "fchs"
5463   [(set_attr "type" "fsgn")
5464    (set_attr "ppro_uops" "few")])
5465
5466 (define_insn "*negextenddfxf2"
5467   [(set (match_operand:XF 0 "register_operand" "=f")
5468         (neg:XF (float_extend:XF
5469                   (match_operand:DF 1 "register_operand" "0"))))]
5470   "TARGET_80387"
5471   "fchs"
5472   [(set_attr "type" "fsgn")
5473    (set_attr "ppro_uops" "few")])
5474
5475 (define_insn "*negextendsfxf2"
5476   [(set (match_operand:XF 0 "register_operand" "=f")
5477         (neg:XF (float_extend:XF
5478                   (match_operand:SF 1 "register_operand" "0"))))]
5479   "TARGET_80387"
5480   "fchs"
5481   [(set_attr "type" "fsgn")
5482    (set_attr "ppro_uops" "few")])
5483 \f
5484 ;; Absolute value instructions
5485
5486 (define_expand "abssf2"
5487   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
5488                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
5489               (clobber (reg:CC 17))])]
5490   "TARGET_80387"
5491   "ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
5492
5493 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5494 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5495 ;; to itself.
5496 (define_insn "*abssf2_if"
5497   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
5498         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
5499    (clobber (reg:CC 17))]
5500   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
5501   "#")
5502
5503 (define_split
5504   [(set (match_operand:SF 0 "register_operand" "")
5505         (abs:SF (match_operand:SF 1 "register_operand" "")))
5506    (clobber (reg:CC 17))]
5507   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
5508   [(set (match_dup 0)
5509         (abs:SF (match_dup 1)))]
5510   "")
5511
5512 (define_split
5513   [(set (match_operand:SF 0 "register_operand" "")
5514         (abs:SF (match_operand:SF 1 "register_operand" "")))
5515    (clobber (reg:CC 17))]
5516   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5517   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
5518               (clobber (reg:CC 17))])]
5519   "operands[1] = GEN_INT (~0x80000000);
5520    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
5521
5522 (define_split
5523   [(set (match_operand 0 "memory_operand" "")
5524         (abs (match_operand 1 "memory_operand" "")))
5525    (clobber (reg:CC 17))]
5526   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5527   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5528               (clobber (reg:CC 17))])]
5529   "
5530 {
5531   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
5532
5533   /* XFmode's size is 12, but only 10 bytes are used.  */
5534   if (size == 12)
5535     size = 10;
5536   operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
5537   operands[0] = adj_offsettable_operand (operands[0], size - 1);
5538   operands[1] = GEN_INT (~0x80);
5539 }")
5540
5541 (define_expand "absdf2"
5542   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
5543                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
5544               (clobber (reg:CC 17))])]
5545   "TARGET_80387"
5546   "ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
5547
5548 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5549 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5550 ;; to itself.
5551 (define_insn "*absdf2_if"
5552   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
5553         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
5554    (clobber (reg:CC 17))]
5555   "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
5556   "#")
5557
5558 (define_split
5559   [(set (match_operand:DF 0 "register_operand" "")
5560         (abs:DF (match_operand:DF 1 "register_operand" "")))
5561    (clobber (reg:CC 17))]
5562   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5563   [(set (match_dup 0)
5564         (abs:DF (match_dup 1)))]
5565   "")
5566
5567 (define_split
5568   [(set (match_operand:DF 0 "register_operand" "")
5569         (abs:DF (match_operand:DF 1 "register_operand" "")))
5570    (clobber (reg:CC 17))]
5571   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5572   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
5573               (clobber (reg:CC 17))])]
5574   "operands[4] = GEN_INT (~0x80000000);
5575    split_di (operands+0, 1, operands+2, operands+3);")
5576
5577 (define_expand "absxf2"
5578   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
5579                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
5580               (clobber (reg:CC 17))])]
5581   "TARGET_80387"
5582   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
5583
5584 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5585 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5586 ;; to itself.
5587 (define_insn "*absxf2_if"
5588   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
5589         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
5590    (clobber (reg:CC 17))]
5591   "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
5592   "#")
5593
5594 (define_split
5595   [(set (match_operand:XF 0 "register_operand" "")
5596         (abs:XF (match_operand:XF 1 "register_operand" "")))
5597    (clobber (reg:CC 17))]
5598   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5599   [(set (match_dup 0)
5600         (abs:XF (match_dup 1)))]
5601   "")
5602
5603 (define_split
5604   [(set (match_operand:XF 0 "register_operand" "")
5605         (abs:XF (match_operand:XF 1 "register_operand" "")))
5606    (clobber (reg:CC 17))]
5607   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5608   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
5609               (clobber (reg:CC 17))])]
5610   "operands[1] = GEN_INT (~0x8000);
5611    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
5612
5613 (define_insn "*abssf2_1"
5614   [(set (match_operand:SF 0 "register_operand" "=f")
5615         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
5616   "TARGET_80387 && reload_completed"
5617   "fabs"
5618   [(set_attr "type" "fsgn")])
5619
5620 (define_insn "*absdf2_1"
5621   [(set (match_operand:DF 0 "register_operand" "=f")
5622         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
5623   "TARGET_80387 && reload_completed"
5624   "fabs"
5625   [(set_attr "type" "fsgn")])
5626
5627 (define_insn "*absextendsfdf2"
5628   [(set (match_operand:DF 0 "register_operand" "=f")
5629         (abs:DF (float_extend:DF
5630                   (match_operand:SF 1 "register_operand" "0"))))]
5631   "TARGET_80387"
5632   "fabs"
5633   [(set_attr "type" "fsgn")])
5634
5635 (define_insn "*absxf2_1"
5636   [(set (match_operand:XF 0 "register_operand" "=f")
5637         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
5638   "TARGET_80387 && reload_completed"
5639   "fabs"
5640   [(set_attr "type" "fsgn")])
5641
5642 (define_insn "*absextenddfxf2"
5643   [(set (match_operand:XF 0 "register_operand" "=f")
5644         (abs:XF (float_extend:XF
5645           (match_operand:DF 1 "register_operand" "0"))))]
5646   "TARGET_80387"
5647   "fabs"
5648   [(set_attr "type" "fsgn")])
5649
5650 (define_insn "*absextendsfxf2"
5651   [(set (match_operand:XF 0 "register_operand" "=f")
5652         (abs:XF (float_extend:XF
5653           (match_operand:SF 1 "register_operand" "0"))))]
5654   "TARGET_80387"
5655   "fabs"
5656   [(set_attr "type" "fsgn")])
5657 \f
5658 ;; One complement instructions
5659
5660 (define_expand "one_cmplsi2"
5661   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5662         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
5663   ""
5664   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
5665
5666 (define_insn "*one_cmplsi2_1"
5667   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5668         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
5669   "ix86_unary_operator_ok (NOT, SImode, operands)"
5670   "not{l}\\t%0"
5671   [(set_attr "type" "negnot")])
5672
5673 (define_insn "*one_cmplsi2_2"
5674   [(set (reg 17)
5675         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
5676                  (const_int 0)))
5677    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5678         (not:SI (match_dup 1)))]
5679   "ix86_match_ccmode (insn, CCNOmode)
5680    && ix86_unary_operator_ok (NOT, SImode, operands)"
5681   "#"
5682   [(set_attr "type" "alu1")])
5683
5684 (define_split
5685   [(set (reg 17)
5686         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
5687                  (const_int 0)))
5688    (set (match_operand:SI 0 "nonimmediate_operand" "")
5689         (not:SI (match_dup 1)))]
5690   "ix86_match_ccmode (insn, CCNOmode)"
5691   [(parallel [(set (reg:CCNO 17)
5692                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
5693                                  (const_int 0)))
5694               (set (match_dup 0)
5695                    (xor:SI (match_dup 1) (const_int -1)))])]
5696   "")
5697
5698 (define_expand "one_cmplhi2"
5699   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5700         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
5701   "TARGET_HIMODE_MATH"
5702   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
5703
5704 (define_insn "*one_cmplhi2_1"
5705   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5706         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
5707   "ix86_unary_operator_ok (NOT, HImode, operands)"
5708   "not{w}\\t%0"
5709   [(set_attr "type" "negnot")])
5710
5711 (define_insn "*one_cmplhi2_2"
5712   [(set (reg 17)
5713         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
5714                  (const_int 0)))
5715    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5716         (not:HI (match_dup 1)))]
5717   "ix86_match_ccmode (insn, CCNOmode)
5718    && ix86_unary_operator_ok (NEG, HImode, operands)"
5719   "#"
5720   [(set_attr "type" "alu1")])
5721
5722 (define_split
5723   [(set (reg 17)
5724         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
5725                  (const_int 0)))
5726    (set (match_operand:HI 0 "nonimmediate_operand" "")
5727         (not:HI (match_dup 1)))]
5728   "ix86_match_ccmode (insn, CCNOmode)"
5729   [(parallel [(set (reg:CCNO 17)
5730                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
5731                                  (const_int 0)))
5732               (set (match_dup 0)
5733                    (xor:HI (match_dup 1) (const_int -1)))])]
5734   "")
5735
5736 ;; %%% Potential partial reg stall on alternative 1.  What to do?
5737 (define_expand "one_cmplqi2"
5738   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5739         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
5740   "TARGET_QIMODE_MATH"
5741   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
5742
5743 (define_insn "*one_cmplqi2_1"
5744   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
5745         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
5746   "ix86_unary_operator_ok (NOT, QImode, operands)"
5747   "@
5748    not{b}\\t%0
5749    not{l}\\t%k0"
5750   [(set_attr "type" "negnot")])
5751
5752 (define_insn "*one_cmplqi2_2"
5753   [(set (reg 17)
5754         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
5755                  (const_int 0)))
5756    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5757         (not:QI (match_dup 1)))]
5758   "ix86_match_ccmode (insn, CCNOmode)
5759    && ix86_unary_operator_ok (NOT, QImode, operands)"
5760   "#"
5761   [(set_attr "type" "alu1")])
5762
5763 (define_split
5764   [(set (reg 17)
5765         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
5766                  (const_int 0)))
5767    (set (match_operand:QI 0 "nonimmediate_operand" "")
5768         (not:QI (match_dup 1)))]
5769   "ix86_match_ccmode (insn, CCNOmode)"
5770   [(parallel [(set (reg:CCNO 17)
5771                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
5772                                  (const_int 0)))
5773               (set (match_dup 0)
5774                    (xor:QI (match_dup 1) (const_int -1)))])]
5775   "")
5776 \f
5777 ;; Arithmetic shift instructions
5778
5779 ;; DImode shifts are implemented using the i386 "shift double" opcode,
5780 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
5781 ;; is variable, then the count is in %cl and the "imm" operand is dropped
5782 ;; from the assembler input.
5783 ;;
5784 ;; This instruction shifts the target reg/mem as usual, but instead of
5785 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
5786 ;; is a left shift double, bits are taken from the high order bits of
5787 ;; reg, else if the insn is a shift right double, bits are taken from the
5788 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
5789 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
5790 ;;
5791 ;; Since sh[lr]d does not change the `reg' operand, that is done
5792 ;; separately, making all shifts emit pairs of shift double and normal
5793 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
5794 ;; support a 63 bit shift, each shift where the count is in a reg expands
5795 ;; to a pair of shifts, a branch, a shift by 32 and a label.
5796 ;;
5797 ;; If the shift count is a constant, we need never emit more than one
5798 ;; shift pair, instead using moves and sign extension for counts greater
5799 ;; than 31.
5800
5801 (define_expand "ashldi3"
5802   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
5803                    (ashift:DI (match_operand:DI 1 "register_operand" "0")
5804                               (match_operand:QI 2 "nonmemory_operand" "Jc")))
5805               (clobber (reg:CC 17))])]
5806   ""
5807   "
5808 {
5809   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
5810     {
5811       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
5812       DONE;
5813     }
5814 }")
5815
5816 (define_insn "ashldi3_1"
5817   [(set (match_operand:DI 0 "register_operand" "=r")
5818         (ashift:DI (match_operand:DI 1 "register_operand" "0")
5819                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
5820    (clobber (match_scratch:SI 3 "=&r"))
5821    (clobber (reg:CC 17))]
5822   "TARGET_CMOVE"
5823   "#"
5824   [(set_attr "type" "multi")])
5825
5826 (define_insn "*ashldi3_2"
5827   [(set (match_operand:DI 0 "register_operand" "=r")
5828         (ashift:DI (match_operand:DI 1 "register_operand" "0")
5829                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
5830    (clobber (reg:CC 17))]
5831   ""
5832   "#"
5833   [(set_attr "type" "multi")])
5834
5835 (define_split
5836   [(set (match_operand:DI 0 "register_operand" "")
5837         (ashift:DI (match_operand:DI 1 "register_operand" "")
5838                    (match_operand:QI 2 "nonmemory_operand" "")))
5839    (clobber (match_scratch:SI 3 ""))
5840    (clobber (reg:CC 17))]
5841   "TARGET_CMOVE && reload_completed"
5842   [(const_int 0)]
5843   "ix86_split_ashldi (operands, operands[3]); DONE;")
5844
5845 (define_split
5846   [(set (match_operand:DI 0 "register_operand" "")
5847         (ashift:DI (match_operand:DI 1 "register_operand" "")
5848                    (match_operand:QI 2 "nonmemory_operand" "")))
5849    (clobber (reg:CC 17))]
5850   "reload_completed"
5851   [(const_int 0)]
5852   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
5853
5854 (define_insn "x86_shld_1"
5855   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
5856         (ior:SI (ashift:SI (match_dup 0)
5857                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
5858                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
5859                   (minus:QI (const_int 32) (match_dup 2)))))
5860    (clobber (reg:CC 17))]
5861   ""
5862   "@
5863    shld{l}\\t{%2, %1, %0|%0, %1, %2}
5864    shld{l}\\t{%s2%1, %0|%0, %1, %2}"
5865   [(set_attr "type" "ishift")
5866    (set_attr "length_opcode" "3")
5867    (set_attr "pent_pair" "np")
5868    (set_attr "athlon_decode" "vector")
5869    (set_attr "ppro_uops" "few")])
5870
5871 (define_expand "x86_shift_adj_1"
5872   [(set (reg:CCZ 17)
5873         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
5874                              (const_int 32))
5875                      (const_int 0)))
5876    (set (match_operand:SI 0 "register_operand" "")
5877         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
5878                          (match_operand:SI 1 "register_operand" "")
5879                          (match_dup 0)))
5880    (set (match_dup 1)
5881         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
5882                          (match_operand:SI 3 "register_operand" "r")
5883                          (match_dup 1)))]
5884   "TARGET_CMOVE"
5885   "")
5886
5887 (define_expand "x86_shift_adj_2"
5888   [(use (match_operand:SI 0 "register_operand" ""))
5889    (use (match_operand:SI 1 "register_operand" ""))
5890    (use (match_operand:QI 2 "register_operand" ""))]
5891   ""
5892   "
5893 {
5894   rtx label = gen_label_rtx ();
5895   rtx tmp;
5896
5897   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
5898
5899   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
5900   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
5901   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5902                               gen_rtx_LABEL_REF (VOIDmode, label),
5903                               pc_rtx);
5904   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
5905   JUMP_LABEL (tmp) = label;
5906
5907   emit_move_insn (operands[0], operands[1]);
5908   emit_move_insn (operands[1], const0_rtx);
5909
5910   emit_label (label);
5911   LABEL_NUSES (label) = 1;
5912
5913   DONE;
5914 }")
5915
5916 (define_expand "ashlsi3"
5917   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5918         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
5919                    (match_operand:QI 2 "nonmemory_operand" "")))
5920    (clobber (reg:CC 17))]
5921   ""
5922   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
5923
5924 (define_insn "*ashlsi3_1"
5925   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5926         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
5927                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
5928    (clobber (reg:CC 17))]
5929   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
5930   "*
5931 {
5932   switch (get_attr_type (insn))
5933     {
5934     case TYPE_ALU:
5935       if (operands[2] != const1_rtx)
5936         abort ();
5937       if (!rtx_equal_p (operands[0], operands[1]))
5938         abort ();
5939       return \"add{l}\\t{%0, %0|%0, %0}\";
5940
5941     case TYPE_LEA:
5942       if (GET_CODE (operands[2]) != CONST_INT
5943           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
5944         abort ();
5945       operands[1] = gen_rtx_MULT (SImode, operands[1],
5946                                   GEN_INT (1 << INTVAL (operands[2])));
5947       return \"lea{l}\\t{%a1, %0|%0, %a1}\";
5948
5949     default:
5950       if (REG_P (operands[2]))
5951         return \"sal{l}\\t{%b2, %0|%0, %b2}\";
5952       else
5953         return \"sal{l}\\t{%2, %0|%0, %2}\";
5954     }
5955 }"
5956   [(set (attr "type")
5957      (cond [(eq_attr "alternative" "1")
5958               (const_string "lea")
5959             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
5960                           (const_int 0))
5961                       (match_operand 0 "register_operand" ""))
5962                  (match_operand 2 "const1_operand" ""))
5963               (const_string "alu")
5964            ]
5965            (const_string "ishift")))])
5966
5967 ;; Convert lea to the lea pattern to avoid flags dependency.
5968 (define_split
5969   [(set (match_operand:SI 0 "register_operand" "")
5970         (ashift:SI (match_operand:SI 1 "register_operand" "")
5971                    (match_operand:QI 2 "immediate_operand" "")))
5972    (clobber (reg:CC 17))]
5973   "reload_completed
5974    && true_regnum (operands[0]) != true_regnum (operands[1])"
5975   [(set (match_dup 0)
5976         (mult:SI (match_dup 1)
5977                  (match_dup 2)))]
5978   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));")
5979
5980 ;; This pattern can't accept a variable shift count, since shifts by
5981 ;; zero don't affect the flags.  We assume that shifts by constant
5982 ;; zero are optimized away.
5983 (define_insn "*ashlsi3_cmpno"
5984   [(set (reg 17)
5985         (compare
5986           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5987                      (match_operand:QI 2 "immediate_operand" "I"))
5988           (const_int 0)))
5989    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5990         (ashift:SI (match_dup 1) (match_dup 2)))]
5991   "ix86_match_ccmode (insn, CCNOmode)
5992    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
5993   "*
5994 {
5995   switch (get_attr_type (insn))
5996     {
5997     case TYPE_ALU:
5998       if (operands[2] != const1_rtx)
5999         abort ();
6000       return \"add{l}\\t{%0, %0|%0, %0}\";
6001
6002     default:
6003       if (REG_P (operands[2]))
6004         return \"sal{l}\\t{%b2, %0|%0, %b2}\";
6005       else
6006         return \"sal{l}\\t{%2, %0|%0, %2}\";
6007     }
6008 }"
6009   [(set (attr "type")
6010      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6011                           (const_int 0))
6012                       (match_operand 0 "register_operand" ""))
6013                  (match_operand 2 "const1_operand" ""))
6014               (const_string "alu")
6015            ]
6016            (const_string "ishift")))])
6017
6018 (define_expand "ashlhi3"
6019   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6020         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
6021                    (match_operand:QI 2 "nonmemory_operand" "")))
6022    (clobber (reg:CC 17))]
6023   "TARGET_HIMODE_MATH"
6024   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
6025
6026 (define_insn "*ashlhi3_1"
6027   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6028         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6029                    (match_operand:QI 2 "nonmemory_operand" "cI")))
6030    (clobber (reg:CC 17))]
6031   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
6032   "*
6033 {
6034   switch (get_attr_type (insn))
6035     {
6036     case TYPE_ALU:
6037       if (operands[2] != const1_rtx)
6038         abort ();
6039       return \"add{w}\\t{%0, %0|%0, %0}\";
6040
6041     default:
6042       if (REG_P (operands[2]))
6043         return \"sal{w}\\t{%b2, %0|%0, %b2}\";
6044       else
6045         return \"sal{w}\\t{%2, %0|%0, %2}\";
6046     }
6047 }"
6048   [(set (attr "type")
6049      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6050                           (const_int 0))
6051                       (match_operand 0 "register_operand" ""))
6052                  (match_operand 2 "const1_operand" ""))
6053               (const_string "alu")
6054            ]
6055            (const_string "ishift")))])
6056
6057 ;; This pattern can't accept a variable shift count, since shifts by
6058 ;; zero don't affect the flags.  We assume that shifts by constant
6059 ;; zero are optimized away.
6060 (define_insn "*ashlhi3_cmpno"
6061   [(set (reg 17)
6062         (compare
6063           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6064                      (match_operand:QI 2 "immediate_operand" "I"))
6065           (const_int 0)))
6066    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6067         (ashift:HI (match_dup 1) (match_dup 2)))]
6068   "ix86_match_ccmode (insn, CCNOmode)
6069    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
6070   "*
6071 {
6072   switch (get_attr_type (insn))
6073     {
6074     case TYPE_ALU:
6075       if (operands[2] != const1_rtx)
6076         abort ();
6077       return \"add{w}\\t{%0, %0|%0, %0}\";
6078
6079     default:
6080       if (REG_P (operands[2]))
6081         return \"sal{w}\\t{%b2, %0|%0, %b2}\";
6082       else
6083         return \"sal{w}\\t{%2, %0|%0, %2}\";
6084     }
6085 }"
6086   [(set (attr "type")
6087      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6088                           (const_int 0))
6089                       (match_operand 0 "register_operand" ""))
6090                  (match_operand 2 "const1_operand" ""))
6091               (const_string "alu")
6092            ]
6093            (const_string "ishift")))])
6094
6095 (define_expand "ashlqi3"
6096   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6097         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
6098                    (match_operand:QI 2 "nonmemory_operand" "")))
6099    (clobber (reg:CC 17))]
6100   "TARGET_QIMODE_MATH"
6101   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
6102
6103 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6104 (define_insn "*ashlqi3_1"
6105   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
6106         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6107                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
6108    (clobber (reg:CC 17))]
6109   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
6110   "*
6111 {
6112   switch (get_attr_type (insn))
6113     {
6114     case TYPE_ALU:
6115       if (operands[2] != const1_rtx)
6116         abort ();
6117       if (NON_QI_REG_P (operands[1]))
6118         return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
6119       else
6120         return \"add{b}\\t{%0, %0|%0, %0}\";
6121
6122     default:
6123       if (REG_P (operands[2]))
6124         {
6125           if (NON_QI_REG_P (operands[1]))
6126             return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
6127           else
6128             return \"sal{b}\\t{%b2, %0|%0, %b2}\";
6129         }
6130       else
6131         {
6132           if (NON_QI_REG_P (operands[1]))
6133             return \"sal{l}\\t{%2, %k0|%k0, %2}\";
6134           else
6135             return \"sal{b}\\t{%2, %0|%0, %2}\";
6136         }
6137     }
6138 }"
6139   [(set (attr "type")
6140      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6141                           (const_int 0))
6142                       (match_operand 0 "register_operand" ""))
6143                  (match_operand 2 "const1_operand" ""))
6144               (const_string "alu")
6145            ]
6146            (const_string "ishift")))])
6147
6148 ;; This pattern can't accept a variable shift count, since shifts by
6149 ;; zero don't affect the flags.  We assume that shifts by constant
6150 ;; zero are optimized away.
6151 (define_insn "*ashlqi3_cmpno"
6152   [(set (reg 17)
6153         (compare
6154           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6155                      (match_operand:QI 2 "immediate_operand" "I"))
6156           (const_int 0)))
6157    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6158         (ashift:QI (match_dup 1) (match_dup 2)))]
6159   "ix86_match_ccmode (insn, CCNOmode)
6160    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
6161   "*
6162 {
6163   switch (get_attr_type (insn))
6164     {
6165     case TYPE_ALU:
6166       if (operands[2] != const1_rtx)
6167         abort ();
6168       return \"add{b}\\t{%0, %0|%0, %0}\";
6169
6170     default:
6171       if (REG_P (operands[2]))
6172         return \"sal{b}\\t{%b2, %0|%0, %b2}\";
6173       else
6174         return \"sal{b}\\t{%2, %0|%0, %2}\";
6175     }
6176 }"
6177   [(set (attr "type")
6178      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6179                           (const_int 0))
6180                       (match_operand 0 "register_operand" ""))
6181                  (match_operand 2 "const1_operand" ""))
6182               (const_string "alu")
6183            ]
6184            (const_string "ishift")))])
6185
6186 ;; See comment above `ashldi3' about how this works.
6187
6188 (define_expand "ashrdi3"
6189   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6190                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6191                                 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6192               (clobber (reg:CC 17))])]
6193   ""
6194   "
6195 {
6196   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6197     {
6198       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
6199       DONE;
6200     }
6201 }")
6202
6203 (define_insn "ashrdi3_1"
6204   [(set (match_operand:DI 0 "register_operand" "=r")
6205         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6206                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
6207    (clobber (match_scratch:SI 3 "=&r"))
6208    (clobber (reg:CC 17))]
6209   "TARGET_CMOVE"
6210   "#"
6211   [(set_attr "type" "multi")])
6212
6213 (define_insn "*ashrdi3_2"
6214   [(set (match_operand:DI 0 "register_operand" "=r")
6215         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6216                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
6217    (clobber (reg:CC 17))]
6218   ""
6219   "#"
6220   [(set_attr "type" "multi")])
6221
6222 (define_split
6223   [(set (match_operand:DI 0 "register_operand" "")
6224         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6225                      (match_operand:QI 2 "nonmemory_operand" "")))
6226    (clobber (match_scratch:SI 3 ""))
6227    (clobber (reg:CC 17))]
6228   "TARGET_CMOVE && reload_completed"
6229   [(const_int 0)]
6230   "ix86_split_ashrdi (operands, operands[3]); DONE;")
6231
6232 (define_split
6233   [(set (match_operand:DI 0 "register_operand" "")
6234         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6235                      (match_operand:QI 2 "nonmemory_operand" "")))
6236    (clobber (reg:CC 17))]
6237   "reload_completed"
6238   [(const_int 0)]
6239   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
6240
6241 (define_insn "x86_shrd_1"
6242   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
6243         (ior:SI (ashiftrt:SI (match_dup 0)
6244                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
6245                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
6246                   (minus:QI (const_int 32) (match_dup 2)))))
6247    (clobber (reg:CC 17))]
6248   ""
6249   "@
6250    shrd{l}\\t{%2, %1, %0|%0, %1, %2}
6251    shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
6252   [(set_attr "type" "ishift")
6253    (set_attr "length_opcode" "3")
6254    (set_attr "pent_pair" "np")
6255    (set_attr "ppro_uops" "few")])
6256
6257 (define_expand "x86_shift_adj_3"
6258   [(use (match_operand:SI 0 "register_operand" ""))
6259    (use (match_operand:SI 1 "register_operand" ""))
6260    (use (match_operand:QI 2 "register_operand" ""))]
6261   ""
6262   "
6263 {
6264   rtx label = gen_label_rtx ();
6265   rtx tmp;
6266
6267   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
6268
6269   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
6270   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6271   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
6272                               gen_rtx_LABEL_REF (VOIDmode, label),
6273                               pc_rtx);
6274   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
6275   JUMP_LABEL (tmp) = label;
6276
6277   emit_move_insn (operands[0], operands[1]);
6278   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
6279
6280   emit_label (label);
6281   LABEL_NUSES (label) = 1;
6282
6283   DONE;
6284 }")
6285
6286 (define_insn "ashrsi3_31"
6287   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
6288         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
6289                      (match_operand:SI 2 "const_int_operand" "i,i")))
6290    (clobber (reg:CC 17))]
6291   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
6292    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6293   "@
6294    {cltd|cdq}
6295    sar{l}\\t{%2, %0|%0, %2}"
6296    [(set_attr "type" "imovx,ishift")
6297     (set_attr "length" "1,*")])
6298
6299 (define_expand "ashrsi3"
6300   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6301         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
6302                      (match_operand:QI 2 "nonmemory_operand" "")))
6303    (clobber (reg:CC 17))]
6304   ""
6305   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
6306
6307 (define_insn "*ashrsi3_1"
6308   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6309         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6310                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6311    (clobber (reg:CC 17))]
6312   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6313   "@
6314    sar{l}\\t{%2, %0|%0, %2}
6315    sar{l}\\t{%b2, %0|%0, %b2}"
6316   [(set_attr "type" "ishift")])
6317
6318 ;; This pattern can't accept a variable shift count, since shifts by
6319 ;; zero don't affect the flags.  We assume that shifts by constant
6320 ;; zero are optimized away.
6321 (define_insn "*ashrsi3_cmpno"
6322   [(set (reg 17)
6323         (compare
6324           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6325                        (match_operand:QI 2 "immediate_operand" "I"))
6326           (const_int 0)))
6327    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6328         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
6329   "ix86_match_ccmode (insn, CCNOmode)
6330    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6331   "@
6332    sar{l}\\t{%2, %0|%0, %2}"
6333   [(set_attr "type" "ishift")])
6334
6335 (define_expand "ashrhi3"
6336   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6337         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
6338                      (match_operand:QI 2 "nonmemory_operand" "")))
6339    (clobber (reg:CC 17))]
6340   "TARGET_HIMODE_MATH"
6341   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
6342
6343 (define_insn "*ashrhi3_1"
6344   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6345         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6346                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6347    (clobber (reg:CC 17))]
6348   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6349   "@
6350    sar{w}\\t{%2, %0|%0, %2}
6351    sar{w}\\t{%b2, %0|%0, %b2}"
6352   [(set_attr "type" "ishift")])
6353
6354 ;; This pattern can't accept a variable shift count, since shifts by
6355 ;; zero don't affect the flags.  We assume that shifts by constant
6356 ;; zero are optimized away.
6357 (define_insn "*ashrhi3_cmpno"
6358   [(set (reg 17)
6359         (compare
6360           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6361                        (match_operand:QI 2 "immediate_operand" "I"))
6362           (const_int 0)))
6363    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6364         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
6365   "ix86_match_ccmode (insn, CCNOmode)
6366    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6367   "@
6368    sar{w}\\t{%2, %0|%0, %2}"
6369   [(set_attr "type" "ishift")])
6370
6371 (define_expand "ashrqi3"
6372   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6373         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
6374                      (match_operand:QI 2 "nonmemory_operand" "")))
6375    (clobber (reg:CC 17))]
6376   "TARGET_QIMODE_MATH"
6377   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
6378
6379 (define_insn "*ashrqi3_1"
6380   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6381         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6382                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6383    (clobber (reg:CC 17))]
6384   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6385   "@
6386    sar{b}\\t{%2, %0|%0, %2}
6387    sar{b}\\t{%b2, %0|%0, %b2}"
6388   [(set_attr "type" "ishift")])
6389
6390 ;; This pattern can't accept a variable shift count, since shifts by
6391 ;; zero don't affect the flags.  We assume that shifts by constant
6392 ;; zero are optimized away.
6393 (define_insn "*ashrqi3_cmpno"
6394   [(set (reg 17)
6395         (compare
6396           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6397                        (match_operand:QI 2 "immediate_operand" "I"))
6398           (const_int 0)))
6399    (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
6400         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
6401   "ix86_match_ccmode (insn, CCNOmode)
6402    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6403   "@
6404    sar{b}\\t{%2, %0|%0, %2}"
6405   [(set_attr "type" "ishift")])
6406 \f
6407 ;; Logical shift instructions
6408
6409 ;; See comment above `ashldi3' about how this works.
6410
6411 (define_expand "lshrdi3"
6412   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6413                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6414                                 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6415               (clobber (reg:CC 17))])]
6416   ""
6417   "
6418 {
6419   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6420     {
6421       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
6422       DONE;
6423     }
6424 }")
6425
6426 (define_insn "lshrdi3_1"
6427   [(set (match_operand:DI 0 "register_operand" "=r")
6428         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6429                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
6430    (clobber (match_scratch:SI 3 "=&r"))
6431    (clobber (reg:CC 17))]
6432   "TARGET_CMOVE"
6433   "#"
6434   [(set_attr "type" "multi")])
6435
6436 (define_insn "*lshrdi3_2"
6437   [(set (match_operand:DI 0 "register_operand" "=r")
6438         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6439                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
6440    (clobber (reg:CC 17))]
6441   ""
6442   "#"
6443   [(set_attr "type" "multi")])
6444
6445 (define_split 
6446   [(set (match_operand:DI 0 "register_operand" "")
6447         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6448                      (match_operand:QI 2 "nonmemory_operand" "")))
6449    (clobber (match_scratch:SI 3 ""))
6450    (clobber (reg:CC 17))]
6451   "TARGET_CMOVE && reload_completed"
6452   [(const_int 0)]
6453   "ix86_split_lshrdi (operands, operands[3]); DONE;")
6454
6455 (define_split 
6456   [(set (match_operand:DI 0 "register_operand" "")
6457         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6458                      (match_operand:QI 2 "nonmemory_operand" "")))
6459    (clobber (reg:CC 17))]
6460   "reload_completed"
6461   [(const_int 0)]
6462   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
6463
6464 (define_expand "lshrsi3"
6465   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6466         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
6467                      (match_operand:QI 2 "nonmemory_operand" "")))
6468    (clobber (reg:CC 17))]
6469   ""
6470   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
6471
6472 (define_insn "*lshrsi3_1"
6473   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6474         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6475                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6476    (clobber (reg:CC 17))]
6477   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6478   "@
6479    shr{l}\\t{%2, %0|%0, %2}
6480    shr{l}\\t{%b2, %0|%0, %b2}"
6481   [(set_attr "type" "ishift")])
6482
6483 ;; This pattern can't accept a variable shift count, since shifts by
6484 ;; zero don't affect the flags.  We assume that shifts by constant
6485 ;; zero are optimized away.
6486 (define_insn "*lshrsi3_cmpno"
6487   [(set (reg 17)
6488         (compare
6489           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6490                        (match_operand:QI 2 "immediate_operand" "I"))
6491           (const_int 0)))
6492    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6493         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
6494   "ix86_match_ccmode (insn, CCNOmode)
6495    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6496   "@
6497    shr{l}\\t{%2, %0|%0, %2}"
6498   [(set_attr "type" "ishift")])
6499
6500 (define_expand "lshrhi3"
6501   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6502         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
6503                      (match_operand:QI 2 "nonmemory_operand" "")))
6504    (clobber (reg:CC 17))]
6505   "TARGET_HIMODE_MATH"
6506   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
6507
6508 (define_insn "*lshrhi3_1"
6509   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6510         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6511                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6512    (clobber (reg:CC 17))]
6513   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6514   "@
6515    shr{w}\\t{%2, %0|%0, %2}
6516    shr{w}\\t{%b2, %0|%0, %b2}"
6517   [(set_attr "type" "ishift")])
6518
6519 ;; This pattern can't accept a variable shift count, since shifts by
6520 ;; zero don't affect the flags.  We assume that shifts by constant
6521 ;; zero are optimized away.
6522 (define_insn "*lshrhi3_cmpno"
6523   [(set (reg 17)
6524         (compare
6525           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6526                        (match_operand:QI 2 "immediate_operand" "I"))
6527           (const_int 0)))
6528    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6529         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
6530   "ix86_match_ccmode (insn, CCNOmode)
6531    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6532   "@
6533    shr{w}\\t{%2, %0|%0, %2}"
6534   [(set_attr "type" "ishift")])
6535
6536 (define_expand "lshrqi3"
6537   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6538         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
6539                      (match_operand:QI 2 "nonmemory_operand" "")))
6540    (clobber (reg:CC 17))]
6541   "TARGET_QIMODE_MATH"
6542   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
6543
6544 (define_insn "*lshrqi3_1"
6545   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6546         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6547                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6548    (clobber (reg:CC 17))]
6549   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
6550   "@
6551    shr{b}\\t{%2, %0|%0, %2}
6552    shr{b}\\t{%b2, %0|%0, %b2}"
6553   [(set_attr "type" "ishift")])
6554
6555 ;; This pattern can't accept a variable shift count, since shifts by
6556 ;; zero don't affect the flags.  We assume that shifts by constant
6557 ;; zero are optimized away.
6558 (define_insn "*lshrqi2_cmpno"
6559   [(set (reg 17)
6560         (compare
6561           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6562                        (match_operand:QI 2 "immediate_operand" "I"))
6563           (const_int 0)))
6564    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6565         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
6566   "ix86_match_ccmode (insn, CCNOmode)
6567    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
6568   "shr{b}\\t{%2, %0|%0, %2}"
6569   [(set_attr "type" "ishift")])
6570 \f
6571 ;; Rotate instructions
6572
6573 (define_expand "rotlsi3"
6574   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6575         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
6576                    (match_operand:QI 2 "nonmemory_operand" "")))
6577    (clobber (reg:CC 17))]
6578   ""
6579   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
6580
6581 (define_insn "*rotlsi3_1"
6582   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6583         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6584                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
6585    (clobber (reg:CC 17))]
6586   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
6587   "@
6588    rol{l}\\t{%2, %0|%0, %2}
6589    rol{l}\\t{%b2, %0|%0, %b2}"
6590   [(set_attr "type" "ishift")])
6591
6592 (define_expand "rotlhi3"
6593   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6594         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
6595                    (match_operand:QI 2 "nonmemory_operand" "")))
6596    (clobber (reg:CC 17))]
6597   "TARGET_HIMODE_MATH"
6598   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
6599
6600 (define_insn "*rotlhi3_1"
6601   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6602         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6603                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
6604    (clobber (reg:CC 17))]
6605   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
6606   "@
6607    rol{w}\\t{%2, %0|%0, %2}
6608    rol{w}\\t{%b2, %0|%0, %b2}"
6609   [(set_attr "type" "ishift")])
6610
6611 (define_expand "rotlqi3"
6612   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6613         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
6614                    (match_operand:QI 2 "nonmemory_operand" "")))
6615    (clobber (reg:CC 17))]
6616   "TARGET_QIMODE_MATH"
6617   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
6618
6619 (define_insn "*rotlqi3_1"
6620   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6621         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6622                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
6623    (clobber (reg:CC 17))]
6624   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
6625   "@
6626    rol{b}\\t{%2, %0|%0, %2}
6627    rol{b}\\t{%b2, %0|%0, %b2}"
6628   [(set_attr "type" "ishift")])
6629
6630 (define_expand "rotrsi3"
6631   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6632         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
6633                      (match_operand:QI 2 "nonmemory_operand" "")))
6634    (clobber (reg:CC 17))]
6635   ""
6636   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
6637
6638 (define_insn "*rotrsi3_1"
6639   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6640         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6641                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6642    (clobber (reg:CC 17))]
6643   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
6644   "@
6645    ror{l}\\t{%2, %0|%0, %2}
6646    ror{l}\\t{%b2, %0|%0, %b2}"
6647   [(set_attr "type" "ishift")])
6648
6649 (define_expand "rotrhi3"
6650   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6651         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
6652                      (match_operand:QI 2 "nonmemory_operand" "")))
6653    (clobber (reg:CC 17))]
6654   "TARGET_HIMODE_MATH"
6655   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
6656
6657 (define_insn "*rotrhi3"
6658   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6659         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6660                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6661    (clobber (reg:CC 17))]
6662   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
6663   "@
6664    ror{w}\\t{%2, %0|%0, %2}
6665    ror{w}\\t{%b2, %0|%0, %b2}"
6666   [(set_attr "type" "ishift")])
6667
6668 (define_expand "rotrqi3"
6669   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6670         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
6671                      (match_operand:QI 2 "nonmemory_operand" "")))
6672    (clobber (reg:CC 17))]
6673   "TARGET_QIMODE_MATH"
6674   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
6675
6676 (define_insn "*rotrqi3_1"
6677   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6678         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6679                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
6680    (clobber (reg:CC 17))]
6681   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
6682   "@
6683    ror{b}\\t{%2, %0|%0, %2}
6684    ror{b}\\t{%b2, %0|%0, %b2}"
6685   [(set_attr "type" "ishift")])
6686 \f
6687 ;; Bit set / bit test instructions
6688
6689 (define_expand "extv"
6690   [(set (match_operand:SI 0 "register_operand" "")
6691         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
6692                          (match_operand:SI 2 "immediate_operand" "")
6693                          (match_operand:SI 3 "immediate_operand" "")))]
6694   ""
6695   "
6696 {
6697   /* Handle extractions from %ah et al.  */
6698   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
6699     FAIL;
6700
6701   /* From mips.md: extract_bit_field doesn't verify that our source
6702      matches the predicate, so check it again here.  */
6703   if (! register_operand (operands[1], VOIDmode))
6704     FAIL;
6705 }")
6706
6707 (define_expand "extzv"
6708   [(set (match_operand:SI 0 "register_operand" "")
6709         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
6710                          (match_operand:SI 2 "immediate_operand" "")
6711                          (match_operand:SI 3 "immediate_operand" "")))]
6712   ""
6713   "
6714 {
6715   /* Handle extractions from %ah et al.  */
6716   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
6717     FAIL;
6718
6719   /* From mips.md: extract_bit_field doesn't verify that our source
6720      matches the predicate, so check it again here.  */
6721   if (! register_operand (operands[1], VOIDmode))
6722     FAIL;
6723 }")
6724
6725 (define_expand "insv"
6726   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
6727                          (match_operand:SI 1 "immediate_operand" "")
6728                          (match_operand:SI 2 "immediate_operand" ""))
6729         (match_operand:SI 3 "register_operand" ""))]
6730   ""
6731   "
6732 {
6733   /* Handle extractions from %ah et al.  */
6734   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
6735     FAIL;
6736
6737   /* From mips.md: insert_bit_field doesn't verify that our source
6738      matches the predicate, so check it again here.  */
6739   if (! register_operand (operands[0], VOIDmode))
6740     FAIL;
6741 }")
6742
6743 ;; %%% bts, btr, btc, bt.
6744 \f
6745 ;; Store-flag instructions.
6746
6747 ;; For all sCOND expanders, also expand the compare or test insn that
6748 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
6749
6750 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
6751 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
6752 ;; way, which can later delete the movzx if only QImode is needed.
6753
6754 (define_expand "seq"
6755   [(set (match_operand:SI 0 "register_operand" "")
6756         (eq:SI (reg:CC 17) (const_int 0)))]
6757   ""
6758   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
6759
6760 (define_expand "sne"
6761   [(set (match_operand:SI 0 "register_operand" "")
6762         (ne:SI (reg:CC 17) (const_int 0)))]
6763   ""
6764   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
6765
6766 (define_expand "sgt"
6767   [(set (match_operand:SI 0 "register_operand" "")
6768         (gt:SI (reg:CC 17) (const_int 0)))]
6769   ""
6770   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
6771
6772 (define_expand "sgtu"
6773   [(set (match_operand:SI 0 "register_operand" "")
6774         (gtu:SI (reg:CC 17) (const_int 0)))]
6775   ""
6776   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
6777
6778 (define_expand "slt"
6779   [(set (match_operand:SI 0 "register_operand" "")
6780         (lt:SI (reg:CC 17) (const_int 0)))]
6781   ""
6782   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
6783
6784 (define_expand "sltu"
6785   [(set (match_operand:SI 0 "register_operand" "")
6786         (ltu:SI (reg:CC 17) (const_int 0)))]
6787   ""
6788   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
6789
6790 (define_expand "sge"
6791   [(set (match_operand:SI 0 "register_operand" "")
6792         (ge:SI (reg:CC 17) (const_int 0)))]
6793   ""
6794   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
6795
6796 (define_expand "sgeu"
6797   [(set (match_operand:SI 0 "register_operand" "")
6798         (geu:SI (reg:CC 17) (const_int 0)))]
6799   ""
6800   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
6801
6802 (define_expand "sle"
6803   [(set (match_operand:SI 0 "register_operand" "")
6804         (le:SI (reg:CC 17) (const_int 0)))]
6805   ""
6806   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
6807
6808 (define_expand "sleu"
6809   [(set (match_operand:SI 0 "register_operand" "")
6810         (leu:SI (reg:CC 17) (const_int 0)))]
6811   ""
6812   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
6813
6814 (define_expand "sunordered"
6815   [(set (match_operand:SI 0 "register_operand" "")
6816         (unordered:SI (reg:CC 17) (const_int 0)))]
6817   "TARGET_80387"
6818   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
6819
6820 (define_expand "sordered"
6821   [(set (match_operand:SI 0 "register_operand" "")
6822         (ordered:SI (reg:CC 17) (const_int 0)))]
6823   "TARGET_80387"
6824   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
6825
6826 (define_expand "suneq"
6827   [(set (match_operand:SI 0 "register_operand" "")
6828         (uneq:SI (reg:CC 17) (const_int 0)))]
6829   "TARGET_80387"
6830   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
6831
6832 (define_expand "sunge"
6833   [(set (match_operand:SI 0 "register_operand" "")
6834         (unge:SI (reg:CC 17) (const_int 0)))]
6835   "TARGET_80387"
6836   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
6837
6838 (define_expand "sungt"
6839   [(set (match_operand:SI 0 "register_operand" "")
6840         (ungt:SI (reg:CC 17) (const_int 0)))]
6841   "TARGET_80387"
6842   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
6843
6844 (define_expand "sunle"
6845   [(set (match_operand:SI 0 "register_operand" "")
6846         (unle:SI (reg:CC 17) (const_int 0)))]
6847   "TARGET_80387"
6848   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
6849
6850 (define_expand "sunlt"
6851   [(set (match_operand:SI 0 "register_operand" "")
6852         (unlt:SI (reg:CC 17) (const_int 0)))]
6853   "TARGET_80387"
6854   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
6855
6856 (define_expand "sltgt"
6857   [(set (match_operand:SI 0 "register_operand" "")
6858         (ltgt:SI (reg:CC 17) (const_int 0)))]
6859   "TARGET_80387"
6860   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
6861
6862 (define_insn "*setcc_1"
6863   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6864         (match_operator:QI 1 "no_comparison_operator"
6865           [(reg 17) (const_int 0)]))]
6866   ""
6867   "set%C1\\t%0"
6868   [(set_attr "type" "setcc")])
6869
6870 (define_insn "*setcc_2"
6871   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
6872         (match_operator:QI 1 "no_comparison_operator"
6873           [(reg 17) (const_int 0)]))]
6874   ""
6875   "set%C1\\t%0"
6876   [(set_attr "type" "setcc")])
6877
6878 (define_insn "*setcc_3"
6879   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6880         (match_operator:QI 1 "uno_comparison_operator"
6881           [(reg:CC 17) (const_int 0)]))]
6882   ""
6883   "set%C1\\t%0"
6884   [(set_attr "type" "setcc")])
6885
6886 (define_insn "*setcc_4"
6887   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
6888         (match_operator:QI 1 "uno_comparison_operator"
6889           [(reg:CC 17) (const_int 0)]))]
6890   ""
6891   "set%C1\\t%0"
6892   [(set_attr "type" "setcc")])
6893 \f
6894 ;; Basic conditional jump instructions.
6895 ;; We ignore the overflow flag for signed branch instructions.
6896
6897 ;; For all bCOND expanders, also expand the compare or test insn that
6898 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
6899
6900 (define_expand "beq"
6901   [(set (pc)
6902         (if_then_else (match_dup 1)
6903                       (label_ref (match_operand 0 "" ""))
6904                       (pc)))]
6905   ""
6906   "ix86_expand_branch (EQ, operands[0]); DONE;")
6907
6908 (define_expand "bne"
6909   [(set (pc)
6910         (if_then_else (match_dup 1)
6911                       (label_ref (match_operand 0 "" ""))
6912                       (pc)))]
6913   ""
6914   "ix86_expand_branch (NE, operands[0]); DONE;")
6915
6916 (define_expand "bgt"
6917   [(set (pc)
6918         (if_then_else (match_dup 1)
6919                       (label_ref (match_operand 0 "" ""))
6920                       (pc)))]
6921   ""
6922   "ix86_expand_branch (GT, operands[0]); DONE;")
6923
6924 (define_expand "bgtu"
6925   [(set (pc)
6926         (if_then_else (match_dup 1)
6927                       (label_ref (match_operand 0 "" ""))
6928                       (pc)))]
6929   ""
6930   "ix86_expand_branch (GTU, operands[0]); DONE;")
6931
6932 (define_expand "blt"
6933   [(set (pc)
6934         (if_then_else (match_dup 1)
6935                       (label_ref (match_operand 0 "" ""))
6936                       (pc)))]
6937   ""
6938   "ix86_expand_branch (LT, operands[0]); DONE;")
6939
6940 (define_expand "bltu"
6941   [(set (pc)
6942         (if_then_else (match_dup 1)
6943                       (label_ref (match_operand 0 "" ""))
6944                       (pc)))]
6945   ""
6946   "ix86_expand_branch (LTU, operands[0]); DONE;")
6947
6948 (define_expand "bge"
6949   [(set (pc)
6950         (if_then_else (match_dup 1)
6951                       (label_ref (match_operand 0 "" ""))
6952                       (pc)))]
6953   ""
6954   "ix86_expand_branch (GE, operands[0]); DONE;")
6955
6956 (define_expand "bgeu"
6957   [(set (pc)
6958         (if_then_else (match_dup 1)
6959                       (label_ref (match_operand 0 "" ""))
6960                       (pc)))]
6961   ""
6962   "ix86_expand_branch (GEU, operands[0]); DONE;")
6963
6964 (define_expand "ble"
6965   [(set (pc)
6966         (if_then_else (match_dup 1)
6967                       (label_ref (match_operand 0 "" ""))
6968                       (pc)))]
6969   ""
6970   "ix86_expand_branch (LE, operands[0]); DONE;")
6971
6972 (define_expand "bleu"
6973   [(set (pc)
6974         (if_then_else (match_dup 1)
6975                       (label_ref (match_operand 0 "" ""))
6976                       (pc)))]
6977   ""
6978   "ix86_expand_branch (LEU, operands[0]); DONE;")
6979
6980 (define_expand "bunordered"
6981   [(set (pc)
6982         (if_then_else (match_dup 1)
6983                       (label_ref (match_operand 0 "" ""))
6984                       (pc)))]
6985   "TARGET_80387"
6986   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
6987
6988 (define_expand "bordered"
6989   [(set (pc)
6990         (if_then_else (match_dup 1)
6991                       (label_ref (match_operand 0 "" ""))
6992                       (pc)))]
6993   "TARGET_80387"
6994   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
6995
6996 (define_expand "buneq"
6997   [(set (pc)
6998         (if_then_else (match_dup 1)
6999                       (label_ref (match_operand 0 "" ""))
7000                       (pc)))]
7001   "TARGET_80387"
7002   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
7003
7004 (define_expand "bunge"
7005   [(set (pc)
7006         (if_then_else (match_dup 1)
7007                       (label_ref (match_operand 0 "" ""))
7008                       (pc)))]
7009   "TARGET_80387"
7010   "ix86_expand_branch (UNGE, operands[0]); DONE;")
7011
7012 (define_expand "bungt"
7013   [(set (pc)
7014         (if_then_else (match_dup 1)
7015                       (label_ref (match_operand 0 "" ""))
7016                       (pc)))]
7017   "TARGET_80387"
7018   "ix86_expand_branch (UNGT, operands[0]); DONE;")
7019
7020 (define_expand "bunle"
7021   [(set (pc)
7022         (if_then_else (match_dup 1)
7023                       (label_ref (match_operand 0 "" ""))
7024                       (pc)))]
7025   "TARGET_80387"
7026   "ix86_expand_branch (UNLE, operands[0]); DONE;")
7027
7028 (define_expand "bunlt"
7029   [(set (pc)
7030         (if_then_else (match_dup 1)
7031                       (label_ref (match_operand 0 "" ""))
7032                       (pc)))]
7033   "TARGET_80387"
7034   "ix86_expand_branch (UNLT, operands[0]); DONE;")
7035
7036 (define_expand "bltgt"
7037   [(set (pc)
7038         (if_then_else (match_dup 1)
7039                       (label_ref (match_operand 0 "" ""))
7040                       (pc)))]
7041   "TARGET_80387"
7042   "ix86_expand_branch (LTGT, operands[0]); DONE;")
7043
7044 (define_insn "*jcc_1"
7045   [(set (pc)
7046         (if_then_else (match_operator 0 "no_comparison_operator"
7047                                       [(reg 17) (const_int 0)])
7048                       (label_ref (match_operand 1 "" ""))
7049                       (pc)))]
7050   ""
7051   "j%C0\\t%l1"
7052   [(set_attr "type" "ibr")
7053    (set (attr "length")
7054         (if_then_else (and (ge (minus (match_dup 1) (pc))
7055                                (const_int -128))
7056                            (lt (minus (match_dup 1) (pc))
7057                                (const_int 124)))
7058           (const_int 2)
7059           (const_int 6)))])
7060
7061 (define_insn "*jcc_2"
7062   [(set (pc)
7063         (if_then_else (match_operator 0 "no_comparison_operator"
7064                                       [(reg 17) (const_int 0)])
7065                       (pc)
7066                       (label_ref (match_operand 1 "" ""))))]
7067   ""
7068   "j%c0\\t%l1"
7069   [(set_attr "type" "ibr")
7070    (set (attr "length")
7071         (if_then_else (and (ge (minus (match_dup 1) (pc))
7072                                (const_int -128))
7073                            (lt (minus (match_dup 1) (pc))
7074                                (const_int 124)))
7075           (const_int 2)
7076           (const_int 6)))])
7077
7078 (define_insn "*jcc_3"
7079   [(set (pc)
7080         (if_then_else (match_operator 0 "uno_comparison_operator"
7081                                       [(reg:CC 17) (const_int 0)])
7082                       (label_ref (match_operand 1 "" ""))
7083                       (pc)))]
7084   ""
7085   "j%C0\\t%l1"
7086   [(set_attr "type" "ibr")
7087    (set (attr "length")
7088         (if_then_else (and (ge (minus (match_dup 1) (pc))
7089                                (const_int -128))
7090                            (lt (minus (match_dup 1) (pc))
7091                                (const_int 124)))
7092           (const_int 2)
7093           (const_int 6)))])
7094
7095 (define_insn "*jcc_4"
7096   [(set (pc)
7097         (if_then_else (match_operator 0 "uno_comparison_operator"
7098                                       [(reg:CC 17) (const_int 0)])
7099                       (pc)
7100                       (label_ref (match_operand 1 "" ""))))]
7101   ""
7102   "j%c0\\t%l1"
7103   [(set_attr "type" "ibr")
7104    (set (attr "length")
7105         (if_then_else (and (ge (minus (match_dup 1) (pc))
7106                                (const_int -128))
7107                            (lt (minus (match_dup 1) (pc))
7108                                (const_int 124)))
7109           (const_int 2)
7110           (const_int 6)))])
7111
7112 ;; Define combination compare-and-branch fp compare instructions to use
7113 ;; during early optimization.  Splitting the operation apart early makes
7114 ;; for bad code when we want to reverse the operation.
7115
7116 (define_insn "*fp_jcc_1"
7117   [(set (pc)
7118         (if_then_else (match_operator 0 "comparison_operator"
7119                         [(match_operand 1 "register_operand" "f")
7120                          (match_operand 2 "register_operand" "f")])
7121           (label_ref (match_operand 3 "" ""))
7122           (pc)))
7123    (clobber (reg:CCFP 18))
7124    (clobber (reg:CCFP 17))]
7125   "TARGET_CMOVE && TARGET_80387
7126    && FLOAT_MODE_P (GET_MODE (operands[1]))
7127    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7128   "#")
7129
7130 (define_insn "*fp_jcc_2"
7131   [(set (pc)
7132         (if_then_else (match_operator 0 "comparison_operator"
7133                         [(match_operand 1 "register_operand" "f")
7134                          (match_operand 2 "register_operand" "f")])
7135           (pc)
7136           (label_ref (match_operand 3 "" ""))))
7137    (clobber (reg:CCFP 18))
7138    (clobber (reg:CCFP 17))]
7139   "TARGET_CMOVE && TARGET_80387
7140    && FLOAT_MODE_P (GET_MODE (operands[1]))
7141    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7142   "#")
7143
7144 (define_insn "*fp_jcc_3"
7145   [(set (pc)
7146         (if_then_else (match_operator:CCFP 0 "comparison_operator"
7147                         [(match_operand 1 "register_operand" "f")
7148                          (match_operand 2 "nonimmediate_operand" "fm")])
7149           (label_ref (match_operand 3 "" ""))
7150           (pc)))
7151    (clobber (reg:CCFP 18))
7152    (clobber (reg:CCFP 17))
7153    (clobber (match_scratch:HI 4 "=a"))]
7154   "TARGET_80387
7155    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
7156    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7157   "#")
7158
7159 (define_insn "*fp_jcc_4"
7160   [(set (pc)
7161         (if_then_else (match_operator:CCFP 0 "comparison_operator"
7162                         [(match_operand 1 "register_operand" "f")
7163                          (match_operand 2 "nonimmediate_operand" "fm")])
7164           (pc)
7165           (label_ref (match_operand 3 "" ""))))
7166    (clobber (reg:CCFP 18))
7167    (clobber (reg:CCFP 17))
7168    (clobber (match_scratch:HI 4 "=a"))]
7169   "TARGET_80387
7170    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
7171    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7172   "#")
7173
7174 (define_insn "*fp_jcc_5"
7175   [(set (pc)
7176         (if_then_else (match_operator 0 "comparison_operator"
7177                         [(match_operand 1 "register_operand" "f")
7178                          (match_operand 2 "register_operand" "f")])
7179           (label_ref (match_operand 3 "" ""))
7180           (pc)))
7181    (clobber (reg:CCFP 18))
7182    (clobber (reg:CCFP 17))
7183    (clobber (match_scratch:HI 4 "=a"))]
7184   "TARGET_80387
7185    && FLOAT_MODE_P (GET_MODE (operands[1]))
7186    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7187   "#")
7188
7189 (define_insn "*fp_jcc_6"
7190   [(set (pc)
7191         (if_then_else (match_operator 0 "comparison_operator"
7192                         [(match_operand 1 "register_operand" "f")
7193                          (match_operand 2 "register_operand" "f")])
7194           (pc)
7195           (label_ref (match_operand 3 "" ""))))
7196    (clobber (reg:CCFP 18))
7197    (clobber (reg:CCFP 17))
7198    (clobber (match_scratch:HI 4 "=a"))]
7199   "TARGET_80387
7200    && FLOAT_MODE_P (GET_MODE (operands[1]))
7201    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7202   "#")
7203
7204 (define_split
7205   [(set (pc)
7206         (if_then_else (match_operator 0 "comparison_operator"
7207                         [(match_operand 1 "register_operand" "")
7208                          (match_operand 2 "nonimmediate_operand" "")])
7209           (match_operand 3 "" "")
7210           (match_operand 4 "" "")))
7211    (clobber (reg:CCFP 18))
7212    (clobber (reg:CCFP 17))]
7213   "reload_completed"
7214   [(set (pc)
7215         (if_then_else (match_dup 5)
7216           (match_dup 3)
7217           (match_dup 4)))]
7218   "
7219 {
7220   operands[5] = ix86_expand_fp_compare (GET_CODE (operands[0]), operands[1],
7221                                         operands[2], NULL_RTX);
7222 }")
7223
7224 (define_split
7225   [(set (pc)
7226         (if_then_else (match_operator 0 "comparison_operator"
7227                         [(match_operand 1 "register_operand" "")
7228                          (match_operand 2 "nonimmediate_operand" "")])
7229           (match_operand 3 "" "")
7230           (match_operand 4 "" "")))
7231    (clobber (reg:CCFP 18))
7232    (clobber (reg:CCFP 17))
7233    (clobber (match_scratch:HI 5 "=a"))]
7234   "reload_completed"
7235   [(set (pc)
7236         (if_then_else (match_dup 6)
7237           (match_dup 3)
7238           (match_dup 4)))]
7239   "
7240 {
7241   operands[6] = ix86_expand_fp_compare (GET_CODE (operands[0]), operands[1],
7242                                         operands[2], operands[5]);
7243 }")
7244 \f
7245 ;; Unconditional and other jump instructions
7246
7247 (define_insn "jump"
7248   [(set (pc)
7249         (label_ref (match_operand 0 "" "")))]
7250   ""
7251   "jmp\\t%l0"
7252   [(set_attr "type" "ibr")
7253    (set (attr "length")
7254         (if_then_else (and (ge (minus (match_dup 0) (pc))
7255                                (const_int -128))
7256                            (lt (minus (match_dup 0) (pc))
7257                                (const_int 124)))
7258           (const_int 2)
7259           (const_int 5)))])
7260
7261 (define_insn "indirect_jump"
7262   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
7263   ""
7264   "jmp\\t%*%0"
7265   [(set_attr "type" "ibr")])
7266
7267 (define_insn "tablejump"
7268   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
7269    (use (label_ref (match_operand 1 "" "")))]
7270   "! flag_pic"
7271   "jmp\\t%*%0"
7272   [(set_attr "type" "ibr")])
7273
7274 ;; Implement switch statements when generating PIC code.  Switches are
7275 ;; implemented by `tablejump' when not using -fpic.
7276 ;;
7277 ;; Emit code here to do the range checking and make the index zero based.
7278 ;;
7279 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
7280 ;; two rules below:
7281 ;; 
7282 ;;      .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
7283 ;; 
7284 ;; 1. An expression involving an external reference may only use the
7285 ;;    addition operator, and only with an assembly-time constant.
7286 ;;    The example above satisfies this because ".-.L2" is a constant.
7287 ;; 
7288 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
7289 ;;    given the value of "GOT - .", where GOT is the actual address of
7290 ;;    the Global Offset Table.  Therefore, the .long above actually
7291 ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
7292 ;;    expression "GOT - .L2" by itself would generate an error from as(1).
7293 ;; 
7294 ;; The pattern below emits code that looks like this:
7295 ;; 
7296 ;;      movl %ebx,reg
7297 ;;      subl TABLE@GOTOFF(%ebx,index,4),reg
7298 ;;      jmp reg
7299 ;; 
7300 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
7301 ;; the addr_diff_vec is known to be part of this module.
7302 ;; 
7303 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
7304 ;; evaluates to just ".L2".
7305
7306 (define_expand "casesi"
7307   [(set (match_dup 5)
7308         (match_operand:SI 0 "general_operand" ""))
7309    (parallel [(set (match_dup 6)
7310                    (minus:SI (match_dup 5)
7311                              (match_operand:SI 1 "general_operand" "")))
7312               (clobber (reg:CC 17))])
7313    (set (reg:CC 17)
7314         (compare:CC (match_dup 6)
7315                     (match_operand:SI 2 "general_operand" "")))
7316    (set (pc)
7317         (if_then_else (gtu (reg:CC 17)
7318                            (const_int 0))
7319                       (label_ref (match_operand 4 "" ""))
7320                       (pc)))
7321    (parallel
7322      [(set (match_dup 7)
7323            (minus:SI (match_dup 8)
7324              (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
7325                               (match_dup 8))
7326                      (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
7327       (clobber (reg:CC 17))])
7328    (parallel [(set (pc) (match_dup 7))
7329               (use (label_ref (match_dup 3)))])]
7330   "flag_pic"
7331   "
7332 {
7333   operands[5] = gen_reg_rtx (SImode);
7334   operands[6] = gen_reg_rtx (SImode);
7335   operands[7] = gen_reg_rtx (SImode);
7336   operands[8] = pic_offset_table_rtx;
7337   current_function_uses_pic_offset_table = 1;
7338 }")
7339
7340 (define_insn "*tablejump_pic"
7341   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
7342    (use (label_ref (match_operand 1 "" "")))]
7343   ""
7344   "jmp\\t%*%0"
7345   [(set_attr "type" "ibr")])
7346 \f
7347 ;; Loop instruction
7348 ;;
7349 ;; This is all complicated by the fact that since this is a jump insn
7350 ;; we must handle our own reloads.
7351
7352 (define_expand "decrement_and_branch_on_count"
7353   [(parallel [(set (pc) (if_then_else
7354                           (ne (match_operand:SI 0 "register_operand" "")
7355                               (const_int 1))
7356                           (label_ref (match_operand 1 "" ""))
7357                           (pc)))
7358               (set (match_dup 0)
7359                    (plus:SI (match_dup 0)
7360                             (const_int -1)))
7361               (clobber (match_scratch:SI 2 ""))
7362               (clobber (reg:CC 17))])]
7363   "TARGET_USE_LOOP"
7364   "")
7365
7366 (define_insn "*dbra_ne"
7367   [(set (pc)
7368         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
7369                           (const_int 1))
7370                       (label_ref (match_operand 0 "" ""))
7371                       (pc)))
7372    (set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
7373         (plus:SI (match_dup 1)
7374                  (const_int -1)))
7375    (clobber (match_scratch:SI 3 "=X,X,r"))
7376    (clobber (reg:CC 17))]
7377   "TARGET_USE_LOOP"
7378   "*
7379 {
7380   if (which_alternative != 0)
7381     return \"#\";
7382   if (get_attr_length (insn) == 2)
7383     return \"loop\\t%l0\";
7384   else
7385     return \"dec{l}\\t%1\;jne\\t%l0\";
7386 }"
7387   [(set_attr "type" "ibr")
7388    (set_attr "ppro_uops" "many")
7389    (set (attr "length")
7390         (if_then_else (and (eq_attr "alternative" "0")
7391                            (and (ge (minus (match_dup 0) (pc))
7392                                     (const_int -128))
7393                                 (lt (minus (match_dup 0) (pc))
7394                                     (const_int 124))))
7395                       (const_int 2)
7396                       (const_int 16)))])
7397
7398 (define_insn "*dbra_ge"
7399   [(set (pc)
7400         (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
7401                           (const_int 0))
7402                       (label_ref (match_operand 0 "" ""))
7403                       (pc)))
7404    (set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
7405         (plus:SI (match_dup 1)
7406                  (const_int -1)))
7407    (clobber (match_scratch:SI 3 "=X,X,r"))
7408    (clobber (reg:CC 17))]
7409   "TARGET_USE_LOOP && find_reg_note (insn, REG_NONNEG, 0)"
7410   "*
7411 {
7412   if (which_alternative != 0)
7413     return \"#\";
7414   if (get_attr_length (insn) == 2)
7415     return \"loop\\t%l0\";
7416   else
7417     return \"dec{l}\\t%1\;jne\\t%l0\";
7418 }"
7419   [(set_attr "type" "ibr")
7420    (set_attr "ppro_uops" "many")
7421    (set (attr "length")
7422         (if_then_else (and (eq_attr "alternative" "0")
7423                            (and (ge (minus (match_dup 0) (pc))
7424                                     (const_int -128))
7425                                 (lt (minus (match_dup 0) (pc))
7426                                     (const_int 124))))
7427                       (const_int 2)
7428                       (const_int 16)))])
7429
7430 (define_split
7431   [(set (pc)
7432         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
7433                           (const_int 1))
7434                       (match_operand 0 "" "")
7435                       (pc)))
7436    (set (match_operand:SI 2 "register_operand" "")
7437         (plus:SI (match_dup 1)
7438                  (const_int -1)))
7439    (clobber (match_scratch:SI 3 ""))
7440    (clobber (reg:CC 17))]
7441   "TARGET_USE_LOOP && reload_completed
7442    && ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
7443   [(set (match_dup 2) (match_dup 1))
7444    (parallel [(set (reg:CCZ 17)
7445                    (compare:CCZ (plus:SI (match_dup 2) (const_int -1))
7446                                  (const_int 0)))
7447               (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
7448    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
7449                            (match_dup 0)
7450                            (pc)))]
7451   "")
7452   
7453 (define_split
7454   [(set (pc)
7455         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
7456                           (const_int 1))
7457                       (match_operand 0 "" "")
7458                       (pc)))
7459    (set (match_operand:SI 2 "memory_operand" "")
7460         (plus:SI (match_dup 1)
7461                  (const_int -1)))
7462    (clobber (match_scratch:SI 3 ""))
7463    (clobber (reg:CC 17))]
7464   "TARGET_USE_LOOP && reload_completed"
7465   [(set (match_dup 3) (match_dup 1))
7466    (parallel [(set (reg:CCZ 17)
7467                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
7468                                 (const_int 0)))
7469               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
7470    (set (match_dup 2) (match_dup 3))
7471    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
7472                            (match_dup 0)
7473                            (pc)))]
7474   "")
7475
7476 (define_split
7477   [(set (pc)
7478         (if_then_else (ge (match_operand:SI 1 "register_operand" "")
7479                           (const_int 0))
7480                       (match_operand 0 "" "")
7481                       (pc)))
7482    (set (match_operand:SI 2 "register_operand" "")
7483         (plus:SI (match_dup 1)
7484                  (const_int -1)))
7485    (clobber (match_scratch:SI 3 ""))
7486    (clobber (reg:CC 17))]
7487   "TARGET_USE_LOOP && reload_completed
7488    && ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
7489   [(set (match_dup 2) (match_dup 1))
7490    (parallel [(set (reg:CCNO 17)
7491                    (compare:CCNO (plus:SI (match_dup 2) (const_int -1))
7492                                  (const_int 0)))
7493               (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
7494    (set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
7495                            (match_dup 0)
7496                            (pc)))]
7497   "")
7498   
7499 (define_split
7500   [(set (pc)
7501         (if_then_else (ge (match_operand:SI 1 "register_operand" "")
7502                           (const_int 0))
7503                       (match_operand 0 "" "")
7504                       (pc)))
7505    (set (match_operand:SI 2 "memory_operand" "")
7506         (plus:SI (match_dup 1)
7507                  (const_int -1)))
7508    (clobber (match_scratch:SI 3 ""))
7509    (clobber (reg:CC 17))]
7510   "TARGET_USE_LOOP && reload_completed"
7511   [(set (match_dup 3) (match_dup 1))
7512    (parallel [(set (reg:CCNO 17)
7513                    (compare:CCNO (plus:SI (match_dup 3) (const_int -1))
7514                                  (const_int 0)))
7515               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
7516    (set (match_dup 2) (match_dup 3))
7517    (set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
7518                            (match_dup 0)
7519                            (pc)))]
7520   "")
7521 \f
7522 ;; Call instructions.
7523
7524 ;; The predicates normally associated with named expanders are not properly
7525 ;; checked for calls.  This is a bug in the generic code, but it isn't that
7526 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
7527
7528 ;; Call subroutine returning no value.
7529
7530 (define_expand "call_pop"
7531   [(parallel [(call (match_operand:QI 0 "" "")
7532                     (match_operand:SI 1 "" ""))
7533               (set (reg:SI 7)
7534                    (plus:SI (reg:SI 7)
7535                             (match_operand:SI 3 "" "")))])]
7536   ""
7537   "
7538 {
7539   if (operands[3] == const0_rtx)
7540     {
7541       emit_insn (gen_call (operands[0], operands[1]));
7542       DONE;
7543     }
7544
7545   /* ??? Not true for calls to static functions.  */
7546   if (flag_pic)
7547     current_function_uses_pic_offset_table = 1;
7548
7549   if (! call_insn_operand (operands[0], QImode))
7550     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7551 }")
7552
7553 (define_insn "*call_pop_0"
7554   [(call (match_operand:QI 0 "constant_call_address_operand" "")
7555          (match_operand:SI 1 "" ""))
7556    (set (reg:SI 7) (plus:SI (reg:SI 7)
7557                             (match_operand:SI 3 "immediate_operand" "")))]
7558   ""
7559   "*
7560 {
7561   if (SIBLING_CALL_P (insn))
7562     return \"jmp\\t%P0\";
7563   else
7564     return \"call\\t%P0\";
7565 }"
7566   [(set_attr "type" "call")])
7567   
7568 (define_insn "*call_pop_1"
7569   [(call (match_operand:QI 0 "call_insn_operand" "m")
7570          (match_operand:SI 1 "" ""))
7571    (set (reg:SI 7) (plus:SI (reg:SI 7)
7572                             (match_operand:SI 3 "immediate_operand" "i")))]
7573   ""
7574   "*
7575 {
7576   if (constant_call_address_operand (operands[0], QImode))
7577     {
7578       if (SIBLING_CALL_P (insn))
7579         return \"jmp\\t%P0\";
7580       else
7581         return \"call\\t%P0\";
7582     }
7583   operands[0] = XEXP (operands[0], 0);
7584   if (SIBLING_CALL_P (insn))
7585     return \"jmp\\t%*%0\";
7586   else
7587     return \"call\\t%*%0\";
7588 }"
7589   [(set_attr "type" "call")])
7590
7591 (define_expand "call"
7592   [(call (match_operand:QI 0 "" "")
7593          (match_operand:SI 1 "" ""))]
7594   ;; Operand 1 not used on the i386.
7595   ""
7596   "
7597 {
7598   /* ??? Not true for calls to static functions.  */
7599   if (flag_pic)
7600     current_function_uses_pic_offset_table = 1;
7601
7602   if (! call_insn_operand (operands[0], QImode))
7603     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7604 }")
7605
7606 (define_insn "*call_0"
7607   [(call (match_operand:QI 0 "constant_call_address_operand" "")
7608          (match_operand:SI 1 "" ""))]
7609   ""
7610   "*
7611 {
7612   if (SIBLING_CALL_P (insn))
7613     return \"jmp\\t%P0\";
7614   else
7615     return \"call\\t%P0\";
7616 }"
7617   [(set_attr "type" "call")])
7618
7619 (define_insn "*call_1"
7620   [(call (match_operand:QI 0 "call_insn_operand" "m")
7621          (match_operand:SI 1 "" ""))]
7622   ""
7623   "*
7624 {
7625   if (constant_call_address_operand (operands[0], QImode))
7626     {
7627       if (SIBLING_CALL_P (insn))
7628         return \"jmp\\t%P0\";
7629       else
7630         return \"call\\t%P0\";
7631     }
7632   operands[0] = XEXP (operands[0], 0);
7633   if (SIBLING_CALL_P (insn))
7634     return \"jmp\\t%*%0\";
7635   else
7636     return \"call\\t%*%0\";
7637 }"
7638   [(set_attr "type" "call")])
7639
7640 ;; Call subroutine, returning value in operand 0
7641 ;; (which must be a hard register).
7642
7643 (define_expand "call_value_pop"
7644   [(parallel [(set (match_operand 0 "" "")
7645                    (call (match_operand:QI 1 "" "")
7646                          (match_operand:SI 2 "" "")))
7647               (set (reg:SI 7)
7648                    (plus:SI (reg:SI 7)
7649                             (match_operand:SI 4 "" "")))])]
7650   ""
7651   "
7652 {
7653   if (operands[4] == const0_rtx)
7654     {
7655       emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
7656       DONE;
7657     }
7658
7659   /* ??? Not true for calls to static functions.  */
7660   if (flag_pic)
7661     current_function_uses_pic_offset_table = 1;
7662
7663   if (! call_insn_operand (operands[1], QImode))
7664     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7665 }")
7666
7667 (define_expand "call_value"
7668   [(set (match_operand 0 "" "")
7669         (call (match_operand:QI 1 "" "")
7670               (match_operand:SI 2 "" "")))]
7671   ;; Operand 2 not used on the i386.
7672   ""
7673   "
7674 {
7675   /* ??? Not true for calls to static functions.  */
7676   if (flag_pic)
7677     current_function_uses_pic_offset_table = 1;
7678
7679   if (! call_insn_operand (operands[1], QImode))
7680     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7681 }")
7682
7683 ;; Call subroutine returning any type.
7684
7685 (define_expand "untyped_call"
7686   [(parallel [(call (match_operand 0 "" "")
7687                     (const_int 0))
7688               (match_operand 1 "" "")
7689               (match_operand 2 "" "")])]
7690   ""
7691   "
7692 {
7693   int i;
7694
7695   /* In order to give reg-stack an easier job in validating two
7696      coprocessor registers as containing a possible return value,
7697      simply pretend the untyped call returns a complex long double
7698      value.  */
7699
7700   emit_call_insn (TARGET_80387
7701                   ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
7702                                     operands[0], const0_rtx)
7703                   : gen_call (operands[0], const0_rtx));
7704
7705   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7706     {
7707       rtx set = XVECEXP (operands[2], 0, i);
7708       emit_move_insn (SET_DEST (set), SET_SRC (set));
7709     }
7710
7711   /* The optimizer does not know that the call sets the function value
7712      registers we stored in the result block.  We avoid problems by
7713      claiming that all hard registers are used and clobbered at this
7714      point.  */
7715   emit_insn (gen_blockage ());
7716
7717   DONE;
7718 }")
7719 \f
7720 ;; Prologue and epilogue instructions
7721
7722 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7723 ;; all of memory.  This blocks insns from being moved across this point.
7724
7725 (define_insn "blockage"
7726   [(unspec_volatile [(const_int 0)] 0)]
7727   ""
7728   ""
7729   [(set_attr "length" "0")])
7730
7731 ;; Insn emitted into the body of a function to return from a function.
7732 ;; This is only done if the function's epilogue is known to be simple.
7733 ;; See comments for simple_386_epilogue in i386.c.
7734
7735 (define_expand "return"
7736   [(return)]
7737   "ix86_can_use_return_insn_p ()"
7738   "
7739 {
7740   if (current_function_pops_args)
7741     {
7742       rtx popc = GEN_INT (current_function_pops_args);
7743       emit_jump_insn (gen_return_pop_internal (popc));
7744       DONE;
7745     }
7746 }")
7747
7748 (define_insn "return_internal"
7749   [(return)]
7750   "reload_completed"
7751   "ret"
7752   [(set_attr "length" "1")])
7753
7754 (define_insn "return_pop_internal"
7755   [(return)
7756    (use (match_operand:SI 0 "const_int_operand" ""))]
7757   "reload_completed"
7758   "ret\\t%0"
7759   [(set_attr "length" "3")])
7760
7761 (define_insn "nop"
7762   [(const_int 0)]
7763   ""
7764   "nop"
7765   [(set_attr "length" "1")
7766    (set_attr "ppro_uops" "one")])
7767
7768 (define_expand "prologue"
7769   [(const_int 1)]
7770   ""
7771   "ix86_expand_prologue (); DONE;")
7772
7773 (define_insn "prologue_set_got"
7774   [(set (match_operand:SI 0 "register_operand" "=r")
7775         (unspec_volatile:SI
7776          [(plus:SI (match_dup 0)
7777                    (plus:SI (match_operand:SI 1 "symbolic_operand" "")
7778                             (minus:SI (pc) (match_operand 2 "" ""))))] 1))
7779    (clobber (reg:CC 17))]
7780   ""
7781   "*
7782 {
7783   if (GET_CODE (operands[2]) == LABEL_REF)
7784      operands[2] = XEXP (operands[2], 0);
7785   if (TARGET_DEEP_BRANCH_PREDICTION) 
7786     return \"add{l}\\t{%1, %0|%0, %1}\";
7787   else  
7788     return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
7789 }"
7790   [(set_attr "type" "alu")])
7791
7792 (define_insn "prologue_get_pc"
7793   [(set (match_operand:SI 0 "register_operand" "=r")
7794     (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
7795   ""
7796   "*
7797 {
7798   if (GET_CODE (operands[1]) == LABEL_REF)
7799     operands[1] = XEXP (operands[1], 0);
7800   output_asm_insn (\"call\\t%X1\", operands);
7801   if (! TARGET_DEEP_BRANCH_PREDICTION)
7802     {
7803       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
7804                                  CODE_LABEL_NUMBER (operands[1]));
7805     }
7806   RET;
7807 }"
7808   [(set_attr "type" "multi")])
7809
7810 (define_expand "epilogue"
7811   [(const_int 1)]
7812   ""
7813   "ix86_expand_epilogue (1); DONE;")
7814
7815 (define_expand "sibcall_epilogue"
7816   [(const_int 1)]
7817   ""
7818   "ix86_expand_epilogue (0); DONE;")
7819
7820 (define_insn "leave"
7821   [(set (reg:SI 7) (reg:SI 6))
7822    (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
7823   ""
7824   "leave"
7825   [(set_attr "length" "1")
7826    (set_attr "athlon_decode" "vector")
7827    (set_attr "ppro_uops" "few")])
7828 \f
7829 (define_expand "ffssi2"
7830   [(set (match_operand:SI 0 "nonimmediate_operand" "") 
7831         (ffs:SI (match_operand:SI 1 "general_operand" "")))]
7832   ""
7833   "
7834 {
7835   rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
7836   rtx in = operands[1];
7837
7838   if (TARGET_CMOVE)
7839     {
7840       emit_move_insn (tmp, constm1_rtx);
7841       emit_insn (gen_ffssi_1 (out, in));
7842       emit_insn (gen_rtx_SET (VOIDmode, out,
7843                   gen_rtx_IF_THEN_ELSE (SImode, 
7844                     gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
7845                                 const0_rtx),
7846                     tmp,
7847                     out)));
7848       emit_insn (gen_addsi3 (out, out, const1_rtx));
7849       emit_move_insn (operands[0], out);
7850     }
7851
7852   /* Pentium bsf instruction is extremly slow.  The following code is
7853      recommended by the Intel Optimizing Manual as a reasonable replacement:
7854            TEST    EAX,EAX
7855            JZ      SHORT BS2
7856            XOR     ECX,ECX
7857            MOV     DWORD PTR [TEMP+4],ECX
7858            SUB     ECX,EAX
7859            AND     EAX,ECX
7860            MOV     DWORD PTR [TEMP],EAX
7861            FILD    QWORD PTR [TEMP]
7862            FSTP    QWORD PTR [TEMP]
7863            WAIT    ; WAIT only needed for compatibility with
7864                    ; earlier processors
7865            MOV     ECX, DWORD PTR [TEMP+4]
7866            SHR     ECX,20
7867            SUB     ECX,3FFH
7868            TEST    EAX,EAX       ; clear zero flag
7869        BS2:
7870      Following piece of code expand ffs to similar beast.
7871        */
7872
7873   else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
7874     {
7875       rtx label = gen_label_rtx ();
7876       rtx lo, hi;
7877       rtx mem = assign_386_stack_local (DImode, 0);
7878       rtx fptmp = gen_reg_rtx (DFmode);
7879       split_di (&mem, 1, &lo, &hi);
7880
7881       emit_move_insn (out, const0_rtx);
7882
7883       emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
7884
7885       emit_move_insn (hi, out);
7886       emit_insn (gen_subsi3 (out, out, in));
7887       emit_insn (gen_andsi3 (out, out, in));
7888       emit_move_insn (lo, out);
7889       emit_insn (gen_floatdidf2 (fptmp,mem));
7890       emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
7891       emit_move_insn (out, hi);
7892       emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
7893       emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
7894
7895       emit_label (label);
7896       LABEL_NUSES (label) = 1;
7897
7898       emit_move_insn (operands[0], out);
7899     }
7900   else
7901     {
7902       emit_move_insn (tmp, const0_rtx);
7903       emit_insn (gen_ffssi_1 (out, in));
7904       emit_insn (gen_rtx_SET (VOIDmode, 
7905                   gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
7906                   gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
7907                               const0_rtx)));
7908       emit_insn (gen_negsi2 (tmp, tmp));
7909       emit_insn (gen_iorsi3 (out, out, tmp));
7910       emit_insn (gen_addsi3 (out, out, const1_rtx));
7911       emit_move_insn (operands[0], out);
7912     }
7913   DONE;  
7914 }")
7915
7916 (define_insn "ffssi_1"
7917   [(set (reg:CCZ 17)
7918         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
7919                      (const_int 0)))
7920    (set (match_operand:SI 0 "register_operand" "=r")
7921         (unspec:SI [(match_dup 1)] 5))]
7922   ""
7923   "bsf{l}\\t{%1, %0|%0, %1}"
7924   [(set_attr "length_opcode" "3")
7925    (set_attr "ppro_uops" "few")])
7926
7927 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
7928 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
7929 \f
7930 ;; These patterns match the binary 387 instructions for addM3, subM3,
7931 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
7932 ;; SFmode.  The first is the normal insn, the second the same insn but
7933 ;; with one operand a conversion, and the third the same insn but with
7934 ;; the other operand a conversion.  The conversion may be SFmode or
7935 ;; SImode if the target mode DFmode, but only SImode if the target mode
7936 ;; is SFmode.
7937
7938 ;; Gcc is slightly more smart about handling normal two address instructions
7939 ;; so use special patterns for add and mull.
7940 (define_insn "*fop_sf_comm"
7941   [(set (match_operand:SF 0 "register_operand" "=f")
7942         (match_operator:SF 3 "binary_fp_operator"
7943                         [(match_operand:SF 1 "register_operand" "%0")
7944                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
7945   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
7946   "* return output_387_binary_op (insn, operands);"
7947   [(set (attr "type") 
7948         (if_then_else (match_operand:SF 3 "mult_operator" "") 
7949            (const_string "fmul")
7950            (const_string "fop")))])
7951
7952 (define_insn "*fop_df_comm"
7953   [(set (match_operand:DF 0 "register_operand" "=f")
7954         (match_operator:DF 3 "binary_fp_operator"
7955                         [(match_operand:DF 1 "register_operand" "%0")
7956                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
7957   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
7958   "* return output_387_binary_op (insn, operands);"
7959   [(set (attr "type") 
7960         (if_then_else (match_operand:DF 3 "mult_operator" "") 
7961            (const_string "fmul")
7962            (const_string "fop")))])
7963
7964 (define_insn "*fop_xf_comm"
7965   [(set (match_operand:XF 0 "register_operand" "=f")
7966         (match_operator:XF 3 "binary_fp_operator"
7967                         [(match_operand:XF 1 "register_operand" "%0")
7968                          (match_operand:XF 2 "register_operand" "f")]))]
7969   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
7970   "* return output_387_binary_op (insn, operands);"
7971   [(set (attr "type") 
7972         (if_then_else (match_operand:XF 3 "mult_operator" "") 
7973            (const_string "fmul")
7974            (const_string "fop")))])
7975
7976 (define_insn "*fop_sf_1"
7977   [(set (match_operand:SF 0 "register_operand" "=f,f")
7978         (match_operator:SF 3 "binary_fp_operator"
7979                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7980                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7981   "TARGET_80387
7982    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
7983    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7984   "* return output_387_binary_op (insn, operands);"
7985   [(set (attr "type") 
7986         (cond [(match_operand:SF 3 "mult_operator" "") 
7987                  (const_string "fmul")
7988                (match_operand:SF 3 "div_operator" "") 
7989                  (const_string "fdiv")
7990               ]
7991               (const_string "fop")))])
7992
7993 (define_insn "*fop_sf_2"
7994   [(set (match_operand:SF 0 "register_operand" "=f,f")
7995         (match_operator:SF 3 "binary_fp_operator"
7996           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
7997            (match_operand:SF 2 "register_operand" "0,0")]))]
7998   "TARGET_80387 && TARGET_USE_FIOP"
7999   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8000   [(set (attr "type") 
8001         (cond [(match_operand:SF 3 "mult_operator" "") 
8002                  (const_string "fmul")
8003                (match_operand:SF 3 "div_operator" "") 
8004                  (const_string "fdiv")
8005               ]
8006               (const_string "fop")))
8007    (set_attr "fp_int_src" "true")
8008    (set_attr "ppro_uops" "many")])
8009
8010 (define_insn "*fop_sf_3"
8011   [(set (match_operand:SF 0 "register_operand" "=f,f")
8012         (match_operator:SF 3 "binary_fp_operator"
8013           [(match_operand:SF 1 "register_operand" "0,0")
8014            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8015   "TARGET_80387 && TARGET_USE_FIOP"
8016   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8017   [(set (attr "type") 
8018         (cond [(match_operand:SF 3 "mult_operator" "") 
8019                  (const_string "fmul")
8020                (match_operand:SF 3 "div_operator" "") 
8021                  (const_string "fdiv")
8022               ]
8023               (const_string "fop")))
8024    (set_attr "fp_int_src" "true")
8025    (set_attr "ppro_uops" "many")])
8026
8027 (define_insn "*fop_df_1"
8028   [(set (match_operand:DF 0 "register_operand" "=f,f")
8029         (match_operator:DF 3 "binary_fp_operator"
8030                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
8031                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
8032   "TARGET_80387
8033    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
8034    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8035   "* return output_387_binary_op (insn, operands);"
8036   [(set (attr "type") 
8037         (cond [(match_operand:DF 3 "mult_operator" "") 
8038                  (const_string "fmul")
8039                (match_operand:DF 3 "div_operator" "") 
8040                  (const_string "fdiv")
8041               ]
8042               (const_string "fop")))])
8043
8044 (define_insn "*fop_df_2"
8045   [(set (match_operand:DF 0 "register_operand" "=f,f")
8046         (match_operator:DF 3 "binary_fp_operator"
8047            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
8048             (match_operand:DF 2 "register_operand" "0,0")]))]
8049   "TARGET_80387 && TARGET_USE_FIOP"
8050   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8051   [(set (attr "type") 
8052         (cond [(match_operand:DF 3 "mult_operator" "") 
8053                  (const_string "fmul")
8054                (match_operand:DF 3 "div_operator" "") 
8055                  (const_string "fdiv")
8056               ]
8057               (const_string "fop")))
8058    (set_attr "fp_int_src" "true")
8059    (set_attr "ppro_uops" "many")])
8060
8061 (define_insn "*fop_df_3"
8062   [(set (match_operand:DF 0 "register_operand" "=f,f")
8063         (match_operator:DF 3 "binary_fp_operator"
8064            [(match_operand:DF 1 "register_operand" "0,0")
8065             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8066   "TARGET_80387 && TARGET_USE_FIOP"
8067   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8068   [(set (attr "type") 
8069         (cond [(match_operand:DF 3 "mult_operator" "") 
8070                  (const_string "fmul")
8071                (match_operand:DF 3 "div_operator" "") 
8072                  (const_string "fdiv")
8073               ]
8074               (const_string "fop")))
8075    (set_attr "fp_int_src" "true")
8076    (set_attr "ppro_uops" "many")])
8077
8078 (define_insn "*fop_df_4"
8079   [(set (match_operand:DF 0 "register_operand" "=f,f")
8080         (match_operator:DF 3 "binary_fp_operator"
8081            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
8082             (match_operand:DF 2 "register_operand" "0,f")]))]
8083   "TARGET_80387
8084    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8085   "* return output_387_binary_op (insn, operands);"
8086   [(set (attr "type") 
8087         (cond [(match_operand:DF 3 "mult_operator" "") 
8088                  (const_string "fmul")
8089                (match_operand:DF 3 "div_operator" "") 
8090                  (const_string "fdiv")
8091               ]
8092               (const_string "fop")))])
8093
8094 (define_insn "*fop_df_5"
8095   [(set (match_operand:DF 0 "register_operand" "=f,f")
8096         (match_operator:DF 3 "binary_fp_operator"
8097           [(match_operand:DF 1 "register_operand" "0,f")
8098            (float_extend:DF
8099             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8100   "TARGET_80387"
8101   "* return output_387_binary_op (insn, operands);"
8102   [(set (attr "type") 
8103         (cond [(match_operand:DF 3 "mult_operator" "") 
8104                  (const_string "fmul")
8105                (match_operand:DF 3 "div_operator" "") 
8106                  (const_string "fdiv")
8107               ]
8108               (const_string "fop")))])
8109
8110 (define_insn "*fop_xf_1"
8111   [(set (match_operand:XF 0 "register_operand" "=f,f")
8112         (match_operator:XF 3 "binary_fp_operator"
8113                         [(match_operand:XF 1 "register_operand" "0,f")
8114                          (match_operand:XF 2 "register_operand" "f,0")]))]
8115   "TARGET_80387
8116    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
8117   "* return output_387_binary_op (insn, operands);"
8118   [(set (attr "type") 
8119         (cond [(match_operand:XF 3 "mult_operator" "") 
8120                  (const_string "fmul")
8121                (match_operand:XF 3 "div_operator" "") 
8122                  (const_string "fdiv")
8123               ]
8124               (const_string "fop")))])
8125
8126 (define_insn "*fop_xf_2"
8127   [(set (match_operand:XF 0 "register_operand" "=f,f")
8128         (match_operator:XF 3 "binary_fp_operator"
8129            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
8130             (match_operand:XF 2 "register_operand" "0,0")]))]
8131   "TARGET_80387 && TARGET_USE_FIOP"
8132   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8133   [(set (attr "type") 
8134         (cond [(match_operand:XF 3 "mult_operator" "") 
8135                  (const_string "fmul")
8136                (match_operand:XF 3 "div_operator" "") 
8137                  (const_string "fdiv")
8138               ]
8139               (const_string "fop")))
8140    (set_attr "fp_int_src" "true")
8141    (set_attr "ppro_uops" "many")])
8142
8143 (define_insn "*fop_xf_3"
8144   [(set (match_operand:XF 0 "register_operand" "=f,f")
8145         (match_operator:XF 3 "binary_fp_operator"
8146           [(match_operand:XF 1 "register_operand" "0,0")
8147            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8148   "TARGET_80387 && TARGET_USE_FIOP"
8149   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8150   [(set (attr "type") 
8151         (cond [(match_operand:XF 3 "mult_operator" "") 
8152                  (const_string "fmul")
8153                (match_operand:XF 3 "div_operator" "") 
8154                  (const_string "fdiv")
8155               ]
8156               (const_string "fop")))
8157    (set_attr "fp_int_src" "true")
8158    (set_attr "ppro_uops" "many")])
8159
8160 (define_insn "*fop_xf_4"
8161   [(set (match_operand:XF 0 "register_operand" "=f,f")
8162         (match_operator:XF 3 "binary_fp_operator"
8163            [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
8164             (match_operand:XF 2 "register_operand" "0,f")]))]
8165   "TARGET_80387"
8166   "* return output_387_binary_op (insn, operands);"
8167   [(set (attr "type") 
8168         (cond [(match_operand:XF 3 "mult_operator" "") 
8169                  (const_string "fmul")
8170                (match_operand:XF 3 "div_operator" "") 
8171                  (const_string "fdiv")
8172               ]
8173               (const_string "fop")))])
8174
8175 (define_insn "*fop_xf_5"
8176   [(set (match_operand:XF 0 "register_operand" "=f,f")
8177         (match_operator:XF 3 "binary_fp_operator"
8178           [(match_operand:XF 1 "register_operand" "0,f")
8179            (float_extend:XF
8180             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8181   "TARGET_80387"
8182   "* return output_387_binary_op (insn, operands);"
8183   [(set (attr "type") 
8184         (cond [(match_operand:XF 3 "mult_operator" "") 
8185                  (const_string "fmul")
8186                (match_operand:XF 3 "div_operator" "") 
8187                  (const_string "fdiv")
8188               ]
8189               (const_string "fop")))])
8190
8191 (define_insn "*fop_xf_6"
8192   [(set (match_operand:XF 0 "register_operand" "=f,f")
8193         (match_operator:XF 3 "binary_fp_operator"
8194            [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
8195             (match_operand:XF 2 "register_operand" "0,f")]))]
8196   "TARGET_80387"
8197   "* return output_387_binary_op (insn, operands);"
8198   [(set (attr "type") 
8199         (cond [(match_operand:XF 3 "mult_operator" "") 
8200                  (const_string "fmul")
8201                (match_operand:XF 3 "div_operator" "") 
8202                  (const_string "fdiv")
8203               ]
8204               (const_string "fop")))])
8205
8206 (define_insn "*fop_xf_7"
8207   [(set (match_operand:XF 0 "register_operand" "=f,f")
8208         (match_operator:XF 3 "binary_fp_operator"
8209           [(match_operand:XF 1 "register_operand" "0,f")
8210            (float_extend:XF
8211             (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
8212   "TARGET_80387"
8213   "* return output_387_binary_op (insn, operands);"
8214   [(set (attr "type") 
8215         (cond [(match_operand:XF 3 "mult_operator" "") 
8216                  (const_string "fmul")
8217                (match_operand:XF 3 "div_operator" "") 
8218                  (const_string "fdiv")
8219               ]
8220               (const_string "fop")))])
8221
8222 (define_split
8223   [(set (match_operand 0 "register_operand" "")
8224         (match_operator 3 "binary_fp_operator"
8225            [(float (match_operand:SI 1 "register_operand" ""))
8226             (match_operand 2 "register_operand" "")]))]
8227   "TARGET_80387 && reload_completed
8228    && FLOAT_MODE_P (GET_MODE (operands[0]))"
8229   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
8230    (set (match_dup 0)
8231         (match_op_dup 3 [(match_dup 4) (match_dup 2)]))
8232    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
8233               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
8234   "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
8235                                 gen_rtx_MEM (SImode, stack_pointer_rtx));")
8236
8237 (define_split
8238   [(set (match_operand 0 "register_operand" "")
8239         (match_operator 3 "binary_fp_operator"
8240            [(match_operand 1 "register_operand" "")
8241             (float (match_operand:SI 2 "register_operand" ""))]))]
8242   "TARGET_80387 && reload_completed
8243    && FLOAT_MODE_P (GET_MODE (operands[0]))"
8244   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
8245    (set (match_dup 0)
8246         (match_op_dup 3 [(match_dup 1) (match_dup 4)]))
8247    (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
8248               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
8249   "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
8250                                 gen_rtx_MEM (SImode, stack_pointer_rtx));")
8251 \f
8252 ;; FPU special functions.
8253
8254 (define_insn "sqrtsf2"
8255   [(set (match_operand:SF 0 "register_operand" "=f")
8256         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
8257   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8258   "fsqrt"
8259   [(set_attr "type" "fpspc")
8260    (set_attr "athlon_decode" "direct")])
8261
8262 (define_insn "sqrtdf2"
8263   [(set (match_operand:DF 0 "register_operand" "=f")
8264         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
8265   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
8266    && (TARGET_IEEE_FP || flag_fast_math) "
8267   "fsqrt"
8268   [(set_attr "type" "fpspc")
8269    (set_attr "athlon_decode" "direct")])
8270
8271 (define_insn "*sqrtextendsfdf2"
8272   [(set (match_operand:DF 0 "register_operand" "=f")
8273         (sqrt:DF (float_extend:DF
8274                   (match_operand:SF 1 "register_operand" "0"))))]
8275   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8276   "fsqrt"
8277   [(set_attr "type" "fpspc")
8278    (set_attr "athlon_decode" "direct")])
8279
8280 (define_insn "sqrtxf2"
8281   [(set (match_operand:XF 0 "register_operand" "=f")
8282         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
8283   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
8284    && (TARGET_IEEE_FP || flag_fast_math) "
8285   "fsqrt"
8286   [(set_attr "type" "fpspc")
8287    (set_attr "athlon_decode" "direct")])
8288
8289 (define_insn "*sqrtextenddfxf2"
8290   [(set (match_operand:XF 0 "register_operand" "=f")
8291         (sqrt:XF (float_extend:XF
8292                   (match_operand:DF 1 "register_operand" "0"))))]
8293   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8294   "fsqrt"
8295   [(set_attr "type" "fpspc")
8296    (set_attr "athlon_decode" "direct")])
8297
8298 (define_insn "*sqrtextendsfxf2"
8299   [(set (match_operand:XF 0 "register_operand" "=f")
8300         (sqrt:XF (float_extend:XF
8301                   (match_operand:SF 1 "register_operand" "0"))))]
8302   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8303   "fsqrt"
8304   [(set_attr "type" "fpspc")
8305    (set_attr "athlon_decode" "direct")])
8306
8307 (define_insn "sindf2"
8308   [(set (match_operand:DF 0 "register_operand" "=f")
8309         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
8310   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
8311   "fsin"
8312   [(set_attr "type" "fpspc")])
8313
8314 (define_insn "sinsf2"
8315   [(set (match_operand:SF 0 "register_operand" "=f")
8316         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
8317   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
8318   "fsin"
8319   [(set_attr "type" "fpspc")])
8320
8321 (define_insn "*sinextendsfdf2"
8322   [(set (match_operand:DF 0 "register_operand" "=f")
8323         (unspec:DF [(float_extend:DF
8324                      (match_operand:SF 1 "register_operand" "0"))] 1))]
8325   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
8326   "fsin"
8327   [(set_attr "type" "fpspc")])
8328
8329 (define_insn "sinxf2"
8330   [(set (match_operand:XF 0 "register_operand" "=f")
8331         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
8332   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
8333   "fsin"
8334   [(set_attr "type" "fpspc")])
8335
8336 (define_insn "cosdf2"
8337   [(set (match_operand:DF 0 "register_operand" "=f")
8338         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
8339   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
8340   "fcos"
8341   [(set_attr "type" "fpspc")])
8342
8343 (define_insn "cossf2"
8344   [(set (match_operand:SF 0 "register_operand" "=f")
8345         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
8346   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
8347   "fcos"
8348   [(set_attr "type" "fpspc")])
8349
8350 (define_insn "*cosextendsfdf2"
8351   [(set (match_operand:DF 0 "register_operand" "=f")
8352         (unspec:DF [(float_extend:DF
8353                      (match_operand:SF 1 "register_operand" "0"))] 2))]
8354   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
8355   "fcos"
8356   [(set_attr "type" "fpspc")])
8357
8358 (define_insn "cosxf2"
8359   [(set (match_operand:XF 0 "register_operand" "=f")
8360         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
8361   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
8362   "fcos"
8363   [(set_attr "type" "fpspc")])
8364 \f
8365 ;; Block operation instructions
8366
8367 (define_insn "cld"
8368  [(set (reg:SI 19) (const_int 0))]
8369  ""
8370  "cld"
8371   [(set_attr "type" "cld")])
8372
8373 (define_expand "movstrsi"
8374   [(use (match_operand:BLK 0 "memory_operand" ""))
8375    (use (match_operand:BLK 1 "memory_operand" ""))
8376    (use (match_operand:SI 2 "nonmemory_operand" ""))
8377    (use (match_operand:SI 3 "const_int_operand" ""))]
8378   ""
8379   "
8380 {
8381   rtx srcreg, destreg, countreg;
8382   int align = 0;
8383   int count = -1;
8384
8385   if (GET_CODE (operands[3]) == CONST_INT)
8386     align = INTVAL (operands[3]);
8387
8388   /* This simple hack avoids all inlining code and simplifies code bellow.  */
8389   if (!TARGET_ALIGN_STRINGOPS)
8390     align = 32;
8391
8392   if (GET_CODE (operands[2]) == CONST_INT)
8393     count = INTVAL (operands[2]);
8394
8395   destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8396   srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
8397
8398   emit_insn (gen_cld());
8399
8400   /* When optimizing for size emit simple rep ; movsb instruction for
8401      counts not divisible by 4.  */
8402
8403   if ((!optimize || optimize_size) 
8404       && (count < 0 || (count & 0x03)))
8405     {
8406       countreg = copy_to_mode_reg (SImode, operands[2]);
8407       emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
8408                                 destreg, srcreg, countreg));
8409     }
8410
8411   /* For constant aligned (or small unaligned) copies use rep movsl
8412      followed by code copying the rest.  For PentiumPro ensure 8 byte
8413      alignment to allow rep movsl acceleration.  */
8414
8415   else if (count >= 0 
8416            && (align >= 8
8417                || (!TARGET_PENTIUMPRO && align >= 4)
8418                || optimize_size || count < 64))
8419     {
8420       if (count & ~0x03)
8421         {
8422           countreg = copy_to_mode_reg (SImode,
8423                                        GEN_INT ((count >> 2)
8424                                                 & 0x3fffffff));
8425           emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
8426                                     destreg, srcreg, countreg));
8427         }
8428       if (count & 0x02)
8429         emit_insn (gen_strmovhi (destreg, srcreg));
8430       if (count & 0x01)
8431         emit_insn (gen_strmovqi (destreg, srcreg));
8432     }
8433   /* The generic code based on the glibc implementation:
8434      - align destination to 4 bytes (8 byte alignment is used for PentiumPro
8435        allowing accelerated copying there)
8436      - copy the data using rep movsl
8437      - copy the rest.  */
8438   else
8439     {
8440       rtx countreg2;
8441       rtx label = NULL;
8442
8443       /* In case we don't know anything about the alignment, default to
8444          library version, since it is usually equally fast and result in
8445          shorter code.  */
8446       if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
8447         FAIL;
8448
8449       if (TARGET_SINGLE_STRINGOP)
8450         emit_insn (gen_cld());
8451
8452       countreg2 = gen_reg_rtx (SImode);
8453       countreg = copy_to_mode_reg (SImode, operands[2]);
8454
8455       /* We don't use loops to align destination and to copy parts smaller
8456          than 4 bytes, because gcc is able to optimize such code better (in
8457          the case the destination or the count really is aligned, gcc is often
8458          able to predict the branches) and also it is friendlier to the
8459          hardware branch prediction.  
8460
8461          Using loops is benefical for generic case, because we can
8462          handle small counts using the loops.  Many CPUs (such as Athlon)
8463          have large REP prefix setup costs.
8464
8465          This is quite costy.  Maybe we can revisit this decision later or
8466          add some customizability to this code.  */
8467
8468       if (count < 0
8469           && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
8470         {
8471           label = gen_label_rtx ();
8472           emit_cmp_and_jump_insns (countreg, GEN_INT (3),
8473                                    LEU, 0, SImode, 1, 0, label);
8474         }
8475       if (align <= 1)
8476         {
8477           rtx label = gen_label_rtx ();
8478           rtx tmpcount = gen_reg_rtx (SImode);
8479           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
8480           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8481                                    SImode, 1, 0, label);
8482           emit_insn (gen_strmovqi (destreg, srcreg));
8483           emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
8484           emit_label (label);
8485           LABEL_NUSES (label) = 1;
8486         }
8487       if (align <= 2)
8488         {
8489           rtx label = gen_label_rtx ();
8490           rtx tmpcount = gen_reg_rtx (SImode);
8491           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
8492           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8493                                    SImode, 1, 0, label);
8494           emit_insn (gen_strmovhi (destreg, srcreg));
8495           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
8496           emit_label (label);
8497           LABEL_NUSES (label) = 1;
8498         }
8499       if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
8500         {
8501           rtx label = gen_label_rtx ();
8502           rtx tmpcount = gen_reg_rtx (SImode);
8503           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
8504           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8505                                    SImode, 1, 0, label);
8506           emit_insn (gen_strmovsi (destreg, srcreg));
8507           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
8508           emit_label (label);
8509           LABEL_NUSES (label) = 1;
8510         }
8511
8512       if (!TARGET_SINGLE_STRINGOP)
8513         emit_insn (gen_cld());
8514       emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
8515       emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
8516                                 destreg, srcreg, countreg2));
8517
8518       if (label)
8519         {
8520           emit_label (label);
8521           LABEL_NUSES (label) = 1;
8522         }
8523       if (align > 2 && count > 0 && (count & 2))
8524         emit_insn (gen_strmovhi (destreg, srcreg));
8525       if (align <= 2 || count < 0)
8526         {
8527           rtx label = gen_label_rtx ();
8528           rtx tmpcount = gen_reg_rtx (SImode);
8529           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
8530           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8531                                    SImode, 1, 0, label);
8532           emit_insn (gen_strmovhi (destreg, srcreg));
8533           emit_label (label);
8534           LABEL_NUSES (label) = 1;
8535         }
8536       if (align > 1 && count > 0 && (count & 1))
8537         emit_insn (gen_strmovsi (destreg, srcreg));
8538       if (align <= 1 || count < 0)
8539         {
8540           rtx label = gen_label_rtx ();
8541           rtx tmpcount = gen_reg_rtx (SImode);
8542           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
8543           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8544                                    SImode, 1, 0, label);
8545           emit_insn (gen_strmovqi (destreg, srcreg));
8546           emit_label (label);
8547           LABEL_NUSES (label) = 1;
8548         }
8549     }
8550   DONE;
8551 }")
8552
8553 ;; Most CPUs don't like single string operations
8554 ;; Handle this case here to simplify previous expander.
8555
8556 (define_expand "strmovsi"
8557   [(set (match_dup 2)
8558         (mem:SI (match_operand:SI 1 "register_operand" "")))
8559    (set (mem:SI (match_operand:SI 0 "register_operand" ""))
8560         (match_dup 2))
8561    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
8562               (clobber (reg:CC 17))])
8563    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
8564               (clobber (reg:CC 17))])]
8565   ""
8566   "
8567 {
8568   if (TARGET_SINGLE_STRINGOP || optimize_size)
8569     {
8570       emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
8571                                 operands[1]));
8572       DONE;
8573     }
8574   else 
8575     operands[2] = gen_reg_rtx (SImode);
8576 }")
8577
8578 (define_expand "strmovhi"
8579   [(set (match_dup 2)
8580         (mem:HI (match_operand:SI 1 "register_operand" "")))
8581    (set (mem:HI (match_operand:SI 0 "register_operand" ""))
8582         (match_dup 2))
8583    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
8584               (clobber (reg:CC 17))])
8585    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
8586               (clobber (reg:CC 17))])]
8587   ""
8588   "
8589 {
8590   if (TARGET_SINGLE_STRINGOP || optimize_size)
8591     {
8592       emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
8593                                 operands[1]));
8594       DONE;
8595     }
8596   else 
8597     operands[2] = gen_reg_rtx (HImode);
8598 }")
8599
8600 (define_expand "strmovqi"
8601   [(set (match_dup 2)
8602         (mem:QI (match_operand:SI 1 "register_operand" "")))
8603    (set (mem:QI (match_operand:SI 0 "register_operand" ""))
8604         (match_dup 2))
8605    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8606               (clobber (reg:CC 17))])
8607    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
8608               (clobber (reg:CC 17))])]
8609   ""
8610   "
8611 {
8612   if (TARGET_SINGLE_STRINGOP || optimize_size)
8613     {
8614       emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
8615                                 operands[1]));
8616       DONE;
8617     }
8618   else 
8619     operands[2] = gen_reg_rtx (QImode);
8620 }")
8621
8622 (define_insn "strmovsi_1"
8623   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
8624         (mem:SI (match_operand:SI 3 "register_operand" "1")))
8625    (set (match_operand:SI 0 "register_operand" "=D")
8626         (plus:SI (match_dup 0)
8627                  (const_int 4)))
8628    (set (match_operand:SI 1 "register_operand" "=S")
8629         (plus:SI (match_dup 1)
8630                  (const_int 4)))
8631    (use (reg:SI 19))]
8632   "TARGET_SINGLE_STRINGOP || optimize_size"
8633   "movsl"
8634   [(set_attr "type" "str")
8635    (set_attr "memory" "both")])
8636
8637 (define_insn "strmovhi_1"
8638   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
8639         (mem:HI (match_operand:SI 3 "register_operand" "1")))
8640    (set (match_operand:SI 0 "register_operand" "=D")
8641         (plus:SI (match_dup 0)
8642                  (const_int 2)))
8643    (set (match_operand:SI 1 "register_operand" "=S")
8644         (plus:SI (match_dup 1)
8645                  (const_int 2)))
8646    (use (reg:SI 19))]
8647   "TARGET_SINGLE_STRINGOP || optimize_size"
8648   "movsw"
8649   [(set_attr "type" "str")
8650    (set_attr "memory" "both")
8651    (set_attr "length_prefix" "1")])
8652
8653 (define_insn "strmovqi_1"
8654   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
8655         (mem:QI (match_operand:SI 3 "register_operand" "1")))
8656    (set (match_operand:SI 0 "register_operand" "=D")
8657         (plus:SI (match_dup 0)
8658                  (const_int 1)))
8659    (set (match_operand:SI 1 "register_operand" "=S")
8660         (plus:SI (match_dup 1)
8661                  (const_int 1)))
8662    (use (reg:SI 19))]
8663   "TARGET_SINGLE_STRINGOP || optimize_size"
8664   "movsb"
8665   [(set_attr "type" "str")
8666    (set_attr "memory" "both")])
8667
8668 ;; It might seem that operands 3 & 4 could use predicate register_operand.
8669 ;; But strength reduction might offset the MEM expression.  So we let
8670 ;; reload put the address into %edi & %esi.
8671
8672 (define_insn "rep_movsi"
8673   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
8674    (use (match_operand:SI 5 "register_operand" "2"))
8675    (set (match_operand:SI 0 "register_operand" "=D") 
8676         (plus:SI (match_operand:SI 3 "address_operand" "0")
8677                  (ashift:SI (match_dup 5) (const_int 2))))
8678    (set (match_operand:SI 1 "register_operand" "=S") 
8679         (plus:SI (match_operand:SI 4 "address_operand" "1")
8680                  (ashift:SI (match_dup 5) (const_int 2))))
8681    (set (mem:BLK (match_dup 3))
8682         (mem:BLK (match_dup 4)))
8683    (use (reg:SI 19))]
8684   ""
8685   "rep\;movsl|rep movsd"
8686   [(set_attr "type" "str")
8687    (set_attr "length_prefix" "1")
8688    (set_attr "memory" "both")])
8689
8690 (define_insn "rep_movqi"
8691   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
8692    (use (match_operand:SI 5 "register_operand" "2"))
8693    (set (match_operand:SI 0 "register_operand" "=D") 
8694         (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 5)))
8695    (set (match_operand:SI 1 "register_operand" "=S") 
8696         (plus:SI (match_operand:SI 4 "address_operand" "1") (match_dup 5)))
8697    (set (mem:BLK (match_dup 3))
8698         (mem:BLK (match_dup 4)))
8699    (use (reg:SI 19))]
8700   ""
8701   "rep\;movsb|rep movsb"
8702   [(set_attr "type" "str")
8703    (set_attr "length_prefix" "1")
8704    (set_attr "memory" "both")])
8705
8706 (define_expand "clrstrsi"
8707    [(use (match_operand:BLK 0 "memory_operand" ""))
8708     (use (match_operand:SI 1 "nonmemory_operand" ""))
8709     (use (match_operand:SI 2 "const_int_operand" ""))]
8710   ""
8711   "
8712 {
8713   /* See comments in movstr expanders.  The code is mostly identical.  */
8714
8715   rtx destreg, zeroreg, countreg;
8716   int align = 0;
8717   int count = -1;
8718
8719   if (GET_CODE (operands[2]) == CONST_INT)
8720     align = INTVAL (operands[2]);
8721
8722   /* This simple hack avoids all inlining code and simplifies code bellow.  */
8723   if (!TARGET_ALIGN_STRINGOPS)
8724     align = 32;
8725
8726   if (GET_CODE (operands[1]) == CONST_INT)
8727     count = INTVAL (operands[1]);
8728
8729   destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8730
8731   emit_insn (gen_cld());
8732
8733   /* When optimizing for size emit simple rep ; movsb instruction for
8734      counts not divisible by 4.  */
8735
8736   if ((!optimize || optimize_size) 
8737       && (count < 0 || (count & 0x03)))
8738     {
8739       countreg = copy_to_mode_reg (SImode, operands[1]);
8740       zeroreg = copy_to_mode_reg (QImode, const0_rtx);
8741       emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
8742                                  destreg, countreg));
8743     }
8744   else if (count >= 0 
8745            && (align >= 8
8746                || (!TARGET_PENTIUMPRO && align >= 4)
8747                || optimize_size || count < 64))
8748     {
8749       zeroreg = copy_to_mode_reg (SImode, const0_rtx);
8750       if (INTVAL (operands[1]) & ~0x03)
8751         {
8752           countreg = copy_to_mode_reg (SImode,
8753                                        GEN_INT ((INTVAL (operands[1]) >> 2)
8754                                                 & 0x3fffffff));
8755           emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
8756                                      destreg, countreg));
8757         }
8758       if (INTVAL (operands[1]) & 0x02)
8759         emit_insn (gen_strsethi (destreg,
8760                                  gen_rtx_SUBREG (HImode, zeroreg, 0)));
8761       if (INTVAL (operands[1]) & 0x01)
8762         emit_insn (gen_strsetqi (destreg,
8763                                  gen_rtx_SUBREG (QImode, zeroreg, 0)));
8764     }
8765   else
8766     {
8767       rtx countreg2;
8768       rtx label = NULL;
8769
8770       /* In case we don't know anything about the alignment, default to
8771          library version, since it is usually equally fast and result in
8772          shorter code.  */
8773       if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
8774         FAIL;
8775
8776       if (TARGET_SINGLE_STRINGOP)
8777         emit_insn (gen_cld());
8778
8779       countreg2 = gen_reg_rtx (SImode);
8780       countreg = copy_to_mode_reg (SImode, operands[1]);
8781       zeroreg = copy_to_mode_reg (SImode, const0_rtx);
8782
8783       if (count < 0
8784           && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
8785         {
8786           label = gen_label_rtx ();
8787           emit_cmp_and_jump_insns (countreg, GEN_INT (3),
8788                                    LEU, 0, SImode, 1, 0, label);
8789         }
8790       if (align <= 1)
8791         {
8792           rtx label = gen_label_rtx ();
8793           rtx tmpcount = gen_reg_rtx (SImode);
8794           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
8795           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8796                                    SImode, 1, 0, label);
8797           emit_insn (gen_strsetqi (destreg,
8798                                    gen_rtx_SUBREG (QImode, zeroreg, 0)));
8799           emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
8800           emit_label (label);
8801           LABEL_NUSES (label) = 1;
8802         }
8803       if (align <= 2)
8804         {
8805           rtx label = gen_label_rtx ();
8806           rtx tmpcount = gen_reg_rtx (SImode);
8807           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
8808           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8809                                    SImode, 1, 0, label);
8810           emit_insn (gen_strsethi (destreg,
8811                                    gen_rtx_SUBREG (HImode, zeroreg, 0)));
8812           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
8813           emit_label (label);
8814           LABEL_NUSES (label) = 1;
8815         }
8816       if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
8817         {
8818           rtx label = gen_label_rtx ();
8819           rtx tmpcount = gen_reg_rtx (SImode);
8820           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
8821           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8822                                    SImode, 1, 0, label);
8823           emit_insn (gen_strsetsi (destreg, zeroreg));
8824           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
8825           emit_label (label);
8826           LABEL_NUSES (label) = 1;
8827         }
8828
8829       if (!TARGET_SINGLE_STRINGOP)
8830         emit_insn (gen_cld());
8831       emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
8832       emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
8833                                  destreg, countreg2));
8834
8835       if (label)
8836         {
8837           emit_label (label);
8838           LABEL_NUSES (label) = 1;
8839         }
8840       if (align > 2 && count > 0 && (count & 2))
8841         emit_insn (gen_strsethi (destreg,
8842                                  gen_rtx_SUBREG (HImode, zeroreg, 0)));
8843       if (align <= 2 || count < 0)
8844         {
8845           rtx label = gen_label_rtx ();
8846           rtx tmpcount = gen_reg_rtx (SImode);
8847           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
8848           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8849                                    SImode, 1, 0, label);
8850           emit_insn (gen_strsethi (destreg,
8851                                    gen_rtx_SUBREG (HImode, zeroreg, 0)));
8852           emit_label (label);
8853           LABEL_NUSES (label) = 1;
8854         }
8855       if (align > 1 && count > 0 && (count & 1))
8856         emit_insn (gen_strsetqi (destreg,
8857                                  gen_rtx_SUBREG (QImode, zeroreg, 0)));
8858       if (align <= 1 || count < 0)
8859         {
8860           rtx label = gen_label_rtx ();
8861           rtx tmpcount = gen_reg_rtx (SImode);
8862           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
8863           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8864                                    SImode, 1, 0, label);
8865           emit_insn (gen_strsetqi (destreg,
8866                                    gen_rtx_SUBREG (QImode, zeroreg, 0)));
8867           emit_label (label);
8868           LABEL_NUSES (label) = 1;
8869         }
8870     }
8871   DONE;
8872 }")
8873
8874 ;; Most CPUs don't like single string operations
8875 ;; Handle this case here to simplify previous expander.
8876
8877 (define_expand "strsetsi"
8878   [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
8879         (match_operand:SI 1 "register_operand" ""))
8880    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
8881               (clobber (reg:CC 17))])]
8882   ""
8883   "
8884 {
8885   if (TARGET_SINGLE_STRINGOP || optimize_size)
8886     {
8887       emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
8888       DONE;
8889     }
8890 }")
8891
8892 (define_expand "strsethi"
8893   [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
8894         (match_operand:HI 1 "register_operand" ""))
8895    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
8896               (clobber (reg:CC 17))])]
8897   ""
8898   "
8899 {
8900   if (TARGET_SINGLE_STRINGOP || optimize_size)
8901     {
8902       emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
8903       DONE;
8904     }
8905 }")
8906
8907 (define_expand "strsetqi"
8908   [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
8909         (match_operand:QI 1 "register_operand" ""))
8910    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8911               (clobber (reg:CC 17))])]
8912   ""
8913   "
8914 {
8915   if (TARGET_SINGLE_STRINGOP || optimize_size)
8916     {
8917       emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
8918       DONE;
8919     }
8920 }")
8921
8922 (define_insn "strsetsi_1"
8923   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
8924         (match_operand:SI 2 "register_operand" "a"))
8925    (set (match_operand:SI 0 "register_operand" "=D")
8926         (plus:SI (match_dup 0)
8927                  (const_int 4)))
8928    (use (reg:SI 19))]
8929   "TARGET_SINGLE_STRINGOP || optimize_size"
8930   "stosl"
8931   [(set_attr "type" "str")
8932    (set_attr "memory" "store")])
8933
8934 (define_insn "strsethi_1"
8935   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
8936         (match_operand:HI 2 "register_operand" "a"))
8937    (set (match_operand:SI 0 "register_operand" "=D")
8938         (plus:SI (match_dup 0)
8939                  (const_int 2)))
8940    (use (reg:SI 19))]
8941   "TARGET_SINGLE_STRINGOP || optimize_size"
8942   "stosw"
8943   [(set_attr "type" "str")
8944    (set_attr "memory" "store")
8945    (set_attr "length_prefix" "1")])
8946
8947 (define_insn "strsetqi_1"
8948   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
8949         (match_operand:QI 2 "register_operand" "a"))
8950    (set (match_operand:SI 0 "register_operand" "=D")
8951         (plus:SI (match_dup 0)
8952                  (const_int 1)))
8953    (use (reg:SI 19))]
8954   "TARGET_SINGLE_STRINGOP || optimize_size"
8955   "stosb"
8956   [(set_attr "type" "str")
8957    (set_attr "memory" "store")])
8958
8959 ;; It might seem that operand 0 could use predicate register_operand.
8960 ;; But strength reduction might offset the MEM expression.  So we let
8961 ;; reload put the address into %edi.
8962
8963 (define_insn "rep_stossi"
8964   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
8965    (use (match_operand:SI 2 "register_operand" "a"))
8966    (use (match_operand:SI 4 "register_operand" "1"))
8967    (set (match_operand:SI 0 "register_operand" "=D") 
8968         (plus:SI (match_operand:SI 3 "address_operand" "0")
8969                  (ashift:SI (match_dup 3) (const_int 2))))
8970    (set (mem:BLK (match_dup 3))
8971         (const_int 0))
8972    (use (reg:SI 19))]
8973   ""
8974   "rep\;stosl|rep stosd"
8975   [(set_attr "type" "str")
8976    (set_attr "length_prefix" "1")
8977    (set_attr "memory" "store")])
8978
8979 (define_insn "rep_stosqi"
8980   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
8981    (use (match_operand:QI 2 "register_operand" "a"))
8982    (use (match_operand:SI 4 "register_operand" "1"))
8983    (set (match_operand:SI 0 "register_operand" "=D") 
8984         (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 3)))
8985    (set (mem:BLK (match_dup 3))
8986         (const_int 0))
8987    (use (reg:SI 19))]
8988   ""
8989   "rep\;stosb|rep stosb"
8990   [(set_attr "type" "str")
8991    (set_attr "length_prefix" "1")
8992    (set_attr "memory" "store")])
8993
8994 (define_expand "cmpstrsi"
8995   [(set (match_operand:SI 0 "register_operand" "")
8996         (compare:SI (match_operand:BLK 1 "general_operand" "")
8997                     (match_operand:BLK 2 "general_operand" "")))
8998    (use (match_operand:SI 3 "general_operand" ""))
8999    (use (match_operand:SI 4 "immediate_operand" ""))]
9000   ""
9001   "
9002 {
9003   rtx addr1, addr2, out, outlow, count, countreg, align;
9004
9005   out = operands[0];
9006   if (GET_CODE (out) != REG)
9007     out = gen_reg_rtx (SImode);
9008
9009   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
9010   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
9011   
9012   count = operands[3];
9013   countreg = copy_to_mode_reg (SImode, count);
9014
9015   /* %%% Iff we are testing strict equality, we can use known alignment
9016      to good advantage.  This may be possible with combine, particularly
9017      once cc0 is dead.  */
9018   align = operands[4];
9019
9020   emit_insn (gen_cld ());
9021   if (GET_CODE (count) == CONST_INT)
9022     {
9023       if (INTVAL (count) == 0)
9024         {
9025           emit_move_insn (operands[0], const0_rtx);
9026           DONE;
9027         }
9028       emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align));
9029     }
9030   else
9031     {
9032       emit_insn (gen_cmpsi_1 (countreg, countreg));
9033       emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align));
9034     }
9035
9036   outlow = gen_lowpart (QImode, out);
9037   emit_insn (gen_cmpintqi (outlow));
9038   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
9039
9040   if (operands[0] != out)
9041     emit_move_insn (operands[0], out);
9042
9043   DONE;
9044 }")
9045
9046 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
9047
9048 (define_expand "cmpintqi"
9049   [(set (match_dup 1)
9050         (gtu:QI (reg:CC 17) (const_int 0)))
9051    (set (match_dup 2)
9052         (ltu:QI (reg:CC 17) (const_int 0)))
9053    (parallel [(set (match_operand:QI 0 "register_operand" "")
9054                    (minus:QI (match_dup 1)
9055                              (match_dup 2)))
9056               (clobber (reg:CC 17))])]
9057   ""
9058   "operands[1] = gen_reg_rtx (QImode);
9059    operands[2] = gen_reg_rtx (QImode);")
9060
9061 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
9062 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
9063 ;;
9064 ;; It might seem that operands 0 & 1 could use predicate register_operand.
9065 ;; But strength reduction might offset the MEM expression.  So we let
9066 ;; reload put the address into %edi & %esi.
9067
9068 (define_insn "cmpstrsi_nz_1"
9069   [(set (reg:CC 17)
9070         (compare:CC (mem:BLK (match_operand:SI 0 "address_operand" "S"))
9071                     (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
9072    (use (match_operand:SI 2 "register_operand" "c"))
9073    (use (match_operand:SI 3 "immediate_operand" "i"))
9074    (use (reg:SI 19))
9075    (clobber (match_dup 0))
9076    (clobber (match_dup 1))
9077    (clobber (match_dup 2))]
9078   ""
9079   "repz{\;| }cmpsb"
9080   [(set_attr "type" "str")
9081    (set_attr "length_prefix" "1")])
9082
9083 ;; The same, but the count is not known to not be zero.
9084
9085 (define_insn "cmpstrsi_1"
9086   [(set (reg:CC 17)
9087         (if_then_else:CC (ne (match_operand:SI 2 "register_operand" "c")
9088                              (const_int 0))
9089           (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
9090                       (mem:BLK (match_operand:SI 1 "address_operand" "D")))
9091           (const_int 0)))
9092    (use (match_operand:SI 3 "immediate_operand" "i"))
9093    (use (reg:CC 17))
9094    (use (reg:SI 19))
9095    (clobber (match_dup 0))
9096    (clobber (match_dup 1))
9097    (clobber (match_dup 2))]
9098   ""
9099   "repz{\;| }cmpsb"
9100   [(set_attr "type" "str")
9101    (set_attr "length_prefix" "1")])
9102
9103 (define_expand "strlensi"
9104   [(set (match_operand:SI 0 "register_operand" "")
9105         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
9106                     (match_operand:QI 2 "immediate_operand" "")
9107                     (match_operand:SI 3 "immediate_operand" "")] 0))]
9108   ""
9109   "
9110 {
9111   rtx out, addr, scratch1, scratch2, scratch3;
9112   rtx eoschar = operands[2];
9113   rtx align = operands[3];
9114
9115   /* The generic case of strlen expander is long.  Avoid it's
9116      expanding unless TARGET_INLINE_ALL_STRINGOPS.  */
9117
9118   if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
9119       && !TARGET_INLINE_ALL_STRINGOPS
9120       && !optimize_size
9121       && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
9122     FAIL;
9123
9124   out = operands[0];
9125   addr = force_reg (Pmode, XEXP (operands[1], 0));
9126   scratch1 = gen_reg_rtx (SImode);
9127
9128   if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
9129       && !optimize_size)
9130     {
9131       /* Well it seems that some optimizer does not combine a call like
9132              foo(strlen(bar), strlen(bar));
9133          when the move and the subtraction is done here.  It does calculate
9134          the length just once when these instructions are done inside of
9135          output_strlen_unroll().  But I think since &bar[strlen(bar)] is
9136          often used and I use one fewer register for the lifetime of
9137          output_strlen_unroll() this is better.  */
9138
9139       if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)
9140         emit_move_insn (scratch1, addr);
9141
9142       emit_move_insn (out, addr);
9143
9144       ix86_expand_strlensi_unroll_1 (out, align, scratch1);
9145
9146       /* strlensi_unroll_1 returns the address of the zero at the end of
9147          the string, like memchr(), so compute the length by subtracting
9148          the start address.  */
9149       emit_insn (gen_subsi3 (out, out, addr));
9150     }
9151   else
9152     {
9153       scratch2 = gen_reg_rtx (SImode);
9154       scratch3 = gen_reg_rtx (SImode);
9155
9156       emit_move_insn (scratch3, addr);
9157
9158       emit_insn (gen_cld ());
9159       emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
9160                                  align, constm1_rtx));
9161       emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
9162       emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
9163     }
9164   DONE;
9165 }")
9166
9167 ;; It might seem that operands 0 & 1 could use predicate register_operand.
9168 ;; But strength reduction might offset the MEM expression.  So we let
9169 ;; reload put the address into %edi.
9170
9171 (define_insn "strlensi_1"
9172   [(set (match_operand:SI 0 "register_operand" "=&c")
9173         (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
9174                     (match_operand:QI 2 "general_operand" "a")
9175                     (match_operand:SI 3 "immediate_operand" "i")
9176                     (match_operand:SI 4 "immediate_operand" "0")] 0))
9177    (use (reg:SI 19))
9178    (clobber (match_dup 1))
9179    (clobber (reg:CC 17))]
9180   ""
9181   "repnz{\;| }scasb"
9182   [(set_attr "type" "str")
9183    (set_attr "length_prefix" "1")])
9184 \f
9185 ;; Conditional move instructions.
9186
9187 (define_expand "movsicc"
9188   [(set (match_operand:SI 0 "register_operand" "")
9189         (if_then_else:SI (match_operand 1 "comparison_operator" "")
9190                          (match_operand:SI 2 "general_operand" "")
9191                          (match_operand:SI 3 "general_operand" "")))]
9192   ""
9193   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
9194
9195 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
9196 ;; the register first winds up with `sbbl $0,reg', which is also weird.
9197 ;; So just document what we're doing explicitly.
9198
9199 (define_insn "x86_movsicc_0_m1"
9200   [(set (match_operand:SI 0 "register_operand" "=r")
9201         (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
9202           (const_int -1)
9203           (const_int 0)))
9204    (clobber (reg:CC 17))]
9205   ""
9206   "sbb{l}\\t%0, %0"
9207   ; Since we don't have the proper number of operands for an alu insn,
9208   ; fill in all the blanks.
9209   [(set_attr "type" "alu")
9210    (set_attr "memory" "none")
9211    (set_attr "imm_disp" "false")
9212    (set_attr "length" "2")])
9213
9214 (define_insn "*movsicc_noc"
9215   [(set (match_operand:SI 0 "register_operand" "=r,r")
9216         (if_then_else:SI (match_operator 1 "no_comparison_operator" 
9217                                 [(reg 17) (const_int 0)])
9218                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
9219                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
9220   "TARGET_CMOVE
9221    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9222   "@
9223    cmov%C1\\t{%2, %0|%0, %2}
9224    cmov%c1\\t{%3, %0|%0, %3}"
9225   [(set_attr "type" "icmov")])
9226
9227 (define_insn "*movsicc_c"
9228   [(set (match_operand:SI 0 "register_operand" "=r,r")
9229         (if_then_else:SI (match_operator 1 "uno_comparison_operator" 
9230                                 [(reg:CC 17) (const_int 0)])
9231                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
9232                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
9233   "TARGET_CMOVE
9234    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9235   "@
9236    cmov%C1\\t{%2, %0|%0, %2}
9237    cmov%c1\\t{%3, %0|%0, %3}"
9238   [(set_attr "type" "icmov")])
9239
9240 (define_expand "movhicc"
9241   [(set (match_operand:HI 0 "register_operand" "")
9242         (if_then_else:HI (match_operand 1 "comparison_operator" "")
9243                          (match_operand:HI 2 "nonimmediate_operand" "")
9244                          (match_operand:HI 3 "nonimmediate_operand" "")))]
9245   "TARGET_CMOVE && TARGET_HIMODE_MATH"
9246   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
9247
9248 (define_insn "*movhicc_noc"
9249   [(set (match_operand:HI 0 "register_operand" "=r,r")
9250         (if_then_else:HI (match_operator 1 "no_comparison_operator" 
9251                                 [(reg 17) (const_int 0)])
9252                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
9253                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
9254   "TARGET_CMOVE
9255    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9256   "@
9257    cmov%C1\\t{%2, %0|%0, %2}
9258    cmov%c1\\t{%3, %0|%0, %3}"
9259   [(set_attr "type" "icmov")])
9260
9261 (define_insn "*movhicc_c"
9262   [(set (match_operand:HI 0 "register_operand" "=r,r")
9263         (if_then_else:HI (match_operator 1 "uno_comparison_operator" 
9264                                 [(reg:CC 17) (const_int 0)])
9265                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
9266                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
9267   "TARGET_CMOVE
9268    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9269   "@
9270    cmov%C1\\t{%2, %0|%0, %2}
9271    cmov%c1\\t{%3, %0|%0, %3}"
9272   [(set_attr "type" "icmov")])
9273
9274 (define_expand "movsfcc"
9275   [(set (match_operand:SF 0 "register_operand" "")
9276         (if_then_else:SF (match_operand 1 "comparison_operator" "")
9277                          (match_operand:SF 2 "register_operand" "")
9278                          (match_operand:SF 3 "register_operand" "")))]
9279   "TARGET_CMOVE"
9280   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
9281
9282 (define_insn "*movsfcc_1"
9283   [(set (match_operand:SF 0 "register_operand" "=f,f")
9284         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
9285                                 [(reg 17) (const_int 0)])
9286                       (match_operand:SF 2 "register_operand" "f,0")
9287                       (match_operand:SF 3 "register_operand" "0,f")))]
9288   "TARGET_CMOVE"
9289   "@
9290    fcmov%F1\\t{%2, %0|%0, %2}
9291    fcmov%f1\\t{%3, %0|%0, %3}"
9292   [(set_attr "type" "fcmov")])
9293
9294 (define_expand "movdfcc"
9295   [(set (match_operand:DF 0 "register_operand" "")
9296         (if_then_else:DF (match_operand 1 "comparison_operator" "")
9297                          (match_operand:DF 2 "register_operand" "")
9298                          (match_operand:DF 3 "register_operand" "")))]
9299   "TARGET_CMOVE"
9300   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
9301
9302 (define_insn "*movdfcc_1"
9303   [(set (match_operand:DF 0 "register_operand" "=f,f")
9304         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
9305                                 [(reg 17) (const_int 0)])
9306                       (match_operand:DF 2 "register_operand" "f,0")
9307                       (match_operand:DF 3 "register_operand" "0,f")))]
9308   "TARGET_CMOVE"
9309   "@
9310    fcmov%F1\\t{%2, %0|%0, %2}
9311    fcmov%f1\\t{%3, %0|%0, %3}"
9312   [(set_attr "type" "fcmov")])
9313
9314 (define_expand "movxfcc"
9315   [(set (match_operand:XF 0 "register_operand" "")
9316         (if_then_else:XF (match_operand 1 "comparison_operator" "")
9317                          (match_operand:XF 2 "register_operand" "")
9318                          (match_operand:XF 3 "register_operand" "")))]
9319   "TARGET_CMOVE"
9320   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
9321
9322 (define_insn "*movxfcc_1"
9323   [(set (match_operand:XF 0 "register_operand" "=f,f")
9324         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
9325                                 [(reg 17) (const_int 0)])
9326                       (match_operand:XF 2 "register_operand" "f,0")
9327                       (match_operand:XF 3 "register_operand" "0,f")))]
9328   "TARGET_CMOVE"
9329   "@
9330    fcmov%F1\\t{%2, %0|%0, %2}
9331    fcmov%f1\\t{%3, %0|%0, %3}"
9332   [(set_attr "type" "fcmov")])
9333 \f
9334 ;; Misc patterns (?)
9335
9336 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
9337 ;; Otherwise there will be nothing to keep
9338 ;; 
9339 ;; [(set (reg ebp) (reg esp))]
9340 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
9341 ;;  (clobber (eflags)]
9342 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
9343 ;;
9344 ;; in proper program order.
9345
9346 (define_insn "pro_epilogue_adjust_stack"
9347   [(set (match_operand:SI 0 "register_operand" "=r,r")
9348         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
9349                  (match_operand:SI 2 "immediate_operand" "i,i")))
9350    (set (match_operand:SI 3 "register_operand" "+r,r")
9351         (match_dup 3))
9352    (clobber (reg:CC 17))]
9353   ""
9354   "*
9355 {
9356   switch (get_attr_type (insn))
9357     {
9358     case TYPE_IMOV:
9359       return \"mov{l}\\t{%1, %0|%0, %1}\";
9360
9361     case TYPE_ALU:
9362       if (GET_CODE (operands[2]) == CONST_INT
9363           && (INTVAL (operands[2]) == 128
9364               || (INTVAL (operands[2]) < 0
9365                   && INTVAL (operands[2]) != -128)))
9366         {
9367           operands[2] = GEN_INT (-INTVAL (operands[2]));
9368           return \"sub{l}\\t{%2, %0|%0, %2}\";
9369         }
9370       return \"add{l}\\t{%2, %0|%0, %2}\";
9371
9372     case TYPE_LEA:
9373       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
9374       return \"lea{l}\\t{%a2, %0|%0, %a2}\";
9375
9376     default:
9377       abort ();
9378     }
9379 }"
9380   [(set (attr "type")
9381         (cond [(eq_attr "alternative" "0")
9382                  (const_string "alu")
9383                (match_operand:SI 2 "const0_operand" "")
9384                  (const_string "imov")
9385               ]
9386               (const_string "lea")))])
9387
9388 (define_insn "allocate_stack_worker"
9389   [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
9390    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
9391    (clobber (match_dup 0))
9392    (clobber (reg:CC 17))]
9393   "TARGET_STACK_PROBE"
9394   "call\\t__alloca"
9395   [(set_attr "type" "multi")
9396    (set_attr "length" "5")])
9397
9398 (define_expand "allocate_stack"
9399   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
9400                    (minus:SI (reg:SI 7)
9401                              (match_operand:SI 1 "general_operand" "")))
9402               (clobber (reg:CC 17))])
9403    (parallel [(set (reg:SI 7)
9404                    (minus:SI (reg:SI 7) (match_dup 1)))
9405               (clobber (reg:CC 17))])]
9406   "TARGET_STACK_PROBE"
9407   "
9408 {
9409 #ifdef CHECK_STACK_LIMIT
9410   if (GET_CODE (operands[1]) == CONST_INT
9411       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
9412     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
9413                            operands[1]));
9414   else 
9415 #endif
9416     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
9417                                                             operands[1])));
9418
9419   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9420   DONE;
9421 }")
9422
9423 (define_expand "exception_receiver"
9424   [(const_int 0)]
9425   "flag_pic"
9426   "
9427 {
9428   load_pic_register ();
9429   DONE;
9430 }")
9431
9432 (define_expand "builtin_setjmp_receiver"
9433   [(label_ref (match_operand 0 "" ""))]
9434   "flag_pic"
9435   "
9436 {
9437   load_pic_register ();
9438   DONE;
9439 }")
9440 \f
9441 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
9442
9443 (define_split
9444   [(set (match_operand 0 "register_operand" "")
9445         (match_operator 3 "promotable_binary_operator"
9446            [(match_operand 1 "register_operand" "")
9447             (match_operand 2 "aligned_operand" "")]))
9448    (clobber (reg:CC 17))]
9449   "! TARGET_PARTIAL_REG_STALL && reload_completed
9450    && ((GET_MODE (operands[0]) == HImode 
9451         && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
9452             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
9453        || (GET_MODE (operands[0]) == QImode 
9454            && (TARGET_PROMOTE_QImode || optimize_size)))"
9455   [(parallel [(set (match_dup 0)
9456                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9457               (clobber (reg:CC 17))])]
9458   "operands[0] = gen_lowpart (SImode, operands[0]);
9459    operands[1] = gen_lowpart (SImode, operands[1]);
9460    if (GET_CODE (operands[3]) != ASHIFT)
9461      operands[2] = gen_lowpart (SImode, operands[2]);
9462    GET_MODE (operands[3]) = SImode;")
9463
9464 (define_split
9465   [(set (reg 17)
9466         (compare (and (match_operand 1 "aligned_operand" "")
9467                       (match_operand 2 "const_int_operand" ""))
9468                  (const_int 0)))
9469    (set (match_operand 0 "register_operand" "")
9470         (and (match_dup 1) (match_dup 2)))]
9471   "! TARGET_PARTIAL_REG_STALL && reload_completed
9472    && ix86_match_ccmode (insn, CCNOmode)
9473    && (GET_MODE (operands[0]) == HImode
9474        || (GET_MODE (operands[0]) == QImode 
9475            && (TARGET_PROMOTE_QImode || optimize_size)))"
9476   [(parallel [(set (reg:CCNO 17)
9477                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
9478                                  (const_int 0)))
9479               (set (match_dup 0)
9480                    (and:SI (match_dup 1) (match_dup 2)))])]
9481   "operands[2]
9482      = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
9483    operands[0] = gen_lowpart (SImode, operands[0]);
9484    operands[1] = gen_lowpart (SImode, operands[1]);")
9485
9486 (define_split
9487   [(set (reg 17)
9488         (compare (and (match_operand 0 "aligned_operand" "")
9489                       (match_operand 1 "const_int_operand" ""))
9490                  (const_int 0)))]
9491   "! TARGET_PARTIAL_REG_STALL && reload_completed
9492    && ix86_match_ccmode (insn, CCNOmode)
9493    && (GET_MODE (operands[0]) == HImode
9494        || (GET_MODE (operands[0]) == QImode 
9495            && (TARGET_PROMOTE_QImode || optimize_size)))"
9496   [(set (reg:CCNO 17)
9497         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
9498                       (const_int 0)))]
9499   "operands[1]
9500      = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
9501    operands[0] = gen_lowpart (SImode, operands[0]);")
9502
9503 (define_split
9504   [(set (match_operand 0 "register_operand" "")
9505         (neg (match_operand 1 "register_operand" "")))
9506    (clobber (reg:CC 17))]
9507   "! TARGET_PARTIAL_REG_STALL && reload_completed
9508    && (GET_MODE (operands[0]) == HImode
9509        || (GET_MODE (operands[0]) == QImode 
9510            && (TARGET_PROMOTE_QImode || optimize_size)))"
9511   [(parallel [(set (match_dup 0)
9512                    (neg:SI (match_dup 1)))
9513               (clobber (reg:CC 17))])]
9514   "operands[0] = gen_lowpart (SImode, operands[0]);
9515    operands[1] = gen_lowpart (SImode, operands[1]);")
9516
9517 (define_split
9518   [(set (match_operand 0 "register_operand" "")
9519         (not (match_operand 1 "register_operand" "")))]
9520   "! TARGET_PARTIAL_REG_STALL && reload_completed
9521    && (GET_MODE (operands[0]) == HImode
9522        || (GET_MODE (operands[0]) == QImode 
9523            && (TARGET_PROMOTE_QImode || optimize_size)))"
9524   [(set (match_dup 0)
9525         (not:SI (match_dup 1)))]
9526   "operands[0] = gen_lowpart (SImode, operands[0]);
9527    operands[1] = gen_lowpart (SImode, operands[1]);")
9528
9529 (define_split 
9530   [(set (match_operand 0 "register_operand" "")
9531         (if_then_else (match_operator 1 "comparison_operator" 
9532                                 [(reg 17) (const_int 0)])
9533                       (match_operand 2 "register_operand" "")
9534                       (match_operand 3 "register_operand" "")))]
9535   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
9536    && (GET_MODE (operands[0]) == HImode
9537        || (GET_MODE (operands[0]) == QImode 
9538            && (TARGET_PROMOTE_QImode || optimize_size)))"
9539   [(set (match_dup 0)
9540         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
9541   "operands[0] = gen_lowpart (SImode, operands[0]);
9542    operands[2] = gen_lowpart (SImode, operands[2]);
9543    operands[3] = gen_lowpart (SImode, operands[3]);")
9544                         
9545 \f
9546 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
9547 ;; transform a complex memory operation into two memory to register operations.
9548
9549 ;; Don't push memory operands
9550 (define_peephole2
9551   [(set (match_operand:SI 0 "push_operand" "")
9552         (match_operand:SI 1 "memory_operand" ""))
9553    (match_scratch:SI 2 "r")]
9554   "! optimize_size && ! TARGET_PUSH_MEMORY"
9555   [(set (match_dup 2) (match_dup 1))
9556    (set (match_dup 0) (match_dup 2))]
9557   "")
9558
9559 ;; We need to handle SFmode only, because DFmode and XFmode is split to
9560 ;; SImode pushes.
9561 (define_peephole2
9562   [(set (match_operand:SF 0 "push_operand" "")
9563         (match_operand:SF 1 "memory_operand" ""))
9564    (match_scratch:SF 2 "r")]
9565   "! optimize_size && ! TARGET_PUSH_MEMORY"
9566   [(set (match_dup 2) (match_dup 1))
9567    (set (match_dup 0) (match_dup 2))]
9568   "")
9569
9570 (define_peephole2
9571   [(set (match_operand:HI 0 "push_operand" "")
9572         (match_operand:HI 1 "memory_operand" ""))
9573    (match_scratch:HI 2 "r")]
9574   "! optimize_size && ! TARGET_PUSH_MEMORY"
9575   [(set (match_dup 2) (match_dup 1))
9576    (set (match_dup 0) (match_dup 2))]
9577   "")
9578
9579 (define_peephole2
9580   [(set (match_operand:QI 0 "push_operand" "")
9581         (match_operand:QI 1 "memory_operand" ""))
9582    (match_scratch:QI 2 "q")]
9583   "! optimize_size && ! TARGET_PUSH_MEMORY"
9584   [(set (match_dup 2) (match_dup 1))
9585    (set (match_dup 0) (match_dup 2))]
9586   "")
9587
9588 ;; Don't move an immediate directly to memory when the instruction
9589 ;; gets too big.
9590 (define_peephole2
9591   [(match_scratch:SI 1 "r")
9592    (set (match_operand:SI 0 "memory_operand" "")
9593         (const_int 0))]
9594   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9595    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9596    && ! TARGET_USE_MOV0
9597    && TARGET_SPLIT_LONG_MOVES"
9598   [(parallel [(set (match_dup 1) (const_int 0))
9599               (clobber (reg:CC 17))])
9600    (set (match_dup 0) (match_dup 1))]
9601   "")
9602
9603 (define_peephole2
9604   [(match_scratch:HI 1 "r")
9605    (set (match_operand:HI 0 "memory_operand" "")
9606         (const_int 0))]
9607   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9608    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9609    && ! TARGET_USE_MOV0
9610    && TARGET_SPLIT_LONG_MOVES"
9611   [(parallel [(set (match_dup 2) (const_int 0))
9612               (clobber (reg:CC 17))])
9613    (set (match_dup 0) (match_dup 1))]
9614   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
9615
9616 (define_peephole2
9617   [(match_scratch:QI 1 "q")
9618    (set (match_operand:QI 0 "memory_operand" "")
9619         (const_int 0))]
9620   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9621    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9622    && ! TARGET_USE_MOV0
9623    && TARGET_SPLIT_LONG_MOVES"
9624   [(parallel [(set (match_dup 2) (const_int 0))
9625               (clobber (reg:CC 17))])
9626    (set (match_dup 0) (match_dup 1))]
9627   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
9628
9629 (define_peephole2
9630   [(match_scratch:SI 2 "r")
9631    (set (match_operand:SI 0 "memory_operand" "")
9632         (match_operand:SI 1 "immediate_operand" ""))]
9633   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9634   && TARGET_SPLIT_LONG_MOVES"
9635   [(set (match_dup 2) (match_dup 1))
9636    (set (match_dup 0) (match_dup 2))]
9637   "")
9638
9639 (define_peephole2
9640   [(match_scratch:HI 2 "r")
9641    (set (match_operand:HI 0 "memory_operand" "")
9642         (match_operand:HI 1 "immediate_operand" ""))]
9643   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9644   && TARGET_SPLIT_LONG_MOVES"
9645   [(set (match_dup 2) (match_dup 1))
9646    (set (match_dup 0) (match_dup 2))]
9647   "")
9648
9649 (define_peephole2
9650   [(match_scratch:QI 2 "q")
9651    (set (match_operand:QI 0 "memory_operand" "")
9652         (match_operand:QI 1 "immediate_operand" ""))]
9653   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9654   && TARGET_SPLIT_LONG_MOVES"
9655   [(set (match_dup 2) (match_dup 1))
9656    (set (match_dup 0) (match_dup 2))]
9657   "")
9658
9659 ;; Don't compare memory with zero, load and use a test instead.
9660 (define_peephole2
9661   [(set (reg 17)
9662         (compare (match_operand:SI 0 "memory_operand" "")
9663                  (const_int 0)))
9664    (match_scratch:SI 3 "r")]
9665   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
9666   [(set (match_dup 3) (match_dup 0))
9667    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
9668   "")
9669
9670 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
9671 ;; Don't split NOTs with a displacement operand, because resulting XOR
9672 ;; will not be pariable anyway.
9673 ;;
9674 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
9675 ;; represented using a modRM byte.  The XOR replacement is long decoded,
9676 ;; so this split helps here as well.
9677 ;;
9678 ;; Note: Can't do this as a regular split because reg_dead_p assumes
9679 ;; resource info is live.
9680
9681 (define_peephole2
9682   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9683         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9684   "!optimize_size
9685    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9686    && ((TARGET_PENTIUM 
9687         && (GET_CODE (operands[0]) != MEM
9688             || !memory_displacement_operand (operands[0], SImode)))
9689        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
9690   [(parallel [(set (match_dup 0)
9691                    (xor:SI (match_dup 1) (const_int -1)))
9692               (clobber (reg:CC 17))])]
9693   "")
9694
9695 (define_peephole2
9696   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9697         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9698   "!optimize_size
9699    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9700    && ((TARGET_PENTIUM 
9701         && (GET_CODE (operands[0]) != MEM
9702             || !memory_displacement_operand (operands[0], HImode)))
9703        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
9704   [(parallel [(set (match_dup 0)
9705                    (xor:HI (match_dup 1) (const_int -1)))
9706               (clobber (reg:CC 17))])]
9707   "")
9708
9709 (define_peephole2
9710   [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
9711         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
9712   "!optimize_size
9713    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9714    && ((TARGET_PENTIUM 
9715         && (GET_CODE (operands[0]) != MEM
9716             || !memory_displacement_operand (operands[0], QImode)))
9717        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
9718   [(parallel [(set (match_dup 0)
9719                    (xor:QI (match_dup 1) (const_int -1)))
9720               (clobber (reg:CC 17))])]
9721   "")
9722
9723 ;; Non pairable "test imm, reg" instructions can be translated to
9724 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
9725 ;; byte opcode instead of two, have a short form for byte operands),
9726 ;; so do it for other CPUs as well.  Given that the value was dead,
9727 ;; this should not create any new dependancies.  Pass on the sub-word
9728 ;; versions if we're concerned about partial register stalls.
9729
9730 (define_peephole2
9731   [(set (reg 17)
9732         (compare (and:SI (match_operand:SI 0 "register_operand" "")
9733                          (match_operand:SI 1 "immediate_operand" ""))
9734                  (const_int 0)))]
9735   "ix86_match_ccmode (insn, CCNOmode)
9736    && (true_regnum (operands[0]) != 0
9737        || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
9738    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9739   [(parallel
9740      [(set (reg:CCNO 17)
9741            (compare:CCNO (and:SI (match_dup 0)
9742                                  (match_dup 1))
9743                          (const_int 0)))
9744       (set (match_dup 0)
9745            (and:SI (match_dup 0) (match_dup 1)))])]
9746   "")
9747
9748 ;; We don't need to handle HImode case, because it will be promoted to SImode
9749 ;; on ! TARGET_PARTIAL_REG_STALL
9750
9751 (define_peephole2
9752   [(set (reg 17)
9753         (compare (and:QI (match_operand:QI 0 "register_operand" "")
9754                          (match_operand:QI 1 "immediate_operand" ""))
9755                  (const_int 0)))]
9756   "! TARGET_PARTIAL_REG_STALL
9757    && ix86_match_ccmode (insn, CCNOmode)
9758    && true_regnum (operands[0]) != 0
9759    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9760   [(parallel
9761      [(set (reg:CCNO 17)
9762            (compare:CCNO (and:QI (match_dup 0)
9763                                  (match_dup 1))
9764                          (const_int 0)))
9765       (set (match_dup 0)
9766            (and:QI (match_dup 0) (match_dup 1)))])]
9767   "")
9768
9769 (define_peephole2
9770   [(set (reg 17)
9771         (compare
9772           (and:SI
9773             (zero_extract:SI
9774               (match_operand 0 "ext_register_operand" "q")
9775               (const_int 8)
9776               (const_int 8))
9777             (match_operand 1 "const_int_operand" "n"))
9778           (const_int 0)))]
9779   "! TARGET_PARTIAL_REG_STALL
9780    && ix86_match_ccmode (insn, CCNOmode)
9781    && true_regnum (operands[0]) != 0
9782    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9783   [(parallel [(set (reg:CCNO 17)
9784                    (compare:CCNO
9785                        (and:SI
9786                          (zero_extract:SI
9787                          (match_dup 0)
9788                          (const_int 8)
9789                          (const_int 8))
9790                         (match_dup 1))
9791                    (const_int 0)))
9792               (set (zero_extract:SI (match_dup 0)
9793                                     (const_int 8)
9794                                     (const_int 8))
9795                    (and:SI 
9796                      (zero_extract:SI
9797                        (match_dup 0)
9798                        (const_int 8)
9799                        (const_int 8))
9800                      (match_dup 1)))])]
9801   "")
9802
9803 ;; Don't do logical operations with memory inputs.
9804 (define_peephole2
9805   [(match_scratch:SI 2 "r")
9806    (parallel [(set (match_operand:SI 0 "register_operand" "")
9807                    (match_operator:SI 3 "arith_or_logical_operator"
9808                      [(match_dup 0)
9809                       (match_operand:SI 1 "memory_operand" "")]))
9810               (clobber (reg:CC 17))])]
9811   "! optimize_size && ! TARGET_READ_MODIFY"
9812   [(set (match_dup 2) (match_dup 1))
9813    (parallel [(set (match_dup 0)
9814                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
9815               (clobber (reg:CC 17))])]
9816   "")
9817
9818 (define_peephole2
9819   [(match_scratch:SI 2 "r")
9820    (parallel [(set (match_operand:SI 0 "register_operand" "")
9821                    (match_operator:SI 3 "arith_or_logical_operator"
9822                      [(match_operand:SI 1 "memory_operand" "")
9823                       (match_dup 0)]))
9824               (clobber (reg:CC 17))])]
9825   "! optimize_size && ! TARGET_READ_MODIFY"
9826   [(set (match_dup 2) (match_dup 1))
9827    (parallel [(set (match_dup 0)
9828                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
9829               (clobber (reg:CC 17))])]
9830   "")
9831
9832 ; Don't do logical operations with memory outputs
9833 ;
9834 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
9835 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
9836 ; the same decoder scheduling characteristics as the original.
9837
9838 (define_peephole2
9839   [(match_scratch:SI 2 "r")
9840    (parallel [(set (match_operand:SI 0 "memory_operand" "")
9841                    (match_operator:SI 3 "arith_or_logical_operator"
9842                      [(match_dup 0)
9843                       (match_operand:SI 1 "nonmemory_operand" "")]))
9844               (clobber (reg:CC 17))])]
9845   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
9846   [(set (match_dup 2) (match_dup 0))
9847    (parallel [(set (match_dup 2)
9848                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
9849               (clobber (reg:CC 17))])
9850    (set (match_dup 0) (match_dup 2))]
9851   "")
9852
9853 (define_peephole2
9854   [(match_scratch:SI 2 "r")
9855    (parallel [(set (match_operand:SI 0 "memory_operand" "")
9856                    (match_operator:SI 3 "arith_or_logical_operator"
9857                      [(match_operand:SI 1 "nonmemory_operand" "")
9858                       (match_dup 0)]))
9859               (clobber (reg:CC 17))])]
9860   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
9861   [(set (match_dup 2) (match_dup 0))
9862    (parallel [(set (match_dup 2)
9863                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9864               (clobber (reg:CC 17))])
9865    (set (match_dup 0) (match_dup 2))]
9866   "")
9867
9868 ;; Attempt to always use XOR for zeroing registers.
9869 (define_peephole2
9870   [(set (match_operand 0 "register_operand" "")
9871         (const_int 0))]
9872   "(GET_MODE (operands[0]) == QImode
9873     || GET_MODE (operands[0]) == HImode
9874     || GET_MODE (operands[0]) == SImode)
9875    && (! TARGET_USE_MOV0 || optimize_size)
9876    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
9877   [(parallel [(set (match_dup 0) (const_int 0))
9878               (clobber (reg:CC 17))])]
9879   "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
9880
9881 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
9882 (define_peephole2
9883   [(set (match_operand 0 "register_operand" "")
9884         (const_int -1))]
9885   "(GET_MODE (operands[0]) == HImode
9886     || GET_MODE (operands[0]) == SImode)
9887    && (optimize_size || TARGET_PENTIUM)
9888    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
9889   [(parallel [(set (match_dup 0) (const_int -1))
9890               (clobber (reg:CC 17))])]
9891   "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
9892
9893 ;; Attempt to convert simple leas to adds. These can be created by
9894 ;; move expanders.
9895 (define_peephole2
9896   [(set (match_operand:SI 0 "register_operand" "")
9897         (plus:SI (match_dup 0)
9898                  (match_operand:SI 1 "nonmemory_operand" "")))]
9899   "reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
9900   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
9901               (clobber (reg:CC 17))])]
9902   "")
9903
9904 (define_peephole2
9905   [(set (match_operand:SI 0 "register_operand" "")
9906         (mult:SI (match_dup 0)
9907                  (match_operand:SI 1 "immediate_operand" "")))]
9908   "reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
9909   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
9910               (clobber (reg:CC 17))])]
9911   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
9912
9913 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
9914 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
9915 ;; many CPUs it is also faster, since special hardware to avoid esp
9916 ;; dependancies is present.
9917
9918 ;; While some of these converisons may be done using splitters, we use peepholes
9919 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
9920
9921 ;; Convert prologue esp substractions to push.
9922 ;; We need register to push.  In order to keep verify_flow_info happy we have
9923 ;; two choices
9924 ;; - use scratch and clobber it in order to avoid dependencies
9925 ;; - use already live register
9926 ;; We can't use the second way right now, since there is no reliable way how to
9927 ;; verify that given register is live.  First choice will also most likely in
9928 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
9929 ;; call clobbered registers are dead.  We may want to use base pointer as an
9930 ;; alternative when no register is available later.
9931
9932 (define_peephole2
9933   [(match_scratch:SI 0 "r")
9934    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
9935               (set (reg:SI 6) (reg:SI 6))
9936               (clobber (reg:CC 17))])]
9937   "optimize_size || !TARGET_SUB_ESP_4"
9938   [(clobber (match_dup 0))
9939    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
9940               (set (reg:SI 6) (reg:SI 6))])])
9941
9942 (define_peephole2
9943   [(match_scratch:SI 0 "r")
9944    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
9945               (set (reg:SI 6) (reg:SI 6))
9946               (clobber (reg:CC 17))])]
9947   "optimize_size || !TARGET_SUB_ESP_8"
9948   [(clobber (match_dup 0))
9949    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
9950    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
9951               (set (reg:SI 6) (reg:SI 6))])])
9952
9953 ;; Convert esp substractions to push.
9954 (define_peephole2
9955   [(match_scratch:SI 0 "r")
9956    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
9957               (clobber (reg:CC 17))])]
9958   "optimize_size || !TARGET_SUB_ESP_4"
9959   [(clobber (match_dup 0))
9960    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
9961
9962 (define_peephole2
9963   [(match_scratch:SI 0 "r")
9964    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
9965               (clobber (reg:CC 17))])]
9966   "optimize_size || !TARGET_SUB_ESP_8"
9967   [(clobber (match_dup 0))
9968    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
9969    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
9970
9971 ;; Convert epilogue deallocator to pop.
9972 (define_peephole2
9973   [(match_scratch:SI 0 "r")
9974    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
9975               (set (reg:SI 6) (reg:SI 6))
9976               (clobber (reg:CC 17))])]
9977   "optimize_size || !TARGET_ADD_ESP_4"
9978   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
9979               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
9980               (set (reg:SI 6) (reg:SI 6))])]
9981   "")
9982
9983 ;; Two pops case is tricky, since pop causes dependency on destination register.
9984 ;; We use two registers if available.
9985 (define_peephole2
9986   [(match_scratch:SI 0 "r")
9987    (match_scratch:SI 1 "r")
9988    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
9989               (set (reg:SI 6) (reg:SI 6))
9990               (clobber (reg:CC 17))])]
9991   "optimize_size || !TARGET_ADD_ESP_8"
9992   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
9993               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
9994               (set (reg:SI 6) (reg:SI 6))])
9995    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
9996               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
9997   "")
9998
9999 (define_peephole2
10000   [(match_scratch:SI 0 "r")
10001    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10002               (set (reg:SI 6) (reg:SI 6))
10003               (clobber (reg:CC 17))])]
10004   "optimize_size"
10005   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10006               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10007               (set (reg:SI 6) (reg:SI 6))])
10008    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10009               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10010   "")
10011
10012 ;; Convert esp additions to pop.
10013 (define_peephole2
10014   [(match_scratch:SI 0 "r")
10015    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10016               (clobber (reg:CC 17))])]
10017   ""
10018   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10019               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10020   "")
10021
10022 ;; Two pops case is tricky, since pop causes dependency on destination register.
10023 ;; We use two registers if available.
10024 (define_peephole2
10025   [(match_scratch:SI 0 "r")
10026    (match_scratch:SI 1 "r")
10027    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10028               (clobber (reg:CC 17))])]
10029   ""
10030   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10031               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
10032    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
10033               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10034   "")
10035
10036 (define_peephole2
10037   [(match_scratch:SI 0 "r")
10038    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10039               (clobber (reg:CC 17))])]
10040   "optimize_size"
10041   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10042               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
10043    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10044               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10045   "")
10046 \f
10047 ;; Call-value patterns last so that the wildcard operand does not
10048 ;; disrupt insn-recog's switch tables.
10049
10050 (define_insn "*call_value_pop_0"
10051   [(set (match_operand 0 "" "")
10052         (call (match_operand:QI 1 "constant_call_address_operand" "")
10053               (match_operand:SI 2 "" "")))
10054    (set (reg:SI 7) (plus:SI (reg:SI 7)
10055                             (match_operand:SI 4 "immediate_operand" "")))]
10056   ""
10057   "*
10058 {
10059   if (SIBLING_CALL_P (insn))
10060     return \"jmp\\t%P1\";
10061   else
10062     return \"call\\t%P1\";
10063 }"
10064   [(set_attr "type" "callv")])
10065
10066 (define_insn "*call_value_pop_1"
10067   [(set (match_operand 0 "" "")
10068         (call (match_operand:QI 1 "call_insn_operand" "m")
10069               (match_operand:SI 2 "" "")))
10070    (set (reg:SI 7) (plus:SI (reg:SI 7)
10071                             (match_operand:SI 4 "immediate_operand" "i")))]
10072   ""
10073   "*
10074 {
10075   if (constant_call_address_operand (operands[1], QImode))
10076     {
10077       if (SIBLING_CALL_P (insn))
10078         return \"jmp\\t%P1\";
10079       else
10080         return \"call\\t%P1\";
10081     }
10082   operands[1] = XEXP (operands[1], 0);
10083   if (SIBLING_CALL_P (insn))
10084     return \"jmp\\t%*%1\";
10085   else
10086     return \"call\\t%*%1\";
10087 }"
10088   [(set_attr "type" "callv")])
10089
10090 (define_insn "*call_value_0"
10091   [(set (match_operand 0 "" "")
10092         (call (match_operand:QI 1 "constant_call_address_operand" "")
10093               (match_operand:SI 2 "" "")))]
10094   ""
10095   "*
10096 {
10097   if (SIBLING_CALL_P (insn))
10098     return \"jmp\\t%P1\";
10099   else
10100     return \"call\\t%P1\";
10101 }"
10102   [(set_attr "type" "callv")])
10103
10104 (define_insn "*call_value_1"
10105   [(set (match_operand 0 "" "")
10106         (call (match_operand:QI 1 "call_insn_operand" "m")
10107               (match_operand:SI 2 "" "")))]
10108   ""
10109   "*
10110 {
10111   if (constant_call_address_operand (operands[1], QImode))
10112     {
10113       if (SIBLING_CALL_P (insn))
10114         return \"jmp\\t%P1\";
10115       else
10116         return \"call\\t%P1\";
10117     }
10118   operands[1] = XEXP (operands[1], 0);
10119   if (SIBLING_CALL_P (insn))
10120     return \"jmp\\t%*%1\";
10121   else
10122     return \"call\\t%*%1\";
10123 }"
10124   [(set_attr "type" "callv")])